From 0b187f3ff8f72bec5ac811a96ee37843933c197f Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sun, 27 Sep 2009 22:58:40 -0400 Subject: [PATCH] Feature - 256-color support - Improved blending algorithm. - Added 16- to 256-color upgrade algorithm. --- src/Color.cpp | 129 ++++++++++++++++++++++++-------------------------- src/Color.h | 11 +++-- 2 files changed, 69 insertions(+), 71 deletions(-) diff --git a/src/Color.cpp b/src/Color.cpp index 8862b8ca0..411e3ca33 100644 --- a/src/Color.cpp +++ b/src/Color.cpp @@ -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) + Color c (other); + value |= (c.value & _COLOR_UNDERLINE); // Always inherit underline. + + // 16 <-- 16. + if (!(value & _COLOR_256) && + !(c.value & _COLOR_256)) { - if (!(other.value & _COLOR_NOBG)) + value |= (c.value & _COLOR_BOLD); // Inherit bold. + value |= (c.value & _COLOR_BRIGHT); // Inherit bright. + + if (!(c.value & _COLOR_NOFG)) { - value &= ~_COLOR_BG; // Remove previous color. - value |= (other.value & _COLOR_BG); // Apply new color. - value &= ~_COLOR_NOBG; // Now have a color. + value &= ~_COLOR_NOFG; // There is now a color. + value &= ~_COLOR_FG; // Remove previous color. + value |= (c.value & _COLOR_FG); // Apply other color. } - if (!(other.value & _COLOR_NOFG)) + if (!(c.value & _COLOR_NOBG)) { - value &= ~_COLOR_FG; // Remove previous color. - value |= (other.value & _COLOR_FG); // Apply new color. - value &= ~_COLOR_NOFG; // Now have a color. + value &= ~_COLOR_NOBG; // There is now a color. + value &= ~_COLOR_BG; // Remove previous color. + value |= (c.value & _COLOR_BG); // Apply other color. } + + return; } - // Matching 16-color specifications. Merge all relevant bits. - else if (!(value & _COLOR_256) && - !(other.value & _COLOR_256)) + // Upgrade either color, if necessary. + if (!(value & _COLOR_256)) upgrade (); + if (!(value & _COLOR_256)) c.upgrade (); + + // 256 <-- 256. + if (!(c.value & _COLOR_NOFG)) { - value |= (other.value & _COLOR_BOLD); // Inherit boldness. - value |= (other.value & _COLOR_BRIGHT); // Inherit brightness. - - 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)) - { - value &= ~_COLOR_FG; // Remove previous color. - value |= (other.value & _COLOR_FG); // Apply new color. - value &= ~_COLOR_NOFG; // Now have a color. - } + value &= ~_COLOR_NOFG; // There is now a color. + value &= ~_COLOR_FG; // Remove previous 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) + if (!(c.value & _COLOR_NOBG)) { - 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_BG; // Remove previous color. - value |= (other.value & _COLOR_BG); // Apply new color. - value &= ~_COLOR_NOBG; // Now have a color. - } - - 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_NOBG; // There is now a color. + value &= ~_COLOR_BG; // Remove previous color. + value |= (c.value & _COLOR_BG); // Apply other color. } +} - value |= (other.value & _COLOR_UNDERLINE); // Always inherit underline. +//////////////////////////////////////////////////////////////////////////////// +void Color::upgrade () +{ + 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); + } + + 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; diff --git a/src/Color.h b/src/Color.h index 32cc0bb4f..4fccd5a27 100644 --- a/src/Color.h +++ b/src/Color.h @@ -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;