-
Notifications
You must be signed in to change notification settings - Fork 8.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Some Unicode characters(U+2714) displayed incorrectly #12537
Comments
Note that As a point of reference, here's what those characters look like in a bunch of different terminals. My test case is: From left to right, top to bottom: XTerm, Gnome Terminal, MLTerm, WezTerm, Contour, St, Alacritty, and Kitty. Gnome Terminal might be letting That said, the Atlas renderer clearly does a better job of dealing with fonts like this than the DX renderer. However, I don't think we should ever expect it to take up two columns. |
If you look closely you can see how the glyph is cut off on both sides in the experimental rendering engine ("AtlasEngine"). Not because I want to make the size of Emojis/symbols inconsistent like in the screenshot, but rather because some scripts only have proportional fonts, which require to be downsized to still be readable (most noticeable with Hebrew on a standard Windows setup). Maybe I can come up with something clever to find a good middle ground... |
I believe there's a bug here in how terminal is handling emoji. Many emoji also exist as characters:
Anyway ... there's a lot. The point is: Unicode has variation selectors, and they were made part of the emoji spec in 2018. Bottom line: Here's the current list of all the variation sequences for 14.0.0. I believe that Windows Terminal is doing the wrong thing here.
It appears to me that terminal is trying to render the emoji in a single character space whenever there's no variation selector. I think this should not be done -- but if you were going to do it, surely you should only do it when it's the "text" variation, and not when the variation is unspecified?! I, for one, can live with always rendering emoji --as far as I know, no fixed-width font has characters for these anyway-- but making them small when the selector is missing is absolutely a bug. For what it's worth, a concrete example. Here's what happens in the terminal: When I copy/paste that from Terminal into github, Github renders it properly. The first is rendered as a character. The second is an emoji. The third one is rendered as a character in code blocks, and an emoji elsewhere (except for the face, hmmmm).
|
BTW I did this just recently in #13549, which will be part of v1.16.
Hmm we're feeding the U+FE0E straight to Direct2D to draw it and I was hoping it would just do the correct thing automatically. I'll check with them whether there's anything we can do differently to fix that.
I believe this is because of what @j4james said:
Additionally, if you notice any weird whitespace gaps around Emojis: That's because of #8000 and I'm currently working on fixing that. 🙂 |
I suppose they are. As I noted earlier, the fonts we're all using don't have these characters in them, usually, because the characters don't fit in a single cell -- that is, they're totally indecipherable when scaled down. I'm concerned about this:
I'm not sure about that one ... downsizing emoji to fit in a single character cell is not the right move, in my opinion. isn't that going to result in the super-tiny examples above (the third character in the each row of the screenshot)? I'm not clear, guess I'll have to wait and see -- because if the only options are "shrink" it to one character or "stretch" it to two wide, I think emoji are going to end up uniformly hideous 😉 |
The downsizing I implemented is at least somewhat better at this than our current approach. We don't want to let glyphs overlap rows for performance and correctness reasons (at the moment, because overlapping glyphs are anything but trivial) and so shrinking large glyphs is an okay-ish and simple solution. For instance this string is about 1.5 rows tall: ⟨င်္က္ကျြွှေို့်ာှီ့ၤဲံ့းႍ⟩ (As explained before the extra whitespace is because we assign at least 1 cell to each code point we process. Since that string has 27 code points it's also 27 cells wide. As part of #8000 this situation will be improved though.) With scaling in general being ultimately necessary, scaling Emojis is basically just a side effect and not actually intentional. Unrelated to the U+FE0E issue, Emojis like U+2714 (❤) without variant selector are fit into a single cell however, simply because that's exactly what other terminals do too (see #2066). So at least that part won't change any time soon. There's also things like #12512 (comment) which I'll probably try to fix as part of #9999. |
Well, I'll have to see what I can do about making my emojis explicitly use the emoji variant. I have to say though -- it seems that if you're going to force the non-variant to a single cell, you really should force the text variant to a single cell too. That's the one where the author meant for it to be a single text character, right? |
That the text variant takes up two cells hearkens back to an ages-old issue in the console: Combine that with DirectWrite's propensity for emoji-fying it even when the variation selector is present, and you get a double-width full-color heart. Bah. |
FYI, the issue of variant selectors was discussed at length in #8970. It's a more complicated problem than just supporting zero-width glyphs, because you're changing the width of the character after it has already been output, and original width can affect the layout of the page in ways that are irreversible. Last I checked, most terminals just ignored them (at least regarding the width change), which seems the most sensible thing to do. |
This is practically a from scratch rewrite of AtlasEngine. The initial approach used a very classic monospace text renderer, where the viewport is subdivided into cells and each cell is assigned one glyph texture, just like how real terminals used to work. While we knew that it would have problems with overly large glyphs, like those found in less often used languages, we didn't expect the absolutely massive number of fonts that this approach would break. For one, the assumption that monospace fonts are actually mostly monospace has turned out to be a complete lie and we can't force users to use better designed fonts. But more importantly, we can't just design an entire Unicode fallback font collection from scratch where every major glyph is monospace either. This is especially problematic for vertical overhangs which are extremely difficult to handle in a way that outperforms the much simpler alternative approach: Just implementing a bog-standard, modern, quad-based text renderer. Such an approach is both, less code and runs faster due to a less complex CPU-side. The text shaping engine (in our case DirectWrite) has to resolve text into glyph indices anyways, so using them directly for text rendering allows reduces the effort of turning it back into text ranges and hashing those. It's memory overhead is also reduced, because we can now break up long ligatures into their individual glyphs. Especially on AMD APUs I found this approach to run much faster. A list of issues I think are either obsolete (and could be closed) or resolved with this PR in combination with #14255: Closes #6864 Closes #6974 Closes #8993 Closes #9940 Closes #10128 Closes #12537 Closes #13064 Closes #13527 Closes #13662 Closes #13700 Closes #13989 Closes #14022 Closes #14057 Closes #14094 Closes #14098 Closes #14117 Closes #14533 Closes #14877 ## PR Checklist * Enabling software rendering enables D2D mode ✅ * Both D2D and D3D: * Background appears correctly ✅✅ * Text appears correctly * Cascadia Code Regular ✅✅ * Cascadia Code Bold ✅✅ * Cascadia Code Italic ✅✅ * Cascadia Code block chars leave (almost) no gaps ✅✅ * Terminus TTF at 13.5pt leaves no gaps between block chars ✅✅ * ``"`u{e0b2}`u{e0b0}"`` in Fira Code Nerd Font forms a square ✅✅ * Cursor appears correctly * Legacy small/medium/large ✅✅ * Vertical bar ✅✅ * Underscore ✅✅ * Empty box ✅✅ * Full box ✅✅ * Double underscore ✅✅ * Changing the cursor color works ✅✅ * Selection appears correctly ✅✅ * Scrolling in various manners always renders correctly ✅✅ * Changing the text antialising mode works ✅✅ * Semi-transparent backgrounds work ✅✅ * Scroll-zooming the font size works ✅✅ * Double-size characters work ✅✅ * Resizing while text is printing works ✅✅ * DWM `+Heatmap_ShowDirtyRegions` shows that only the cursor region is dirty when it's blinking ✅✅ * D2D * Margins are filled with background color ❌ They're filled with the neighboring's cell background color for convenience, as D2D doesn't support `D3D11_TEXTURE_ADDRESS_BORDER` * D3D * Margins are filled with background color ✅ * Soft fonts work ✅ * Custom shaders enable continous redraw if time constant is used ✅ * Retro shader appears correctly ✅ * Resizing while a custom shader is running works ✅
Windows Terminal version
1.12.10393.0
Windows build number
10.0.19044.0
Other Software
PowerShell 7.2.1
wsl.exe
Steps to reproduce
Using PowerShell 7.2.1 to print some Unicode characters like "✔" and the size is too small
Expected Behavior
In Fluent Terminal
Actual Behavior
In WT
The text was updated successfully, but these errors were encountered: