/*
Color utilities.
Copyright (C) 2005 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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "defs.h"
#include <cstdlib>
/*
* Colors derived from http://www.w3.org/TR/SVG/types.html#ColorKeywords
* which is also referenced in the CSS3 spec from w3.org as being the
* same colors supported by X11.
*/
static const struct {
const char* cn;
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},
};
/*
* 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:
* #<hex number for RGB value>
* <decimal nummber for BBGGRR value>
* <color named in CSS1 spec>
* return the BBGGRR value for it.
*/
int
color_to_bbggrr(const char* opt_color)
{
char* ep;
int color_num = strtol(opt_color, &ep, 10);
if (ep != opt_color) {
return color_num;
}
if (opt_color[0] == '#') {
color_num = (HexByte(opt_color+1)) + // red
(HexByte(opt_color+3)<<8) + // green
(HexByte(opt_color+5)<<16); // blue
return color_num;
}
for (auto i : color_table) {
if (0 == case_ignore_strcmp(opt_color, i.cn)) {
return (i.b << 16) +
(i.g << 8) +
i.r;
}
}
fatal("unrecognized color name %s\n", opt_color);
return -1;
}