From 5c1031305c98fbfe8ea288d68b5c309d10f17760 Mon Sep 17 00:00:00 2001 From: tsteven4 <13596209+tsteven4@users.noreply.github.com> Date: Tue, 22 Oct 2024 08:09:51 -0600 Subject: [PATCH] Qtize rgbcolors. (#1356) * Qtize rgbcolors. * use big stick to validate hex color codes --- defs.h | 2 +- ozi.cc | 4 +- rgbcolors.cc | 367 ++++++++++++++++++++++------------------------- testo.d/ozi.test | 3 + 4 files changed, 181 insertions(+), 195 deletions(-) diff --git a/defs.h b/defs.h index 5a2749243..ac8c54382 100644 --- a/defs.h +++ b/defs.h @@ -1037,7 +1037,7 @@ int parse_speed(const QString& str, double* val, double scale, const char* modul /* * Color helpers. */ -int color_to_bbggrr(const char* cname); +int color_to_bbggrr(const QString& cname); /* * A constant for unknown altitude. It's tempting to just use zero diff --git a/ozi.cc b/ozi.cc index 1c156e3e6..283c5f4cd 100644 --- a/ozi.cc +++ b/ozi.cc @@ -96,8 +96,8 @@ OziFormat::ozi_alloc_fsdata() auto* fsdata = new ozi_fsdata; /* Provide defaults via command line defaults */ - fsdata->fgcolor = color_to_bbggrr(wptfgcolor); - fsdata->bgcolor = color_to_bbggrr(wptbgcolor); + fsdata->fgcolor = color_to_bbggrr(wptfgcolor.get()); + fsdata->bgcolor = color_to_bbggrr(wptbgcolor.get()); return fsdata; } diff --git a/rgbcolors.cc b/rgbcolors.cc index a82fa3f8b..564c659d3 100644 --- a/rgbcolors.cc +++ b/rgbcolors.cc @@ -1,7 +1,7 @@ /* Color utilities. - Copyright (C) 2005 Robert Lipe, robertlipe+source@gpsbabel.org + Copyright (C) 2005,2024 Robert Lipe, robertlipe+source@gpsbabel.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,8 +19,15 @@ */ -#include "defs.h" -#include +#include // for assert + +#include // for QByteArray +#include // for QHash +#include // for QRegularExpression, QRegularExpressionMatch +#include // for QString, QTypeInfo<>::isRelocatable +#include // for qPrintable + +#include "defs.h" // for fatal, color_to_bbggrr /* * Colors derived from http://www.w3.org/TR/SVG/types.html#ColorKeywords @@ -28,187 +35,166 @@ * same colors supported by X11. */ -static const struct { - const char* cn; +struct rgb_t { unsigned char r; unsigned char g; unsigned char b; -} color_table[] = { - {"aliceblue", 240, 248, 255}, - {"antiquewhite", 250, 235, 215}, - {"aqua", 0, 255, 255}, - {"aquamarine", 127, 255, 212}, - {"azure", 240, 255, 255}, - {"beige", 245, 245, 220}, - {"bisque", 255, 228, 196}, - {"black", 0, 0, 0}, - {"blanchedalmond", 255, 235, 205}, - {"blue", 0, 0, 255}, - {"blueviolet", 138, 43, 226}, - {"brown", 165, 42, 42}, - {"burlywood", 222, 184, 135}, - {"cadetblue", 95, 158, 160}, - {"chartreuse", 127, 255, 0}, - {"chocolate", 210, 105, 30}, - {"coral", 255, 127, 80}, - {"cornflowerblue", 100, 149, 237}, - {"cornsilk", 255, 248, 220}, - {"crimson", 220, 20, 60}, - {"cyan", 0, 255, 255}, - {"darkblue", 0, 0, 139}, - {"darkcyan", 0, 139, 139}, - {"darkgoldenrod", 184, 134, 11}, - {"darkgray", 169, 169, 169}, - {"darkgreen", 0, 100, 0}, - {"darkgrey", 169, 169, 169}, - {"darkkhaki", 189, 183, 107}, - {"darkmagenta", 139, 0, 139}, - {"darkolivegreen", 85, 107, 47}, - {"darkorange", 255, 140, 0}, - {"darkorchid", 153, 50, 204}, - {"darkred", 139, 0, 0}, - {"darksalmon", 233, 150, 122}, - {"darkseagreen", 143, 188, 143}, - {"darkslateblue", 72, 61, 139}, - {"darkslategray", 47, 79, 79}, - {"darkslategrey", 47, 79, 79}, - {"darkturquoise", 0, 206, 209}, - {"darkviolet", 148, 0, 211}, - {"deeppink", 255, 20, 147}, - {"deepskyblue", 0, 191, 255}, - {"dimgray", 105, 105, 105}, - {"dimgrey", 105, 105, 105}, - {"dodgerblue", 30, 144, 255}, - {"firebrick", 178, 34, 34}, - {"floralwhite", 255, 250, 240}, - {"forestgreen", 34, 139, 34}, - {"fuchsia", 255, 0, 255}, - {"gainsboro", 220, 220, 220}, - {"ghostwhite", 248, 248, 255}, - {"gold", 255, 215, 0}, - {"goldenrod", 218, 165, 32}, - {"gray", 128, 128, 128}, - {"grey", 128, 128, 128}, - {"green", 0, 128, 0}, - {"greenyellow", 173, 255, 47}, - {"honeydew", 240, 255, 240}, - {"hotpink", 255, 105, 180}, - {"indianred", 205, 92, 92}, - {"indigo", 75, 0, 130}, - {"ivory", 255, 255, 240}, - {"khaki", 240, 230, 140}, - {"lavender", 230, 230, 250}, - {"lavenderblush", 255, 240, 245}, - {"lawngreen", 124, 252, 0}, - {"lemonchiffon", 255, 250, 205}, - {"lightblue", 173, 216, 230}, - {"lightcoral", 240, 128, 128}, - {"lightcyan", 224, 255, 255}, - {"lightgoldenrodyellow", 250, 250, 210}, - {"lightgray", 211, 211, 211}, - {"lightgreen", 144, 238, 144}, - {"lightgrey", 211, 211, 211}, - {"lightpink", 255, 182, 193}, - {"lightsalmon", 255, 160, 122}, - {"lightseagreen", 32, 178, 170}, - {"lightskyblue", 135, 206, 250}, - {"lightslategray", 119, 136, 153}, - {"lightslategrey", 119, 136, 153}, - {"lightsteelblue", 176, 196, 222}, - {"lightyellow", 255, 255, 224}, - {"lime", 0, 255, 0}, - {"limegreen", 50, 205, 50}, - {"linen", 250, 240, 230}, - {"magenta", 255, 0, 255}, - {"maroon", 128, 0, 0}, - {"mediumaquamarine", 102, 205, 170}, - {"mediumblue", 0, 0, 205}, - {"mediumorchid", 186, 85, 211}, - {"mediumpurple", 147, 112, 219}, - {"mediumseagreen", 60, 179, 113}, - {"mediumslateblue", 123, 104, 238}, - {"mediumspringgreen", 0, 250, 154}, - {"mediumturquoise", 72, 209, 204}, - {"mediumvioletred", 199, 21, 133}, - {"midnightblue", 25, 25, 112}, - {"mintcream", 245, 255, 250}, - {"mistyrose", 255, 228, 225}, - {"moccasin", 255, 228, 181}, - {"navajowhite", 255, 222, 173}, - {"navy", 0, 0, 128}, - {"oldlace", 253, 245, 230}, - {"olive", 128, 128, 0}, - {"olivedrab", 107, 142, 35}, - {"orange", 255, 165, 0}, - {"orangered", 255, 69, 0}, - {"orchid", 218, 112, 214}, - {"palegoldenrod", 238, 232, 170}, - {"palegreen", 152, 251, 152}, - {"paleturquoise", 175, 238, 238}, - {"palevioletred", 219, 112, 147}, - {"papayawhip", 255, 239, 213}, - {"peachpuff", 255, 218, 185}, - {"peru", 205, 133, 63}, - {"pink", 255, 192, 203}, - {"plum", 221, 160, 221}, - {"powderblue", 176, 224, 230}, - {"purple", 128, 0, 128}, - {"red", 255, 0, 0}, - {"rosybrown", 188, 143, 143}, - {"royalblue", 65, 105, 225}, - {"saddlebrown", 139, 69, 19}, - {"salmon", 250, 128, 114}, - {"sandybrown", 244, 164, 96}, - {"seagreen", 46, 139, 87}, - {"seashell", 255, 245, 238}, - {"sienna", 160, 82, 45}, - {"silver", 192, 192, 192}, - {"skyblue", 135, 206, 235}, - {"slateblue", 106, 90, 205}, - {"slategray", 112, 128, 144}, - {"slategrey", 112, 128, 144}, - {"snow", 255, 250, 250}, - {"springgreen", 0, 255, 127}, - {"steelblue", 70, 130, 180}, - {"tan", 210, 180, 140}, - {"teal", 0, 128, 128}, - {"thistle", 216, 191, 216}, - {"tomato", 255, 99, 71}, - {"turquoise", 64, 224, 208}, - {"violet", 238, 130, 238}, - {"wheat", 245, 222, 179}, - {"white", 255, 255, 255}, - {"whitesmoke", 245, 245, 245}, - {"yellow", 255, 255, 0}, - {"yellowgreen", 154, 205, 50}, +}; + +static const QHash color_table = { + {"aliceblue", {240, 248, 255}}, + {"antiquewhite", {250, 235, 215}}, + {"aqua", { 0, 255, 255}}, + {"aquamarine", {127, 255, 212}}, + {"azure", {240, 255, 255}}, + {"beige", {245, 245, 220}}, + {"bisque", {255, 228, 196}}, + {"black", { 0, 0, 0}}, + {"blanchedalmond", {255, 235, 205}}, + {"blue", { 0, 0, 255}}, + {"blueviolet", {138, 43, 226}}, + {"brown", {165, 42, 42}}, + {"burlywood", {222, 184, 135}}, + {"cadetblue", { 95, 158, 160}}, + {"chartreuse", {127, 255, 0}}, + {"chocolate", {210, 105, 30}}, + {"coral", {255, 127, 80}}, + {"cornflowerblue", {100, 149, 237}}, + {"cornsilk", {255, 248, 220}}, + {"crimson", {220, 20, 60}}, + {"cyan", { 0, 255, 255}}, + {"darkblue", { 0, 0, 139}}, + {"darkcyan", { 0, 139, 139}}, + {"darkgoldenrod", {184, 134, 11}}, + {"darkgray", {169, 169, 169}}, + {"darkgreen", { 0, 100, 0}}, + {"darkgrey", {169, 169, 169}}, + {"darkkhaki", {189, 183, 107}}, + {"darkmagenta", {139, 0, 139}}, + {"darkolivegreen", { 85, 107, 47}}, + {"darkorange", {255, 140, 0}}, + {"darkorchid", {153, 50, 204}}, + {"darkred", {139, 0, 0}}, + {"darksalmon", {233, 150, 122}}, + {"darkseagreen", {143, 188, 143}}, + {"darkslateblue", { 72, 61, 139}}, + {"darkslategray", { 47, 79, 79}}, + {"darkslategrey", { 47, 79, 79}}, + {"darkturquoise", { 0, 206, 209}}, + {"darkviolet", {148, 0, 211}}, + {"deeppink", {255, 20, 147}}, + {"deepskyblue", { 0, 191, 255}}, + {"dimgray", {105, 105, 105}}, + {"dimgrey", {105, 105, 105}}, + {"dodgerblue", { 30, 144, 255}}, + {"firebrick", {178, 34, 34}}, + {"floralwhite", {255, 250, 240}}, + {"forestgreen", { 34, 139, 34}}, + {"fuchsia", {255, 0, 255}}, + {"gainsboro", {220, 220, 220}}, + {"ghostwhite", {248, 248, 255}}, + {"gold", {255, 215, 0}}, + {"goldenrod", {218, 165, 32}}, + {"gray", {128, 128, 128}}, + {"grey", {128, 128, 128}}, + {"green", { 0, 128, 0}}, + {"greenyellow", {173, 255, 47}}, + {"honeydew", {240, 255, 240}}, + {"hotpink", {255, 105, 180}}, + {"indianred", {205, 92, 92}}, + {"indigo", { 75, 0, 130}}, + {"ivory", {255, 255, 240}}, + {"khaki", {240, 230, 140}}, + {"lavender", {230, 230, 250}}, + {"lavenderblush", {255, 240, 245}}, + {"lawngreen", {124, 252, 0}}, + {"lemonchiffon", {255, 250, 205}}, + {"lightblue", {173, 216, 230}}, + {"lightcoral", {240, 128, 128}}, + {"lightcyan", {224, 255, 255}}, + {"lightgoldenrodyellow", {250, 250, 210}}, + {"lightgray", {211, 211, 211}}, + {"lightgreen", {144, 238, 144}}, + {"lightgrey", {211, 211, 211}}, + {"lightpink", {255, 182, 193}}, + {"lightsalmon", {255, 160, 122}}, + {"lightseagreen", { 32, 178, 170}}, + {"lightskyblue", {135, 206, 250}}, + {"lightslategray", {119, 136, 153}}, + {"lightslategrey", {119, 136, 153}}, + {"lightsteelblue", {176, 196, 222}}, + {"lightyellow", {255, 255, 224}}, + {"lime", { 0, 255, 0}}, + {"limegreen", { 50, 205, 50}}, + {"linen", {250, 240, 230}}, + {"magenta", {255, 0, 255}}, + {"maroon", {128, 0, 0}}, + {"mediumaquamarine", {102, 205, 170}}, + {"mediumblue", { 0, 0, 205}}, + {"mediumorchid", {186, 85, 211}}, + {"mediumpurple", {147, 112, 219}}, + {"mediumseagreen", { 60, 179, 113}}, + {"mediumslateblue", {123, 104, 238}}, + {"mediumspringgreen", { 0, 250, 154}}, + {"mediumturquoise", { 72, 209, 204}}, + {"mediumvioletred", {199, 21, 133}}, + {"midnightblue", { 25, 25, 112}}, + {"mintcream", {245, 255, 250}}, + {"mistyrose", {255, 228, 225}}, + {"moccasin", {255, 228, 181}}, + {"navajowhite", {255, 222, 173}}, + {"navy", { 0, 0, 128}}, + {"oldlace", {253, 245, 230}}, + {"olive", {128, 128, 0}}, + {"olivedrab", {107, 142, 35}}, + {"orange", {255, 165, 0}}, + {"orangered", {255, 69, 0}}, + {"orchid", {218, 112, 214}}, + {"palegoldenrod", {238, 232, 170}}, + {"palegreen", {152, 251, 152}}, + {"paleturquoise", {175, 238, 238}}, + {"palevioletred", {219, 112, 147}}, + {"papayawhip", {255, 239, 213}}, + {"peachpuff", {255, 218, 185}}, + {"peru", {205, 133, 63}}, + {"pink", {255, 192, 203}}, + {"plum", {221, 160, 221}}, + {"powderblue", {176, 224, 230}}, + {"purple", {128, 0, 128}}, + {"red", {255, 0, 0}}, + {"rosybrown", {188, 143, 143}}, + {"royalblue", { 65, 105, 225}}, + {"saddlebrown", {139, 69, 19}}, + {"salmon", {250, 128, 114}}, + {"sandybrown", {244, 164, 96}}, + {"seagreen", { 46, 139, 87}}, + {"seashell", {255, 245, 238}}, + {"sienna", {160, 82, 45}}, + {"silver", {192, 192, 192}}, + {"skyblue", {135, 206, 235}}, + {"slateblue", {106, 90, 205}}, + {"slategray", {112, 128, 144}}, + {"slategrey", {112, 128, 144}}, + {"snow", {255, 250, 250}}, + {"springgreen", { 0, 255, 127}}, + {"steelblue", { 70, 130, 180}}, + {"tan", {210, 180, 140}}, + {"teal", { 0, 128, 128}}, + {"thistle", {216, 191, 216}}, + {"tomato", {255, 99, 71}}, + {"turquoise", { 64, 224, 208}}, + {"violet", {238, 130, 238}}, + {"wheat", {245, 222, 179}}, + {"white", {255, 255, 255}}, + {"whitesmoke", {245, 245, 245}}, + {"yellow", {255, 255, 0}}, + {"yellowgreen", {154, 205, 50}}, }; /* * Functions for converting human-readable colors to BBGGRR value. - * Substantial optimization opportunities remain. */ -static int HexDigit(char hex) -{ - const char* Digits = "0123456789ABCDEF"; - const char* digits = "0123456789abcdef"; - const char* ofs = strchr(digits, hex); - if (ofs) { - return ofs-digits; - } - - ofs = strchr(Digits, hex); - if (ofs) { - return ofs-Digits; - } - return 0; -} - -static int HexByte(const char* hex) -{ - int b = (HexDigit(hex[0])<<4)+HexDigit(hex[1]); - return b; -} /* * Given an input of the form: @@ -219,31 +205,28 @@ static int HexByte(const char* hex) */ int -color_to_bbggrr(const char* cname) +color_to_bbggrr(const QString& cname) { - char* ep; - - int color_num = strtol(cname, &ep, 10); + bool ok; + int color_num = cname.toInt(&ok); - if (ep != cname) { + if (ok) { return color_num; } - if (cname[0] == '#') { - color_num = (HexByte(cname+1)) + // red - (HexByte(cname+3)<<8) + // green - (HexByte(cname+5)<<16); // blue - return color_num; + static const QRegularExpression re("^#(?[[:xdigit:]]{2})(?[[:xdigit:]]{2})(?[[:xdigit:]]{2})$"); + assert(re.isValid()); + if (QRegularExpressionMatch match = re.match(cname); match.hasMatch()) { + return (match.captured("red").toInt(nullptr, 16) + + (match.captured("green").toInt(nullptr, 16) << 8) + + (match.captured("blue").toInt(nullptr, 16) << 16)); } - for (auto i : color_table) { - if (0 == case_ignore_strcmp(cname, i.cn)) { - return (i.b << 16) + - (i.g << 8) + - i.r; - } + if (color_table.contains(cname)) { + auto entry = color_table.value(cname); + return (entry.b << 16) + (entry.g << 8) + entry.r; } - fatal("unrecognized color name %s\n", cname); + fatal("unrecognized color name %s\n", qPrintable(cname)); return -1; } diff --git a/testo.d/ozi.test b/testo.d/ozi.test index 1a94e465e..de5410ca6 100644 --- a/testo.d/ozi.test +++ b/testo.d/ozi.test @@ -8,6 +8,9 @@ compare ${TMPDIR}/ozi.wpt ${REFERENCE} # Same, but with colors set gpsbabel -i geo -f ${REFERENCE}/geocaching.loc -o ozi,wptfgcolor=#de0000,wptbgcolor=red -F ${TMPDIR}/ozi-color.wpt compare ${TMPDIR}/ozi-color.wpt ${REFERENCE} +gpsbabel -i geo -f ${REFERENCE}/geocaching.loc -o ozi,wptfgcolor=222,wptbgcolor=red -F ${TMPDIR}/ozi-color.wpt +compare ${TMPDIR}/ozi-color.wpt ${REFERENCE} + # Test Ozi routes. gpsbabel -i ozi -f ${REFERENCE}/route/ozi.rte -o gpx -F ${TMPDIR}/ozi~gpx.gpx