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_BOLD;
value &= ~_COLOR_BRIGHT;
}
// rgbRGB, where 0 <= R,G,B <= 5.
@ -199,8 +197,6 @@ Color::Color (const std::string& spec)
}
value |= _COLOR_256;
value &= ~_COLOR_BOLD;
value &= ~_COLOR_BRIGHT;
}
// colorN, where 0 <= N <= 255.
@ -222,8 +218,6 @@ Color::Color (const std::string& spec)
}
value |= _COLOR_256;
value &= ~_COLOR_BOLD;
value &= ~_COLOR_BRIGHT;
}
else
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;
if (value & _COLOR_BOLD) description += "bold";
@ -319,85 +313,88 @@ Color::operator std::string ()
}
////////////////////////////////////////////////////////////////////////////////
Color::operator int ()
Color::operator int () const
{
return (int) value;
}
////////////////////////////////////////////////////////////////////////////////
// If 'other' has styles that are compatible, merge them into this. Colors in
// other overwrite.
// other take precedence.
void Color::blend (const Color& other)
{
// Matching 256-color specifications. Merge all relevant bits.
if (value & _COLOR_256 &&
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.
}
Color c (other);
value |= (c.value & _COLOR_UNDERLINE); // Always inherit underline.
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 |= (other.value & _COLOR_FG); // Apply new color.
value &= ~_COLOR_NOFG; // Now have a color.
}
value |= (c.value & _COLOR_FG); // Apply other color.
}
// Matching 16-color specifications. Merge all relevant bits.
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))
if (!(c.value & _COLOR_NOBG))
{
value &= ~_COLOR_NOBG; // There is now a color.
value &= ~_COLOR_BG; // Remove previous color.
value |= (other.value & _COLOR_BG); // Apply new color.
value &= ~_COLOR_NOBG; // Now have a color.
value |= (c.value & _COLOR_BG); // Apply other 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 |= (other.value & _COLOR_FG); // Apply new color.
value &= ~_COLOR_NOFG; // Now have a color.
}
value |= (c.value & _COLOR_FG); // Apply other 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)
{
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 (!(c.value & _COLOR_NOBG))
{
value &= ~_COLOR_NOBG; // There is now a color.
value &= ~_COLOR_BG; // Remove previous color.
value |= (other.value & _COLOR_BG); // Apply new color.
value &= ~_COLOR_NOBG; // Now have a color.
value |= (c.value & _COLOR_BG); // Apply other color.
}
}
if (!(other.value & _COLOR_NOFG))
////////////////////////////////////////////////////////////////////////////////
void Color::upgrade ()
{
value &= ~_COLOR_FG; // Remove previous color.
value |= (other.value & _COLOR_FG); // Apply new color.
value &= ~_COLOR_NOFG; // Now have a color.
}
if (!(value & _COLOR_256))
{
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;
@ -538,7 +535,7 @@ std::string Color::fg ()
}
////////////////////////////////////////////////////////////////////////////////
std::string Color::bg ()
std::string Color::bg () const
{
int index = (value & _COLOR_BG) >> 8;

View file

@ -42,7 +42,7 @@
class Color
{
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 (const Color&);
@ -53,9 +53,10 @@ public:
Color (color_id, color_id, bool, bool, bool); // fg, bg, underline, bold, bright
~Color ();
Color& operator= (const Color&);
operator std::string ();
operator int ();
operator std::string () const;
operator int () const;
void upgrade ();
void blend (const Color&);
std::string colorize (const std::string&);
@ -65,8 +66,8 @@ public:
private:
int find (const std::string&);
std::string fg ();
std::string bg ();
std::string fg () const;
std::string bg () const;
private:
unsigned int value;