From beedc5ab847bebf14e8c8a51ea687db7c20bb3ce Mon Sep 17 00:00:00 2001 From: Michael Carlberg Date: Fri, 27 Jan 2017 13:46:27 +0100 Subject: [PATCH] fix(color_util): Parsing --- include/utils/color.hpp | 17 ++++++++++---- src/components/bar.cpp | 12 +++++----- src/components/config.cpp | 9 +------ src/components/parser.cpp | 9 ++++--- tests/unit_tests/utils/color.cpp | 40 +++++++++++++++++++++++++++++--- 5 files changed, 61 insertions(+), 26 deletions(-) diff --git a/include/utils/color.hpp b/include/utils/color.hpp index cebf86c1..e461efc4 100644 --- a/include/utils/color.hpp +++ b/include/utils/color.hpp @@ -99,7 +99,7 @@ namespace color_util { inline string simplify_hex(string hex) { // convert #ffrrggbb to #rrggbb - if (hex.length() == 9 && hex[1] == 'f' && hex[2] == 'f') { + if (hex.length() == 9 && std::toupper(hex[1]) == 'F' && std::toupper(hex[2]) == 'F') { hex.erase(1, 2); } @@ -122,10 +122,19 @@ struct rgb { // clang-format off explicit rgb(double r, double g, double b) : r(r), g(g), b(b) {} explicit rgb(unsigned int color) : rgb( - color_util::red_channel(color_util::premultiply_alpha(color) / 255.0), - color_util::green_channel(color_util::premultiply_alpha(color) / 255.0), - color_util::blue_channel(color_util::premultiply_alpha(color) / 255.0)) {} + color_util::red_channel(color_util::premultiply_alpha(color)) / 255.0, + color_util::green_channel(color_util::premultiply_alpha(color)) / 255.0, + color_util::blue_channel(color_util::premultiply_alpha(color)) / 255.0) {} // clang-format on + + operator unsigned int() { + // clang-format off + return 0xFF << 24 + | static_cast(r * 255) << 16 + | static_cast(g * 255) << 8 + | static_cast(b * 255); + // clang-format on + } }; struct rgba { diff --git a/src/components/bar.cpp b/src/components/bar.cpp index a6fbe121..33e5cf67 100644 --- a/src/components/bar.cpp +++ b/src/components/bar.cpp @@ -172,9 +172,9 @@ bar::bar(connection& conn, signal_emitter& emitter, const config& config, const } } - const auto parse_or_throw = [&](string key, string def) { + const auto parse_or_throw = [&](string key, unsigned int def) -> unsigned int { try { - return color_util::parse(m_conf.get(bs, key, def)); + return m_conf.get(bs, key, rgba{def}); } catch (const exception& err) { throw application_error(sstream() << "Failed to set " << key << " (reason: " << err.what() << ")"); } @@ -192,14 +192,14 @@ bar::bar(connection& conn, signal_emitter& emitter, const config& config, const m_log.warn("Ignoring `%s.background` (overridden by gradient background)", bs); } } else { - m_opts.background = parse_or_throw("background", color_util::hex(m_opts.background)); + m_opts.background = parse_or_throw("background", m_opts.background); } // Load foreground - m_opts.foreground = parse_or_throw("foreground", color_util::hex(m_opts.foreground)); + m_opts.foreground = parse_or_throw("foreground", m_opts.foreground); // Load over-/underline - auto line_color = m_conf.get(bs, "line-color", "#ffff0000"s); + auto line_color = m_conf.get(bs, "line-color", rgba{0xFFFF0000}); auto line_size = m_conf.get(bs, "line-size", 0); m_opts.overline.size = m_conf.get(bs, "overline-size", line_size); @@ -208,7 +208,7 @@ bar::bar(connection& conn, signal_emitter& emitter, const config& config, const m_opts.underline.color = parse_or_throw("underline-color", line_color); // Load border settings - auto border_color = m_conf.get(bs, "border-color", "#00000000"s); + auto border_color = m_conf.get(bs, "border-color", rgba{0x00000000}); auto border_size = m_conf.get(bs, "border-size", 0); m_opts.borders.emplace(edge::TOP, border_settings{}); diff --git a/src/components/config.cpp b/src/components/config.cpp index d5d547d6..83a942bd 100644 --- a/src/components/config.cpp +++ b/src/components/config.cpp @@ -315,14 +315,7 @@ chrono::duration config::convert(string&& value) const { template <> rgba config::convert(string&& value) const { - auto color = color_util::parse(value, 0); - // clang-format off - return rgba{ - color_util::red_channel(color) / 255.0, - color_util::green_channel(color) / 255.0, - color_util::blue_channel(color) / 255.0, - color_util::alpha_channel(color) / 255.0}; - // clang-format on + return rgba{color_util::parse(value, 0)}; } template <> diff --git a/src/components/parser.cpp b/src/components/parser.cpp index d074c097..f30e5802 100644 --- a/src/components/parser.cpp +++ b/src/components/parser.cpp @@ -77,7 +77,7 @@ void parser::codeblock(string&& data, const bar_settings& bar) { switch (tag) { case 'B': - m_sig.emit(change_background{parse_color(value, bar.background)}); + m_sig.emit(change_background{parse_color(value, 0)}); break; case 'F': @@ -181,11 +181,10 @@ size_t parser::text(string&& data) { * Process color hex string and convert it to the correct value */ unsigned int parser::parse_color(const string& s, unsigned int fallback) { - unsigned int color{0}; - if (s.empty() || s[0] == '-' || (color = color_util::parse(s, fallback)) == fallback) { - return fallback; + if (!s.empty() && s[0] != '-') { + return color_util::parse(s, fallback); } - return color_util::premultiply_alpha(color); + return fallback; } /** diff --git a/tests/unit_tests/utils/color.cpp b/tests/unit_tests/utils/color.cpp index a94e6bed..13f31ee2 100644 --- a/tests/unit_tests/utils/color.cpp +++ b/tests/unit_tests/utils/color.cpp @@ -11,6 +11,11 @@ int main() { expect(color_util::green_channel(color) == 0x34); expect(color_util::green_channel(color) == 0x3434); expect(color_util::blue_channel(color) == 0x56); + + expect(rgb{0xFF112233}.b == 0x33 / 255.0); + expect(rgb{0x88449933}.g == 0x51 / 255.0); + expect(rgb{0xee111111} == 0xff0f0f0f); + expect(rgb{0x99112233} == 0xff0a141e); }; "rgba"_test = []{ @@ -20,20 +25,49 @@ int main() { expect(color_util::red_channel(color) == 0x12); expect(color_util::green_channel(color) == 0x3434); expect(color_util::blue_channel(color) == 0x5656); + + expect(rgba{0xCC112233}.a == 0xCC / 255.0); + expect(rgba{0x88449933}.g == 0x99 / 255.0); + expect(static_cast(rgba{0xFF111111}) == 0xFF111111); + expect(static_cast(rgba{0x00FFFFFF}) == 0x00FFFFFF); }; "hex"_test = [] { unsigned int colorA{0x123456}; - expect(color_util::hex(colorA).compare("#123456") == 0); + expect(color_util::hex(colorA) == "#123456"s); unsigned int colorB{0xCC123456}; - expect(color_util::hex(colorB).compare("#cc123456") == 0); + expect(color_util::hex(colorB) == "#cc123456"s); unsigned int colorC{0x00ffffff}; - expect(color_util::hex(colorC).compare("#00ffffff") == 0); + expect(color_util::hex(colorC) == "#00ffffff"s); + }; + + "parse_hex"_test = [] { + expect(color_util::parse_hex("#fff") == "#ffffffff"); + expect(color_util::parse_hex("#123") == "#ff112233"); + expect(color_util::parse_hex("#888888") == "#ff888888"); + expect(color_util::parse_hex("#00aa00aa") == "#00aa00aa"); + }; + + "parse"_test = [] { + expect(color_util::parse("invalid") == 0); + expect(color_util::parse("#f") == 0); + expect(color_util::parse("#ff") == 0); + expect(color_util::parse("invalid", 0xFF999999) == 0xFF999999); + expect(color_util::parse("invalid", 0x00111111) == 0x00111111); + expect(color_util::parse("invalid", 0xFF000000) == 0xFF000000); + expect(color_util::parse("#fff") == 0xffffffff); + expect(color_util::parse("#890") == 0xFF889900); + expect(color_util::parse("#55888777") == 0x55888777); + expect(color_util::parse("#88aaaaaa") == 0x88aaaaaa); + expect(color_util::parse("#00aaaaaa") == 0x00aaaaaa); + expect(color_util::parse("#00FFFFFF") == 0x00FFFFFF); }; "simplify"_test = [] { + expect(color_util::simplify_hex("#FF111111") == "#111"); expect(color_util::simplify_hex("#ff223344") == "#234"); expect(color_util::simplify_hex("#ee223344") == "#ee223344"); expect(color_util::simplify_hex("#ff234567") == "#234567"); + expect(color_util::simplify_hex("#00223344") == "#00223344"); }; }