Faint (ESC[2m) should be configurable to render as light font weight #21286

Closed
opened 2026-01-31 07:38:44 +00:00 by claunia · 7 comments
Owner

Originally created by @PhMajerus on GitHub (Feb 20, 2024).

Option to render faint text as light font weight instead of semitransparency

The ANSI/VT escape sequence ESC[1m can be used to render strong text. It can be rendered as a brighter color, or as a heavier font weight (bold), according to user's preference.
The ANSI/VT escape sequence ESC[2m is used for faint text. It is currently rendered as semi-transparent to make it less contrasted from the background color.
However, faint could also be implemented as a lighter font.

ITU T.416 describes them as the following:

  SGR 1   Bold or increased intensity
  SGR 2   Faint or decreased intensity
  SGR 22  Normal intensity (neither bold nor faint)

The Wikipedia article on ANSI escape code (https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters) even mentions that both bold and faint were originally intended to change the font weight, and have been implemented as brighter and darker/semitransparent colors because of PC hardware limitations.

Proposed technical implementation details

Considering that Aaron included Light and ExtraLight font weights in Cascadia, wouldn't it be nice to let it shine in the Terminal by providing an option to render faint as a lighter font weight instead of a transparency level?

This would work exactly like it does today for Strong/Bold:
image

A second option Faint text style in Text Formatting would let you select None, Light font, Semitransparent colors, or Light font with semitransparent colors as the preferred rendering for ESC[2m.

Originally created by @PhMajerus on GitHub (Feb 20, 2024). # Option to render faint text as light font weight instead of semitransparency The ANSI/VT escape sequence `ESC[1m` can be used to render strong text. It can be rendered as a brighter color, or as a heavier font weight (bold), according to user's preference. The ANSI/VT escape sequence `ESC[2m` is used for faint text. It is currently rendered as semi-transparent to make it less contrasted from the background color. However, faint could also be implemented as a lighter font. ITU T.416 describes them as the following: ``` SGR 1 Bold or increased intensity SGR 2 Faint or decreased intensity SGR 22 Normal intensity (neither bold nor faint) ``` The Wikipedia article on ANSI escape code (https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters) even mentions that both bold and faint were originally intended to change the font weight, and have been implemented as brighter and darker/semitransparent colors because of PC hardware limitations. # Proposed technical implementation details Considering that Aaron included Light and ExtraLight font weights in Cascadia, wouldn't it be nice to let it shine in the Terminal by providing an option to render `faint` as a lighter font weight instead of a transparency level? This would work exactly like it does today for Strong/Bold: ![image](https://github.com/microsoft/terminal/assets/25664275/4a755f28-cdfa-4016-af4f-8481aaaa243d) A second option `Faint text style` in Text Formatting would let you select `None`, `Light font`, `Semitransparent colors`, or `Light font with semitransparent colors` as the preferred rendering for `ESC[2m`.
claunia added the Issue-FeatureArea-RenderingNeeds-Tag-FixProduct-Terminal labels 2026-01-31 07:38:44 +00:00
Author
Owner

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

I think overall, we agree this is a fun idea. I'm sure it's not technically up-to-spec with more traditional terminal emulation, but it does make sense.

We would, however, need to align this with #10577. What does bold+faint look like? It kinda turns this into a whole matrix of {original font flags x intense font style x faint font style x attributes}... So someone would need to write up a mini spec for how that all plays together, but I think it's a good idea

@zadjii-msft commented on GitHub (Feb 21, 2024): I think overall, we agree this is a fun idea. I'm sure it's not technically up-to-spec with more traditional terminal emulation, but it does _make sense_. We would, however, need to align this with #10577. What does bold+faint look like? It kinda turns this into a whole matrix of {original font flags x intense font style x faint font style x attributes}... So someone would need to write up a mini spec for how that all plays together, but I think it's a good idea
Author
Owner

@PhMajerus commented on GitHub (Feb 22, 2024):

It's not how it was done back in the days because this is what their Regular weight characters ROM looked like:
image
Not much opportunity to make a lighter version, and this was on high-end terminals with a finer display than most of the other terminals back then.

Many others had 8×8 pixels characters, but needed two pixels width for vertical bars to display on contemporary CRT displays…
How do you make a light version of a font such as this one:
image
When you need to keep vertical lines 2 pixels wide for them to display at all?

Basically, it seems clear to me the traditional implementation was a technical compromise, and it's ok to reinterpret the intent in modern terminals instead of trying to replicate the limitations we had 50 years ago. We're not just trying to keep legacy terminal apps working as close as they were back then, we're trying to make the modern terminal the best it can be for modern text-based apps.

I know you probably already agree, old terminals didn't exactly have Acrylic translucency and shaders either, I'm just giving more arguments for this feature to make it. 😉

@PhMajerus commented on GitHub (Feb 22, 2024): It's not how it was done back in the days because this is what their Regular weight characters ROM looked like: ![image](https://github.com/microsoft/terminal/assets/25664275/2fc4a6e3-7135-4cbb-964a-00fb38591c58) Not much opportunity to make a lighter version, and this was on high-end terminals with a finer display than most of the other terminals back then. Many others had 8×8 pixels characters, but needed two pixels width for vertical bars to display on contemporary CRT displays… How do you make a light version of a font such as this one: ![image](https://github.com/microsoft/terminal/assets/25664275/da21961c-a6cb-4946-9085-c0fcb2df52db) When you need to keep vertical lines 2 pixels wide for them to display at all? Basically, it seems clear to me the traditional implementation was a technical compromise, and it's ok to reinterpret the intent in modern terminals instead of trying to replicate the limitations we had 50 years ago. We're not just trying to keep legacy terminal apps working as close as they were back then, we're trying to make the modern terminal the best it can be for modern text-based apps. I know you probably already agree, old terminals didn't exactly have Acrylic translucency and shaders either, I'm just giving more arguments for this feature to make it. 😉
Author
Owner

@j4james commented on GitHub (Feb 22, 2024):

There are a couple of points I think are worth correcting.

It is currently rendered as semi-transparent to make it less contrasted from the background color.

Technically what's happening is that the foreground color is rendered at half intensity (or at least an approximation of that), but when reversed (i.e. SGR 7), it's the background color that is affected. And once we support DECBBSM, we would potentially need to dim both the foreground and background colors at the same time.

The Wikipedia article on ANSI escape code even mentions that both bold and faint were originally intended to change the font weight, and have been implemented as brighter and darker/semitransparent colors because of PC hardware limitations.

That Wikipedia article is nonsense. All of the DEC terminals from that era rendered bold with an increased intensity. And DEC representatives were on the committee that wrote the spec (at least the ANSI version), and they were one of the first companies to develop an ANSI-compatible terminal.

The point of the standard was to define a set of escape sequences that could be implemented compatibly across a broad range of devices, which included both cathode ray terminals as well as printers. So when they defined SGR 1 as "bold or increased intensity", the intention was that a printer could render it with a bold font weight, while a cathode ray terminal would render it with an increased intensity.

As you've noted, it's very unlikely that hardware terminals back then would have been capable of supporting multiple font weights. It had nothing to do with PC limitations.

We're not just trying to keep legacy terminal apps working as close as they were back then

I can't speak for anyone else, but I certainly am.

@j4james commented on GitHub (Feb 22, 2024): There are a couple of points I think are worth correcting. > It is currently rendered as semi-transparent to make it less contrasted from the background color. Technically what's happening is that the foreground color is rendered at half intensity (or at least an approximation of that), but when reversed (i.e. `SGR 7`), it's the background color that is affected. And once we support `DECBBSM`, we would potentially need to dim both the foreground and background colors at the same time. > The Wikipedia article on ANSI escape code even mentions that both bold and faint were originally intended to change the font weight, and have been implemented as brighter and darker/semitransparent colors because of PC hardware limitations. That Wikipedia article is nonsense. All of the DEC terminals from that era rendered bold with an increased intensity. And DEC representatives were on the committee that wrote the spec (at least the ANSI version), and they were one of the first companies to develop an ANSI-compatible terminal. The point of the standard was to define a set of escape sequences that could be implemented compatibly across a broad range of devices, which included both cathode ray terminals as well as printers. So when they defined `SGR 1` as "bold or increased intensity", the intention was that a printer could render it with a bold font weight, while a cathode ray terminal would render it with an increased intensity. As you've noted, it's very unlikely that hardware terminals back then would have been capable of supporting multiple font weights. It had nothing to do with PC limitations. > We're not just trying to keep legacy terminal apps working as close as they were back then I can't speak for anyone else, but I certainly am.
Author
Owner

@PhMajerus commented on GitHub (Feb 22, 2024):

Thanks @j4james, these are some interesting points. Do you know how they handled Faint on printers back then? Was it supported at all?

I appreciate your goal of being compatible with legacy terminals, and that is why I said "not just". I'm only trying to say it's ok to also benefit from modern capabilities. Modern CUI apps are already using features no legacy terminal could support. The ability to use Unicode without simulating characters set ROMs and SI/SO them for use is good, I know I appreciate not having to configure code points charset banks emulation in the config file. Taking advantage of modern fonts seemed to me like such an improvement as well.

I agree you're facing a lot of difficult stuff with the colors and SGR effects, they're definitely not easy to modernize without breaking stuff. That's also why I suggested having this as an option, not change the default behavior.

@PhMajerus commented on GitHub (Feb 22, 2024): Thanks @j4james, these are some interesting points. Do you know how they handled `Faint` on printers back then? Was it supported at all? I appreciate your goal of being compatible with legacy terminals, and that is why I said "not just". I'm only trying to say it's ok to also benefit from modern capabilities. Modern CUI apps are already using features no legacy terminal could support. The ability to use Unicode without simulating characters set ROMs and SI/SO them for use is good, I know I appreciate not having to configure code points charset banks emulation in the config file. Taking advantage of modern fonts seemed to me like such an improvement as well. I agree you're facing a lot of difficult stuff with the colors and SGR effects, they're definitely not easy to modernize without breaking stuff. That's also why I suggested having this as an option, not change the default behavior.
Author
Owner

@j4james commented on GitHub (Feb 22, 2024):

Do you know how they handled Faint on printers back then? Was it supported at all?

It's possible it was supported, but I don't actually know of any printers that did. I do know they sometimes had the ability to switch between "draft" and "near letter quality" modes, with the latter using multiple passes to achieve higher DPI, so draft would tend to be fainter than NLQ. But if you were setting the print quality with an escape sequence, it would likely be done with a font selection sequence (SGR 10 to SGR 19).

Similarly, a printer may have had a selection of font styles to choose from, so in theory you could have a style that would look thinner or appear to be a lighter weight, but again that style would be chosen with a font sequence.

The ability to use Unicode without simulating characters set ROMs and SI/SO them for use is good, I know I appreciate not having to configure code points charset banks emulation in the config file. Taking advantage of modern fonts seemed to me like such an improvement as well.

But adding Unicode support didn't break all existing SI/SO code, and it was following a well defined standard. You're proposing a replacement of the existing SGR 2 functionality. Saying it's behind a setting is a cop-out, because that suggests it's just a stylistic choice, but you're really asking for new functionality.

Imagine apps start taking advantage of this new ability to select a light font weight with SGR 2. Now you've got it being used for two different purposes, and users would have to flip a setting when switching apps depending on what each one was intending SGR 2 to do. It's not the end of the world, but I don't think it's a great user experience.

I know VTE was at one point considering a colon variant of SGR 1 to select font weight (something like SGR 1:2 for weight 200, SGR 1:4 for weight 400, etc.), which I think is a more reasonable proposal. It doesn't break existing SGR 2 usage, and if apps need to detect whether the functionality is supported, they can do so with a DECRQSS sequence.

@j4james commented on GitHub (Feb 22, 2024): > Do you know how they handled Faint on printers back then? Was it supported at all? It's possible it was supported, but I don't actually know of any printers that did. I do know they sometimes had the ability to switch between "draft" and "near letter quality" modes, with the latter using multiple passes to achieve higher DPI, so draft would tend to be fainter than NLQ. But if you were setting the print quality with an escape sequence, it would likely be done with a font selection sequence (`SGR 10` to `SGR 19`). Similarly, a printer may have had a selection of font styles to choose from, so in theory you could have a style that would look thinner or appear to be a lighter weight, but again that style would be chosen with a font sequence. > The ability to use Unicode without simulating characters set ROMs and SI/SO them for use is good, I know I appreciate not having to configure code points charset banks emulation in the config file. Taking advantage of modern fonts seemed to me like such an improvement as well. But adding Unicode support didn't break all existing SI/SO code, and it was following a well defined standard. You're proposing a replacement of the existing `SGR 2` functionality. Saying it's behind a setting is a cop-out, because that suggests it's just a stylistic choice, but you're really asking for new functionality. Imagine apps start taking advantage of this new ability to select a light font weight with `SGR 2`. Now you've got it being used for two different purposes, and users would have to flip a setting when switching apps depending on what each one was intending `SGR 2` to do. It's not the end of the world, but I don't think it's a great user experience. I know VTE was at one point considering a colon variant of `SGR 1` to select font weight (something like `SGR 1:2` for weight 200, `SGR 1:4` for weight 400, etc.), which I think is a more reasonable proposal. It doesn't break existing `SGR 2` usage, and if apps need to detect whether the functionality is supported, they can do so with a `DECRQSS` sequence.
Author
Owner

@PhMajerus commented on GitHub (Feb 22, 2024):

@j4james Ok, thanks for all the insight.
I thought it would be a nice option conveying the same information to the user, but the interactions with other SGR codes appear to make it unpractical.

There are definitely more important things to be working on to improve standardized features, so I'll be closing this one.
Thanks again for your time considering it, and for taking the time to explain the reasoning and not just closing it out.

@PhMajerus commented on GitHub (Feb 22, 2024): @j4james Ok, thanks for all the insight. I thought it would be a nice option conveying the same information to the user, but the interactions with other SGR codes appear to make it unpractical. There are definitely more important things to be working on to improve standardized features, so I'll be closing this one. Thanks again for your time considering it, and for taking the time to explain the reasoning and not just closing it out.
Author
Owner

@j4james commented on GitHub (Feb 22, 2024):

@PhMajerus I should point out that I don't actually get to decide what features are accepted or rejected in WT. I was just offering my opinion, but the MS devs may well disagree with me on this.

@j4james commented on GitHub (Feb 22, 2024): @PhMajerus I should point out that I don't actually get to decide what features are accepted or rejected in WT. I was just offering my opinion, but the MS devs may well disagree with me on this.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#21286