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