Feature - 256-color support
- Eliminated old color implementation. - Integration, debugging remains.
This commit is contained in:
239
src/Color.cpp
239
src/Color.cpp
@@ -31,6 +31,7 @@
|
||||
#include <algorithm>
|
||||
#include "Color.h"
|
||||
#include "text.h"
|
||||
#include "i18n.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static struct
|
||||
@@ -41,16 +42,16 @@ static struct
|
||||
int index; // offset red=3 (therefore fg=33, bg=43)
|
||||
} allColors[] =
|
||||
{
|
||||
// Color.h enum i18n.h English Index
|
||||
{ Color::nocolor, 0, "", 0},
|
||||
{ Color::black, 0/*COLOR_BLACK*/, "black", 1}, // fg 29+0 bg 39+0
|
||||
{ Color::red, 0/*COLOR_RED*/, "red", 2},
|
||||
{ Color::green, 0/*COLOR_GREEN*/, "green", 3},
|
||||
{ Color::yellow, 0/*COLOR_YELLOW*/, "yellow", 4},
|
||||
{ Color::blue, 0/*COLOR_BLUE*/, "blue", 5},
|
||||
{ Color::magenta, 0/*COLOR_MAGENTA*/, "magenta", 6},
|
||||
{ Color::cyan, 0/*COLOR_CYAN*/, "cyan", 7},
|
||||
{ Color::white, 0/*COLOR_WHITE*/, "white", 8},
|
||||
// Color.h enum i18n.h English Index
|
||||
{ Color::nocolor, 0, "", 0},
|
||||
{ Color::black, COLOR_BLACK, "black", 1}, // fg 29+0 bg 39+0
|
||||
{ Color::red, COLOR_RED, "red", 2},
|
||||
{ Color::green, COLOR_GREEN, "green", 3},
|
||||
{ Color::yellow, COLOR_YELLOW, "yellow", 4},
|
||||
{ Color::blue, COLOR_BLUE, "blue", 5},
|
||||
{ Color::magenta, COLOR_MAGENTA, "magenta", 6},
|
||||
{ Color::cyan, COLOR_CYAN, "cyan", 7},
|
||||
{ Color::white, COLOR_WHITE, "white", 8},
|
||||
|
||||
};
|
||||
|
||||
@@ -58,7 +59,7 @@ static struct
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Color::Color ()
|
||||
: value (COLOR_NOFG | COLOR_NOBG)
|
||||
: value (_COLOR_NOFG | _COLOR_NOBG)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -70,13 +71,13 @@ Color::Color (const Color& other)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Color::Color (unsigned int c)
|
||||
: value (COLOR_NOFG | COLOR_NOBG)
|
||||
: value (_COLOR_NOFG | _COLOR_NOBG)
|
||||
{
|
||||
if (!(c & COLOR_FG)) value &= ~COLOR_FG;
|
||||
if (!(c & COLOR_BG)) value &= ~COLOR_BG;
|
||||
if (!(c & _COLOR_FG)) value &= ~_COLOR_FG;
|
||||
if (!(c & _COLOR_BG)) value &= ~_COLOR_BG;
|
||||
|
||||
value = c & (COLOR_256 | COLOR_UNDERLINE | COLOR_BOLD | COLOR_BRIGHT |
|
||||
COLOR_BG | COLOR_FG);
|
||||
value = c & (_COLOR_256 | _COLOR_UNDERLINE | _COLOR_BOLD | _COLOR_BRIGHT |
|
||||
_COLOR_BG | _COLOR_FG);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -92,7 +93,7 @@ Color::Color (unsigned int c)
|
||||
// colorN 0 <= N <= 255 fg 38;5;N bg 48;5;N
|
||||
// rgbRGB 0 <= R,G,B <= 5 fg 38;5;16 + R*36 + G*6 + B bg 48;5;16 + R*36 + G*6 + B
|
||||
Color::Color (const std::string& spec)
|
||||
: value (COLOR_NOFG | COLOR_NOBG)
|
||||
: value (_COLOR_NOFG | _COLOR_NOBG)
|
||||
{
|
||||
// By converting underscores to spaces, we inherently support the old "on_red"
|
||||
// style of specifying background colors.
|
||||
@@ -113,17 +114,17 @@ Color::Color (const std::string& spec)
|
||||
|
||||
if (word == "bold")
|
||||
{
|
||||
value |= COLOR_BOLD;
|
||||
value &= ~COLOR_256;
|
||||
value |= _COLOR_BOLD;
|
||||
value &= ~_COLOR_256;
|
||||
}
|
||||
else if (word == "bright")
|
||||
{
|
||||
value |= COLOR_BRIGHT;
|
||||
value &= ~COLOR_256;
|
||||
value |= _COLOR_BRIGHT;
|
||||
value &= ~_COLOR_256;
|
||||
}
|
||||
else if (word == "underline")
|
||||
{
|
||||
value |= COLOR_UNDERLINE;
|
||||
value |= _COLOR_UNDERLINE;
|
||||
}
|
||||
else if (word == "on")
|
||||
{
|
||||
@@ -135,12 +136,12 @@ Color::Color (const std::string& spec)
|
||||
{
|
||||
if (bg)
|
||||
{
|
||||
value &= ~COLOR_NOBG;
|
||||
value &= ~_COLOR_NOBG;
|
||||
value |= index << 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
value &= ~COLOR_NOFG;
|
||||
value &= ~_COLOR_NOFG;
|
||||
value |= index;
|
||||
}
|
||||
}
|
||||
@@ -155,16 +156,16 @@ Color::Color (const std::string& spec)
|
||||
|
||||
if (bg)
|
||||
{
|
||||
value &= ~COLOR_NOBG;
|
||||
value &= ~_COLOR_NOBG;
|
||||
value |= (index + 232) << 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
value &= ~COLOR_NOFG;
|
||||
value &= ~_COLOR_NOFG;
|
||||
value |= index + 232;
|
||||
}
|
||||
|
||||
value |= COLOR_256;
|
||||
value |= _COLOR_256;
|
||||
}
|
||||
|
||||
// rgbRGB, where 0 <= R,G,B <= 5.
|
||||
@@ -186,16 +187,16 @@ Color::Color (const std::string& spec)
|
||||
index = 16 + r*36 + g*6 + b;
|
||||
if (bg)
|
||||
{
|
||||
value &= ~COLOR_NOBG;
|
||||
value &= ~_COLOR_NOBG;
|
||||
value |= index << 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
value &= ~COLOR_NOFG;
|
||||
value &= ~_COLOR_NOFG;
|
||||
value |= index;
|
||||
}
|
||||
|
||||
value |= COLOR_256;
|
||||
value |= _COLOR_256;
|
||||
}
|
||||
|
||||
// colorN, where 0 <= N <= 255.
|
||||
@@ -207,16 +208,16 @@ Color::Color (const std::string& spec)
|
||||
|
||||
if (bg)
|
||||
{
|
||||
value &= ~COLOR_NOBG;
|
||||
value &= ~_COLOR_NOBG;
|
||||
value |= index << 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
value &= ~COLOR_NOFG;
|
||||
value &= ~_COLOR_NOFG;
|
||||
value |= index;
|
||||
}
|
||||
|
||||
value |= COLOR_256;
|
||||
value |= _COLOR_256;
|
||||
}
|
||||
else
|
||||
throw std::string ("The color '") + *it + "' is not recognized.";
|
||||
@@ -224,22 +225,50 @@ Color::Color (const std::string& spec)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Color::Color (color_id fg, color_id bg, bool underline, bool bold, bool bright)
|
||||
: value (COLOR_NOFG | COLOR_NOBG)
|
||||
Color::Color (color_id fg)
|
||||
: value (_COLOR_NOFG | _COLOR_NOBG)
|
||||
{
|
||||
value = ((underline ? 1 : 0) << 18)
|
||||
| ((bold ? 1 : 0) << 17)
|
||||
| ((bright ? 1 : 0) << 16);
|
||||
if (fg != Color::nocolor)
|
||||
{
|
||||
value &= ~_COLOR_NOFG;
|
||||
value |= fg;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Color::Color (color_id fg, color_id bg)
|
||||
: value (_COLOR_NOFG | _COLOR_NOBG)
|
||||
{
|
||||
if (bg != Color::nocolor)
|
||||
{
|
||||
value &= ~COLOR_NOBG;
|
||||
value &= ~_COLOR_NOBG;
|
||||
value |= (bg << 8);
|
||||
}
|
||||
|
||||
if (fg != Color::nocolor)
|
||||
{
|
||||
value &= ~COLOR_NOFG;
|
||||
value &= ~_COLOR_NOFG;
|
||||
value |= fg;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Color::Color (color_id fg, color_id bg, bool underline, bool bold, bool bright)
|
||||
: value (_COLOR_NOFG | _COLOR_NOBG)
|
||||
{
|
||||
value |= ((underline ? 1 : 0) << 18)
|
||||
| ((bold ? 1 : 0) << 17)
|
||||
| ((bright ? 1 : 0) << 16);
|
||||
|
||||
if (bg != Color::nocolor)
|
||||
{
|
||||
value &= ~_COLOR_NOBG;
|
||||
value |= (bg << 8);
|
||||
}
|
||||
|
||||
if (fg != Color::nocolor)
|
||||
{
|
||||
value &= ~_COLOR_NOFG;
|
||||
value |= fg;
|
||||
}
|
||||
}
|
||||
@@ -262,19 +291,19 @@ Color& Color::operator= (const Color& other)
|
||||
Color::operator std::string ()
|
||||
{
|
||||
std::string description;
|
||||
if (value & COLOR_BOLD) description += "bold";
|
||||
if (value & _COLOR_BOLD) description += "bold";
|
||||
|
||||
if (value & COLOR_UNDERLINE)
|
||||
if (value & _COLOR_UNDERLINE)
|
||||
description += std::string (description.length () ? " " : "") + "underline";
|
||||
|
||||
if (!(value & COLOR_NOFG))
|
||||
if (!(value & _COLOR_NOFG))
|
||||
description += std::string (description.length () ? " " : "") + fg ();
|
||||
|
||||
if (!(value & COLOR_NOBG))
|
||||
if (!(value & _COLOR_NOBG))
|
||||
{
|
||||
description += std::string (description.length () ? " " : "") + "on";
|
||||
|
||||
if (value & COLOR_BRIGHT)
|
||||
if (value & _COLOR_BRIGHT)
|
||||
description += std::string (description.length () ? " " : "") + "bright";
|
||||
|
||||
description += " " + bg ();
|
||||
@@ -295,74 +324,74 @@ Color::operator int ()
|
||||
void Color::blend (const Color& other)
|
||||
{
|
||||
// Matching 256-color specifications. Merge all relevant bits.
|
||||
if (value & COLOR_256 &&
|
||||
other.value & COLOR_256)
|
||||
if (value & _COLOR_256 &&
|
||||
other.value & _COLOR_256)
|
||||
{
|
||||
if (!(other.value & COLOR_NOBG))
|
||||
if (!(other.value & _COLOR_NOBG))
|
||||
{
|
||||
value &= ~COLOR_BG; // Remove previous color.
|
||||
value |= (other.value & COLOR_BG); // Apply new color.
|
||||
value &= ~COLOR_NOBG; // Now have a color.
|
||||
value &= ~_COLOR_BG; // Remove previous color.
|
||||
value |= (other.value & _COLOR_BG); // Apply new color.
|
||||
value &= ~_COLOR_NOBG; // Now have a color.
|
||||
}
|
||||
|
||||
if (!(other.value & COLOR_NOFG))
|
||||
if (!(other.value & _COLOR_NOFG))
|
||||
{
|
||||
value &= ~COLOR_FG; // Remove previous color.
|
||||
value |= (other.value & COLOR_FG); // Apply new color.
|
||||
value &= ~COLOR_NOFG; // Now have a color.
|
||||
value &= ~_COLOR_FG; // Remove previous color.
|
||||
value |= (other.value & _COLOR_FG); // Apply new color.
|
||||
value &= ~_COLOR_NOFG; // Now have a color.
|
||||
}
|
||||
}
|
||||
|
||||
// Matching 16-color specifications. Merge all relevant bits.
|
||||
else if (!(value & COLOR_256) &&
|
||||
!(other.value & COLOR_256))
|
||||
else if (!(value & _COLOR_256) &&
|
||||
!(other.value & _COLOR_256))
|
||||
{
|
||||
value |= (other.value & COLOR_BOLD); // Inherit boldness.
|
||||
value |= (other.value & COLOR_BRIGHT); // Inherit brightness.
|
||||
value |= (other.value & _COLOR_BOLD); // Inherit boldness.
|
||||
value |= (other.value & _COLOR_BRIGHT); // Inherit brightness.
|
||||
|
||||
if (!(other.value & COLOR_NOBG))
|
||||
if (!(other.value & _COLOR_NOBG))
|
||||
{
|
||||
value &= ~COLOR_BG; // Remove previous color.
|
||||
value |= (other.value & COLOR_BG); // Apply new color.
|
||||
value &= ~COLOR_NOBG; // Now have a color.
|
||||
value &= ~_COLOR_BG; // Remove previous color.
|
||||
value |= (other.value & _COLOR_BG); // Apply new color.
|
||||
value &= ~_COLOR_NOBG; // Now have a color.
|
||||
}
|
||||
|
||||
if (!(other.value & COLOR_NOFG))
|
||||
if (!(other.value & _COLOR_NOFG))
|
||||
{
|
||||
value &= ~COLOR_FG; // Remove previous color.
|
||||
value |= (other.value & COLOR_FG); // Apply new color.
|
||||
value &= ~COLOR_NOFG; // Now have a color.
|
||||
value &= ~_COLOR_FG; // Remove previous color.
|
||||
value |= (other.value & _COLOR_FG); // Apply new color.
|
||||
value &= ~_COLOR_NOFG; // Now have a color.
|
||||
}
|
||||
}
|
||||
|
||||
// If a 16-color is blended with a 256-color, then the 16-color is upgraded.
|
||||
else if (!(value & COLOR_256) &&
|
||||
other.value & COLOR_256)
|
||||
else if (!(value & _COLOR_256) &&
|
||||
other.value & _COLOR_256)
|
||||
{
|
||||
value |= COLOR_256; // Upgrade to 256-color.
|
||||
value &= ~COLOR_BOLD; // Ignore boldness.
|
||||
value &= ~COLOR_BRIGHT; // Ignore brightness.
|
||||
value &= ~COLOR_FG; // Ignore original 16-color.
|
||||
value &= ~COLOR_BG; // Ignore original 16-color.
|
||||
value |= COLOR_NOFG; // No fg.
|
||||
value |= COLOR_NOBG; // No bg.
|
||||
value |= _COLOR_256; // Upgrade to 256-color.
|
||||
value &= ~_COLOR_BOLD; // Ignore boldness.
|
||||
value &= ~_COLOR_BRIGHT; // Ignore brightness.
|
||||
value &= ~_COLOR_FG; // Ignore original 16-color.
|
||||
value &= ~_COLOR_BG; // Ignore original 16-color.
|
||||
value |= _COLOR_NOFG; // No fg.
|
||||
value |= _COLOR_NOBG; // No bg.
|
||||
|
||||
if (!(other.value & COLOR_NOBG))
|
||||
if (!(other.value & _COLOR_NOBG))
|
||||
{
|
||||
value &= ~COLOR_BG; // Remove previous color.
|
||||
value |= (other.value & COLOR_BG); // Apply new color.
|
||||
value &= ~COLOR_NOBG; // Now have a color.
|
||||
value &= ~_COLOR_BG; // Remove previous color.
|
||||
value |= (other.value & _COLOR_BG); // Apply new color.
|
||||
value &= ~_COLOR_NOBG; // Now have a color.
|
||||
}
|
||||
|
||||
if (!(other.value & COLOR_NOFG))
|
||||
if (!(other.value & _COLOR_NOFG))
|
||||
{
|
||||
value &= ~COLOR_FG; // Remove previous color.
|
||||
value |= (other.value & COLOR_FG); // Apply new color.
|
||||
value &= ~COLOR_NOFG; // Now have a color.
|
||||
value &= ~_COLOR_FG; // Remove previous color.
|
||||
value |= (other.value & _COLOR_FG); // Apply new color.
|
||||
value &= ~_COLOR_NOFG; // Now have a color.
|
||||
}
|
||||
}
|
||||
|
||||
value |= (other.value & COLOR_UNDERLINE); // Always inherit underline.
|
||||
value |= (other.value & _COLOR_UNDERLINE); // Always inherit underline.
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -387,16 +416,16 @@ std::string Color::colorize (const std::string& input)
|
||||
std::stringstream result;
|
||||
|
||||
// 256 color
|
||||
if (value & COLOR_256)
|
||||
if (value & _COLOR_256)
|
||||
{
|
||||
if (value & COLOR_UNDERLINE)
|
||||
if (value & _COLOR_UNDERLINE)
|
||||
result << "\033[4m";
|
||||
|
||||
if (!(value & COLOR_NOFG))
|
||||
result << "\033[38;5;" << (value & COLOR_FG) << "m";
|
||||
if (!(value & _COLOR_NOFG))
|
||||
result << "\033[38;5;" << (value & _COLOR_FG) << "m";
|
||||
|
||||
if (!(value & COLOR_NOBG))
|
||||
result << "\033[48;5;" << ((value & COLOR_BG) >> 8) << "m";
|
||||
if (!(value & _COLOR_NOBG))
|
||||
result << "\033[48;5;" << ((value & _COLOR_BG) >> 8) << "m";
|
||||
}
|
||||
|
||||
// 16 color
|
||||
@@ -404,28 +433,28 @@ std::string Color::colorize (const std::string& input)
|
||||
{
|
||||
result << "\033[";
|
||||
|
||||
if (value & COLOR_BOLD)
|
||||
if (value & _COLOR_BOLD)
|
||||
{
|
||||
if (count++) result << ";";
|
||||
result << "1";
|
||||
}
|
||||
|
||||
if (value & COLOR_UNDERLINE)
|
||||
if (value & _COLOR_UNDERLINE)
|
||||
{
|
||||
if (count++) result << ";";
|
||||
result << "4";
|
||||
}
|
||||
|
||||
if (!(value & COLOR_NOBG))
|
||||
if (!(value & _COLOR_NOBG))
|
||||
{
|
||||
if (count++) result << ";";
|
||||
result << ((value & COLOR_BRIGHT ? 99 : 39) + ((value & COLOR_BG) >> 8));
|
||||
result << ((value & _COLOR_BRIGHT ? 99 : 39) + ((value & _COLOR_BG) >> 8));
|
||||
}
|
||||
|
||||
if (!(value & COLOR_NOFG))
|
||||
if (!(value & _COLOR_NOFG))
|
||||
{
|
||||
if (count++) result << ";";
|
||||
result << (29 + (value & COLOR_FG));
|
||||
result << (29 + (value & _COLOR_FG));
|
||||
}
|
||||
|
||||
result << "m";
|
||||
@@ -455,14 +484,14 @@ int Color::find (const std::string& input)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string Color::fg ()
|
||||
{
|
||||
int index = value & COLOR_FG;
|
||||
int index = value & _COLOR_FG;
|
||||
|
||||
if (value & COLOR_256)
|
||||
if (value & _COLOR_256)
|
||||
{
|
||||
if (!(value & COLOR_NOFG))
|
||||
if (!(value & _COLOR_NOFG))
|
||||
{
|
||||
std::stringstream s;
|
||||
s << "color" << (value & COLOR_FG);
|
||||
s << "color" << (value & _COLOR_FG);
|
||||
return s.str ();
|
||||
}
|
||||
}
|
||||
@@ -479,14 +508,14 @@ std::string Color::fg ()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string Color::bg ()
|
||||
{
|
||||
int index = (value & COLOR_BG) >> 8;
|
||||
int index = (value & _COLOR_BG) >> 8;
|
||||
|
||||
if (value & COLOR_256)
|
||||
if (value & _COLOR_256)
|
||||
{
|
||||
if (!(value & COLOR_NOBG))
|
||||
if (!(value & _COLOR_NOBG))
|
||||
{
|
||||
std::stringstream s;
|
||||
s << "color" << ((value & COLOR_BG) >> 8);
|
||||
s << "color" << ((value & _COLOR_BG) >> 8);
|
||||
return s.str ();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user