Improve palette usage

Support the entire 256-color palette.  When specifying an index or RGB
color, find the nearest match in the console palette.  Preserve bold and
underline when setting color by index.	Getting all palette entries will
stop at 15 if the initial index is below that (i.e. `0;*` will get 0 to
15 and `16;*` will get 16 to 255).
This commit is contained in:
Jason Hood 2017-12-28 12:47:09 +10:00
parent 05e765c881
commit 3c61ef860d
5 changed files with 247 additions and 75 deletions

185
ANSI.c
View File

@ -180,12 +180,13 @@
added DECSTR & RIS; added DECSTR & RIS;
fix state problems with windowless processes. fix state problems with windowless processes.
v1.81-wip, 26 December, 2017: v1.81-wip, 26 to 28 December, 2017:
combine multiple CRs as one (to ignore all CRs before LF); combine multiple CRs as one (to ignore all CRs before LF);
don't process CR or BS during CRM; don't process CR or BS during CRM;
don't flush CR immediately (to catch following LF); don't flush CR immediately (to catch following LF);
fix CRM with all partial RM sequences; fix CRM with all partial RM sequences;
check for the empty buffer within the critical section. check for the empty buffer within the critical section;
palette improvements.
*/ */
#include "ansicon.h" #include "ansicon.h"
@ -229,7 +230,7 @@ TCHAR suffix2; // escape sequence intermediate byte
int ibytes; // count of intermediate bytes int ibytes; // count of intermediate bytes
int es_argc; // escape sequence args count int es_argc; // escape sequence args count
int es_argv[MAX_ARG]; // escape sequence args int es_argv[MAX_ARG]; // escape sequence args
TCHAR Pt_arg[MAX_PATH*2]; // text parameter for Operating System Command TCHAR Pt_arg[4096]; // text parameter for Operating System Command
int Pt_len; int Pt_len;
BOOL shifted, G0_special, SaveG0; BOOL shifted, G0_special, SaveG0;
BOOL awm = TRUE; // autowrap mode BOOL awm = TRUE; // autowrap mode
@ -369,6 +370,12 @@ typedef BOOL (WINAPI *PHCSBIX)(
PHCSBIX GetConsoleScreenBufferInfoX, SetConsoleScreenBufferInfoX; PHCSBIX GetConsoleScreenBufferInfoX, SetConsoleScreenBufferInfoX;
BOOL WINAPI GetConsoleScreenBufferInfoEx_repl( HANDLE h,
PCONSOLE_SCREEN_BUFFER_INFOX i )
{
return FALSE;
}
typedef struct _CONSOLE_FONT_INFOX { typedef struct _CONSOLE_FONT_INFOX {
ULONG cbSize; ULONG cbSize;
@ -426,7 +433,8 @@ typedef struct
SHORT top_margin; SHORT top_margin;
SHORT bot_margin; SHORT bot_margin;
COORD SavePos; // saved cursor position COORD SavePos; // saved cursor position
COLORREF palette[16]; COLORREF o_palette[16]; // original palette, for resetting
COLORREF x_palette[240]; // xterm 256-color palette, less 16 system colors
SHORT buf_width; // buffer width prior to setting 132 columns SHORT buf_width; // buffer width prior to setting 132 columns
SHORT win_width; // window width prior to setting 132 columns SHORT win_width; // window width prior to setting 132 columns
BYTE noclear; // don't clear the screen on column mode change BYTE noclear; // don't clear the screen on column mode change
@ -439,6 +447,8 @@ PSTATE pState = &default_state;
BOOL valid_state; BOOL valid_state;
HANDLE hMap; HANDLE hMap;
#include "palette.h"
void set_ansicon( PCONSOLE_SCREEN_BUFFER_INFO ); void set_ansicon( PCONSOLE_SCREEN_BUFFER_INFO );
@ -480,15 +490,17 @@ void get_state( void )
FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL ); NULL, OPEN_EXISTING, 0, NULL );
csbix.cbSize = sizeof(csbix); csbix.cbSize = sizeof(csbix);
if (GetConsoleScreenBufferInfoX && if (GetConsoleScreenBufferInfoX( hConOut, &csbix ))
GetConsoleScreenBufferInfoX( hConOut, &csbix ))
{ {
Info.dwSize = csbix.dwSize; Info.dwSize = csbix.dwSize;
ATTR = csbix.wAttributes; ATTR = csbix.wAttributes;
WIN = csbix.srWindow; WIN = csbix.srWindow;
memcpy( pState->palette, csbix.ColorTable, sizeof(csbix.ColorTable) ); memcpy( pState->o_palette, csbix.ColorTable, sizeof(csbix.ColorTable) );
} }
else if (!GetConsoleScreenBufferInfo( hConOut, &Info )) else
{
memcpy( pState->o_palette, legacy_palette, sizeof(legacy_palette) );
if (!GetConsoleScreenBufferInfo( hConOut, &Info ))
{ {
DEBUGSTR( 1, "Failed to get screen buffer info (%u) - assuming defaults", DEBUGSTR( 1, "Failed to get screen buffer info (%u) - assuming defaults",
GetLastError() ); GetLastError() );
@ -500,6 +512,8 @@ void get_state( void )
TOP = 0; TOP = 0;
BOTTOM = 24; BOTTOM = 24;
} }
}
memcpy( pState->x_palette, xterm_palette, sizeof(xterm_palette) );
if (GetEnvironmentVariable( L"ANSICON_REVERSE", NULL, 0 )) if (GetEnvironmentVariable( L"ANSICON_REVERSE", NULL, 0 ))
{ {
SetEnvironmentVariable( L"ANSICON_REVERSE", NULL ); SetEnvironmentVariable( L"ANSICON_REVERSE", NULL );
@ -985,7 +999,7 @@ void send_palette_sequence( COLORREF c )
r = GetRValue( c ); r = GetRValue( c );
g = GetGValue( c ); g = GetGValue( c );
b = GetBValue( c ); b = GetBValue( c );
if ((c & 0x0F0F0F) == ((c & 0xF0F0F0) >> 4)) if ((c & 0x0F0F0F) == ((c >> 4) & 0x0F0F0F))
wsprintf( buf, L"#%X%X%X", r & 0xF, g & 0xF, b & 0xF ); wsprintf( buf, L"#%X%X%X", r & 0xF, g & 0xF, b & 0xF );
else else
wsprintf( buf, L"#%02X%02X%02X", r, g, b ); wsprintf( buf, L"#%02X%02X%02X", r, g, b );
@ -1005,6 +1019,49 @@ void init_tabs( int size )
} }
// Find the "distance" between two colors.
// https://www.compuphase.com/cmetric.htm
int color_distance( COLORREF c1, COLORREF c2 )
{
int rmean = (GetRValue( c1 ) + GetRValue( c2 )) / 2;
int r = GetRValue( c1 ) - GetRValue( c2 );
int g = GetGValue( c1 ) - GetGValue( c2 );
int b = GetBValue( c1 ) - GetBValue( c2 );
return (((512 + rmean) * r * r) >> 8) +
4 * g * g +
(((767 - rmean) * b * b) >> 8);
}
// Find the nearest color to a system color.
int find_nearest_color( COLORREF col )
{
int d, d_min;
int i, idx;
CONSOLE_SCREEN_BUFFER_INFOX csbix;
const COLORREF* table;
csbix.cbSize = sizeof(csbix);
table = (GetConsoleScreenBufferInfoX( hConOut, &csbix ))
? csbix.ColorTable : legacy_palette;
d_min = color_distance( col, table[0] );
if (d_min == 0) return 0;
idx = 0;
for (i = 1; i < 16; ++i)
{
d = color_distance( col, table[i] );
if (d < d_min)
{
if (d == 0) return i;
d_min = d;
idx = i;
}
}
return idx;
}
// ========== Reset // ========== Reset
void InterpretEscSeq( void ); void InterpretEscSeq( void );
@ -1043,14 +1100,14 @@ void Reset( BOOL hard )
InterpretEscSeq(); InterpretEscSeq();
screen_top = -1; screen_top = -1;
csbix.cbSize = sizeof(csbix); csbix.cbSize = sizeof(csbix);
if (GetConsoleScreenBufferInfoX && if (GetConsoleScreenBufferInfoX( hConOut, &csbix ))
GetConsoleScreenBufferInfoX( hConOut, &csbix ))
{ {
memcpy( csbix.ColorTable, pState->palette, sizeof(csbix.ColorTable) ); memcpy( csbix.ColorTable, pState->o_palette, sizeof(csbix.ColorTable) );
++csbix.srWindow.Right; ++csbix.srWindow.Right;
++csbix.srWindow.Bottom; ++csbix.srWindow.Bottom;
SetConsoleScreenBufferInfoX( hConOut, &csbix ); SetConsoleScreenBufferInfoX( hConOut, &csbix );
} }
memcpy( pState->x_palette, xterm_palette, sizeof(xterm_palette) );
} }
} }
@ -1206,6 +1263,10 @@ void InterpretEscSeq( void )
if (suffix2 == 0 || suffix2 == '+') switch (suffix) if (suffix2 == 0 || suffix2 == '+') switch (suffix)
{ {
case 'm': // SGR case 'm': // SGR
{
BYTE b = FOREGROUND_INTENSITY;
BYTE u = BACKGROUND_INTENSITY;
if (es_argc == 0) es_argc++; // ESC[m == ESC[0m if (es_argc == 0) es_argc++; // ESC[m == ESC[0m
for (i = 0; i < es_argc; i++) for (i = 0; i < es_argc; i++)
{ {
@ -1232,27 +1293,43 @@ void InterpretEscSeq( void )
// only one parameter, which is divided into elements. So where // 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). // a color space identifier).
if (i+1 < es_argc) if (++i < es_argc)
{ {
if (es_argv[i+1] == 2) // rgb COLORREF col = CLR_INVALID;
i += 4; int idx = -1;
else if (es_argv[i+1] == 5) // index int arg = es_argv[i-1];
if (es_argv[i] == 2) // rgb
{ {
if (i+2 < es_argc && es_argv[i+2] < 16) if (i+3 < es_argc)
col = RGB( es_argv[i+1], es_argv[i+2], es_argv[i+3] );
i += 3;
}
else if (es_argv[i] == 5) // index
{ {
if (es_argv[i] == 38) if (++i < es_argc)
{ {
pState->sgr.foreground = es_argv[i+2]; if (es_argv[i] < 16)
pState->sgr.bold = es_argv[i+2] & FOREGROUND_INTENSITY; idx = es_argv[i];
else if (es_argv[i] < 256)
col = pState->x_palette[es_argv[i] - 16];
}
}
if (col != CLR_INVALID)
idx = attr2ansi[find_nearest_color( col )];
if (idx != -1)
{
if (arg == 38)
{
pState->sgr.foreground = idx;
b = 0;
} }
else else
{ {
pState->sgr.background = es_argv[i+2]; pState->sgr.background = idx;
pState->sgr.underline = es_argv[i+2] & BACKGROUND_INTENSITY; u = 0;
} }
} }
i += 2;
}
} }
} }
else switch (es_argv[i]) else switch (es_argv[i])
@ -1308,20 +1385,22 @@ void InterpretEscSeq( void )
case 28: pState->sgr.concealed = 0; break; case 28: pState->sgr.concealed = 0; break;
} }
} }
b &= pState->sgr.bold;
u &= pState->sgr.underline;
if (pState->sgr.concealed) if (pState->sgr.concealed)
{ {
if (pState->sgr.rvideo) if (pState->sgr.rvideo)
{ {
attribut = foregroundcolor[pState->sgr.foreground] attribut = foregroundcolor[pState->sgr.foreground]
| backgroundcolor[pState->sgr.foreground]; | backgroundcolor[pState->sgr.foreground];
if (pState->sgr.bold) if (b)
attribut |= FOREGROUND_INTENSITY | BACKGROUND_INTENSITY; attribut |= FOREGROUND_INTENSITY | BACKGROUND_INTENSITY;
} }
else else
{ {
attribut = foregroundcolor[pState->sgr.background] attribut = foregroundcolor[pState->sgr.background]
| backgroundcolor[pState->sgr.background]; | backgroundcolor[pState->sgr.background];
if (pState->sgr.underline) if (u)
attribut |= FOREGROUND_INTENSITY | BACKGROUND_INTENSITY; attribut |= FOREGROUND_INTENSITY | BACKGROUND_INTENSITY;
} }
} }
@ -1329,17 +1408,16 @@ void InterpretEscSeq( void )
{ {
attribut = foregroundcolor[pState->sgr.background] attribut = foregroundcolor[pState->sgr.background]
| backgroundcolor[pState->sgr.foreground]; | backgroundcolor[pState->sgr.foreground];
if (pState->sgr.bold) if (b) attribut |= BACKGROUND_INTENSITY;
attribut |= BACKGROUND_INTENSITY; if (u) attribut |= FOREGROUND_INTENSITY;
if (pState->sgr.underline)
attribut |= FOREGROUND_INTENSITY;
} }
else else
attribut = foregroundcolor[pState->sgr.foreground] | pState->sgr.bold attribut = foregroundcolor[pState->sgr.foreground] | b
| backgroundcolor[pState->sgr.background] | pState->sgr.underline; | backgroundcolor[pState->sgr.background] | u;
if (pState->sgr.reverse) if (pState->sgr.reverse)
attribut = ((attribut >> 4) & 15) | ((attribut & 15) << 4); attribut = ((attribut >> 4) & 15) | ((attribut & 15) << 4);
SetConsoleTextAttribute( hConOut, attribut ); SetConsoleTextAttribute( hConOut, attribut );
}
return; return;
case 'J': // ED case 'J': // ED
@ -1788,9 +1866,8 @@ void InterpretEscSeq( void )
{ {
CONSOLE_SCREEN_BUFFER_INFOX csbix; CONSOLE_SCREEN_BUFFER_INFOX csbix;
csbix.cbSize = sizeof(csbix); csbix.cbSize = sizeof(csbix);
if (!GetConsoleScreenBufferInfoX || if (!GetConsoleScreenBufferInfoX( hConOut, &csbix ))
!GetConsoleScreenBufferInfoX( hConOut, &csbix )) memcpy( csbix.ColorTable, legacy_palette, sizeof(legacy_palette) );
return;
if (es_argv[0] == 4) if (es_argv[0] == 4)
{ {
BYTE r, g, b; BYTE r, g, b;
@ -1800,7 +1877,7 @@ void InterpretEscSeq( void )
for (beg = Pt_arg;; beg = end + 1) for (beg = Pt_arg;; beg = end + 1)
{ {
i = (int)wcstoul( beg, &end, 10 ); i = (int)wcstoul( beg, &end, 10 );
if (end == beg || (*end != ';' && *end != '\0') || i >= 16) if (end == beg || (*end != ';' && *end != '\0') || i >= 256)
break; break;
if (end[2] == ';' || end[2] == '\0') if (end[2] == ';' || end[2] == '\0')
{ {
@ -1809,11 +1886,18 @@ void InterpretEscSeq( void )
SendSequence( L"\33]4;" ); SendSequence( L"\33]4;" );
end[1] = '\0'; end[1] = '\0';
SendSequence( beg ); SendSequence( beg );
if (i < 16)
for (; i < 16; ++i) for (; i < 16; ++i)
{ {
send_palette_sequence( csbix.ColorTable[attr2ansi[i]] ); send_palette_sequence( csbix.ColorTable[attr2ansi[i]] );
SendSequence( (i == 15) ? L"\a" : L"," ); SendSequence( (i == 15) ? L"\a" : L"," );
} }
else
for (; i < 256; ++i)
{
send_palette_sequence( pState->x_palette[i - 16] );
SendSequence( (i == 255) ? L"\a" : L"," );
}
} }
else if (end[1] == '?') else if (end[1] == '?')
{ {
@ -1825,7 +1909,8 @@ void InterpretEscSeq( void )
SendSequence( L";" ); SendSequence( L";" );
end[1] = '\0'; end[1] = '\0';
SendSequence( beg ); SendSequence( beg );
send_palette_sequence( csbix.ColorTable[attr2ansi[i]] ); send_palette_sequence( (i < 16) ? csbix.ColorTable[attr2ansi[i]]
: pState->x_palette[i - 16] );
} }
else else
break; break;
@ -1905,8 +1990,13 @@ void InterpretEscSeq( void )
} }
} }
if (valid) if (valid)
{
if (i < 16)
csbix.ColorTable[attr2ansi[i++]] = RGB( r, g, b ); csbix.ColorTable[attr2ansi[i++]] = RGB( r, g, b );
if (*end != ',' || i == 16) else
pState->x_palette[i++ - 16] = RGB( r, g, b );
}
if (*end != ',' || i == 256)
{ {
while (*end != ';' && *end != '\0') while (*end != ';' && *end != '\0')
++end; ++end;
@ -1924,28 +2014,39 @@ void InterpretEscSeq( void )
{ {
// Reset each index, or the entire palette. // Reset each index, or the entire palette.
if (Pt_len == 0) if (Pt_len == 0)
memcpy( csbix.ColorTable, pState->palette, sizeof(csbix.ColorTable) ); {
memcpy(csbix.ColorTable, pState->o_palette, sizeof(csbix.ColorTable));
memcpy( pState->x_palette, xterm_palette, sizeof(xterm_palette) );
}
else else
{ {
LPTSTR beg, end; LPTSTR beg, end;
for (beg = Pt_arg;; beg = end + 1) for (beg = Pt_arg;; beg = end + 1)
{ {
i = (int)wcstoul( beg, &end, 10 ); i = (int)wcstoul( beg, &end, 10 );
if (end == beg || (*end != ';' && *end != '\0') || i >= 16) if (end == beg || (*end != ';' && *end != '\0') || i >= 256)
break; break;
if (i < 16)
{
i = attr2ansi[i]; i = attr2ansi[i];
csbix.ColorTable[i] = pState->palette[i]; csbix.ColorTable[i] = pState->o_palette[i];
}
else
pState->x_palette[i - 16] = xterm_palette[i - 16];
if (*end == '\0') if (*end == '\0')
break; break;
} }
} }
} }
if (SetConsoleScreenBufferInfoX)
{
++csbix.srWindow.Right; ++csbix.srWindow.Right;
++csbix.srWindow.Bottom; ++csbix.srWindow.Bottom;
SetConsoleScreenBufferInfoX( hConOut, &csbix ); SetConsoleScreenBufferInfoX( hConOut, &csbix );
} }
} }
} }
}
void MoveDown( BOOL home ) void MoveDown( BOOL home )
@ -3709,6 +3810,8 @@ BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved )
hKernel = GetModuleHandleA( APIKernel ); hKernel = GetModuleHandleA( APIKernel );
GetConsoleScreenBufferInfoX = (PHCSBIX)GetProcAddress( GetConsoleScreenBufferInfoX = (PHCSBIX)GetProcAddress(
hKernel, "GetConsoleScreenBufferInfoEx" ); hKernel, "GetConsoleScreenBufferInfoEx" );
if (GetConsoleScreenBufferInfoX == NULL)
GetConsoleScreenBufferInfoX = GetConsoleScreenBufferInfoEx_repl;
SetConsoleScreenBufferInfoX = (PHCSBIX)GetProcAddress( SetConsoleScreenBufferInfoX = (PHCSBIX)GetProcAddress(
hKernel, "SetConsoleScreenBufferInfoEx" ); hKernel, "SetConsoleScreenBufferInfoEx" );
SetCurrentConsoleFontX = (PHBCFIX)GetProcAddress( SetCurrentConsoleFontX = (PHBCFIX)GetProcAddress(

View File

@ -91,7 +91,7 @@
use -pu to unload from the parent. use -pu to unload from the parent.
*/ */
#define PDATE L"26 December, 2017" #define PDATE L"28 December, 2017"
#include "ansicon.h" #include "ansicon.h"
#include "version.h" #include "version.h"

58
palette.h Normal file
View File

@ -0,0 +1,58 @@
// Legacy console colors for XP (later systems get the actual palette).
static const COLORREF legacy_palette[] =
{
0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080, 0x008080, 0xC0C0C0,
0x808080, 0xFF0000, 0x00FF00, 0xFFFF00, 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF,
};
// This is the Windows (10.0.15063) version of the xterm 256-color palette.
static const COLORREF xterm_palette[] =
{
// 16 system colors left out.
// RGB 6x6x6 color cube.
0x000000, 0x5F0000, 0x870000, 0xAF0000, 0xD70000, 0xFF0000,
0x005F00, 0x5F5F00, 0x875F00, 0xAF5F00, 0xD75F00, 0xFF5F00,
0x008700, 0x5F8700, 0x878700, 0xAF8700, 0xD78700, 0xFF8700,
0x00AF00, 0x5FAF00, 0x87AF00, 0xAFAF00, 0xD7AF00, 0xFFAF00,
0x00D700, 0x5FD700, 0x87D700, 0xAFD700, 0xD7D700, 0xFFD700,
0x00FF00, 0x5FFF00, 0x87FF00, 0xAFFF00, 0xD7FF00, 0xFFFF00,
0x00005F, 0x5F005F, 0x87005F, 0xAF005F, 0xD7005F, 0xFF005F,
0x005F5F, 0x5F5F5F, 0x875F5F, 0xAF5F5F, 0xD75F5F, 0xFF5F5F,
0x00875F, 0x5F875F, 0x87875F, 0xAF875F, 0xD7875F, 0xFF875F,
0x00AF5F, 0x5FAF5F, 0x87AF5F, 0xAFAF5F, 0xD7AF5F, 0xFFAF5F,
0x00D75F, 0x5FD75F, 0x87D75F, 0xAFD75F, 0xD7D75F, 0xFFD75F,
0x00FF5F, 0x5FFF5F, 0x87FF5F, 0xAFFF5F, 0xD7FF5F, 0xFFFF5F,
0x000087, 0x5F0087, 0x870087, 0xAF0087, 0xD70087, 0xFF0087,
0x005F87, 0x5F5F87, 0x875F87, 0xAF5F87, 0xD75F87, 0xFF5F87,
0x008787, 0x5F8787, 0x878787, 0xAF8787, 0xD78787, 0xFF8787,
0x00AF87, 0x5FAF87, 0x87AF87, 0xAFAF87, 0xD7AF87, 0xFFAF87,
0x00D787, 0x5FD787, 0x87D787, 0xAFD787, 0xD7D787, 0xFFD787,
0x00FF87, 0x5FFF87, 0x87FF87, 0xAFFF87, 0xD7FF87, 0xFFFF87,
0x0000AF, 0x5F00AF, 0x8700AF, 0xAF00AF, 0xD700AF, 0xFF00AF,
0x005FAF, 0x5F5FAF, 0x875FAF, 0xAF5FAF, 0xD75FAF, 0xFF5FAF,
0x0087AF, 0x5F87AF, 0x8787AF, 0xAF87AF, 0xD787AF, 0xFF87AF,
0x00AFAF, 0x5FAFAF, 0x87AFAF, 0xAFAFAF, 0xD7AFAF, 0xFFAFAF,
0x00D7AF, 0x5FD7AF, 0x87D7AF, 0xAFD7AF, 0xD7D7AF, 0xFFD7AF,
0x00FFAF, 0x5FFFAF, 0x87FFAF, 0xAFFFAF, 0xD7FFAF, 0xFFFFAF,
0x0000D7, 0x5F00D7, 0x8700D7, 0xAF00D7, 0xD700D7, 0xFF00D7,
0x005FD7, 0x5F5FD7, 0x875FD7, 0xAF5FD7, 0xD75FD7, 0xFF5FD7,
0x0087D7, 0x5F87D7, 0x8787D7, 0xAF87D7, 0xD787D7, 0xFF87D7,
0x00AFDF, 0x5FAFDF, 0x87AFDF, 0xAFAFDF, 0xD7AFDF, 0xFFAFDF, // xterm uses
0x00D7DF, 0x5FD7DF, 0x87D7DF, 0xAFD7DF, 0xD7D7DF, 0xFFD7DF, // R = 0xD7
0x00FFDF, 0x5FFFDF, 0x87FFDF, 0xAFFFDF, 0xD7FFDF, 0xFFFFDF, // here
0x0000FF, 0x5F00FF, 0x8700FF, 0xAF00FF, 0xD700FF, 0xFF00FF,
0x005FFF, 0x5F5FFF, 0x875FFF, 0xAF5FFF, 0xD75FFF, 0xFF5FFF,
0x0087FF, 0x5F87FF, 0x8787FF, 0xAF87FF, 0xD787FF, 0xFF87FF,
0x00AFFF, 0x5FAFFF, 0x87AFFF, 0xAFAFFF, 0xD7AFFF, 0xFFAFFF,
0x00D7FF, 0x5FD7FF, 0x87D7FF, 0xAFD7FF, 0xD7D7FF, 0xFFD7FF,
0x00FFFF, 0x5FFFFF, 0x87FFFF, 0xAFFFFF, 0xD7FFFF, 0xFFFFFF,
// Grayscale, without black or white.
0x080808, 0x121212, 0x1C1C1C, 0x262626, 0x303030, 0x3A3A3A,
0x444444, 0x4E4E4E, 0x585858, 0x626262, 0x6C6C6C, 0x767676,
0x808080, 0x8A8A8A, 0x949494, 0x9E9E9E, 0xA8A8A8, 0xB2B2B2,
0xBCBCBC, 0xC6C6C6, 0xD0D0D0, 0xDADADA, 0xE4E4E4, 0xEEEEEE,
};

View File

@ -334,10 +334,13 @@ Version History
Legend: + added, - bug-fixed, * changed. Legend: + added, - bug-fixed, * changed.
1.81-wip - 26 December, 2017: 1.81-wip - 28 December, 2017:
- fix multiple CRs before LF (including preventing an immediate flush); - fix multiple CRs before LF (including preventing an immediate flush);
- fix CR, BS and partial RM during CRM; - fix CR, BS and partial RM during CRM;
- fix buffer overflow caused by incorrect critical section. - fix buffer overflow caused by incorrect critical section;
* support the entire 256-color palette;
* setting color by index or RGB will use the nearest console color;
* setting color by index will leave bold/underline unchanged.
1.80 - 24 December, 2017: 1.80 - 24 December, 2017:
- fix unloading; - fix unloading;
@ -573,6 +576,8 @@ Acknowledgments
Vincent Fatica for pointing out \e[K was not right. Vincent Fatica for pointing out \e[K was not right.
Nat Kuhn for pointing out the problem with report cursor position. Nat Kuhn for pointing out the problem with report cursor position.
Thiadmer Riemersma for the nearest color algorithm.
Contact Contact
======= =======
@ -595,4 +600,4 @@ Distribution
============================== ==============================
Jason Hood, 26 December, 2017. Jason Hood, 28 December, 2017.

View File

@ -1,8 +1,8 @@
ANSICON ANSICON
Version 1.80 Version 1.81
This is a complete list of the ANSI escape sequences recognised by ANSICON, This is a complete list of the ANSI/VT escape sequences recognised by ANSICON,
roughly ordered by function. The initial escape character is assumed. The roughly ordered by function. The initial escape character is assumed. The
display consists of the buffer width and window height; add '+' before the display consists of the buffer width and window height; add '+' before the
final character to use the buffer height (e.g. "[2J" will erase the window, final character to use the buffer height (e.g. "[2J" will erase the window,
@ -32,8 +32,8 @@ the Windows default beep (but only if it's not already playing).
35 foreground magenta 35 foreground magenta
36 foreground cyan 36 foreground cyan
37 foreground white 37 foreground white
38;2;# foreground & bold based on index (0-15) 38;2;# foreground based on index (0-255)
38;5;#;#;# ignored (RGB) 38;5;#;#;# foreground based on RGB
39 default foreground (using current intensity) 39 default foreground (using current intensity)
40 background black 40 background black
41 background red 41 background red
@ -43,8 +43,8 @@ the Windows default beep (but only if it's not already playing).
45 background magenta 45 background magenta
46 background cyan 46 background cyan
47 background white 47 background white
48;2;# background & underline based on index (0-15) 48;2;# background based on index (0-255)
48;5;#;#;# ignored (RGB) 48;5;#;#;# background based on RGB
49 default background (using current intensity) 49 default background (using current intensity)
90 foreground bright black 90 foreground bright black
91 foreground bright red 91 foreground bright red
@ -63,6 +63,11 @@ the Windows default beep (but only if it's not already playing).
106 background bright cyan 106 background bright cyan
107 background bright white 107 background bright white
Index is 0-7 for the normal colors and 8-15 for the bright; 16-231
are a 6x6x6 color cube; and 232-255 are a grayscale ramp (without
black or white). Indices 16-255 and RGB colors will find the nearest
color from the first 16.
[J erase from cursor to the end of display [J erase from cursor to the end of display
[0J as above [0J as above
[1J erase from the start of diplay to cursor (inclusive) [1J erase from the start of diplay to cursor (inclusive)
@ -212,10 +217,11 @@ c hard reset:
character 7 (BEL) or escape and backslash character 7 (BEL) or escape and backslash
]4;#;spec,spec...;#...ST ]4;#;spec,spec...;#...ST
set or query the palette: set or query the palette:
# is the ANSI index (0-7, or 8-15 for bold/underline) # is the ANSI index (0-7, or 8-15 for bright)
spec is: spec is:
? send the current value to console input ? send the current value to console input
* send the current and all subsequent values * send the current and all subsequent values
(up to 15 if index is less than that)
#RGB set the color (hexadecimal) #RGB set the color (hexadecimal)
#RRGGBB set the color (hexadecimal) #RRGGBB set the color (hexadecimal)
R,G,B set the color (decimal) R,G,B set the color (decimal)