Browse Source

Math: ability to Debug colors as actual colored squares.

pull/338/head
Vladimír Vondruš 7 years ago
parent
commit
4b6fabb004
  1. 3
      doc/changelog.dox
  2. 15
      doc/snippets/MagnumMath.cpp
  3. 115
      src/Magnum/Math/Color.cpp
  4. 59
      src/Magnum/Math/Color.h
  5. 50
      src/Magnum/Math/Test/ColorTest.cpp

3
doc/changelog.dox

@ -114,6 +114,9 @@ See also:
- @ref Math::Frustum::begin() / @ref Math::Frustum::end() accessors for
easy range-for access to @ref Math::Frustum planes
- @ref Color3ub and @ref Color4ub can be printed with
@ref Corrade::Utility::Debug as actual colors using the
@ref Corrade::Utility::Debug::color modifier
- Added convenience @ref BoolVector2, @ref BoolVector3 and @ref BoolVector4
typedefs to the root namespace

15
doc/snippets/MagnumMath.cpp

@ -777,6 +777,21 @@ Math::Vector4<UnsignedByte> srgbAlpha = color.toSrgbAlpha<UnsignedByte>();
static_cast<void>(srgbAlpha);
}
{
/* [Color3-debug] */
Debug{Debug::Flag::Color} << 0xdcdcdc_rgb << 0xa5c9ea_rgb << 0x3bd267_rgb
<< 0xc7cf2f_rgb << 0xcd3431_rgb << 0x2f83cc_rgb << 0x747474_rgb;
/* [Color3-debug] */
}
{
/* [Color4-debug] */
Debug{Debug::Flag::Color}
<< 0x3bd26700_rgba << 0x3bd26733_rgba << 0x3bd26766_rgba
<< 0x3bd26799_rgba << 0x3bd267cc_rgba << 0x3bd267ff_rgba;
/* [Color4-debug] */
}
{
/* [_rgb] */
using namespace Math::Literals;

115
src/Magnum/Math/Color.cpp

@ -39,27 +39,106 @@ namespace {
}
Corrade::Utility::Debug& operator<<(Corrade::Utility::Debug& debug, const Color3<UnsignedByte>& value) {
char out[] = "#______";
out[1] = Hex[(value.r() >> 4) & 0xf];
out[2] = Hex[(value.r() >> 0) & 0xf];
out[3] = Hex[(value.g() >> 4) & 0xf];
out[4] = Hex[(value.g() >> 0) & 0xf];
out[5] = Hex[(value.b() >> 4) & 0xf];
out[6] = Hex[(value.b() >> 0) & 0xf];
return debug << out;
/* Print an actual colored square if requested */
if(debug.immediateFlags() & Corrade::Utility::Debug::Flag::Color) {
/* Pick a shade based on calculated lightness */
const Float valueValue = value.value();
const char* shade;
if(valueValue <= 0.2f) shade = " ";
else if(valueValue <= 0.4f) shade = "░░";
else if(valueValue <= 0.6f) shade = "▒▒";
else if(valueValue <= 0.8f) shade = "▓▓";
else shade = "██";
/* If ANSI colors are disabled, use just the shade */
if(debug.immediateFlags() & Corrade::Utility::Debug::Flag::DisableColors)
return debug << shade;
else {
debug << "\033[38;2;";
/* Disable space between values for everything after the initial
value */
const Corrade::Utility::Debug::Flags previousFlags = debug.flags();
debug.setFlags(previousFlags|Corrade::Utility::Debug::Flag::NoSpace);
/* Set both background and foreground, reset back after */
debug << int(value.r()) << ";" << int(value.g()) << ";"
<< int(value.b()) << "m\033[48;2;" << int(value.r()) << ";" <<
int(value.g()) << ";" << int(value.b()) << "m" << shade << "\033[0m";
/* Reset original flags */
debug.setFlags(previousFlags);
return debug;
}
/* Otherwise print a CSS color */
} else {
char out[] = "#______";
out[1] = Hex[(value.r() >> 4) & 0xf];
out[2] = Hex[(value.r() >> 0) & 0xf];
out[3] = Hex[(value.g() >> 4) & 0xf];
out[4] = Hex[(value.g() >> 0) & 0xf];
out[5] = Hex[(value.b() >> 4) & 0xf];
out[6] = Hex[(value.b() >> 0) & 0xf];
return debug << out;
}
}
Corrade::Utility::Debug& operator<<(Corrade::Utility::Debug& debug, const Color4<UnsignedByte>& value) {
char out[] = "#________";
out[1] = Hex[(value.r() >> 4) & 0xf];
out[2] = Hex[(value.r() >> 0) & 0xf];
out[3] = Hex[(value.g() >> 4) & 0xf];
out[4] = Hex[(value.g() >> 0) & 0xf];
out[5] = Hex[(value.b() >> 4) & 0xf];
out[6] = Hex[(value.b() >> 0) & 0xf];
out[7] = Hex[(value.a() >> 4) & 0xf];
out[8] = Hex[(value.a() >> 0) & 0xf];
return debug << out;
/* Print an actual colored square if requested */
if(debug.immediateFlags() & Corrade::Utility::Debug::Flag::Color) {
/* Pick a shade based on calculated lightness */
const Float valueValue = value.value();
const Float alpha = Math::unpack<Float>(value.a());
const Float valueAlpha = valueValue*alpha;
const char* shade;
if(valueAlpha <= 0.2f) shade = " ";
else if(valueAlpha <= 0.4f) shade = "░░";
else if(valueAlpha <= 0.6f) shade = "▒▒";
else if(valueAlpha <= 0.8f) shade = "▓▓";
else shade = "██";
/* If ANSI colors are disabled, use just the shade */
if(debug.immediateFlags() & Corrade::Utility::Debug::Flag::DisableColors)
return debug << shade;
else {
debug << "\033[38;2;";
/* Disable space between values for everything after the initial
value */
const Corrade::Utility::Debug::Flags previousFlags = debug.flags();
debug.setFlags(previousFlags|Corrade::Utility::Debug::Flag::NoSpace);
/* Print foreground color */
debug << int(value.r()) << ";" << int(value.g()) << ";"
<< int(value.b()) << "m";
/* If alpha is larger than perceived value, set also background */
if(alpha > valueValue)
debug << "\033[48;2;" << int(value.r()) << ";" <<
int(value.g()) << ";" << int(value.b()) << "m";
/* Print the shade and reset color back */
debug << shade << "\033[0m";
/* Reset original flags */
debug.setFlags(previousFlags);
return debug;
}
/* Otherwise print a CSS color */
} else {
char out[] = "#________";
out[1] = Hex[(value.r() >> 4) & 0xf];
out[2] = Hex[(value.r() >> 0) & 0xf];
out[3] = Hex[(value.g() >> 4) & 0xf];
out[4] = Hex[(value.g() >> 0) & 0xf];
out[5] = Hex[(value.b() >> 4) & 0xf];
out[6] = Hex[(value.b() >> 0) & 0xf];
out[7] = Hex[(value.a() >> 4) & 0xf];
out[8] = Hex[(value.a() >> 0) & 0xf];
return debug << out;
}
}
}}

59
src/Magnum/Math/Color.h

@ -1292,16 +1292,69 @@ inline Color4<Float> operator "" _srgbaf(unsigned long long value) {
/**
@debugoperator{Color3}
Prints the value as hex color (e.g. @cb{.shell-session} #ff33aa @ce). Other
underlying types are handled by @ref operator<<(Corrade::Utility::Debug&, const Vector<size, T>&).
If @ref Corrade::Utility::Debug::Flag::Color is enabled or
@ref Corrade::Utility::Debug::color was set immediately before, prints the
value as an ANSI 24bit color escape sequence using two successive Unicode block
characters (to have it roughly square). To preserve at least some information
when text is copied, the square consists of one of the five
@cb{.shell-session} @ce shades, however the color is set for both
foreground and background so the actual block character is indistinguishable
when seen on a terminal.
If @ref Corrade::Utility::Debug::Flag::Color is enabled and
@ref Corrade::Utility::Debug::Flag::DisableColors is set, only the shaded
character is used, without any ANSI color escape sequence.
If @ref Corrade::Utility::Debug::Flag::Color is not enabled, the value is
printed as a hex color (e.g. @cb{.shell-session} #ff33aa @ce). Other underlying
types are handled by @ref operator<<(Corrade::Utility::Debug&, const Vector<size, T>&).
For example, the following snippet:
@snippet MagnumMath.cpp Color3-debug
<b></b>
@m_class{m-noindent}
prints the following on terminals that support it:
@include MathColor3-debug.ansi
*/
MAGNUM_EXPORT Corrade::Utility::Debug& operator<<(Corrade::Utility::Debug& debug, const Color3<UnsignedByte>& value);
/**
@debugoperator{Color4}
Prints the value as hex color (e.g. @cb{.shell-session} #9933aaff @ce). Other
If @ref Corrade::Utility::Debug::Flag::Color is enabled or
@ref Corrade::Utility::Debug::color was set immediately before, prints the
value as an ANSI 24bit color escape sequence using two successive Unicode block
characters (to have it roughly square). To preserve at least some information
when text is copied, the square consists of one of the five
@cb{.shell-session} @ce shades. The square shade is calculated as a
product of @ref Color4::value() and @ref Color4::a(). If calculated color value
is less than alpha, the colored square has the color set for both background
and foreground, otherwise the background is left at the default.
If @ref Corrade::Utility::Debug::Flag::Color is enabled and
@ref Corrade::Utility::Debug::Flag::DisableColors is set, only the shaded
character is used, without any ANSI color escape sequence.
If @ref Corrade::Utility::Debug::Flag::Color is not enabled, the value is
printed as a hex color (e.g. @cb{.shell-session} #ff33aaff @ce). Other
underlying types are handled by @ref operator<<(Corrade::Utility::Debug&, const Vector<size, T>&).
For example, the following snippet:
@snippet MagnumMath.cpp Color4-debug
<b></b>
@m_class{m-noindent}
prints the following on terminals that support it:
@include MathColor4-debug.ansi
*/
MAGNUM_EXPORT Corrade::Utility::Debug& operator<<(Corrade::Utility::Debug& debug, const Color4<UnsignedByte>& value);
#endif

50
src/Magnum/Math/Test/ColorTest.cpp

@ -122,6 +122,8 @@ struct ColorTest: Corrade::TestSuite::Tester {
void swizzleType();
void debug();
void debugUb();
void debugUbColor();
void debugUbColorColorsDisabled();
void debugHsv();
#if defined(DOXYGEN_GENERATING_OUTPUT) || defined(CORRADE_TARGET_UNIX) || (defined(CORRADE_TARGET_WINDOWS) && !defined(CORRADE_TARGET_WINDOWS_RT)) || defined(CORRADE_TARGET_EMSCRIPTEN)
@ -246,6 +248,8 @@ ColorTest::ColorTest() {
&ColorTest::swizzleType,
&ColorTest::debug,
&ColorTest::debugUb,
&ColorTest::debugUbColor,
&ColorTest::debugUbColorColorsDisabled,
&ColorTest::debugHsv});
#if defined(DOXYGEN_GENERATING_OUTPUT) || defined(CORRADE_TARGET_UNIX) || (defined(CORRADE_TARGET_WINDOWS) && !defined(CORRADE_TARGET_WINDOWS_RT)) || defined(CORRADE_TARGET_EMSCRIPTEN)
@ -1019,6 +1023,52 @@ void ColorTest::debugUb() {
CORRADE_COMPARE(o.str(), "#12345678 #90abcdef\n");
}
void ColorTest::debugUbColor() {
Debug{} << "The following should be the Magnum / m.css color palette:";
Debug{Debug::Flag::Color}
<< 0xdcdcdc_rgb << 0xa5c9ea_rgb << 0x3bd267_rgb
<< 0xc7cf2f_rgb << 0xcd3431_rgb << 0x2f83cc_rgb << 0x747474_rgb;
Debug{} << "The following should have increasing (overmultiplied) alpha:";
Debug{Debug::Flag::Color}
<< 0x3bd26700_rgba << 0x3bd26733_rgba << 0x3bd26766_rgba
<< 0x3bd26799_rgba << 0x3bd267cc_rgba << 0x3bd267ff_rgba;
/* It should work just for the immediately following value */
std::ostringstream out;
Debug{&out}
<< Debug::color << 0x3bd267_rgb
<< Debug::color << 0x2f83cc99_rgba
<< 0x3bd267_rgb << 0x2f83cc99_rgba;
CORRADE_COMPARE(out.str(),
"\033[38;2;59;210;103m\033[48;2;59;210;103m██\033[0m "
"\033[38;2;47;131;204m▒▒\033[0m #3bd267 #2f83cc99\n");
}
void ColorTest::debugUbColorColorsDisabled() {
Debug{} << "The following should be the Magnum / m.css uncolored palette:";
Debug{Debug::Flag::Color|Debug::Flag::DisableColors}
<< 0xdcdcdc_rgb << 0xa5c9ea_rgb << 0x3bd267_rgb
<< 0xc7cf2f_rgb << 0xcd3431_rgb << 0x2f83cc_rgb << 0x747474_rgb;
Debug{} << "The following should have increasing (overmultiplied) alpha:";
Debug{Debug::Flag::Color|Debug::Flag::DisableColors}
<< 0x3bd26700_rgba << 0x3bd26733_rgba << 0x3bd26766_rgba
<< 0x3bd26799_rgba << 0x3bd267cc_rgba << 0x3bd267ff_rgba;
/* It should work just for the immediately following value */
std::ostringstream out;
Debug{&out, Debug::Flag::DisableColors}
<< Debug::color << 0x2f83cc_rgb
<< Debug::color << 0x2f83cc99_rgba
<< 0x2f83cc_rgb << 0x2f83cc99_rgba;
CORRADE_COMPARE(out.str(), "▓▓ ▒▒ #2f83cc #2f83cc99\n");
}
void ColorTest::debugHsv() {
std::ostringstream out;
Debug{&out} << ColorHsv(135.0_degf, 0.75f, 0.3f);

Loading…
Cancel
Save