Feature - 256-color support

- Improved blending algorithm.
- Added 16- to 256-color upgrade algorithm.
This commit is contained in:
Paul Beckingham 2009-09-27 22:58:40 -04:00
parent bb2eb5f266
commit 0b187f3ff8
2 changed files with 69 additions and 71 deletions

View file

@ -166,8 +166,6 @@ Color::Color (const std::string& spec)
} }
value |= _COLOR_256; value |= _COLOR_256;
value &= ~_COLOR_BOLD;
value &= ~_COLOR_BRIGHT;
} }
// rgbRGB, where 0 <= R,G,B <= 5. // rgbRGB, where 0 <= R,G,B <= 5.
@ -199,8 +197,6 @@ Color::Color (const std::string& spec)
} }
value |= _COLOR_256; value |= _COLOR_256;
value &= ~_COLOR_BOLD;
value &= ~_COLOR_BRIGHT;
} }
// colorN, where 0 <= N <= 255. // colorN, where 0 <= N <= 255.
@ -222,8 +218,6 @@ Color::Color (const std::string& spec)
} }
value |= _COLOR_256; value |= _COLOR_256;
value &= ~_COLOR_BOLD;
value &= ~_COLOR_BRIGHT;
} }
else else
throw std::string ("The color '") + *it + "' is not recognized."; throw std::string ("The color '") + *it + "' is not recognized.";
@ -294,7 +288,7 @@ Color& Color::operator= (const Color& other)
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Color::operator std::string () Color::operator std::string () const
{ {
std::string description; std::string description;
if (value & _COLOR_BOLD) description += "bold"; if (value & _COLOR_BOLD) description += "bold";
@ -319,85 +313,88 @@ Color::operator std::string ()
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Color::operator int () Color::operator int () const
{ {
return (int) value; return (int) value;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// If 'other' has styles that are compatible, merge them into this. Colors in // If 'other' has styles that are compatible, merge them into this. Colors in
// other overwrite. // other take precedence.
void Color::blend (const Color& other) void Color::blend (const Color& other)
{ {
// Matching 256-color specifications. Merge all relevant bits. Color c (other);
if (value & _COLOR_256 && value |= (c.value & _COLOR_UNDERLINE); // Always inherit underline.
other.value & _COLOR_256)
{
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.
}
if (!(other.value & _COLOR_NOFG)) // 16 <-- 16.
if (!(value & _COLOR_256) &&
!(c.value & _COLOR_256))
{ {
value |= (c.value & _COLOR_BOLD); // Inherit bold.
value |= (c.value & _COLOR_BRIGHT); // Inherit bright.
if (!(c.value & _COLOR_NOFG))
{
value &= ~_COLOR_NOFG; // There is now a color.
value &= ~_COLOR_FG; // Remove previous color. value &= ~_COLOR_FG; // Remove previous color.
value |= (other.value & _COLOR_FG); // Apply new color. value |= (c.value & _COLOR_FG); // Apply other color.
value &= ~_COLOR_NOFG; // Now have a color.
}
} }
// Matching 16-color specifications. Merge all relevant bits. if (!(c.value & _COLOR_NOBG))
else if (!(value & _COLOR_256) &&
!(other.value & _COLOR_256))
{
value |= (other.value & _COLOR_BOLD); // Inherit boldness.
value |= (other.value & _COLOR_BRIGHT); // Inherit brightness.
if (!(other.value & _COLOR_NOBG))
{ {
value &= ~_COLOR_NOBG; // There is now a color.
value &= ~_COLOR_BG; // Remove previous color. value &= ~_COLOR_BG; // Remove previous color.
value |= (other.value & _COLOR_BG); // Apply new color. value |= (c.value & _COLOR_BG); // Apply other color.
value &= ~_COLOR_NOBG; // Now have a color.
} }
if (!(other.value & _COLOR_NOFG)) return;
}
// Upgrade either color, if necessary.
if (!(value & _COLOR_256)) upgrade ();
if (!(value & _COLOR_256)) c.upgrade ();
// 256 <-- 256.
if (!(c.value & _COLOR_NOFG))
{ {
value &= ~_COLOR_NOFG; // There is now a color.
value &= ~_COLOR_FG; // Remove previous color. value &= ~_COLOR_FG; // Remove previous color.
value |= (other.value & _COLOR_FG); // Apply new color. value |= (c.value & _COLOR_FG); // Apply other color.
value &= ~_COLOR_NOFG; // Now have a color.
}
} }
// If a 16-color is blended with a 256-color, then the 16-color is upgraded. if (!(c.value & _COLOR_NOBG))
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.
if (!(other.value & _COLOR_NOBG))
{ {
value &= ~_COLOR_NOBG; // There is now a color.
value &= ~_COLOR_BG; // Remove previous color. value &= ~_COLOR_BG; // Remove previous color.
value |= (other.value & _COLOR_BG); // Apply new color. value |= (c.value & _COLOR_BG); // Apply other color.
value &= ~_COLOR_NOBG; // Now have a color. }
} }
if (!(other.value & _COLOR_NOFG)) ////////////////////////////////////////////////////////////////////////////////
void Color::upgrade ()
{ {
value &= ~_COLOR_FG; // Remove previous color. if (!(value & _COLOR_256))
value |= (other.value & _COLOR_FG); // Apply new color. {
value &= ~_COLOR_NOFG; // Now have a color. if (!(value & _COLOR_NOFG))
} {
bool bold = value & _COLOR_BOLD;
unsigned int fg = value & _COLOR_FG;
value &= ~_COLOR_FG;
value &= ~_COLOR_BOLD;
value |= (bold ? fg + 7 : fg - 1);
} }
value |= (other.value & _COLOR_UNDERLINE); // Always inherit underline. if (!(value & _COLOR_NOBG))
{
bool bright = value & _COLOR_BRIGHT;
unsigned int bg = (value & _COLOR_BG) >> 8;
value &= ~_COLOR_BG;
value &= ~_COLOR_BRIGHT;
value |= (bright ? bg + 7 : bg - 1) << 8;
}
value |= _COLOR_256;
}
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -514,7 +511,7 @@ int Color::find (const std::string& input)
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::string Color::fg () std::string Color::fg () const
{ {
int index = value & _COLOR_FG; int index = value & _COLOR_FG;
@ -538,7 +535,7 @@ std::string Color::fg ()
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::string Color::bg () std::string Color::bg () const
{ {
int index = (value & _COLOR_BG) >> 8; int index = (value & _COLOR_BG) >> 8;

View file

@ -42,7 +42,7 @@
class Color class Color
{ {
public: public:
enum color_id {nocolor = 0, black, red, blue, green, magenta, cyan, yellow, white}; enum color_id {nocolor = 0, black, red, green, yellow, blue, magenta, cyan, white};
Color (); Color ();
Color (const Color&); Color (const Color&);
@ -53,9 +53,10 @@ public:
Color (color_id, color_id, bool, bool, bool); // fg, bg, underline, bold, bright Color (color_id, color_id, bool, bool, bool); // fg, bg, underline, bold, bright
~Color (); ~Color ();
Color& operator= (const Color&); Color& operator= (const Color&);
operator std::string (); operator std::string () const;
operator int (); operator int () const;
void upgrade ();
void blend (const Color&); void blend (const Color&);
std::string colorize (const std::string&); std::string colorize (const std::string&);
@ -65,8 +66,8 @@ public:
private: private:
int find (const std::string&); int find (const std::string&);
std::string fg (); std::string fg () const;
std::string bg (); std::string bg () const;
private: private:
unsigned int value; unsigned int value;