Bug Fix - #372 Color blending/mapping broken

- Corrected problem in unit test that expected the wrong result.
- Fixed Color::Color (const std::string&) so that the foreground and
  background are now considered two different colors, are upgraded
  separately, if necessary, and then blended.  The problem affected
  all instances of "<256-color> on <16-color>".  Hooray for unit
  tests.
This commit is contained in:
Paul Beckingham 2010-02-06 16:54:07 -05:00
parent 89ae64c5fb
commit 579ebe6130
3 changed files with 49 additions and 42 deletions

View file

@ -83,6 +83,8 @@
+ Fixed bug #371 which caused task to mis-apply certain color rules, like
color.alternate, which was (a) not applied first, and (b) not blended
with the other color rules (thanks to Richard Querin).
+ Fixed bug #372 which incorrectly mapped 16-color backgrounds into the
256-color space.
------ old releases ------------------------------

View file

@ -105,6 +105,12 @@ Color::Color (const std::string& spec)
std::vector <std::string> words;
split (words, modifiable_spec, ' ');
// Construct the color as two separate colors, then blend them later. This
// make it possible to declare a color such as "color1 on black", and have
// the upgrade work properly.
unsigned int fg_value = 0;
unsigned int bg_value = 0;
bool bg = false;
int index;
std::string word;
@ -113,9 +119,9 @@ Color::Color (const std::string& spec)
{
word = lowerCase (trim (*it));
if (word == "bold") value |= _COLOR_BOLD;
else if (word == "bright") value |= _COLOR_BRIGHT;
else if (word == "underline") value |= _COLOR_UNDERLINE;
if (word == "bold") fg_value |= _COLOR_BOLD;
else if (word == "bright") bg_value |= _COLOR_BRIGHT;
else if (word == "underline") fg_value |= _COLOR_UNDERLINE;
else if (word == "on") bg = true;
// X where X is one of black, red, blue ...
@ -123,13 +129,13 @@ Color::Color (const std::string& spec)
{
if (bg)
{
value |= _COLOR_HASBG;
value |= index << 8;
bg_value |= _COLOR_HASBG;
bg_value |= index << 8;
}
else
{
value |= _COLOR_HASFG;
value |= index;
fg_value |= _COLOR_HASFG;
fg_value |= index;
}
}
@ -141,20 +147,18 @@ Color::Color (const std::string& spec)
if (index < 0 || index > 23)
throw std::string ("The color '") + *it + "' is not recognized.";
upgrade ();
if (bg)
{
value |= _COLOR_HASBG;
value |= (index + 232) << 8;
bg_value |= _COLOR_HASBG;
bg_value |= (index + 232) << 8;
bg_value |= _COLOR_256;
}
else
{
value |= _COLOR_HASFG;
value |= index + 232;
fg_value |= _COLOR_HASFG;
fg_value |= index + 232;
fg_value |= _COLOR_256;
}
value |= _COLOR_256;
}
// rgbRGB, where 0 <= R,G,B <= 5.
@ -175,20 +179,18 @@ Color::Color (const std::string& spec)
index = 16 + r*36 + g*6 + b;
upgrade ();
if (bg)
{
value |= _COLOR_HASBG;
value |= index << 8;
bg_value |= _COLOR_HASBG;
bg_value |= index << 8;
bg_value |= _COLOR_256;
}
else
{
value |= _COLOR_HASFG;
value |= index;
fg_value |= _COLOR_HASFG;
fg_value |= index;
fg_value |= _COLOR_256;
}
value |= _COLOR_256;
}
// colorN, where 0 <= N <= 255.
@ -202,20 +204,24 @@ Color::Color (const std::string& spec)
if (bg)
{
value |= _COLOR_HASBG;
value |= index << 8;
bg_value |= _COLOR_HASBG;
bg_value |= index << 8;
bg_value |= _COLOR_256;
}
else
{
value |= _COLOR_HASFG;
value |= index;
fg_value |= _COLOR_HASFG;
fg_value |= index;
fg_value |= _COLOR_256;
}
value |= _COLOR_256;
}
else if (word != "")
throw std::string ("The color '") + *it + "' is not recognized.";
}
// Now combine the fg and bg into a single color.
value = fg_value;
blend (Color (bg_value));
}
////////////////////////////////////////////////////////////////////////////////
@ -392,18 +398,17 @@ void Color::upgrade ()
}
////////////////////////////////////////////////////////////////////////////////
/*
red \033[31m
bold red \033[91m
underline red \033[4;31m
bold underline red \033[1;4;31m
on red \033[41m
on bright red \033[101m
256 fg \033[38;5;Nm
256 bg \033[48;5;Nm
*/
// Sample color codes:
// red \033[31m
// bold red \033[91m
// underline red \033[4;31m
// bold underline red \033[1;4;31m
//
// on red \033[41m
// on bright red \033[101m
//
// 256 fg \033[38;5;Nm
// 256 bg \033[48;5;Nm
std::string Color::colorize (const std::string& input)
{
if (value == 0)

View file

@ -102,7 +102,7 @@ int main (int argc, char** argv)
t.is (Color::colorize ("foo", "white"), std::string ("\033[37mfoo\033[0m"), "white -> ^[[37m");
// 16-color backgrounds.
t.is (Color::colorize ("foo", "on bright black"), std::string ("\033[90mfoo\033[0m"), "on bright black -> ^[[90m");
t.is (Color::colorize ("foo", "on bright black"), std::string ("\033[100mfoo\033[0m"), "on bright black -> ^[[100m");
t.is (Color::colorize ("foo", "on black"), std::string ("\033[40mfoo\033[0m"), "on black -> ^[[40m");
t.is (Color::colorize ("foo", "on red"), std::string ("\033[41mfoo\033[0m"), "on red -> ^[[41m");