Skip to content
Snippets Groups Projects
Commit 740c77db authored by George Nachman's avatar George Nachman
Browse files

Deal with CSI 38:2 which turns out it has a color type and color space and...

Deal with CSI 38:2 which turns out it has a color type and color space and everyone did it wrong. Issue 6377
parent 1ef1952b
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -685,30 +685,40 @@ static const int kMaxScreenRows = 4096;
graphicRendition_.bgColorMode = ColorModeAlternate;
break;
case VT100CHARATTR_FG_256:
// First subparam means: # additional subparams: Accepts optional params:
// 1: transparent 0 NO
// 2: RGB 3 YES
// 3: CMY 3 YES
// 4: CMYK 4 YES
// 5: Indexed color 1 NO
// The actual spec for this is called ITU T.416-199303
// You can download it for free! If you prefer to spend money, ISO/IEC 8613-6
// is supposedly the same thing.
//
// Optional paramters go at position 7 and 8, and indicate toleranace as an
// integer; and color space (0=CIELUV, 1=CIELAB). Example:
// Here's a sad story about CSI 38:2, which is used to do 24-bit color.
//
// CSI 38:2:255:128:64:0:5:1 m
// Lots of terminal emulators, iTerm2 included, misunderstood the spec. That's
// easy to understand if you read it, which I can't recommend doing unless
// you're looking for inspiration for your next Bulwer-Lytton Fiction Contest
// entry.
//
// Also accepted for xterm compatibility, but never with optional parameters:
// CSI 38;2;255;128;64 m
// See issue 6377 for more context.
//
// Set the foreground color to red=255, green=128, blue=64 with a tolerance of
// 5 in the CIELAB color space. The 0 at the 6th position has no meaning and
// is just a filler.
//
// For 256-color mode (indexed) use this for the foreground:
// CSI 38;5;N m
// where N is a value between 0 and 255. See the colors described in screen_char_t
// in the comments for fgColorCode.
// Ignoring color types we don't support like CMYK, the spec says to do this:
// CSI 38:2:[color space]:[red]:[green]:[blue]:[unused]:[tolerance]:[tolerance colorspace]
//
// Everything after [blue] is optional. Values are decimal numbers in 0...255.
//
// Unfortunately, what was implemented for a long time was this:
// CSI 38:2:[red]:[green]:[blue]:[unused]:[tolerance]:[tolerance colorspace]
//
// And for xterm compatibility, the following was also accepted:
// CSI 38;2;[red];[green];[blue]
//
// The New Order
// -------------
// Tolerance never did anything, so we'll accept this non-standards compliant
// code, which people use:
// CSI 38:2:[red]:[green]:[blue]
//
// As well as the following forms:
// CSI 38:2:[colorspace]:[red]:[green]:[blue]
// CSI 38:2:[colorspace]:[red]:[green]:[blue]:<one or more additional colon-delimited arguments, all ignored>
// CSI 38;2;[red];[green];[blue] // Notice semicolons in place of colons here
if (token.csi->subCount[i] > 0) {
// Preferred syntax using colons to delimit subparameters
if (token.csi->subCount[i] >= 2 && token.csi->sub[i][0] == 5) {
Loading
Loading
@@ -718,15 +728,30 @@ static const int kMaxScreenRows = 4096;
graphicRendition_.fgBlue = 0;
graphicRendition_.fgColorMode = ColorModeNormal;
} else if (token.csi->subCount[i] >= 4 && token.csi->sub[i][0] == 2) {
// CSI 38:2:R:G:B m
// 24-bit color
graphicRendition_.fgColorCode = token.csi->sub[i][1];
graphicRendition_.fgGreen = token.csi->sub[i][2];
graphicRendition_.fgBlue = token.csi->sub[i][3];
graphicRendition_.fgColorMode = ColorMode24bit;
if (token.csi->subCount[i] >= 5) {
// Spec-compliant. Likely rarely used in 2017.
// CSI 38:2:colorspace:R:G:B m
// TODO: Respect the color space argument. See ITU-T Rec. T.414,
// but good luck actually finding the colour space IDs.
graphicRendition_.fgColorCode = token.csi->sub[i][2];
graphicRendition_.fgGreen = token.csi->sub[i][3];
graphicRendition_.fgBlue = token.csi->sub[i][4];
graphicRendition_.fgColorMode = ColorMode24bit;
} else {
// Misinterpration compliant.
// CSI 38:2:R:G:B m <- misinterpration compliant
graphicRendition_.fgColorCode = token.csi->sub[i][1];
graphicRendition_.fgGreen = token.csi->sub[i][2];
graphicRendition_.fgBlue = token.csi->sub[i][3];
graphicRendition_.fgColorMode = ColorMode24bit;
}
}
} else if (token.csi->count - i >= 3 && token.csi->p[i + 1] == 5) {
// CSI 38;5;P m
// For 256-color mode (indexed) use this for the foreground:
// CSI 38;5;N m
// where N is a value between 0 and 255. See the colors described in screen_char_t
// in the comments for fgColorCode.
graphicRendition_.fgColorCode = token.csi->p[i + 2];
graphicRendition_.fgGreen = 0;
graphicRendition_.fgBlue = 0;
Loading
Loading
@@ -734,6 +759,7 @@ static const int kMaxScreenRows = 4096;
i += 2;
} else if (token.csi->count - i >= 5 && token.csi->p[i + 1] == 2) {
// CSI 38;2;R;G;B m
// Hack for xterm compatibility
// 24-bit color support
graphicRendition_.fgColorCode = token.csi->p[i + 2];
graphicRendition_.fgGreen = token.csi->p[i + 3];
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment