From 66c527a624fe9f6cb87136318036121304ebb7b8 Mon Sep 17 00:00:00 2001 From: Jason Hood Date: Thu, 14 Dec 2017 22:16:55 +1000 Subject: [PATCH] Tweak colors SGR parameters 90-97 are bright foreground (leaving bold unchanged) and 100-107 are bright background (leaving underline/blink unchanged); `38;5;#` & `48;5;#` will work for the first 16 colors, setting both foreground & bold or background & underline (0-7 bold/underline off, 8-15 bold/underline on). --- ANSI.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++----- ansicon.c | 2 +- readme.txt | 8 +++--- sequences.txt | 32 ++++++++++++++++++---- 4 files changed, 100 insertions(+), 15 deletions(-) diff --git a/ANSI.c b/ANSI.c index da862b7..f418b05 100644 --- a/ANSI.c +++ b/ANSI.c @@ -152,7 +152,7 @@ remove wcstok, avoiding potential interference with the host; similarly, use a private heap instead of malloc. - v1.80, 26 October to 11 December, 2017: + v1.80, 26 October to 16 December, 2017: fix unloading; revert back to (re)storing buffer cursor position; increase cache to five handles; @@ -171,7 +171,8 @@ partially support SCS (just G0 as DEC special & ASCII); an explicit zero parameter should still default to one; restrict parameters to a maximum value of 32767; - added tab handling. + added tab handling; + added the bright SGR colors, recognised the system indices. */ #include "ansicon.h" @@ -272,7 +273,7 @@ const WCHAR G1[] = #define BACKGROUND_BLACK 0 #define BACKGROUND_WHITE BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE -const BYTE foregroundcolor[8] = +const BYTE foregroundcolor[16] = { FOREGROUND_BLACK, // black foreground FOREGROUND_RED, // red foreground @@ -281,10 +282,18 @@ const BYTE foregroundcolor[8] = FOREGROUND_BLUE, // blue foreground FOREGROUND_BLUE | FOREGROUND_RED, // magenta foreground FOREGROUND_BLUE | FOREGROUND_GREEN, // cyan foreground - FOREGROUND_WHITE // white foreground + FOREGROUND_WHITE, // white foreground + FOREGROUND_INTENSITY | FOREGROUND_BLACK, + FOREGROUND_INTENSITY | FOREGROUND_RED, + FOREGROUND_INTENSITY | FOREGROUND_GREEN, + FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN, + FOREGROUND_INTENSITY | FOREGROUND_BLUE, + FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_RED, + FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_GREEN, + FOREGROUND_INTENSITY | FOREGROUND_WHITE }; -const BYTE backgroundcolor[8] = +const BYTE backgroundcolor[16] = { BACKGROUND_BLACK, // black background BACKGROUND_RED, // red background @@ -294,6 +303,14 @@ const BYTE backgroundcolor[8] = BACKGROUND_BLUE | BACKGROUND_RED, // magenta background BACKGROUND_BLUE | BACKGROUND_GREEN, // cyan background BACKGROUND_WHITE, // white background + BACKGROUND_INTENSITY | BACKGROUND_BLACK, + BACKGROUND_INTENSITY | BACKGROUND_RED, + BACKGROUND_INTENSITY | BACKGROUND_GREEN, + BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN, + BACKGROUND_INTENSITY | BACKGROUND_BLUE, + BACKGROUND_INTENSITY | BACKGROUND_BLUE | BACKGROUND_RED, + BACKGROUND_INTENSITY | BACKGROUND_BLUE | BACKGROUND_GREEN, + BACKGROUND_INTENSITY | BACKGROUND_WHITE }; const BYTE attr2ansi[16] = // map console attribute to ANSI number @@ -896,19 +913,42 @@ void InterpretEscSeq( void ) { pState->sgr.background = es_argv[i] - 40; } + else if (90 <= es_argv[i] && es_argv[i] <= 97) + { + pState->sgr.foreground = es_argv[i] - 90 + 8; + } + else if (100 <= es_argv[i] && es_argv[i] <= 107) + { + pState->sgr.background = es_argv[i] - 100 + 8; + } else if (es_argv[i] == 38 || es_argv[i] == 48) { // This is technically incorrect, but it's what xterm does, so // that's what we do. According to T.416 (ISO 8613-6), there is // only one parameter, which is divided into elements. So where - // xterm does "38;2;R;G;B" it should really be "38;2:I:R:G:B" (I is + // xterm does "38;2;R;G;B" it should really be "38:2:I:R:G:B" (I is // a color space identifier). if (i+1 < es_argc) { if (es_argv[i+1] == 2) // rgb i += 4; else if (es_argv[i+1] == 5) // index + { + if (i+2 < es_argc && es_argv[i+2] < 16) + { + if (es_argv[i] == 38) + { + pState->sgr.foreground = es_argv[i+2]; + pState->sgr.bold = es_argv[i+2] & FOREGROUND_INTENSITY; + } + else + { + pState->sgr.background = es_argv[i+2]; + pState->sgr.underline = es_argv[i+2] & BACKGROUND_INTENSITY; + } + } i += 2; + } } } else switch (es_argv[i]) @@ -1478,6 +1518,27 @@ void InterpretEscSeq( void ) else valid = FALSE; } + else if (wcsncmp( beg, L"rgb:", 4 ) == 0) + { + valid = FALSE; + c = (DWORD)wcstoul( beg += 4, &end, 16 ); + if (*end == '/' && (end - beg == 2 || end - beg == 4)) + { + r = (BYTE)(end - beg == 2 ? c : c >> 8); + c = (DWORD)wcstoul( beg = end + 1, &end, 16 ); + if (*end == '/' && (end - beg == 2 || end - beg == 4)) + { + g = (BYTE)(end - beg == 2 ? c : c >> 8); + c = (DWORD)wcstoul( beg = end + 1, &end, 16 ); + if ((*end == ',' || *end == ';' || *end == '\0') && + (end - beg == 2 || end - beg == 4)) + { + b = (BYTE)(end - beg == 2 ? c : c >> 8); + valid = TRUE; + } + } + } + } else { valid = FALSE; diff --git a/ansicon.c b/ansicon.c index 809c8c1..a3b18f4 100644 --- a/ansicon.c +++ b/ansicon.c @@ -91,7 +91,7 @@ use -pu to unload from the parent. */ -#define PDATE L"11 December, 2017" +#define PDATE L"16 December, 2017" #include "ansicon.h" #include "version.h" diff --git a/readme.txt b/readme.txt index ad67c12..5fe7a6a 100644 --- a/readme.txt +++ b/readme.txt @@ -310,7 +310,7 @@ Version History Legend: + added, - bug-fixed, * changed. - 1.80 - 11 December, 2017: + 1.80 - 16 December, 2017: - fix unloading; - fix -e et al when redirecting to CON; - hook CreateFile and CreateConsoleScreenBuffer to force read/write access @@ -318,15 +318,17 @@ Version History - fix cursor report with duplicated digits (e.g. "11" was only writing "1"); - fix issues with CRM; - fix explicit zero parameters not defaulting to 1; + - set color by index (also setting bold/underline); * limit parameters to a maximum value of 32767; * go back to saving the buffer cursor position; * preserve escape that isn't part of a sequence; - * escape control characters; + * escaped control characters will display the control; * change the graphics SCAN characters to their Unicode equivalents; + use the system default sound for the bell; + added Play Sound DECPS; + added '+' intermediate byte to use the buffer, rather than the window; + added palette sequences; + + added the bright SGR colors; + added -pu to unload from the parent; + added IND, NEL, RI, DA, DECCOLM, DECNCSM, DECSC & DECRC; + added SCS, but only for special/ASCII (same as Win10); @@ -559,4 +561,4 @@ Distribution ============================== -Jason Hood, 11 December, 2017. +Jason Hood, 16 December, 2017. diff --git a/sequences.txt b/sequences.txt index e319aa2..7d09f68 100644 --- a/sequences.txt +++ b/sequences.txt @@ -32,6 +32,8 @@ the Windows default beep (but only if it's not already playing). 35 foreground magenta 36 foreground cyan 37 foreground white + 38;2;# foreground & bold based on index (0-15) + 38;5;#;#;# ignored (RGB) 39 default foreground (using current intensity) 40 background black 41 background red @@ -41,7 +43,25 @@ the Windows default beep (but only if it's not already playing). 45 background magenta 46 background cyan 47 background white + 48;2;# background & underline based on index (0-15) + 48;5;#;#;# ignored (RGB) 49 default background (using current intensity) + 90 foreground bright black + 91 foreground bright red + 92 foreground bright green + 93 foreground bright yellow + 94 foreground bright blue + 95 foreground bright magenta + 96 foreground bright cyan + 97 foreground bright white + 100 background bright black + 101 background bright red + 102 background bright green + 103 background bright yellow + 104 background bright blue + 105 background bright magenta + 106 background bright cyan + 107 background bright white [J erase from cursor to the end of display [0J as above @@ -159,11 +179,13 @@ H set tab stop set or query the palette: # is the ANSI index (0-7, or 8-15 for bold/underline) spec is: - ? send the current value to console input - * send the current and all subsequent values - #RGB set the color (hexadecimal) - #RRGGBB set the color (hexadecimal) - R,G,B set the color (decimal) + ? send the current value to console input + * send the current and all subsequent values + #RGB set the color (hexadecimal) + #RRGGBB set the color (hexadecimal) + R,G,B set the color (decimal) + rgb:RR/GG/BB set the color (hexadecimal) + rgb:RRRR/GGGG/BBBB set the color (hexadecimal, high byte) ]104ST restore the entire palette ]104;#...ST restore the color of each index