Bridges-C++ 3.5.0-dev1
Bridges(C++ API)
Loading...
Searching...
No Matches
Color.h
Go to the documentation of this file.
1#ifndef COLOR_H
2#define COLOR_H
3
4#include <iostream> //cerr
5#include <array> //array
6#include <regex> //regex
7#include <unordered_map> //unordered_map
8#include <cmath> //log
9
10#include <sstream>
11#include <iomanip>
12
13#include "DataStructure.h" //string, using std
14#include <JSONutil.h>
15
16namespace bridges {
17 namespace datastructure {
50 class Color {
51 private:
52 // The named colors' rgba channel value mappings
53 static const unordered_map<string, const array<int, 4 >> &
54 ColorNames() {
55 static unordered_map<string, const array<int, 4 >> cn {
56
57 { {"aliceblue", {{240, 248, 255, 255}}},
58 {"antiquewhite", {{250, 235, 215, 255}}},
59 {"cyan", {{0, 255, 255, 255}}},
60 {"aquamarine", {{127, 255, 212, 255}}},
61 {"azure", {{240, 255, 255, 255}}},
62 {"beige", {{245, 245, 220, 255}}},
63 {"bisque", {{255, 228, 196, 255}}},
64 {"black", {{0, 0, 0, 255}}},
65 {"blanchedalmond", {{255, 235, 205, 255}}},
66 {"blue", {{0, 0, 255, 255}}},
67 {"blueviolet", {{138, 43, 226, 255}}},
68 {"brown", {{165, 42, 42, 255}}},
69 {"burlywood", {{222, 184, 135, 255}}},
70 {"cadetblue", {{95, 158, 160, 255}}},
71 {"chartreuse", {{127, 255, 0, 255}}},
72 {"chocolate", {{210, 105, 30, 255}}},
73 {"coral", {{255, 127, 80, 255}}},
74 {"cornflowerblue", {{100, 149, 237, 255}}},
75 {"cornsilk", {{255, 248, 220, 255}}},
76 {"crimson", {{220, 20, 60, 255}}},
77 {"darkblue", {{0, 0, 139, 255}}},
78 {"darkcyan", {{0, 139, 139, 255}}},
79 {"darkgoldenrod", {{184, 134, 11, 255}}},
80 {"darkgrey", {{169, 169, 169, 255}}},
81 {"darkgreen", {{0, 100, 0, 255}}},
82 {"darkkhaki", {{189, 183, 107, 255}}},
83 {"darkmagenta", {{139, 0, 139, 255}}},
84 {"darkolivegreen", {{85, 107, 47, 255}}},
85 {"darkorange", {{255, 140, 0, 255}}},
86 {"darkorchid", {{153, 50, 204, 255}}},
87 {"darkred", {{139, 0, 0, 255}}},
88 {"darksalmon", {{233, 150, 122, 255}}},
89 {"darkseagreen", {{143, 188, 143, 255}}},
90 {"darkslateblue", {{72, 61, 139, 255}}},
91 {"darkslategrey", {{47, 79, 79, 255}}},
92 {"darkturquoise", {{0, 206, 209, 255}}},
93 {"darkviolet", {{148, 0, 211, 255}}},
94 {"deeppink", {{255, 20, 147, 255}}},
95 {"deepskyblue", {{0, 191, 255, 255}}},
96 {"dimgrey", {{105, 105, 105, 255}}},
97 {"dodgerblue", {{30, 144, 255, 255}}},
98 {"firebrick", {{178, 34, 34, 255}}},
99 {"floralwhite", {{255, 250, 240, 255}}},
100 {"forestgreen", {{34, 139, 34, 255}}},
101 {"magenta", {{255, 0, 255, 255}}},
102 {"gainsboro", {{220, 220, 220, 255}}},
103 {"ghostwhite", {{248, 248, 255, 255}}},
104 {"gold", {{255, 215, 0, 255}}},
105 {"goldenrod", {{218, 165, 32, 255}}},
106 {"grey", {{128, 128, 128, 255}}},
107 {"green", {{0, 128, 0, 255}}},
108 {"greenyellow", {{173, 255, 47, 255}}},
109 {"honeydew", {{240, 255, 240, 255}}},
110 {"hotpink", {{255, 105, 180, 255}}},
111 {"indianred", {{205, 92, 92, 255}}},
112 {"indigo", {{75, 0, 130, 255}}},
113 {"ivory", {{255, 255, 240, 255}}},
114 {"khaki", {{240, 230, 140, 255}}},
115 {"lavender", {{230, 230, 250, 255}}},
116 {"lavenderblush", {{255, 240, 245, 255}}},
117 {"lawngreen", {{124, 252, 0, 255}}},
118 {"lemonchiffon", {{255, 250, 205, 255}}},
119 {"lightblue", {{173, 216, 230, 255}}},
120 {"lightcoral", {{240, 128, 128, 255}}},
121 {"lightcyan", {{224, 255, 255, 255}}},
122 {"lightgoldenrodyellow", {{250, 250, 210, 255}}},
123 {"lightgrey", {{211, 211, 211, 255}}},
124 {"lightgreen", {{144, 238, 144, 255}}},
125 {"lightpink", {{255, 182, 193, 255}}},
126 {"lightsalmon", {{255, 160, 122, 255}}},
127 {"lightseagreen", {{32, 178, 170, 255}}},
128 {"lightskyblue", {{135, 206, 250, 255}}},
129 {"lightslategrey", {{119, 136, 153, 255}}},
130 {"lightsteelblue", {{176, 196, 222, 255}}},
131 {"lightyellow", {{255, 255, 224, 255}}},
132 {"lime", {{0, 255, 0, 255}}},
133 {"limegreen", {{50, 205, 50, 255}}},
134 {"linen", {{250, 240, 230, 255}}},
135 {"maroon", {{128, 0, 0, 255}}},
136 {"mediumaquamarine", {{102, 205, 170, 255}}},
137 {"mediumblue", {{0, 0, 205, 255}}},
138 {"mediumorchid", {{186, 85, 211, 255}}},
139 {"mediumpurple", {{147, 112, 219, 255}}},
140 {"mediumseagreen", {{60, 179, 113, 255}}},
141 {"mediumslateblue", {{123, 104, 238, 255}}},
142 {"mediumspringgreen", {{0, 250, 154, 255}}},
143 {"mediumturquoise", {{72, 209, 204, 255}}},
144 {"mediumvioletred", {{199, 21, 133, 255}}},
145 {"midnightblue", {{25, 25, 112, 255}}},
146 {"mintcream", {{245, 255, 250, 255}}},
147 {"mistyrose", {{255, 228, 225, 255}}},
148 {"moccasin", {{255, 228, 181, 255}}},
149 {"navajowhite", {{255, 222, 173, 255}}},
150 {"navy", {{0, 0, 128, 255}}},
151 {"oldlace", {{253, 245, 230, 255}}},
152 {"olive", {{128, 128, 0, 255}}},
153 {"olivedrab", {{107, 142, 35, 255}}},
154 {"orange", {{255, 165, 0, 255}}},
155 {"orangered", {{255, 69, 0, 255}}},
156 {"orchid", {{218, 112, 214, 255}}},
157 {"palegoldenrod", {{238, 232, 170, 255}}},
158 {"palegreen", {{152, 251, 152, 255}}},
159 {"paleturquoise", {{175, 238, 238, 255}}},
160 {"palevioletred", {{219, 112, 147, 255}}},
161 {"papayawhip", {{255, 239, 213, 255}}},
162 {"peachpuff", {{255, 218, 185, 255}}},
163 {"peru", {{205, 133, 63, 255}}},
164 {"pink", {{255, 192, 203, 255}}},
165 {"plum", {{221, 160, 221, 255}}},
166 {"powderblue", {{176, 224, 230, 255}}},
167 {"purple", {{128, 0, 128, 255}}},
168 {"red", {{255, 0, 0, 255}}},
169 {"rosybrown", {{188, 143, 143, 255}}},
170 {"royalblue", {{65, 105, 225, 255}}},
171 {"saddlebrown", {{139, 69, 19, 255}}},
172 {"salmon", {{250, 128, 114, 255}}},
173 {"sandybrown", {{244, 164, 96, 255}}},
174 {"seagreen", {{46, 139, 87, 255}}},
175 {"seashell", {{255, 245, 238, 255}}},
176 {"sienna", {{160, 82, 45, 255}}},
177 {"silver", {{192, 192, 192, 255}}},
178 {"skyblue", {{135, 206, 235, 255}}},
179 {"slateblue", {{106, 90, 205, 255}}},
180 {"slategrey", {{112, 128, 144, 255}}},
181 {"snow", {{255, 250, 250, 255}}},
182 {"springgreen", {{0, 255, 127, 255}}},
183 {"steelblue", {{70, 130, 180, 255}}},
184 {"tan", {{210, 180, 140, 255}}},
185 {"teal", {{0, 128, 128, 255}}},
186 {"thistle", {{216, 191, 216, 255}}},
187 {"tomato", {{255, 99, 71, 255}}},
188 {"turquoise", {{64, 224, 208, 255}}},
189 {"violet", {{238, 130, 238, 255}}},
190 {"wheat", {{245, 222, 179, 255}}},
191 {"white", {{255, 255, 255, 255}}},
192 {"whitesmoke", {{245, 245, 245, 255}}},
193 {"yellow", {{255, 255, 0, 255}}},
194 {"yellowgreen", {{154, 205, 50, 255}}}
195 }
196 };
197 return cn;
198 }
199
200 // The rgba channel values of this Color
201 array<int, 4> channels{{255, 255, 255, 255}};
202 public:
208 setRed(0);
209 setGreen(0);
210 setBlue(0);
211 setAlpha(255);
212 }
222 Color(const int r, const int g, const int b, const int a = 255) {
223 setValue(r, g, b, a);
224 }
232 Color(const string& name) {
233 setValue(name);
234 }
239 bool operator==(const Color& that) const {
240 return channels == that.channels;
241 }
246 bool operator!=(const Color& that) const {
247 return channels != that.channels;
248 }
250 bool isOpaque() const {
251 return getAlpha() == 255;
252 }
257 bool isTransparent() const {
258 return getAlpha() == 0;
259 }
260
265 int getRed() const {
266 return channels.at(0);
267 }
272 int getGreen() const {
273 return channels.at(1);
274 }
279 int getBlue() const {
280 return channels.at(2);
281 }
286 int getAlpha() const {
287 return channels.at(3);
288 }
289
291 string getHexValue() const {
292 std::stringstream ss;
293 ss << "#";
294 ss << std::hex << std::setfill('0') << std::setw(2) << getRed();
295 ss << std::hex << std::setfill('0') << std::setw(2) << getGreen();
296 ss << std::hex << std::setfill('0') << std::setw(2) << getBlue();
297 ss << std::hex << std::setfill('0') << std::setw(2) << getAlpha();
298
299 return ss.str();
300 }
305 void setRed(int r) {
306 setChannel(r, 0);
307 }
312 void setGreen(int g) {
313 setChannel(g, 1);
314 }
319 void setBlue(int b) {
320 setChannel(b, 2);
321 }
326 void setAlpha(int a) {
327 setChannel(a, 3);
328 }
329
339 void setValue(int r, int g, int b, int a = 255) {
340 setRed(r);
341 setGreen(g);
342 setBlue(b);
343 setAlpha(a);
344 }
353 void setValue(string name) {
354 //marking static to avoid rebuilding the regexp every time.
355 //greedy, so checks for 8(RRGGBBAA), then 6(RRGGBB) then 4(RGBA) then 3(RGB)
356 static const regex HEX_RANGE("^#([[:xdigit:]]{8}|[[:xdigit:]]{6}|[[:xdigit:]]{3,4})$");
357
358 for (char& c : name) {
359 c = (char) tolower((unsigned char)c); //convert to lowercase
360 }
361 auto it = ColorNames().find(name);
362
363 if (it != ColorNames().end()) {
364 channels = it->second; //Named value
365 }
366 else if (regex_match(name, HEX_RANGE)) { //#Hex value
367 name.erase(0, 1); //removes "#"
368 // alpha value, overwritten if present by loop number
369 // of chars representing a channel
370 channels.at(3) = 255;
371 const int chanChars = (name.size() == 3 || name.size() == 4) ? 1 : 2;
372 //unit place scale factor, handles channel size variance
373 const int chanMultiplier = (chanChars == 1) ? 17 : 1;
374 for (size_t i = 0; i < name.size() / chanChars; i++) {
375 //converts and save hex val to rgba val
376 channels.at(i) = (int) strtol(name.substr(i * chanChars,
377 chanChars).c_str(), nullptr, 16) * chanMultiplier;
378 }
379 }
380 else { //invalid color
381 string errStr = "Invalid Color: " + name + "\nMust be a hexadecimal(#RRGGBBAA, #RRGGBB, #RGBA, or #RGB) color representation\nOr one of these supported named colors: ";
382 for (const auto& p : ColorNames()) {
383 errStr += " \"" + p.first + "\"";
384 }
385 errStr += "\n";
386 throw errStr;
387 }
388 }
389 const string getRepresentation () const {
390 return string(
391 "[" + to_string(getRed()) + "," +
392 to_string(getGreen()) + "," +
393 to_string(getBlue()) + "," +
394 to_string(getAlpha()) +
395 "]");
396 }
403 const string getCSSRepresentation() const {
405 if (this->isTransparent()) {
406 //leaves off other channels if transparent
407 return "[0, 0, 0, 0.0]";
408 }
409 const string strCSS =
410 JSONencode(this->getRed()) + "," +
411 JSONencode(this->getGreen()) + "," +
412 JSONencode(this->getBlue()) + "," +
413 JSONencode( ((float) (this->getAlpha()) / 255.0f));
414
415 return OPEN_BOX + strCSS + CLOSE_BOX;
416 }
417 const void getCSSRepresentation(rapidjson::Document& d) const {
418
419 using namespace rapidjson;
420 double r = 0, g = 0, b = 0, alpha = 0;
421 Value v;
422 d.SetObject();
423 Document::AllocatorType& allocator = d.GetAllocator();
424 Value col_arr(kArrayType);
425 if (this->isTransparent()) {
426 //leaves off other channels if transparent
427 // d.AddMember("color", v.SetString("[0, 0, 0, 0]"),
428 // allocator);
429 col_arr.PushBack(0., allocator);
430 col_arr.PushBack(0., allocator);
431 col_arr.PushBack(0., allocator);
432 col_arr.PushBack(0., allocator);
433 }
434 else {
435 col_arr.PushBack(v.SetDouble(this->getRed()), allocator);
436 col_arr.PushBack(v.SetDouble(this->getGreen()), allocator);
437 col_arr.PushBack(v.SetDouble(this->getBlue()), allocator);
438 col_arr.PushBack(v.SetDouble(this->getAlpha()), allocator);
439 }
440 d.AddMember("color", col_arr, allocator);
441 }
442
443 private:
444
452 void setChannel(const int& value, const int& channel) {
453 (value < 0 || 255 < value)
454 ? throw "Invalid channel parameter: " + to_string(value) +
455 " Must be in the [0,255] range"
456 : channels.at(channel) = value;
457 }
458 };//end of color class
459 }
460};//end of bridge namespace
461#endif
This class represents Color, and supports rgba, hexadecimal and named color values.
Definition Color.h:50
int getAlpha() const
Definition Color.h:286
int getBlue() const
Definition Color.h:279
void setAlpha(int a)
Definition Color.h:326
const string getRepresentation() const
Definition Color.h:389
bool operator==(const Color &that) const
Definition Color.h:239
void setRed(int r)
Definition Color.h:305
string getHexValue() const
Definition Color.h:291
int getGreen() const
Definition Color.h:272
const void getCSSRepresentation(rapidjson::Document &d) const
Definition Color.h:417
Color(const int r, const int g, const int b, const int a=255)
Definition Color.h:222
int getRed() const
Definition Color.h:265
bool isTransparent() const
Definition Color.h:257
void setBlue(int b)
Definition Color.h:319
Color(const string &name)
Definition Color.h:232
void setValue(int r, int g, int b, int a=255)
Definition Color.h:339
bool operator!=(const Color &that) const
Definition Color.h:246
const string getCSSRepresentation() const
Definition Color.h:403
void setGreen(int g)
Definition Color.h:312
bool isOpaque() const
Definition Color.h:250
Color()
Definition Color.h:207
void setValue(string name)
Definition Color.h:353
std::string JSONencode(const T &d)
Definition JSONutil.h:38
Support for drawing Bar charts.
Definition alltypes.h:4
const string OPEN_BOX
Definition DataStructure.h:55
const string CLOSE_BOX
Definition DataStructure.h:56