1 // color.cpp
2 //
3 // Copyright (C) 2001-2008, the Celestia Development Team
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9 
10 #include <cstdio>
11 #include <cstring>
12 #include <cctype>
13 #include "color.h"
14 
15 using namespace std;
16 
17 
18 Color::ColorMap Color::x11Colors;
19 
20 const Color Color::White = Color(1.0f, 1.0f, 1.0f);
21 const Color Color::Black = Color(0.0f,0.0f, 0.0f);
22 
clamp(T x)23 template<class T> T clamp(T x)
24 {
25     if (x < 0)
26         return 0;
27     else if (x > 1)
28         return 1;
29     else
30         return x;
31 }
32 
Color()33 Color::Color()
34 {
35     c[Red] = c[Green] = c[Blue] = 0;
36     c[Alpha] = 0xff;
37 }
38 
39 
Color(float r,float g,float b)40 Color::Color(float r, float g, float b)
41 {
42     c[Red] = (unsigned char) (clamp(r) * 255.99f);
43     c[Green] = (unsigned char) (clamp(g) * 255.99f);
44     c[Blue] = (unsigned char) (clamp(b) * 255.99f);
45     c[Alpha] = 0xff;
46 }
47 
48 
Color(float r,float g,float b,float a)49 Color::Color(float r, float g, float b, float a)
50 {
51     c[Red]   = (unsigned char) (clamp(r) * 255.99f);
52     c[Green] = (unsigned char) (clamp(g) * 255.99f);
53     c[Blue]  = (unsigned char) (clamp(b) * 255.99f);
54     c[Alpha] = (unsigned char) (clamp(a) * 255.99f);
55 }
56 
57 
Color(unsigned char r,unsigned char g,unsigned char b)58 Color::Color(unsigned char r, unsigned char g, unsigned char b)
59 {
60     c[Red] = r;
61     c[Green] = g;
62     c[Blue] = b;
63     c[Alpha] = 0xff;
64 }
65 
66 
Color(const Color & color,float alpha)67 Color::Color(const Color& color, float alpha)
68 {
69     *this = color;
70     c[Alpha] = (unsigned char) (clamp(alpha) * 255.99f);
71 }
72 
73 
74 /*! Parse a color string and return true if it was a valid color, otherwise
75  *  false.  Accetable inputs are HTML/X11 style #xxxxxx colors (where x is
76  *  hexadecimal digit) or one of a list of named colors.
77  */
parse(const char * s,Color & c)78 bool Color::parse(const char* s, Color& c)
79 {
80     // Initialize the color dictionary if this is the first
81     // time Color::parse has been called.
82     if (x11Colors.empty())
83     {
84         buildX11ColorMap();
85     }
86 
87     if (s[0] == '#')
88     {
89         s++;
90 
91         int length = strlen(s);
92 
93         // Verify that the string contains only hex digits
94         for (int i = 0; i < length; i++)
95         {
96             if (!isxdigit(s[i]))
97                 return false;
98         }
99 
100         unsigned int n;
101         sscanf(s, "%x", &n);
102         if (length == 3)
103         {
104             c = Color((unsigned char) ((n >> 8) * 17),
105                       (unsigned char) (((n & 0x0f0) >> 4) * 17),
106                       (unsigned char) ((n & 0x00f) * 17));
107             return true;
108         }
109         else if (length == 6)
110         {
111             c = Color((unsigned char) (n >> 16),
112                       (unsigned char) ((n & 0x00ff00) >> 8),
113                       (unsigned char) (n & 0x0000ff));
114             return true;
115         }
116         else
117         {
118             return false;
119         }
120     }
121     else
122     {
123        if (x11Colors.find(s) != x11Colors.end())
124        {
125            c = x11Colors.find(s)->second;
126            return true;
127        }
128        else
129        {
130            return false;
131        }
132     }
133 }
134 
135 
136 // X11 Colors STL map
buildX11ColorMap()137 void Color::buildX11ColorMap()
138 {
139     x11Colors["aliceblue"]            = Color((unsigned char)240, (unsigned char)248, (unsigned char)255);
140     x11Colors["antiquewhite"]         = Color((unsigned char)250, (unsigned char)235, (unsigned char)215);
141     x11Colors["aqua"]                 = Color((unsigned char)0,   (unsigned char)255, (unsigned char)255);
142     x11Colors["aquamarine"]           = Color((unsigned char)127, (unsigned char)255, (unsigned char)212);
143     x11Colors["azure"]                = Color((unsigned char)240, (unsigned char)255, (unsigned char)255);
144     x11Colors["beige"]                = Color((unsigned char)245, (unsigned char)245, (unsigned char)220);
145     x11Colors["bisque"]               = Color((unsigned char)255, (unsigned char)228, (unsigned char)196);
146     x11Colors["black"]                = Color((unsigned char)0,   (unsigned char)0,   (unsigned char)0);
147     x11Colors["blanchedalmond"]       = Color((unsigned char)255, (unsigned char)235, (unsigned char)205);
148     x11Colors["blue"]                 = Color((unsigned char)0,   (unsigned char)0,   (unsigned char)255);
149     x11Colors["blueviolet"]           = Color((unsigned char)138, (unsigned char)43,  (unsigned char)226);
150     x11Colors["brown"]                = Color((unsigned char)165, (unsigned char)42,  (unsigned char)42);
151     x11Colors["burlywood"]            = Color((unsigned char)222, (unsigned char)184, (unsigned char)135);
152     x11Colors["cadetblue"]            = Color((unsigned char)95,  (unsigned char)158, (unsigned char)160);
153     x11Colors["chartreuse"]           = Color((unsigned char)127, (unsigned char)255, (unsigned char)0);
154     x11Colors["chocolate"]            = Color((unsigned char)210, (unsigned char)105, (unsigned char)30);
155     x11Colors["coral"]                = Color((unsigned char)255, (unsigned char)127, (unsigned char)80);
156     x11Colors["cornflowerblue"]       = Color((unsigned char)100, (unsigned char)149, (unsigned char)237);
157     x11Colors["cornsilk"]             = Color((unsigned char)255, (unsigned char)248, (unsigned char)220);
158     x11Colors["crimson"]              = Color((unsigned char)220, (unsigned char)20,  (unsigned char)60);
159     x11Colors["cyan"]                 = Color((unsigned char)0,   (unsigned char)255, (unsigned char)255);
160     x11Colors["darkblue"]             = Color((unsigned char)0,   (unsigned char)0,   (unsigned char)139);
161     x11Colors["darkcyan"]             = Color((unsigned char)0,   (unsigned char)139, (unsigned char)139);
162     x11Colors["darkgoldenrod"]        = Color((unsigned char)184, (unsigned char)134, (unsigned char)11);
163     x11Colors["darkgray"]             = Color((unsigned char)169, (unsigned char)169, (unsigned char)169);
164     x11Colors["darkgreen"]            = Color((unsigned char)0,   (unsigned char)100, (unsigned char)0);
165     x11Colors["darkkhaki"]            = Color((unsigned char)189, (unsigned char)183, (unsigned char)107);
166     x11Colors["darkmagenta"]          = Color((unsigned char)139, (unsigned char)0,   (unsigned char)139);
167     x11Colors["darkolivegreen"]       = Color((unsigned char)85,  (unsigned char)107, (unsigned char)47);
168     x11Colors["darkorange"]           = Color((unsigned char)255, (unsigned char)140, (unsigned char)0);
169     x11Colors["darkorchid"]           = Color((unsigned char)153, (unsigned char)50,  (unsigned char)204);
170     x11Colors["darkred"]              = Color((unsigned char)139, (unsigned char)0,   (unsigned char)0);
171     x11Colors["darksalmon"]           = Color((unsigned char)233, (unsigned char)150, (unsigned char)122);
172     x11Colors["darkseagreen"]         = Color((unsigned char)143, (unsigned char)188, (unsigned char)143);
173     x11Colors["darkslateblue"]        = Color((unsigned char)72,  (unsigned char)61,  (unsigned char)139);
174     x11Colors["darkslategray"]        = Color((unsigned char)47,  (unsigned char)79,  (unsigned char)79);
175     x11Colors["darkturquoise"]        = Color((unsigned char)0,   (unsigned char)206, (unsigned char)209);
176     x11Colors["darkviolet"]           = Color((unsigned char)148, (unsigned char)0,   (unsigned char)211);
177     x11Colors["deeppink"]             = Color((unsigned char)255, (unsigned char)20,  (unsigned char)147);
178     x11Colors["deepskyblue"]          = Color((unsigned char)0,   (unsigned char)191, (unsigned char)255);
179     x11Colors["dimgray"]              = Color((unsigned char)105, (unsigned char)105, (unsigned char)105);
180     x11Colors["dodgerblue"]           = Color((unsigned char)30,  (unsigned char)144, (unsigned char)255);
181     x11Colors["firebrick"]            = Color((unsigned char)178, (unsigned char)34,  (unsigned char)34);
182     x11Colors["floralwhite"]          = Color((unsigned char)255, (unsigned char)250, (unsigned char)240);
183     x11Colors["forestgreen"]          = Color((unsigned char)34,  (unsigned char)139, (unsigned char)34);
184     x11Colors["fuchsia"]              = Color((unsigned char)255, (unsigned char)0,   (unsigned char)255);
185     x11Colors["gainsboro"]            = Color((unsigned char)220, (unsigned char)220, (unsigned char)220);
186     x11Colors["ghostwhite"]           = Color((unsigned char)248, (unsigned char)248, (unsigned char)255);
187     x11Colors["gold"]                 = Color((unsigned char)255, (unsigned char)215, (unsigned char)0);
188     x11Colors["goldenrod"]            = Color((unsigned char)218, (unsigned char)165, (unsigned char)32);
189     x11Colors["gray"]                 = Color((unsigned char)128, (unsigned char)128, (unsigned char)128);
190     x11Colors["green"]                = Color((unsigned char)0,   (unsigned char)128, (unsigned char)0);
191     x11Colors["greenyellow"]          = Color((unsigned char)173, (unsigned char)255, (unsigned char)47);
192     x11Colors["honeydew"]             = Color((unsigned char)240, (unsigned char)255, (unsigned char)240);
193     x11Colors["hotpink"]              = Color((unsigned char)255, (unsigned char)105, (unsigned char)180);
194     x11Colors["indianred"]            = Color((unsigned char)205, (unsigned char)92,  (unsigned char)92);
195     x11Colors["indigo"]               = Color((unsigned char)75,  (unsigned char)0,   (unsigned char)130);
196     x11Colors["ivory"]                = Color((unsigned char)255, (unsigned char)255, (unsigned char)240);
197     x11Colors["khaki"]                = Color((unsigned char)240, (unsigned char)230, (unsigned char)140);
198     x11Colors["lavender"]             = Color((unsigned char)230, (unsigned char)230, (unsigned char)250);
199     x11Colors["lavenderblush"]        = Color((unsigned char)255, (unsigned char)240, (unsigned char)245 );
200     x11Colors["lawngreen"]            = Color((unsigned char)124, (unsigned char)252, (unsigned char)0);
201     x11Colors["lemonchiffon"]         = Color((unsigned char)255, (unsigned char)250, (unsigned char)205);
202     x11Colors["lightblue"]            = Color((unsigned char)173, (unsigned char)216, (unsigned char)230);
203     x11Colors["lightcoral"]           = Color((unsigned char)240, (unsigned char)128, (unsigned char)128);
204     x11Colors["lightcyan"]            = Color((unsigned char)224, (unsigned char)255, (unsigned char)255);
205     x11Colors["lightgoldenrodyellow"] = Color((unsigned char)250, (unsigned char)250, (unsigned char)210);
206     x11Colors["lightgreen"]           = Color((unsigned char)144, (unsigned char)238, (unsigned char)144);
207     x11Colors["lightgrey"]            = Color((unsigned char)211, (unsigned char)211, (unsigned char)211);
208     x11Colors["lightpink"]            = Color((unsigned char)255, (unsigned char)182, (unsigned char)193);
209     x11Colors["lightsalmon"]          = Color((unsigned char)255, (unsigned char)160, (unsigned char)122);
210     x11Colors["lightseagreen"]        = Color((unsigned char)32,  (unsigned char)178, (unsigned char)170);
211     x11Colors["lightskyblue"]         = Color((unsigned char)135, (unsigned char)206, (unsigned char)250);
212     x11Colors["lightslategray"]       = Color((unsigned char)119, (unsigned char)136, (unsigned char)153);
213     x11Colors["lightsteelblue"]       = Color((unsigned char)176, (unsigned char)196, (unsigned char)222);
214     x11Colors["lightyellow"]          = Color((unsigned char)255, (unsigned char)255, (unsigned char)224);
215     x11Colors["lime"]                 = Color((unsigned char)0,   (unsigned char)255, (unsigned char)0);
216     x11Colors["limegreen"]            = Color((unsigned char)50,  (unsigned char)205, (unsigned char)50);
217     x11Colors["linen"]                = Color((unsigned char)250, (unsigned char)240, (unsigned char)230);
218     x11Colors["magenta"]              = Color((unsigned char)255, (unsigned char)0,   (unsigned char)255);
219     x11Colors["maroon"]               = Color((unsigned char)128, (unsigned char)0,   (unsigned char)0);
220     x11Colors["mediumaquamarine"]     = Color((unsigned char)102, (unsigned char)205, (unsigned char)170);
221     x11Colors["mediumblue"]           = Color((unsigned char)0,   (unsigned char)0,   (unsigned char)205);
222     x11Colors["mediumorchid"]         = Color((unsigned char)186, (unsigned char)85,  (unsigned char)211);
223     x11Colors["mediumpurple"]         = Color((unsigned char)147, (unsigned char)112, (unsigned char)219);
224     x11Colors["mediumseagreen"]       = Color((unsigned char)60,  (unsigned char)179, (unsigned char)113);
225     x11Colors["mediumslateblue"]      = Color((unsigned char)123, (unsigned char)104, (unsigned char)238);
226     x11Colors["mediumspringgreen"]    = Color((unsigned char)0,   (unsigned char)250, (unsigned char)154);
227     x11Colors["mediumturquoise"]      = Color((unsigned char)72,  (unsigned char)209, (unsigned char)204);
228     x11Colors["mediumvioletred"]      = Color((unsigned char)199, (unsigned char)21,  (unsigned char)133);
229     x11Colors["midnightblue"]         = Color((unsigned char)25,  (unsigned char)25,  (unsigned char)112);
230     x11Colors["mintcream"]            = Color((unsigned char)245, (unsigned char)255, (unsigned char)250);
231     x11Colors["mistyrose"]            = Color((unsigned char)255, (unsigned char)228, (unsigned char)225);
232     x11Colors["moccasin"]             = Color((unsigned char)255, (unsigned char)228, (unsigned char)181);
233     x11Colors["navajowhite"]          = Color((unsigned char)255, (unsigned char)222, (unsigned char)173);
234     x11Colors["navy"]                 = Color((unsigned char)0,   (unsigned char)0,   (unsigned char)128);
235     x11Colors["oldlace"]              = Color((unsigned char)253, (unsigned char)245, (unsigned char)230);
236     x11Colors["olive"]                = Color((unsigned char)128, (unsigned char)128, (unsigned char)0);
237     x11Colors["olivedrab"]            = Color((unsigned char)107, (unsigned char)142, (unsigned char)35);
238     x11Colors["orange"]               = Color((unsigned char)255, (unsigned char)165, (unsigned char)0);
239     x11Colors["orangered"]            = Color((unsigned char)255, (unsigned char)69,  (unsigned char)0);
240     x11Colors["orchid"]               = Color((unsigned char)218, (unsigned char)112, (unsigned char)214);
241     x11Colors["palegoldenrod"]        = Color((unsigned char)238, (unsigned char)232, (unsigned char)170);
242     x11Colors["palegreen"]            = Color((unsigned char)152, (unsigned char)251, (unsigned char)152);
243     x11Colors["paleturquoise"]        = Color((unsigned char)175, (unsigned char)238, (unsigned char)238);
244     x11Colors["palevioletred"]        = Color((unsigned char)219, (unsigned char)112, (unsigned char)147);
245     x11Colors["papayawhip"]           = Color((unsigned char)255, (unsigned char)239, (unsigned char)213);
246     x11Colors["peachpuff"]            = Color((unsigned char)255, (unsigned char)218, (unsigned char)185);
247     x11Colors["peru"]                 = Color((unsigned char)205, (unsigned char)133, (unsigned char)63);
248     x11Colors["pink"]                 = Color((unsigned char)255, (unsigned char)192, (unsigned char)203);
249     x11Colors["plum"]                 = Color((unsigned char)221, (unsigned char)160, (unsigned char)221);
250     x11Colors["powderblue"]           = Color((unsigned char)176, (unsigned char)224, (unsigned char)230);
251     x11Colors["purple"]               = Color((unsigned char)128, (unsigned char)0,   (unsigned char)128);
252     x11Colors["red"]                  = Color((unsigned char)255, (unsigned char)0,   (unsigned char)0);
253     x11Colors["rosybrown"]            = Color((unsigned char)188, (unsigned char)143, (unsigned char)143);
254     x11Colors["royalblue"]            = Color((unsigned char)65,  (unsigned char)105, (unsigned char)225);
255     x11Colors["saddlebrown"]          = Color((unsigned char)139, (unsigned char)69,  (unsigned char)19);
256     x11Colors["salmon"]               = Color((unsigned char)250, (unsigned char)128, (unsigned char)114);
257     x11Colors["sandybrown"]           = Color((unsigned char)244, (unsigned char)164, (unsigned char)96);
258     x11Colors["seagreen"]             = Color((unsigned char)46,  (unsigned char)139, (unsigned char)87);
259     x11Colors["seashell"]             = Color((unsigned char)255, (unsigned char)245, (unsigned char)238);
260     x11Colors["sienna"]               = Color((unsigned char)160, (unsigned char)82,  (unsigned char)45);
261     x11Colors["silver"]               = Color((unsigned char)192, (unsigned char)192, (unsigned char)192);
262     x11Colors["skyblue"]              = Color((unsigned char)135, (unsigned char)206, (unsigned char)235);
263     x11Colors["slateblue"]            = Color((unsigned char)106, (unsigned char)90,  (unsigned char)205);
264     x11Colors["slategray"]            = Color((unsigned char)112, (unsigned char)128, (unsigned char)144);
265     x11Colors["snow"]                 = Color((unsigned char)255, (unsigned char)250, (unsigned char)250);
266     x11Colors["springgreen"]          = Color((unsigned char)0,   (unsigned char)255, (unsigned char)127);
267     x11Colors["steelblue"]            = Color((unsigned char)70,  (unsigned char)130, (unsigned char)180);
268     x11Colors["tan"]                  = Color((unsigned char)210, (unsigned char)180, (unsigned char)140);
269     x11Colors["teal"]                 = Color((unsigned char)0,   (unsigned char)128, (unsigned char)128);
270     x11Colors["thistle"]              = Color((unsigned char)216, (unsigned char)191, (unsigned char)216);
271     x11Colors["tomato"]               = Color((unsigned char)255, (unsigned char)99,  (unsigned char)71);
272     x11Colors["turquoise"]            = Color((unsigned char)64,  (unsigned char)224, (unsigned char)208);
273     x11Colors["violet"]               = Color((unsigned char)238, (unsigned char)130, (unsigned char)238);
274     x11Colors["wheat"]                = Color((unsigned char)245, (unsigned char)222, (unsigned char)179);
275     x11Colors["white"]                = Color((unsigned char)255, (unsigned char)255, (unsigned char)255);
276     x11Colors["whitesmoke"]           = Color((unsigned char)245, (unsigned char)245, (unsigned char)245);
277     x11Colors["yellow"]               = Color((unsigned char)255, (unsigned char)255, (unsigned char)0);
278     x11Colors["yellowgreen"]          = Color((unsigned char)154, (unsigned char)205, (unsigned char)50);
279 }
280