diff options
Diffstat (limited to 'far2l/src/console/AnsiEsc.cpp')
-rw-r--r-- | far2l/src/console/AnsiEsc.cpp | 138 |
1 files changed, 96 insertions, 42 deletions
diff --git a/far2l/src/console/AnsiEsc.cpp b/far2l/src/console/AnsiEsc.cpp index 0bcf536b..3dc43aa0 100644 --- a/far2l/src/console/AnsiEsc.cpp +++ b/far2l/src/console/AnsiEsc.cpp @@ -2,6 +2,7 @@ #include "AnsiEsc.hpp" #include "interf.hpp" #include "colors.hpp" +#include "VT256ColorTable.h" namespace AnsiEsc { @@ -54,7 +55,7 @@ static const BYTE BackgroundColor[16] = { }; -static const BYTE Attr2Ansi[8] = { // map console attribute to ANSI number +const BYTE Attr2Ansi[8] = { // map console attribute to ANSI number 0, // black 4, // blue 2, // green @@ -65,6 +66,12 @@ static const BYTE Attr2Ansi[8] = { // map console attribute to ANSI number 7 // white }; +BYTE ConsoleColorToAnsi(BYTE clr) +{ + return Attr2Ansi[clr & 7] | (clr & 8); +} + + ///////////////// void FontState::ParseSuffixM(const int *args, int argc) { @@ -78,15 +85,19 @@ void FontState::ParseSuffixM(const int *args, int argc) const int a = args[i]; if (30 <= a && a <= 37) { foreground = a - 30; + use_rgb_foreground = false; } else if (90 <= a && a <= 97) { foreground = (a - 90) + 8; + use_rgb_foreground = false; } else if (40 <= a && a <= 47) { background = a - 40; + use_rgb_background = false; } else if (100 <= a && a <= 107) { background = (a - 100) + 8; + use_rgb_background = false; } else if (a == 38 || a == 48) { // This is technically incorrect, but it's what xterm does, so @@ -94,11 +105,41 @@ void FontState::ParseSuffixM(const int *args, int argc) // 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 // a colour space identifier). - if (i + 1 < argc) { - if (args[i + 1] == 2) // rgb - i += 4; - else if (args[i + 1] == 5) // index - i += 2; + DWORD rgb = (DWORD)-1; + if (i + 4 < argc && args[i + 1] == 2) { + rgb = args[i + 2] | (args[i + 3] << 8) | (args[i + 4] << 16); + i+= 4; + + } else if (i + 2 < argc && args[i + 1] == 5) { + unsigned int color_index = args[i + 2]; + if (color_index < 16) { + if (a == 38) { + foreground = (BYTE)color_index; + use_rgb_foreground = false; + } else { + background = (BYTE)color_index; + use_rgb_background = false; + } + + } else if (color_index - 16 < VT_256COLOR_TABLE_COUNT) { + rgb = g_VT256ColorTable[color_index - 16]; + } + i+= 2; + + } else { + fprintf(stderr, "ParseSuffixM: bad RGB color\n"); + } + + if (rgb == (DWORD)-1) { + ;// nothing + + } else if (a == 38) { + use_rgb_foreground = true; + rgb_foreground = rgb; + + } else { + use_rgb_background = true; + rgb_background = rgb; } } else switch (a) { @@ -110,13 +151,16 @@ void FontState::ParseSuffixM(const int *args, int argc) case 39: case 49: { - const BYTE def_attr = 7;//FOREGROUND_WHITE; - reverse = false; + rvideo = false; if (a != 49) { - foreground = Attr2Ansi[def_attr & 15]; + foreground = 7; // white + use_rgb_foreground = false; + rgb_foreground = 0; } if (a != 39) { - background = Attr2Ansi[(def_attr >> 4) & 15]; + background = 0; // black + use_rgb_background = false; + rgb_background = 0; } } break; @@ -126,7 +170,7 @@ void FontState::ParseSuffixM(const int *args, int argc) case 5: // blink case 4: underline = true; - break; + break; case 7: rvideo = 1; break; @@ -152,50 +196,60 @@ void FontState::ParseSuffixM(const int *args, int argc) } } -void FontState::FromConsoleAttributes(WORD wAttributes) +void FontState::FromConsoleAttributes(DWORD64 qAttributes) { - bold = (wAttributes & FOREGROUND_INTENSITY) != 0; - underline = (wAttributes & BACKGROUND_INTENSITY) != 0; - foreground = Attr2Ansi[wAttributes & 7]; - background = Attr2Ansi[(wAttributes >> 4) & 7]; + bold = (qAttributes & FOREGROUND_INTENSITY) != 0; + underline = (qAttributes & COMMON_LVB_UNDERSCORE) != 0; + rvideo = (qAttributes & COMMON_LVB_REVERSE_VIDEO) != 0; + foreground = Attr2Ansi[qAttributes & 7]; + background = Attr2Ansi[(qAttributes >> 4) & 7]; + + use_rgb_foreground = (qAttributes & FOREGROUND_TRUECOLOR) != 0; + if (use_rgb_foreground) { + rgb_foreground = GET_RGB_FORE(qAttributes); + } + + use_rgb_background = (qAttributes & BACKGROUND_TRUECOLOR) != 0; + if (use_rgb_background) { + rgb_background = GET_RGB_BACK(qAttributes); + } } -WORD FontState::ToConsoleAttributes() +DWORD64 FontState::ToConsoleAttributes() { - WORD attribut = 0; + DWORD64 attribut = 0; if (concealed) { - if (rvideo) { - attribut = ForegroundColor[foreground] | BackgroundColor[foreground]; - if (bold) { - attribut|= FOREGROUND_INTENSITY | BACKGROUND_INTENSITY; - } - } else { - attribut = ForegroundColor[background] | BackgroundColor[background]; - if (underline) { - attribut|= FOREGROUND_INTENSITY | BACKGROUND_INTENSITY; - } - } - } else if (rvideo) { - attribut = ForegroundColor[background] | BackgroundColor[foreground]; - if (bold) { - attribut|= BACKGROUND_INTENSITY; - } - if (underline) { - attribut|= FOREGROUND_INTENSITY; + attribut = ForegroundColor[background] | BackgroundColor[background]; + + if (use_rgb_background) { + SET_RGB_BOTH(attribut, rgb_background, rgb_background); } + } else { attribut = ForegroundColor[foreground] | BackgroundColor[background]; - if (bold) { - attribut|= FOREGROUND_INTENSITY; + + if (use_rgb_foreground) { + SET_RGB_FORE(attribut, rgb_foreground); } - if (underline) { - attribut|= BACKGROUND_INTENSITY; + + if (use_rgb_background) { + SET_RGB_BACK(attribut, rgb_background); } } - if (reverse) { - attribut = ((attribut >> 4) & 15) | ((attribut & 15) << 4); + + if (bold) { + attribut|= FOREGROUND_INTENSITY; + } + + if (rvideo) { + attribut|= COMMON_LVB_REVERSE_VIDEO; + } + + if (underline) { + attribut|= COMMON_LVB_UNDERSCORE; } + return attribut; } |