terminal: Investigate alternative ways to handle box drawing/block elements

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

Links

  • #6161 Block-drawing glyphs aren’t antialiased
  • #3498 may affect how we choose to draw these “pixel-perfect” glyphs.
  • #7260

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 2
  • Comments: 38 (9 by maintainers)

Commits related to this issue

Most upvoted comments

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.

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 😉

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. 🙂

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)

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.