Thoughts about faint (SGR 2)
@egmontkob
Submitted by Egmont Koblinger Link to original bug (#791596)
Description
ECMA-48 says: SGR 1 bold or increased intensity SGR 2 faint, decreased intensity or second colour SGR 22 normal colour or normal intensity (neither bold nor faint)
ITU-T Recommendation T.416 says: SGR 1 Bold or increased intensity SGR 2 Faint or decreased intensity SGR 22 Normal intensity (neither bold nor faint)
(We often call SGR 2 "dim" or "half" in our code.)
Neither of them state explicitly, but the wording, and the common SGR code for turning them off implicitly suggests to me that most likely SGR 1 and 2 were meant to be mutually exclusive. That's not the case in VTE's current implementation, and not in xterm or konsole either, as you can see e.g. in the output of perf/256test.sh.
With the introduction of the 256-color palette, it became clear that SGR 1 should mean bold and is not meant to tamper with the color (at least for the extended color codes). True color support obviously further strenghtened this. In bug 762247 we made yet another step to get closer to this state: a new API allows to turn off SGR 1's increased intensity even for the legacy first 8 color codes, making it strictly bold only and never to alter the color.
At the current state of things and direction we're going, the faint attribute (or at least its current interpretation) just doesn't fit this picture. It's an odd one that uses a hardcoded formula to compute the exact RGB color, not settable individually via API or OSC 4-like codes.
Furthermore, the formula (copied exactly from xterm) just multiplies each color channel by 2/3. With white-on-black color schemes it's somewhat okay, with black-on-white the default black color isn't made any fainter.
Konsole's color editing dialog presents a 3x10 table: foreground, background and the standard 8 color slots, and for each of them "Color", "Intense color" and "Faint color". This is way too much for me, and in the opposite direction that I'd like to move. Interestingly, enabling both SGR 1 & 2 result in the original color, just in bold. Maybe that's konsole's way of achieving what we introduced that new API for?
Following the existing pattern, and the desire that color should be separated from other attributes, I believe the most reasonable thing would be for SGR 2 to mean an even thinner font than the default, and indeed be mutually exclusive with SGR 1.
Setting PANGO_WEIGHT_THIN doesn't do anything for me. Apparently it relies on having such a font weight being installed on the system, and all the monospace fonts I have ship regular and bold weights only. If we go this way, it'll only work for a very few users who set up such a font with at least 3 different weights, e.g. http://input.fontbureau.com/ .
Or we could do something analogous to our former "faux bold" feature: "faux thin". We'd render the glyph on a temporary canvas (before downscaling), shift by some amount (probably less than 1px, that is, less than PANGO_SCALE), "AND" the bits, and then downscale by PANGO_SCALE. It might look terrible, I don't know.
Another, simpler to implement approach could be to revise the formula used in mangling the color: let's say, move the foreground color 1/3 of the way towards the background (this wouldn't even change the result on black background), or something similar along these lines. This could probably provide a similar visual experience to a thinner font with the original color.
This still wouldn't solve the philosophical problem though: in presence of 256 and even 16M colors, there shouldn't be another attribute for changing the color only. But we could say that this is the best we could reasonably come up with in order to emulate the look of a thinner font. After all, with antialiasing and thin fonts, we might speak about not mangling the colors, but chances are when a letter is rendered, none of its pixels will be exactly the desired color.
(And then still make this property mutually exclusive to bold or not??)
Version: git master