Investigate alternative ways to handle box drawing/block elements #8133

Closed
opened 2026-01-31 01:21:33 +00:00 by claunia · 38 comments
Owner

Originally created by @DHowett-MSFT on GitHub (May 14, 2020).

Originally assigned to: @lhecker on GitHub.

There've been some concerns about how we scale glyphs in the Box Drawing character block.

Other terminal emulators do interesting things:

  • Gnome-terminal uses little 5x5 bitmaps and stretches them to fill the entire cell (shout-out to @egmontkob for telling me this!)
    • This results in pixel perfect lines and shading.
  • [Other popular terminal] uses line-drawing primitives at the graphics layer to mimic box drawing and rect-filling primitives with opacity to mimic block elements
    • This also results in pixel-perfect lines and cool blended shading glyphs.

We chose not to do these things for v1.0 because we learned that certain fonts (monofur is a good one) have their own unique styles for box drawing and block elements that we wanted to preserve.

Proposed solution

  • Add a setting for "Let Windows Terminal handle block / powerline drawing"
    • This is a per-profile setting. profile::compatibility.builtinBlockDrawing
    • When enabled, Terminal will manually draw box-drawing and powerline glyphs, replacing the glyph from the font
    • Enable this by default
      • Obviously, users will be able to opt out
      • This will give us the benefit of getting PL glyphs even for fonts without them!
    • We should probably start with a few of the glyphs as higher pri:
      image
      • Green: Definitely, in v0
      • Yellow: okay probably yea
      • Orange: meh
      • red: probably too expensive (engineering wise)
      • white: I can't imagine we'll actually need to draw these
  • Add a secondary setting for "Replace filled rectangles with transparent glyphs"
    • Only enable if compatibility.builtinBlockDrawing is enabled
Originally created by @DHowett-MSFT on GitHub (May 14, 2020). Originally assigned to: @lhecker on GitHub. There've been some concerns about how we scale glyphs in the [Box Drawing character block](https://www.unicode.org/charts/PDF/U2500.pdf). Other terminal emulators do interesting things: * Gnome-terminal uses little 5x5 bitmaps and stretches them to fill the entire cell (shout-out to @egmontkob for telling me this!) * This results in pixel perfect lines and shading. * [Other popular terminal] uses line-drawing primitives at the graphics layer to mimic box drawing and rect-filling primitives with opacity to mimic block elements * This also results in pixel-perfect lines _and_ cool blended shading glyphs. We chose not to do these things _for v1.0_ because we learned that certain fonts (monofur is a good one) have their own unique styles for box drawing and block elements that we wanted to preserve. ## Proposed solution * Add a setting for "Let Windows Terminal handle block / powerline drawing" * This is a per-profile setting. `profile::compatibility.builtinBlockDrawing` * When enabled, Terminal will manually draw box-drawing and powerline glyphs, _replacing the glyph from the font_ * Enable this by default * Obviously, users will be able to opt out * This will give us the benefit of getting PL glyphs even for fonts without them! * We should probably start with a few of the glyphs as higher pri: ![image](https://github.com/microsoft/terminal/assets/18356694/6c2759b9-6b20-48c3-9357-79060eef35b1) * Green: Definitely, in v0 * Yellow: okay probably yea * Orange: meh * red: probably too expensive (engineering wise) * white: I can't imagine we'll actually need to draw these * Add a secondary setting for "Replace filled rectangles with transparent glyphs" * Only enable if `compatibility.builtinBlockDrawing` is enabled ### Links * [ ] #6161 Block-drawing glyphs aren't antialiased * [ ] #3498 may affect how we choose to draw these "pixel-perfect" glyphs. * [ ] #7260
Author
Owner

@benc-uk commented on GitHub (May 14, 2020):

The shaded/hatched boxes now look really bad since the last update.
A lot of themes like Powerlevel10k use these

This is my prompt now in Windows Terminal
image

This is what it should look like (In VS Code)
image

@benc-uk commented on GitHub (May 14, 2020): The shaded/hatched boxes now look really bad since the last update. A lot of themes like Powerlevel10k use these This is my prompt now in Windows Terminal ![image](https://user-images.githubusercontent.com/14982936/81902673-6fc62880-95b8-11ea-992d-6fabcab1f224.png) This is what it should look like (In VS Code) ![image](https://user-images.githubusercontent.com/14982936/81902636-5d4bef00-95b8-11ea-8ee1-abdd64e25d41.png)
Author
Owner

@DHowett-MSFT commented on GitHub (May 14, 2020):

yikes.

@DHowett-MSFT commented on GitHub (May 14, 2020): _yikes._
Author
Owner

@DHowett-MSFT commented on GitHub (May 14, 2020):

Though, that looks like Cascadia Code. The version released yesterday with the new metrics works properly with Terminal. You may need to update.

@DHowett-MSFT commented on GitHub (May 14, 2020): Though, that looks like Cascadia Code. The version released yesterday with the new metrics works properly with Terminal. You may need to update.
Author
Owner

@benc-uk commented on GitHub (May 14, 2020):

Hi, I just updated to CascadiaCode_2004.30, and I didn't see any difference :(
image

Weirdly if I set my font size to 15, the shading disappears altogether, and at font size 19 it looks perfect, but that's just too huge to use!

@benc-uk commented on GitHub (May 14, 2020): Hi, I just updated to CascadiaCode_2004.30, and I didn't see any difference :( ![image](https://user-images.githubusercontent.com/14982936/81904677-7f933c00-95bb-11ea-853f-d2ff63552880.png) Weirdly if I set my font size to 15, the shading **disappears altogether**, and at font size 19 it looks perfect, but that's just too huge to use!
Author
Owner

@benc-uk commented on GitHub (May 14, 2020):

Some further tests with Cascadia Code.

At font size 14 the line elements are super thin and the curved corner lacks any antialiasing/smoothing
image

At font size 13 they look much better
image

@benc-uk commented on GitHub (May 14, 2020): Some further tests with Cascadia Code. At font size 14 the line elements are super thin and the curved corner lacks any antialiasing/smoothing ![image](https://user-images.githubusercontent.com/14982936/81905793-27f5d000-95bd-11ea-9af7-7d51faec0e5d.png) At font size 13 they look much better ![image](https://user-images.githubusercontent.com/14982936/81905770-1ad8e100-95bd-11ea-9684-aacc2f89066b.png)
Author
Owner

@mdtauk commented on GitHub (May 14, 2020):

I think if this is added, it should be behind a setting. Something like

☑ Let Windows Terminal handle block character drawing

Cascadia code has an interesting approach to the character of some of it's Block Characters, and other fonts will also. That character is lost by Terminal doing it itself - so it should be optional IMO

@mdtauk commented on GitHub (May 14, 2020): I think if this is added, it should be behind a setting. Something like **☑ Let Windows Terminal handle block character drawing** Cascadia code has an interesting approach to the character of some of it's Block Characters, and other fonts will also. That character is lost by Terminal doing it itself - so it should be optional IMO
Author
Owner

@ionut-botizan commented on GitHub (May 19, 2020):

I'd really love to see those "rect-filling primitives with opacity" make it into the Windows Terminal:

  1. top left - Windows Terminal with Fira Code 12px
  2. bottom left - Windows Terminal with Fira Code 15 px
  3. top right - [Other popular terminal] with Fira Code 12px

(the filling char I'm using is $([char]0x2592) or "░")

image

Obviously, the best looking one is the one on the right and the second best one is the one with the 15px font size. Sadly, 15px is way too big, so I'm stuck with the ugly looking one for now. 🙂

@ionut-botizan commented on GitHub (May 19, 2020): I'd really love to see those "rect-filling primitives with opacity" make it into the Windows Terminal: 1. top left - Windows Terminal with Fira Code 12px 2. bottom left - Windows Terminal with Fira Code 15 px 3. top right - [Other popular terminal] with Fira Code 12px (the filling char I'm using is `$([char]0x2592)` or "░") ![image](https://user-images.githubusercontent.com/408501/82290209-088ce780-99af-11ea-890d-6685243d772b.png) Obviously, the best looking one is the one on the right and the second best one is the one with the 15px font size. Sadly, 15px is way too big, so I'm stuck with the ugly looking one for now. 🙂
Author
Owner

@DHowett commented on GitHub (May 19, 2020):

(that's a nice prompt line)

@DHowett commented on GitHub (May 19, 2020): (that's a nice prompt line)
Author
Owner

@j4james commented on GitHub (May 19, 2020):

Obviously, the best looking one is the one on the right and the second best one is the one with the 15px font size. Sadly, 15px is way too big, so I'm stuck with the ugly looking one for now. 🙂

I understand the desire for a better rendering of theses characters, but the terminal on the right is just displaying a solid block in a different color as far I can see. If that's what you want, you should really be using U+2588. U+2591 to U+2593 are distinct characters where the cell is filled with a pattern to produce a degree of shading. The latest version of Unicode has even added an inverse version of U+2592. That would be impossible to distinguish from U+2592 if you're just renderning them as solid blocks.

@j4james commented on GitHub (May 19, 2020): > Obviously, the best looking one is the one on the right and the second best one is the one with the 15px font size. Sadly, 15px is way too big, so I'm stuck with the ugly looking one for now. 🙂 I understand the desire for a better rendering of theses characters, but the terminal on the right is just displaying a solid block in a different color as far I can see. If that's what you want, you should really be using U+2588. U+2591 to U+2593 are distinct characters where the cell is filled with a pattern to produce a degree of shading. The latest version of Unicode has even added an inverse version of U+2592. That would be impossible to distinguish from U+2592 if you're just renderning them as solid blocks.
Author
Owner

@egmontkob commented on GitHub (May 19, 2020):

the terminal on the right is just displaying a solid block in a different color

This is what VTE does, too. It's a heavily debated feature/bug: https://bugzilla.gnome.org/show_bug.cgi?id=778122.

@egmontkob commented on GitHub (May 19, 2020): > the terminal on the right is just displaying a solid block in a different color This is what VTE does, too. It's a heavily debated feature/bug: https://bugzilla.gnome.org/show_bug.cgi?id=778122.
Author
Owner

@j4james commented on GitHub (May 19, 2020):

I can understand choosing to render those characters with a solid block as a compromise solution if that's the best we can do - it's probably better than the scaling artifacts. But it is a compromise - it's not what we should be aiming for as the ideal solution.

For me the ideal would be appropriately designed fill patterns, possibly scaled to account for the DPI (as long as the pattern can be retained). Those fill patterns would then be rendered to align with the coordinate system, rather than the character boundaries, so they can repeat perfectly across a range of cells.

It's possible something like that just isn't feasible for performance reasons, or API limitations, but I think we should at least consider ways to do this correctly before resorting to a compromise solution.

Edit: I've just read the whole VTE thread and I see you were proposing the same sort of thing there.

@j4james commented on GitHub (May 19, 2020): I can understand choosing to render those characters with a solid block as a compromise solution if that's the best we can do - it's probably better than the scaling artifacts. But it is a compromise - it's not what we should be aiming for as the ideal solution. For me the ideal would be appropriately designed fill patterns, possibly scaled to account for the DPI (as long as the pattern can be retained). Those fill patterns would then be rendered to align with the coordinate system, rather than the character boundaries, so they can repeat perfectly across a range of cells. It's possible something like that just isn't feasible for performance reasons, or API limitations, but I think we should at least consider ways to do this correctly before resorting to a compromise solution. Edit: I've just read the whole VTE thread and I see you were proposing the same sort of thing there.
Author
Owner

@egmontkob commented on GitHub (May 19, 2020):

Yup this also occurred to us at VTE, but this method also has a drawback: as these glyphs scroll, the pattern changes. This is again hardly the expected user behavior.

This is clearly a field with contradicting requirements, and thus no single perfect solution. A compromise has to be made somewhere. It's really hard to decide or argue which solution is better or worse.

@egmontkob commented on GitHub (May 19, 2020): Yup this also occurred to us at VTE, but this method also has a drawback: as these glyphs scroll, the pattern changes. This is again hardly the expected user behavior. This is clearly a field with contradicting requirements, and thus no single perfect solution. A compromise has to be made somewhere. It's really hard to decide or argue which solution is better or worse.
Author
Owner

@PhMajerus commented on GitHub (May 24, 2020):

There seems to be something wrong with both how Windows Terminal 1.0.1401.0 scales glyphs for shading blocks and how these glyphs appear in Cascadia Code 2005.15.

And because I know you like nice test files, here's a new one for this issue (I probably spent way too long on this one) : https://github.com/PhMajerus/ANSI-art/blob/master/Sonic%20Green%20Hill%20Zone.ans
(Edit: Added a 256 colors one so you don't have to stare at the base 16 colors all the time : https://github.com/PhMajerus/ANSI-art/blob/master/Sonic%20Green%20Hill%20Zone%20(256%20colors).ans )

Windows Terminal seems to scale shading blocks without anti-aliasing, to me it looks like a nearest neighbor that loses some pixels in pattern that depend on single pixel regularity:

Windows Terminal with Consolas, see the irregular patterns in the clouds:
image

Windows Terminal with Cascadia Code, see how shading blocks do not fill their cells heights (clouds and waterfall):
image

It seems that the issue is only at some font sizes, as if the terminal is zoomed a bit, the shading blocks are then rendered properly (I believe this is equivalent to fontSize:13):
image

Conhost with Cascadia Code, see how all block drawing and shading blocks heights are wrong:
image

And same file in conhost with Consolas as a reference of how it is supposed to look:
image

@PhMajerus commented on GitHub (May 24, 2020): There seems to be something wrong with both how Windows Terminal 1.0.1401.0 scales glyphs for shading blocks and how these glyphs appear in Cascadia Code 2005.15. And because I know you like nice test files, here's a new one for this issue (I probably spent way too long on this one) : https://github.com/PhMajerus/ANSI-art/blob/master/Sonic%20Green%20Hill%20Zone.ans (Edit: Added a 256 colors one so you don't have to stare at the base 16 colors all the time : https://github.com/PhMajerus/ANSI-art/blob/master/Sonic%20Green%20Hill%20Zone%20(256%20colors).ans ) Windows Terminal seems to scale shading blocks without anti-aliasing, to me it looks like a nearest neighbor that loses some pixels in pattern that depend on single pixel regularity: Windows Terminal with Consolas, see the irregular patterns in the clouds: ![image](https://user-images.githubusercontent.com/25664275/82763592-350a8e80-9e09-11ea-88c3-f960e10c8c05.png) Windows Terminal with Cascadia Code, see how shading blocks do not fill their cells heights (clouds and waterfall): ![image](https://user-images.githubusercontent.com/25664275/82763676-af3b1300-9e09-11ea-9bc5-b2bd46a8cffc.png) It seems that the issue is only at some font sizes, as if the terminal is zoomed a bit, the shading blocks are then rendered properly (I believe this is equivalent to fontSize:13): ![image](https://user-images.githubusercontent.com/25664275/82765334-2e364880-9e16-11ea-89ca-25210128aeaa.png) Conhost with Cascadia Code, see how all block drawing and shading blocks heights are wrong: ![image](https://user-images.githubusercontent.com/25664275/82763719-ed383700-9e09-11ea-862c-8cabc7d6c45e.png) And same file in conhost with Consolas as a reference of how it is supposed to look: ![image](https://user-images.githubusercontent.com/25664275/82763765-38eae080-9e0a-11ea-80a5-35c979f7f30c.png)
Author
Owner

@mdtauk commented on GitHub (May 24, 2020):

What would the consensus be with the halftone filled shapes? Should they be rendered with some kind of crosshatching like with fonts, or just an opacity fill?

This is if Terminal was to offer the ability to "handle" or "override" the box drawing.

@mdtauk commented on GitHub (May 24, 2020): What would the consensus be with the halftone filled shapes? Should they be rendered with some kind of crosshatching like with fonts, or just an opacity fill? This is if Terminal was to offer the ability to "handle" or "override" the box drawing.
Author
Owner

@j4james commented on GitHub (May 25, 2020):

What would the consensus be with the halftone filled shapes? Should they be rendered with some kind of crosshatching like with fonts, or just an opacity fill?

I don't understand why anyone would ask for the patterned characters to rendered with an opacity fill, unless there was no other option. You can already get an opacity effect - with much finer control - just using the existing block characters with appropriate colors. All you'd be doing is preventing other people from using patterns, which seems a spiteful sort of thing to want.

I could understand if the current rendering was the best we could achieve, and the question was do you prefer that or an opacity fill. But we haven't even tried other rendering techniques yet.

@j4james commented on GitHub (May 25, 2020): > What would the consensus be with the halftone filled shapes? Should they be rendered with some kind of crosshatching like with fonts, or just an opacity fill? I don't understand why anyone would ask for the patterned characters to rendered with an opacity fill, unless there was no other option. You can already get an opacity effect - with much finer control - just using the existing block characters with appropriate colors. All you'd be doing is preventing other people from using patterns, which seems a spiteful sort of thing to want. I could understand if the current rendering was the best we could achieve, and the question was do you prefer _that_ or an opacity fill. But we haven't even tried other rendering techniques yet.
Author
Owner

@mdtauk commented on GitHub (May 25, 2020):

What would the consensus be with the halftone filled shapes? Should they be rendered with some kind of crosshatching like with fonts, or just an opacity fill?

I don't understand why anyone would ask for the patterned characters to rendered with an opacity fill, unless there was no other option. You can already get an opacity effect - with much finer control - just using the existing block characters with appropriate colors. All you'd be doing is preventing other people from using patterns, which seems a spiteful sort of thing to want.

I could understand if the current rendering was the best we could achieve, and the question was do you prefer that or an opacity fill. But we haven't even tried other rendering techniques yet.

My thinking is that the intention behind those characters would originally have substituted for a gradient or semi-transparent element. Back with 16 colours or monochrome terminals.

Some fonts use half-tone dots/squares, others (like Cascadia) use a diagonal hatching getting progressively heavier/darker.

If Windows Terminal is going to include an option to override the font's characters, and to get proper horizontal, vertical, and diagonal connecting glyphs - as well as rounded corners etc - there should perhaps be a neutral design approach, so they don't stand out as odd amongst different fonts.

So do you go for the intent behind the characters, a simulation of different shades - by actually using shades of the glyph colour - or pick a particular approach and run with it?

@mdtauk commented on GitHub (May 25, 2020): > > What would the consensus be with the halftone filled shapes? Should they be rendered with some kind of crosshatching like with fonts, or just an opacity fill? > > I don't understand why anyone would ask for the patterned characters to rendered with an opacity fill, unless there was no other option. You can already get an opacity effect - with much finer control - just using the existing block characters with appropriate colors. All you'd be doing is preventing other people from using patterns, which seems a spiteful sort of thing to want. > > I could understand if the current rendering was the best we could achieve, and the question was do you prefer _that_ or an opacity fill. But we haven't even tried other rendering techniques yet. > My thinking is that the intention behind those characters would originally have substituted for a gradient or semi-transparent element. Back with 16 colours or monochrome terminals. Some fonts use half-tone dots/squares, others (like Cascadia) use a diagonal hatching getting progressively heavier/darker. If Windows Terminal is going to include an option to override the font's characters, and to get proper horizontal, vertical, and diagonal connecting glyphs - as well as rounded corners etc - there should perhaps be a neutral design approach, so they don't stand out as odd amongst different fonts. So do you go for the intent behind the characters, a simulation of different shades - by actually using shades of the glyph colour - or pick a particular approach and run with it?
Author
Owner

@PhMajerus commented on GitHub (May 25, 2020):

I guess it started as a way to do intermediate colors and gradients, but over the years shading blocks got used for their texturing features as well. Now that we can use 256 and RGB colors, the pattern they provide is more interesting than the color mix.
I might agree that for a built-in rendering of blocks and lines not based on a font, a pure color mix could work as a default, but it is critical to get the ability to use patterns provided by fonts. And once fonts with blocks work correctly, why would you want to return to a built-in rendering?

Even if some fonts work properly and other don't, the ability to configure a set of fonts for different blocks of Unicode characters, which will probably be required to properly handle a mix of latin, asian (CJK) and technical characters (Math, powerline, nerd font,...), would make it possible to simply specify a font that works for the block and line characters while using other fonts for everything else, so no other fallback required.
See my suggestion at https://github.com/microsoft/terminal/issues/455#issuecomment-621735991

@PhMajerus commented on GitHub (May 25, 2020): I guess it started as a way to do intermediate colors and gradients, but over the years shading blocks got used for their texturing features as well. Now that we can use 256 and RGB colors, the pattern they provide is more interesting than the color mix. I might agree that for a built-in rendering of blocks and lines not based on a font, a pure color mix could work as a default, but it is critical to get the ability to use patterns provided by fonts. And once fonts with blocks work correctly, why would you want to return to a built-in rendering? Even if some fonts work properly and other don't, the ability to configure a set of fonts for different blocks of Unicode characters, which will probably be required to properly handle a mix of latin, asian (CJK) and technical characters (Math, powerline, nerd font,...), would make it possible to simply specify a font that works for the block and line characters while using other fonts for everything else, so no other fallback required. See my suggestion at https://github.com/microsoft/terminal/issues/455#issuecomment-621735991
Author
Owner

@j4james commented on GitHub (May 25, 2020):

I guess it started as a way to do intermediate colors and gradients

Did it though? I haven't seen any evidence to suggest that was the only intended usage. People use patterned fills in graphing all the time, both with and without the availability of RGB colors. It's just as reasonable to suppose that these patterned characters were intended to be used as actual patterns. Emulating gradients is just one of the things you could do with those patterns.

And note that the comments on U+2592 in the Unicode standard actually includes the description "speckles fill, dotted fill". The reference glyphs, while not prescriptive, are clearly rendered with patterned fills.

Even ignoring all of the above, I've yet to hear anyone explain how they would render U+1FB90 with an opacity fill. It's the exact same shade as U+2592, only the pixels are "inverted". How do we achieve that with a solid block?

simply specify a font that works for the block and line characters while using other fonts for everything else, so no other fallback required.

In theory I like this idea, but that assumes there are fonts capable of rendering all of these patterns and things like diagonals (e.g. see #6161) while still lining up perfectly with different font sizes and DPI scaling. However, if it could be achieved with a well-designed font, that would be preferable I think.

@j4james commented on GitHub (May 25, 2020): > I guess it started as a way to do intermediate colors and gradients Did it though? I haven't seen any evidence to suggest that was the only intended usage. People use patterned fills in graphing all the time, both with and without the availability of RGB colors. It's just as reasonable to suppose that these patterned characters were intended to be used as actual patterns. Emulating gradients is just one of the things you could do with those patterns. And note that the comments on `U+2592` in the Unicode standard actually includes the description "speckles fill, dotted fill". The reference glyphs, while not prescriptive, are clearly rendered with patterned fills. Even ignoring all of the above, I've yet to hear anyone explain how they would render `U+1FB90` with an opacity fill. It's the exact same shade as `U+2592`, only the pixels are "inverted". How do we achieve that with a solid block? > simply specify a font that works for the block and line characters while using other fonts for everything else, so no other fallback required. In theory I like this idea, but that assumes there are fonts capable of rendering all of these patterns and things like diagonals (e.g. see #6161) while still lining up perfectly with different font sizes and DPI scaling. However, if it _could_ be achieved with a well-designed font, that would be preferable I think.
Author
Owner

@egmontkob commented on GitHub (May 25, 2020):

I've yet to hear anyone explain how they would render U+1FB90 with an opacity fill. It's the exact same shade as U+2592, only the pixels are "inverted". How do we achieve that with a solid block?

In VTE these two are manually rendered as exactly the same solid blocks.

I'm not saying it's great, nor that it's my preferred approach, nor that this is what WT should do. But these are not the first pair of homoglyphs, so I don't think this approach is inherently wrong either.

@egmontkob commented on GitHub (May 25, 2020): > I've yet to hear anyone explain how they would render U+1FB90 with an opacity fill. It's the exact same shade as U+2592, only the pixels are "inverted". How do we achieve that with a solid block? In VTE these two are manually rendered as exactly the same solid blocks. I'm not saying it's great, nor that it's my preferred approach, nor that this is what WT should do. But these are not the first pair of homoglyphs, so I don't think this approach is inherently wrong either.
Author
Owner

@mdtauk commented on GitHub (May 25, 2020):

Even if some fonts work properly and other don't, the ability to configure a set of fonts for different blocks of Unicode characters, which will probably be required to properly handle a mix of latin, asian (CJK) and technical characters (Math, powerline, nerd font,...), would make it possible to simply specify a font that works for the block and line characters while using other fonts for everything else, so no other fallback required.

Sure you could include a font specific for the block drawing elements, but that leaves the same problem when elements like Linespacing is added. Which would break any font's approach to block drawing.

As linespacing is increased, Terminal drawn block elements, could still be flush so as not to break UIs

@mdtauk commented on GitHub (May 25, 2020): > Even if some fonts work properly and other don't, the ability to configure a set of fonts for different blocks of Unicode characters, which will probably be required to properly handle a mix of latin, asian (CJK) and technical characters (Math, powerline, nerd font,...), would make it possible to simply specify a font that works for the block and line characters while using other fonts for everything else, so no other fallback required. > Sure you could include a font specific for the block drawing elements, but that leaves the same problem when elements like Linespacing is added. Which would break any font's approach to block drawing. As linespacing is increased, Terminal drawn block elements, could still be flush so as not to break UIs
Author
Owner

@ionut-botizan commented on GitHub (May 25, 2020):

I guess it started as a way to do intermediate colors and gradients

Did it though?

Yes, it did.

A number of existing national and vendors standards, including IBM PC Code Page 437, contain a number of characters intended to enable a simple kind of character cell graphic by filling some fraction of each cell, or by filling each character cell by some degree of shading.
[...]
Also included are a series of shades based on one-quarter shadings.

^ Page 92 in "The Unicode Standard, Version 1", published in 1991 (page 19 in the online PDF).


The only reason they appear as they do are technological limitations of the past, where the number of colors you could use was limited so font designers had to resort to even older artistic techniques (some of them centuries old) to emulate shadows, such as:

  • Ben Day dots - Consolas
  • Hatching - Cascadia Code
  • Halftone - Source Code Pro

image


And note that the comments on U+2592 in the Unicode standard actually includes the description "speckles fill, dotted fill".

Funny that you mention that, because the very same comments are very clear about the names of the character (they are spelled in caps - very hard to miss) and the percentage of shading each represents:

  • 2591 ░ LIGHT SHADE
    • 25%
  • 2592 ▒ MEDIUM SHADE
    • = speckles fill, dotted fill
    • 50%
    • used in mapping to cp949
    • 1FB90 🮐 inverse medium shade
  • 2593 ▓ DARK SHADE
    • 75%

Lastly, since you're so fond of the 1FB90 character, how would you see it rendered?
Because, simply inverting the pixels obviously wouldn't work and here are a couple examples why:

  • Courier New - inverting the pixels would result in the same pattern as 2593 - Dark Shade 75% which I think you'll agree isn't the inverse of 50%
    image
  • Cascadia - inverting the pixels would result in a even darker shade than Dark Shade 75%; obviously not the opposite of 50%
    image
  • Fira Code - inverting the pixels would result in the exact same pattern so how's it any different than a solid block with 50% transparency?
    image

So, how would you define that character in such a way that it would convey the same idea across a huge variety of fonts?

P.S.: I am in favor of having both implementations because, even though I mostly prefer the solid block with alpha mixing approach, there are exceptions where I might use the other such as if I were to use a font like Source Code Pro which has a beautiful halftone implementation of these characters.

P.S. 2: Your suggestion to use a solid block with a custom color is not valid as, in the vast majority of the cases, the user does not control the output of 3rd party programs/scripts.

@ionut-botizan commented on GitHub (May 25, 2020): > > I guess it started as a way to do intermediate colors and gradients > > Did it though? Yes, it did. > A number of existing national and vendors standards, including IBM PC Code Page 437, contain a number of characters intended to enable a simple kind of character cell graphic by filling some fraction of each cell, or by **filling** each character cell **by some degree of shading**. > [...] > Also included are a series of shades based on one-quarter shadings. ^ _Page 92 in ["The Unicode Standard, Version 1"](http://www.unicode.org/versions/Unicode1.0.0/), published in 1991 (page 19 in [the online PDF](https://www.unicode.org/versions/Unicode1.0.0/ch03_2.pdf))._ --- The only reason they appear as they do are technological limitations of the past, where the number of colors you could use was limited so font designers had to resort to even older artistic techniques (some of them centuries old) to emulate shadows, such as: * Ben Day dots - Consolas * Hatching - Cascadia Code * Halftone - Source Code Pro ![image](https://user-images.githubusercontent.com/408501/82842294-a3bb1b00-9ee1-11ea-9ff8-a13b3e9e7d8a.png) --- > And note that the comments on U+2592 in the Unicode standard actually includes the description "speckles fill, dotted fill". Funny that you mention that, because [the very same comments](https://www.unicode.org/charts/nameslist/n_2580.html) are very clear about the names of the character (they are spelled in caps - very hard to miss) and the percentage of shading each represents: * `2591` ░ LIGHT SHADE * 25% * `2592` ▒ MEDIUM SHADE * = speckles fill, dotted fill * 50% * used in mapping to cp949 * → `1FB90` 🮐 inverse medium shade * `2593` ▓ DARK SHADE * 75% --- Lastly, since you're so fond of the `1FB90` character, how would **you** see it rendered? Because, simply inverting the pixels obviously wouldn't work and here are a couple examples why: * Courier New - inverting the pixels would result in the same pattern as `2593 - Dark Shade 75%` which I think you'll agree isn't the inverse of 50% ![image](https://user-images.githubusercontent.com/408501/82843708-a9672f80-9ee6-11ea-8c6b-e89f06054bf0.png) * Cascadia - inverting the pixels would result in a even darker shade than `Dark Shade 75%`; obviously not the opposite of 50% ![image](https://user-images.githubusercontent.com/408501/82843733-c3a10d80-9ee6-11ea-8c1a-df9b55f58bee.png) * Fira Code - inverting the pixels would result in the exact same pattern so how's it any different than a solid block with 50% transparency? ![image](https://user-images.githubusercontent.com/408501/82843646-73c24680-9ee6-11ea-9019-2b1dc9222a3b.png) So, how would you define that character in such a way that it would convey the same idea across a huge variety of fonts? P.S.: I am in favor of having **both** implementations because, even though I mostly prefer the solid block with alpha mixing approach, there are exceptions where I might use the other such as if I were to use a font like `Source Code Pro` which has a beautiful halftone implementation of these characters. P.S. 2: Your suggestion to use a solid block with a custom color is not valid as, in the vast majority of the cases, the user does not control the output of 3rd party programs/scripts.
Author
Owner

@j4james commented on GitHub (May 25, 2020):

A number of existing national and vendors standards, including IBM PC Code Page 437, contain a number of characters intended to enable a simple kind of character cell graphic by filling some fraction of each cell, or by filling each character cell by some degree of shading.

I'm not sure how you're reading that to mean the characters were intended to be used for gradients? The intent was "a simple kind of character cell graphic". The method that was used to achieve that was "by filling each character cell by some degree of shading". If you want to know what "some degree of shading" means in that context, you simply have to look at the glyphs as they were rendered at the time, which funnily enough is exactly what the reference glyphs in the Unicode standard look like.

Lastly, since you're so fond of the 1FB90 character, how would you see it rendered?
Because, simply inverting the pixels obviously wouldn't work and here are a couple examples why:

If it doesn't work with a particular font, that's simply because the font is incorrect. By definition, if the pattern the font was rendering produced a 50% shade, then the inverse of that pattern would still produce a 50% shade.

If you want an example of how those characters could be rendered, again you can simply look at the reference glyphs in the Unicode standard.

image

Side by side, those two pattern produce the effect of subtle dividing line where they meet, I'm not saying it's a huge loss if we couldn't render them differently. The point I was making was that the standard clearly intended them to be different, and a solid block can't possibly achieve that.

But as I've said before, if that's the best we can do, then that's fine. I just don't think it's ideal.

@j4james commented on GitHub (May 25, 2020): > A number of existing national and vendors standards, including IBM PC Code Page 437, contain a number of characters intended to enable a simple kind of character cell graphic by filling some fraction of each cell, or by filling each character cell by some degree of shading. I'm not sure how you're reading that to mean the characters were intended to be used for gradients? The intent was "a simple kind of character cell graphic". The method that was used to achieve that was "by filling each character cell by some degree of shading". If you want to know what "some degree of shading" means in that context, you simply have to look at the glyphs as they were rendered at the time, which funnily enough is exactly what the reference glyphs in the Unicode standard look like. > Lastly, since you're so fond of the `1FB90` character, how would you see it rendered? Because, simply inverting the pixels obviously wouldn't work and here are a couple examples why: If it doesn't work with a particular font, that's simply because the font is incorrect. By definition, if the pattern the font was rendering produced a 50% shade, then the inverse of that pattern would still produce a 50% shade. If you want an example of how those characters could be rendered, again you can simply look at the reference glyphs in the Unicode standard. ![image](https://user-images.githubusercontent.com/4181424/82845405-538d8a00-9edc-11ea-9c7c-0430199c5d31.png) Side by side, those two pattern produce the effect of subtle dividing line where they meet, I'm not saying it's a huge loss if we couldn't render them differently. The point I was making was that the standard clearly intended them to be different, and a solid block can't possibly achieve that. But as I've said before, if that's the best we can do, then that's fine. I just don't think it's ideal.
Author
Owner

@mdtauk commented on GitHub (May 26, 2020):

So instead of using a pattern to simulate a shade of the glyph's colour - just change the opacity of the glyph/cell itself

image

@mdtauk commented on GitHub (May 26, 2020): So instead of using a pattern to simulate a shade of the glyph's colour - just change the opacity of the glyph/cell itself ![image](https://user-images.githubusercontent.com/7389110/82847599-edf2cb00-9ee6-11ea-9841-8a78547b4261.png)
Author
Owner

@reli-msft commented on GitHub (Jun 2, 2020):

Could we just measure the line height from the box-drawing characters?
An idea may be rasterize the U+2588 FULL BLOCK character and use the pixel rows that have pure black pixels to determine the height of cells. Using this way can be used to handle fonts that is either hinted or unhinted.

@reli-msft commented on GitHub (Jun 2, 2020): Could we just measure the line height from the box-drawing characters? An idea may be rasterize the U+2588 `FULL BLOCK` character and **use the pixel rows that have pure black pixels** to determine the height of cells. Using this way can be used to handle fonts that is either hinted or unhinted.
Author
Owner

@oising commented on GitHub (Jun 7, 2020):

Reminder that we already have a good alignment/render test file in the repo:

https://github.com/microsoft/terminal/blob/master/doc/reference/UTF8-torture-test.txt

image

(font: Fira Code)

@oising commented on GitHub (Jun 7, 2020): Reminder that we already have a good alignment/render test file in the repo: https://github.com/microsoft/terminal/blob/master/doc/reference/UTF8-torture-test.txt ![image](https://user-images.githubusercontent.com/1844001/83977158-4ef9a600-a8cc-11ea-9095-dba21066aae8.png) (font: Fira Code)
Author
Owner

@tycho commented on GitHub (Jun 30, 2020):

So instead of using a pattern to simulate a shade of the glyph's colour - just change the opacity of the glyph/cell itself

image

I really like the third row in this image. It matches the behavior of MinTTY:

mintty_dbZEXIglNI

@tycho commented on GitHub (Jun 30, 2020): > So instead of using a pattern to simulate a shade of the glyph's colour - just change the opacity of the glyph/cell itself > > ![image](https://user-images.githubusercontent.com/7389110/82847599-edf2cb00-9ee6-11ea-9841-8a78547b4261.png) I really like the third row in this image. It matches the behavior of MinTTY: ![mintty_dbZEXIglNI](https://user-images.githubusercontent.com/29616/86171333-67c33900-bad1-11ea-9c99-5deebd5f6dec.png)
Author
Owner

@rbeesley commented on GitHub (Jul 3, 2020):

I'm glad I found this issue. I've been trying to track down how to describe the problem I'm seeing and I think this is it.

image

At first I had characters I was using for box art to disappear on only some rows, so I tried to write a script to isolate that. I thought it was maybe related to the ANSI ESC sequence I was using, so I experimented with that, but the test script was failing in different ways. I thought maybe the problem was the font, so I changed the font in conhost.exe by opening cmd.exe, and it worked there.

In summary, Lucida Console on both conhost.exe and Windows Terminal works. Cascadia Code on conhost.exe works. Cascadia Code on Windows Terminal sometimes doesn't draw, sometimes. I actually had for awhile where Medium Shade \u2592 was sometimes drawing on consecutive lines, would not draw for one, and then would resume drawing on another. Trying to isolate that specific case in another script, it stopped reproducing and instead only Dark Shade \u2593 was drawing.

Frustrating to chase down.

@rbeesley commented on GitHub (Jul 3, 2020): I'm glad I found this issue. I've been trying to track down how to describe the problem I'm seeing and I think this is it. ![image](https://user-images.githubusercontent.com/3703112/86437048-7c155a80-bcb8-11ea-8d35-640717583907.png) At first I had characters I was using for box art to disappear on only some rows, so I tried to write a script to isolate that. I thought it was maybe related to the ANSI ESC sequence I was using, so I experimented with that, but the test script was failing in different ways. I thought maybe the problem was the font, so I changed the font in conhost.exe by opening cmd.exe, and it worked there. In summary, Lucida Console on both conhost.exe and Windows Terminal works. Cascadia Code on conhost.exe works. Cascadia Code on Windows Terminal sometimes doesn't draw, sometimes. I actually had for awhile where Medium Shade \u2592 was sometimes drawing on consecutive lines, would not draw for one, and then would resume drawing on another. Trying to isolate that specific case in another script, it stopped reproducing and instead only Dark Shade \u2593 was drawing. Frustrating to chase down.
Author
Owner

@rbeesley commented on GitHub (Jul 3, 2020):

Side by side, those two pattern produce the effect of subtle dividing line where they meet, I'm not saying it's a huge loss if we couldn't render them differently. The point I was making was that the standard clearly intended them to be different, and a solid block can't possibly achieve that.

I don't think you should count out that there could still be a seam created when certain characters are rendered next to each other. It'd take a little work to achieve the right result, but at least for horizontal alignment couldn't this be handled with a ligature? W3C is looking at how to handle vertical text alignment in Unicode, so presumably there will also be a need for vertical ligatures.

@rbeesley commented on GitHub (Jul 3, 2020): > Side by side, those two pattern produce the effect of subtle dividing line where they meet, I'm not saying it's a huge loss if we couldn't render them differently. The point I was making was that the standard clearly intended them to be different, and a solid block can't possibly achieve that. I don't think you should count out that there could still be a seam created when certain characters are rendered next to each other. It'd take a little work to achieve the right result, but at least for horizontal alignment couldn't this be handled with a ligature? W3C is looking at how to handle [vertical text alignment ](https://github.com/w3c/i18n-activity/issues/596) in Unicode, so presumably there will also be a need for vertical ligatures.
Author
Owner

@Qix- commented on GitHub (Mar 21, 2021):

For the box drawing characters, I see this too.

This is what it's supposed to look like (captured from Asciiflow):

image

but depending on the zoom level, either the horizontal lines are missing, the vertical lines or missing, or the horizontal lines have noticeable gaps between them.

image

image

image

The font has to be considerably larger (too large for me to comfortably work with) in order to see all of them properly, and even then the horizontal lines have gaps.

image

@Qix- commented on GitHub (Mar 21, 2021): For the box drawing characters, I see this too. This is what it's supposed to look like (captured from Asciiflow): ![image](https://user-images.githubusercontent.com/885648/111890111-df7e1e80-89e6-11eb-80a4-f1fd5852b315.png) but depending on the zoom level, either the horizontal lines are missing, the vertical lines or missing, or the horizontal lines have noticeable gaps between them. ![image](https://user-images.githubusercontent.com/885648/111890124-f6bd0c00-89e6-11eb-869a-c8ea396c1f89.png) ![image](https://user-images.githubusercontent.com/885648/111890133-fde41a00-89e6-11eb-84ff-ab300c9f02b3.png) ![image](https://user-images.githubusercontent.com/885648/111890140-08061880-89e7-11eb-8675-dd0f4356a3c7.png) The font has to be considerably larger (too large for me to comfortably work with) in order to see all of them properly, and even then the horizontal lines have gaps. ![image](https://user-images.githubusercontent.com/885648/111890156-223ff680-89e7-11eb-92d3-ad78f86dd632.png)
Author
Owner

@rbeesley commented on GitHub (Mar 26, 2021):

Strangely I stumbled into this defect again. Earlier in this thread I mentioned that Windows Terminal was sometimes not rendering glyphs, but I now have additional details. New information for repro, which might not matter when this defect is addressed, I'm seeing the missing glyphs at specific font sizes; 1, 2, 3, and 15. The glyphs have rendering problems at other font sizes as well, but it seems like the shade boxes aren't shown at 15 and might have been a condition when I ran into this 9 months ago.

@rbeesley commented on GitHub (Mar 26, 2021): Strangely I stumbled into this defect again. Earlier in this thread I mentioned that Windows Terminal was sometimes not rendering glyphs, but I now have additional details. New information for repro, which might not matter when this defect is addressed, I'm seeing the missing glyphs at specific font sizes; 1, 2, 3, and 15. The glyphs have rendering problems at other font sizes as well, but it seems like the shade boxes aren't shown at 15 and might have been a condition when I ran into this 9 months ago.
Author
Owner

@felipecrs commented on GitHub (Jun 14, 2022):

I would report the following:

image

But I'm a little confused whether it's covered by this issue already or not. Any clue?

@felipecrs commented on GitHub (Jun 14, 2022): I would report the following: ![image](https://user-images.githubusercontent.com/29582865/173688125-36216c61-b7e4-40bf-9478-902d87092697.png) But I'm a little confused whether it's covered by this issue already or not. Any clue?
Author
Owner

@DHowett commented on GitHub (Jun 14, 2022):

@felipecrs what you're reporting seems to be another case of #6864, the cause of which is explained in https://github.com/microsoft/terminal/issues/6864#issuecomment-659544490. :)

@DHowett commented on GitHub (Jun 14, 2022): @felipecrs what you're reporting seems to be another case of #6864, the cause of which is explained in https://github.com/microsoft/terminal/issues/6864#issuecomment-659544490. :)
Author
Owner

@he3als commented on GitHub (Jun 15, 2022):

Are there any ways to fix this issue at the moment? I am using the default font.

@he3als commented on GitHub (Jun 15, 2022): Are there any ways to fix this issue at the moment? I am using the default font.
Author
Owner

@jaminthorns commented on GitHub (Feb 3, 2023):

I'd really love to see this implemented as it can provide a much nicer TUI experience. If this ends up happening, it'd be great if the Powerline symbols were implemented as well (don't forget the slants/triangles!).

Here's some further reading for anyone interested in how some other terminals handle rendering of box drawing characters:

@jaminthorns commented on GitHub (Feb 3, 2023): I'd really love to see this implemented as it can provide a much nicer TUI experience. If this ends up happening, it'd be great if the Powerline symbols were implemented as well (don't forget the [slants/triangles](https://code.visualstudio.com/updates/v1_75#_powerline-triangle-and-diagonal-line-custom-glyphs)!). Here's some further reading for anyone interested in how some other terminals handle rendering of box drawing characters: - Xterm.js (used by VS Code and many other projects) - Issue: https://github.com/xtermjs/xterm.js/issues/2409 - Implementation: https://github.com/xtermjs/xterm.js/blob/master/src/browser/renderer/shared/CustomGlyphs.ts - Kitty terminal: https://github.com/kovidgoyal/kitty/blob/master/kitty/fonts/box_drawing.py - `st` terminal: https://st.suckless.org/patches/boxdraw/
Author
Owner

@ShelpAm commented on GitHub (Dec 4, 2023):

So, if there is any solution to the problem? There are annoying gaps between characters.

@ShelpAm commented on GitHub (Dec 4, 2023): So, if there is any solution to the problem? There are annoying gaps between characters.
Author
Owner

@Mystic8b commented on GitHub (Feb 6, 2024):

Well, #16664 was closed, so I'm writing here.
I and tens of thousands of other people use zsh + p10k. And AtlasEngine breaks the prompt in p10k by cutting off the bottom pixel or something like that. In the last release you enabled Atlas by default, which means you are sure there are no problems, but this is not the case! This is a huge problem. Pay attention to this. Thank you!

Old engine:
image

New engine:
image

And no, it's not a font problem, I've tried every variation of Nerd Fonts. I asked the developer of p10k, he also said that it was a terminal problem.


  • Terminal ver: 1.19.10302.0
  • ZSH
  • p10k (rainbow theme)
  • MesloLGS Nerd Font (from p10k repo)
  • 9pt font size
  • 100% scale screen (1080p 2560x1080)
@Mystic8b commented on GitHub (Feb 6, 2024): Well, #16664 was closed, so I'm writing here. I and tens of thousands of other people use zsh + p10k. And AtlasEngine breaks the prompt in p10k by cutting off the bottom pixel or something like that. In the last release you enabled Atlas by default, which means you are sure there are no problems, but this is not the case! This is a huge problem. Pay attention to this. Thank you! Old engine: ![image](https://github.com/microsoft/terminal/assets/35394377/346cfc4e-44f8-4f93-ba1f-bf2f650415b3) New engine: ![image](https://github.com/microsoft/terminal/assets/35394377/d4baebf0-3c73-4801-9523-e34607256e11) And no, it's not a font problem, I've tried every variation of Nerd Fonts. I asked the developer of p10k, he also [said](https://github.com/romkatv/powerlevel10k/issues/2557#issuecomment-1925877628) that it was a terminal problem. --- - Terminal ver: 1.19.10302.0 - ZSH - p10k (rainbow theme) - MesloLGS Nerd Font (from p10k repo) - 9pt font size - 100% scale screen (1080p 2560x1080)
Author
Owner

@zadjii-msft commented on GitHub (Feb 6, 2024):

To loop back on this: I've updated the OP with our plan-of-record. Adding a setting to force Terminal to draw pixel-perfect glyphs seems like the right plan. It'll be a setting, so users can always feel free to opt-out if they want the glyph from their font instead.

Adding the setting itself is trivial.
Figuring out how to get the renderer to draw each of those shapes: that's a little more work. Hence why we've tried to group them by priority.

We'd probably appreciate help here, if someone's willing to figure out the glyph drawing 😉

@zadjii-msft commented on GitHub (Feb 6, 2024): To loop back on this: I've updated the OP with our plan-of-record. Adding a setting to force Terminal to draw pixel-perfect glyphs seems like the right plan. It'll be a setting, so users can always feel free to opt-out if they want the glyph from their font instead. Adding the setting itself is trivial. Figuring out how to get the renderer to draw each of those shapes: that's a little more work. Hence why we've tried to group them by priority. We'd probably appreciate help here, if someone's willing to figure out the glyph drawing 😉
Author
Owner

@lhecker commented on GitHub (Feb 16, 2024):

Box drawing and block element glyphs are done:
image

Powerline glyphs are much more difficult to do, because a user's font may not have powerline glyphs in the first place and so there's nothing to MapCharacters to. This made me realize that I need to do my own MapCharacters in addition to what DWrite is doing and that will take some time because it requires additional work on the text renderer - work that isn't trivial unfortunately since DWrite is a little unwieldy.

@lhecker commented on GitHub (Feb 16, 2024): Box drawing and block element glyphs are done: ![image](https://github.com/microsoft/terminal/assets/2256941/27724ef2-db95-438b-b75c-e6c810f50aa6) Powerline glyphs are much more difficult to do, because a user's font may not have powerline glyphs in the first place and so there's nothing to `MapCharacters` to. This made me realize that I need to do my own `MapCharacters` in addition to what DWrite is doing and that will take some time because it requires additional work on the text renderer - work that isn't trivial unfortunately since DWrite is a little unwieldy.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#8133