-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
1px line between powerline glyphs #8993
Comments
There isn't a specific place. Those links and this issue are good enough. |
This comment has been minimized.
This comment has been minimized.
I just wanted to share that on 1.13.10983.0 with Windows 10 19043.1645 (21H1) and with |
What fixed it for me, as a AMD GPU user, was disabling VSR(Virtual Super Resolution) and Integer Scaling. Both settings can be found on AMD SOFTWARE. Hope it helps. |
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 ✅
@zadjii-msft - this looks like its back (or maybe it never went away...) on the right side only, though: |
@kaysond We use the so called "glyph advance width" of the character "0" to determine the width of the cells in the terminal. That value might not always match powerline glyphs exactly (down to the pixel), because many such fonts aren't designed perfectly either. I would definitely recommend trying out the latest version of your font first. Maybe it got improved already? But if you open the {
"profiles":
{
"defaults":
{
"font":
{
"face": "...",
"cellWidth": "10px"
}
},
},
} You'll have to experiment a little bit what value works best for you. The setting works just like CSS units so you can also use a relative value like |
I tried the latest version of the font from nerdfonts, and it didn't help. Presumably since the glyphs are added programmatically, they'd be the same width... I could be wrong though - how would I test this?
That doesn't really work - looks like the default is 9px; if I change it down to 8px, it compresses everything else in the terminal prompt, ruining the rest of the look. Seems fractional values aren't possible (I was wondering if it's a resolution thing) |
So I did some digging, and this is definitely a rendering issue. The glyphs themselves are exactly the same width. You can see the source here:
I tried two different nerdfonts: Ubuntu Mono and Roboto Mono. These should both have the exact same glyph. Depending on the font size and the font, the issue appears or goes away:
Given that this is the case, and that the font size matters and the problem only happens on one direction, I wonder if there's some kind of rounding/flooring error when the glyph is being scaled... |
Our terminal doesn't allow proportional font rendering (just like most other terminals), but Nerd Fonts are not "perfectly" monospace, visually speaking. They would need manual hinting to work correctly here. You can verify our renderer's behavior with Microsoft's reference text renderer "VisualTrueType" (VTT). In theory it should match it exactly (after pressing Alt+G / enabling GASP in VTT). I've tested it with the NF (non-Mono) variant and the latest version 3.0.2 and the result looks immediately exactly like what you're reporting: It's the same 21px tall as in your screenshot, has the same single, dark pixel at the bottom, and shows that the right border has been anti-aliased in the same, unfortunate way: It's tinted blue in this case, but with your current foreground color of Do you have a proposal what we could do better here? |
@lhecker - this is a cool tool, thanks! I tried to match your setup with ClearType settings (I did turn on GASP mode) and while it's not exacty the same, it seems to be close enough in terms of dimensions... Btw, I'm using Knowing nothing about font rendering, here are my observations:
The most interesting thing to my eye, though, is that the space between the vertical blue lines, which I've marked, is always10px. I'm guessing maybe that's the glyph width? If you look down a column, you'll see that all those glyphs line up very nicely. Even with the anti-aliasing, if a 10px wide column were used, corresponding to those lines, and the glyphs were rendered and positioned as in VTT, there would be no gaps in the rendering between powerline glyphs, right? |
Bump. @lhecker @zadjii-msft can you reopen this? Based on the above I don't think it's resolved. |
@kaysond I'm sorry, I forgot to respond last time.
That's the advance width. It indicates how much the "cursor" moves when writing that glyph. For monospace fonts the advance width is usually always the same for all glyphs, but of course that's not a strict requirement. Glyphs might also be wider than the advance width. That's especially true for cursive/italic text. When you mix in font fallback however, almost no monospace text ends up being strictly monospace. (But Windows Terminal forces glyphs into a monospace grid.) That width is not measured in pixels, but rather in "font design units". The header of each .ttf file includes a "units per em" (UPM) field, which indicates how many units result in 1em. Usually that value is 2048, but 1000 or similar are also common. All values in .ttf are expressed in "font design units". The advance width for Consolas for instance is 1126 and it has an UPM of 2048, which results in an advance width of about 0.55em. At a font size of 20pt, this results in an advance width of pretty much exactly 1126 / 2048 * 20 = 11pt. Ubuntu Mono NF has an advance width of 500 and a UPM of 1000 (= 10pt).
Yep, there would be no gaps. (But there would be slightly visible red/blue lines when ClearType is used, because the glyphs do slightly overlap. This comment shows them: #8993 (comment)) But the problem is that you set VTT to a font size of 20pt at a display resolution of 72 DPI (the default in VTT). 72 DPI is the resolution of "pt" but if you want "px" at 100% display scale you need to choose 96 DPI (150% display scale = 144 DPI, and so on). For instance, the 0 glyph at 13pt and 96 DPI looks like this (17ppem, 8 dx (width), 11 dy (height), I forgot to enable GASP mode - it will look a bit different then): The problem is the advance width there, which is "8 43/64 dx", or 8.67px. We currently round that value to the nearest pixel value which is 9px (as you've already found), but you've also said that 8px feels too squished. If we were to support a technique called "subpixel positioning", we could probably solve the issue. It's a common technique in modern font rendering where you (for instance) have 3x the horizontal resolution for glyph positions. For every glyph you prepare 3 versions with a 0/3rd, 1/3rd and 2/3rd pixel offset. This will make them all 3 look a tiny bit different. So, if you encounter a glyph coordinate like 8.67px you choose the 3rd variant with the 0.67px offset. If you have 15 "0"s in a row you're at coordinate 15*8.67 = 130px, so you chose the 1st variant. |
@lhecker Thank you very much for the deep dive! Makes sense to me. |
Encountered the same. With any font size except 10pt, JetBrains Mono Nerd Font seems fine. But at size 10 specifically, the glyph e0b6 has this line next to it whenever text follows. Unfortunately, size 9 feels way too small, and size 11 too big. I'm wondering if there is any solution to fix this specifically for size 10? Closest solution I've found is to set the font size to 10.5. |
FYI #16729 was merged recently and it fixes this issue fundamentally. It will ship in 1.21 in a few months. In the meantime, you can find the Canary version that has it already here: https://aka.ms/terminal-canary-installer If you find any issues with that version, please don't comment here, but open a new issue instead (a simple screenshot of the issue will be sufficient). |
Environment
Steps to reproduce
Install any nerdfont
Set up anything that uses powerline glyphs (in my case, bobthefish plugin on fish shell)
Expected behavior
Clean rendering/placement of powerline glyphs (see Color schemes @ https://github.com/oh-my-fish/theme-bobthefish)
Actual behavior
The glyphs have a 1px line of the adjacent glyph color
Funnily enough, you can see the same thing in the powerline setup tutorial: https://docs.microsoft.com/en-us/windows/terminal/tutorials/powerline-setup
Setting
"useAcrylic": true
and"acrylicOpacity" : 0.899
fixes one glyph, but not the other:I've tried a variety of rendering options, fonts, sizes, etc, but none completely solve the problem. I also have the Windows text scaling set to 100%. I am on a high-dpi monitor (2560x1440) though.
I searched around and found #3626 #455 #4930 #633 #6669 but those aren't quite what's happening here. Sorry if I missed a dupe.
The text was updated successfully, but these errors were encountered: