Skip to content

Commit 37fabd8

Browse files
committed
csscolorparser: optimization
1 parent 7bdb3eb commit 37fabd8

File tree

1 file changed

+162
-81
lines changed

1 file changed

+162
-81
lines changed

csscolorparser.cpp

Lines changed: 162 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
// https://github.com/deanm/css-color-parser-js
55
// https://github.com/kkaefer/css-color-parser-cpp
66
//
7+
// Hannes Janetzek, 2015
8+
// - Added binary search for NamedColor lookup
9+
//
710
// Permission is hereby granted, free of charge, to any person obtaining a copy
811
// of this software and associated documentation files (the "Software"), to
912
// deal in the Software without restriction, including without limitation the
@@ -28,87 +31,162 @@
2831
#include <vector>
2932
#include <sstream>
3033
#include <cmath>
34+
#include <cstring>
3135
#include <algorithm>
3236

3337
using namespace CSSColorParser;
3438

3539
// http://www.w3.org/TR/css3-color/
3640
struct NamedColor { const char *const name; const Color color; };
3741
const NamedColor namedColors[] = {
38-
{ "transparent", { 0, 0, 0, 0 } }, { "aliceblue", { 240, 248, 255, 1 } },
39-
{ "antiquewhite", { 250, 235, 215, 1 } }, { "aqua", { 0, 255, 255, 1 } },
40-
{ "aquamarine", { 127, 255, 212, 1 } }, { "azure", { 240, 255, 255, 1 } },
41-
{ "beige", { 245, 245, 220, 1 } }, { "bisque", { 255, 228, 196, 1 } },
42-
{ "black", { 0, 0, 0, 1 } }, { "blanchedalmond", { 255, 235, 205, 1 } },
43-
{ "blue", { 0, 0, 255, 1 } }, { "blueviolet", { 138, 43, 226, 1 } },
44-
{ "brown", { 165, 42, 42, 1 } }, { "burlywood", { 222, 184, 135, 1 } },
45-
{ "cadetblue", { 95, 158, 160, 1 } }, { "chartreuse", { 127, 255, 0, 1 } },
46-
{ "chocolate", { 210, 105, 30, 1 } }, { "coral", { 255, 127, 80, 1 } },
47-
{ "cornflowerblue", { 100, 149, 237, 1 } }, { "cornsilk", { 255, 248, 220, 1 } },
48-
{ "crimson", { 220, 20, 60, 1 } }, { "cyan", { 0, 255, 255, 1 } },
49-
{ "darkblue", { 0, 0, 139, 1 } }, { "darkcyan", { 0, 139, 139, 1 } },
50-
{ "darkgoldenrod", { 184, 134, 11, 1 } }, { "darkgray", { 169, 169, 169, 1 } },
51-
{ "darkgreen", { 0, 100, 0, 1 } }, { "darkgrey", { 169, 169, 169, 1 } },
52-
{ "darkkhaki", { 189, 183, 107, 1 } }, { "darkmagenta", { 139, 0, 139, 1 } },
53-
{ "darkolivegreen", { 85, 107, 47, 1 } }, { "darkorange", { 255, 140, 0, 1 } },
54-
{ "darkorchid", { 153, 50, 204, 1 } }, { "darkred", { 139, 0, 0, 1 } },
55-
{ "darksalmon", { 233, 150, 122, 1 } }, { "darkseagreen", { 143, 188, 143, 1 } },
56-
{ "darkslateblue", { 72, 61, 139, 1 } }, { "darkslategray", { 47, 79, 79, 1 } },
57-
{ "darkslategrey", { 47, 79, 79, 1 } }, { "darkturquoise", { 0, 206, 209, 1 } },
58-
{ "darkviolet", { 148, 0, 211, 1 } }, { "deeppink", { 255, 20, 147, 1 } },
59-
{ "deepskyblue", { 0, 191, 255, 1 } }, { "dimgray", { 105, 105, 105, 1 } },
60-
{ "dimgrey", { 105, 105, 105, 1 } }, { "dodgerblue", { 30, 144, 255, 1 } },
61-
{ "firebrick", { 178, 34, 34, 1 } }, { "floralwhite", { 255, 250, 240, 1 } },
62-
{ "forestgreen", { 34, 139, 34, 1 } }, { "fuchsia", { 255, 0, 255, 1 } },
63-
{ "gainsboro", { 220, 220, 220, 1 } }, { "ghostwhite", { 248, 248, 255, 1 } },
64-
{ "gold", { 255, 215, 0, 1 } }, { "goldenrod", { 218, 165, 32, 1 } },
65-
{ "gray", { 128, 128, 128, 1 } }, { "green", { 0, 128, 0, 1 } },
66-
{ "greenyellow", { 173, 255, 47, 1 } }, { "grey", { 128, 128, 128, 1 } },
67-
{ "honeydew", { 240, 255, 240, 1 } }, { "hotpink", { 255, 105, 180, 1 } },
68-
{ "indianred", { 205, 92, 92, 1 } }, { "indigo", { 75, 0, 130, 1 } },
69-
{ "ivory", { 255, 255, 240, 1 } }, { "khaki", { 240, 230, 140, 1 } },
70-
{ "lavender", { 230, 230, 250, 1 } }, { "lavenderblush", { 255, 240, 245, 1 } },
71-
{ "lawngreen", { 124, 252, 0, 1 } }, { "lemonchiffon", { 255, 250, 205, 1 } },
72-
{ "lightblue", { 173, 216, 230, 1 } }, { "lightcoral", { 240, 128, 128, 1 } },
73-
{ "lightcyan", { 224, 255, 255, 1 } }, { "lightgoldenrodyellow", { 250, 250, 210, 1 } },
74-
{ "lightgray", { 211, 211, 211, 1 } }, { "lightgreen", { 144, 238, 144, 1 } },
75-
{ "lightgrey", { 211, 211, 211, 1 } }, { "lightpink", { 255, 182, 193, 1 } },
76-
{ "lightsalmon", { 255, 160, 122, 1 } }, { "lightseagreen", { 32, 178, 170, 1 } },
77-
{ "lightskyblue", { 135, 206, 250, 1 } }, { "lightslategray", { 119, 136, 153, 1 } },
78-
{ "lightslategrey", { 119, 136, 153, 1 } }, { "lightsteelblue", { 176, 196, 222, 1 } },
79-
{ "lightyellow", { 255, 255, 224, 1 } }, { "lime", { 0, 255, 0, 1 } },
80-
{ "limegreen", { 50, 205, 50, 1 } }, { "linen", { 250, 240, 230, 1 } },
81-
{ "magenta", { 255, 0, 255, 1 } }, { "maroon", { 128, 0, 0, 1 } },
82-
{ "mediumaquamarine", { 102, 205, 170, 1 } }, { "mediumblue", { 0, 0, 205, 1 } },
83-
{ "mediumorchid", { 186, 85, 211, 1 } }, { "mediumpurple", { 147, 112, 219, 1 } },
84-
{ "mediumseagreen", { 60, 179, 113, 1 } }, { "mediumslateblue", { 123, 104, 238, 1 } },
85-
{ "mediumspringgreen", { 0, 250, 154, 1 } }, { "mediumturquoise", { 72, 209, 204, 1 } },
86-
{ "mediumvioletred", { 199, 21, 133, 1 } }, { "midnightblue", { 25, 25, 112, 1 } },
87-
{ "mintcream", { 245, 255, 250, 1 } }, { "mistyrose", { 255, 228, 225, 1 } },
88-
{ "moccasin", { 255, 228, 181, 1 } }, { "navajowhite", { 255, 222, 173, 1 } },
89-
{ "navy", { 0, 0, 128, 1 } }, { "oldlace", { 253, 245, 230, 1 } },
90-
{ "olive", { 128, 128, 0, 1 } }, { "olivedrab", { 107, 142, 35, 1 } },
91-
{ "orange", { 255, 165, 0, 1 } }, { "orangered", { 255, 69, 0, 1 } },
92-
{ "orchid", { 218, 112, 214, 1 } }, { "palegoldenrod", { 238, 232, 170, 1 } },
93-
{ "palegreen", { 152, 251, 152, 1 } }, { "paleturquoise", { 175, 238, 238, 1 } },
94-
{ "palevioletred", { 219, 112, 147, 1 } }, { "papayawhip", { 255, 239, 213, 1 } },
95-
{ "peachpuff", { 255, 218, 185, 1 } }, { "peru", { 205, 133, 63, 1 } },
96-
{ "pink", { 255, 192, 203, 1 } }, { "plum", { 221, 160, 221, 1 } },
97-
{ "powderblue", { 176, 224, 230, 1 } }, { "purple", { 128, 0, 128, 1 } },
98-
{ "red", { 255, 0, 0, 1 } }, { "rosybrown", { 188, 143, 143, 1 } },
99-
{ "royalblue", { 65, 105, 225, 1 } }, { "saddlebrown", { 139, 69, 19, 1 } },
100-
{ "salmon", { 250, 128, 114, 1 } }, { "sandybrown", { 244, 164, 96, 1 } },
101-
{ "seagreen", { 46, 139, 87, 1 } }, { "seashell", { 255, 245, 238, 1 } },
102-
{ "sienna", { 160, 82, 45, 1 } }, { "silver", { 192, 192, 192, 1 } },
103-
{ "skyblue", { 135, 206, 235, 1 } }, { "slateblue", { 106, 90, 205, 1 } },
104-
{ "slategray", { 112, 128, 144, 1 } }, { "slategrey", { 112, 128, 144, 1 } },
105-
{ "snow", { 255, 250, 250, 1 } }, { "springgreen", { 0, 255, 127, 1 } },
106-
{ "steelblue", { 70, 130, 180, 1 } }, { "tan", { 210, 180, 140, 1 } },
107-
{ "teal", { 0, 128, 128, 1 } }, { "thistle", { 216, 191, 216, 1 } },
108-
{ "tomato", { 255, 99, 71, 1 } }, { "turquoise", { 64, 224, 208, 1 } },
109-
{ "violet", { 238, 130, 238, 1 } }, { "wheat", { 245, 222, 179, 1 } },
110-
{ "white", { 255, 255, 255, 1 } }, { "whitesmoke", { 245, 245, 245, 1 } },
111-
{ "yellow", { 255, 255, 0, 1 } }, { "yellowgreen", { 154, 205, 50, 1 } }
42+
{ "aliceblue", { 240, 248, 255, 1 } },
43+
{ "antiquewhite", { 250, 235, 215, 1 } },
44+
{ "aqua", { 0, 255, 255, 1 } },
45+
{ "aquamarine", { 127, 255, 212, 1 } },
46+
{ "azure", { 240, 255, 255, 1 } },
47+
{ "beige", { 245, 245, 220, 1 } },
48+
{ "bisque", { 255, 228, 196, 1 } },
49+
{ "black", { 0, 0, 0, 1 } },
50+
{ "blanchedalmond", { 255, 235, 205, 1 } },
51+
{ "blue", { 0, 0, 255, 1 } },
52+
{ "blueviolet", { 138, 43, 226, 1 } },
53+
{ "brown", { 165, 42, 42, 1 } },
54+
{ "burlywood", { 222, 184, 135, 1 } },
55+
{ "cadetblue", { 95, 158, 160, 1 } },
56+
{ "chartreuse", { 127, 255, 0, 1 } },
57+
{ "chocolate", { 210, 105, 30, 1 } },
58+
{ "coral", { 255, 127, 80, 1 } },
59+
{ "cornflowerblue", { 100, 149, 237, 1 } },
60+
{ "cornsilk", { 255, 248, 220, 1 } },
61+
{ "crimson", { 220, 20, 60, 1 } },
62+
{ "cyan", { 0, 255, 255, 1 } },
63+
{ "darkblue", { 0, 0, 139, 1 } },
64+
{ "darkcyan", { 0, 139, 139, 1 } },
65+
{ "darkgoldenrod", { 184, 134, 11, 1 } },
66+
{ "darkgray", { 169, 169, 169, 1 } },
67+
{ "darkgreen", { 0, 100, 0, 1 } },
68+
{ "darkgrey", { 169, 169, 169, 1 } },
69+
{ "darkkhaki", { 189, 183, 107, 1 } },
70+
{ "darkmagenta", { 139, 0, 139, 1 } },
71+
{ "darkolivegreen", { 85, 107, 47, 1 } },
72+
{ "darkorange", { 255, 140, 0, 1 } },
73+
{ "darkorchid", { 153, 50, 204, 1 } },
74+
{ "darkred", { 139, 0, 0, 1 } },
75+
{ "darksalmon", { 233, 150, 122, 1 } },
76+
{ "darkseagreen", { 143, 188, 143, 1 } },
77+
{ "darkslateblue", { 72, 61, 139, 1 } },
78+
{ "darkslategray", { 47, 79, 79, 1 } },
79+
{ "darkslategrey", { 47, 79, 79, 1 } },
80+
{ "darkturquoise", { 0, 206, 209, 1 } },
81+
{ "darkviolet", { 148, 0, 211, 1 } },
82+
{ "deeppink", { 255, 20, 147, 1 } },
83+
{ "deepskyblue", { 0, 191, 255, 1 } },
84+
{ "dimgray", { 105, 105, 105, 1 } },
85+
{ "dimgrey", { 105, 105, 105, 1 } },
86+
{ "dodgerblue", { 30, 144, 255, 1 } },
87+
{ "firebrick", { 178, 34, 34, 1 } },
88+
{ "floralwhite", { 255, 250, 240, 1 } },
89+
{ "forestgreen", { 34, 139, 34, 1 } },
90+
{ "fuchsia", { 255, 0, 255, 1 } },
91+
{ "gainsboro", { 220, 220, 220, 1 } },
92+
{ "ghostwhite", { 248, 248, 255, 1 } },
93+
{ "gold", { 255, 215, 0, 1 } },
94+
{ "goldenrod", { 218, 165, 32, 1 } },
95+
{ "gray", { 128, 128, 128, 1 } },
96+
{ "green", { 0, 128, 0, 1 } },
97+
{ "greenyellow", { 173, 255, 47, 1 } },
98+
{ "grey", { 128, 128, 128, 1 } },
99+
{ "honeydew", { 240, 255, 240, 1 } },
100+
{ "hotpink", { 255, 105, 180, 1 } },
101+
{ "indianred", { 205, 92, 92, 1 } },
102+
{ "indigo", { 75, 0, 130, 1 } },
103+
{ "ivory", { 255, 255, 240, 1 } },
104+
{ "khaki", { 240, 230, 140, 1 } },
105+
{ "lavender", { 230, 230, 250, 1 } },
106+
{ "lavenderblush", { 255, 240, 245, 1 } },
107+
{ "lawngreen", { 124, 252, 0, 1 } },
108+
{ "lemonchiffon", { 255, 250, 205, 1 } },
109+
{ "lightblue", { 173, 216, 230, 1 } },
110+
{ "lightcoral", { 240, 128, 128, 1 } },
111+
{ "lightcyan", { 224, 255, 255, 1 } },
112+
{ "lightgoldenrodyellow", { 250, 250, 210, 1 } },
113+
{ "lightgray", { 211, 211, 211, 1 } },
114+
{ "lightgreen", { 144, 238, 144, 1 } },
115+
{ "lightgrey", { 211, 211, 211, 1 } },
116+
{ "lightpink", { 255, 182, 193, 1 } },
117+
{ "lightsalmon", { 255, 160, 122, 1 } },
118+
{ "lightseagreen", { 32, 178, 170, 1 } },
119+
{ "lightskyblue", { 135, 206, 250, 1 } },
120+
{ "lightslategray", { 119, 136, 153, 1 } },
121+
{ "lightslategrey", { 119, 136, 153, 1 } },
122+
{ "lightsteelblue", { 176, 196, 222, 1 } },
123+
{ "lightyellow", { 255, 255, 224, 1 } },
124+
{ "lime", { 0, 255, 0, 1 } },
125+
{ "limegreen", { 50, 205, 50, 1 } },
126+
{ "linen", { 250, 240, 230, 1 } },
127+
{ "magenta", { 255, 0, 255, 1 } },
128+
{ "maroon", { 128, 0, 0, 1 } },
129+
{ "mediumaquamarine", { 102, 205, 170, 1 } },
130+
{ "mediumblue", { 0, 0, 205, 1 } },
131+
{ "mediumorchid", { 186, 85, 211, 1 } },
132+
{ "mediumpurple", { 147, 112, 219, 1 } },
133+
{ "mediumseagreen", { 60, 179, 113, 1 } },
134+
{ "mediumslateblue", { 123, 104, 238, 1 } },
135+
{ "mediumspringgreen", { 0, 250, 154, 1 } },
136+
{ "mediumturquoise", { 72, 209, 204, 1 } },
137+
{ "mediumvioletred", { 199, 21, 133, 1 } },
138+
{ "midnightblue", { 25, 25, 112, 1 } },
139+
{ "mintcream", { 245, 255, 250, 1 } },
140+
{ "mistyrose", { 255, 228, 225, 1 } },
141+
{ "moccasin", { 255, 228, 181, 1 } },
142+
{ "navajowhite", { 255, 222, 173, 1 } },
143+
{ "navy", { 0, 0, 128, 1 } },
144+
{ "oldlace", { 253, 245, 230, 1 } },
145+
{ "olive", { 128, 128, 0, 1 } },
146+
{ "olivedrab", { 107, 142, 35, 1 } },
147+
{ "orange", { 255, 165, 0, 1 } },
148+
{ "orangered", { 255, 69, 0, 1 } },
149+
{ "orchid", { 218, 112, 214, 1 } },
150+
{ "palegoldenrod", { 238, 232, 170, 1 } },
151+
{ "palegreen", { 152, 251, 152, 1 } },
152+
{ "paleturquoise", { 175, 238, 238, 1 } },
153+
{ "palevioletred", { 219, 112, 147, 1 } },
154+
{ "papayawhip", { 255, 239, 213, 1 } },
155+
{ "peachpuff", { 255, 218, 185, 1 } },
156+
{ "peru", { 205, 133, 63, 1 } },
157+
{ "pink", { 255, 192, 203, 1 } },
158+
{ "plum", { 221, 160, 221, 1 } },
159+
{ "powderblue", { 176, 224, 230, 1 } },
160+
{ "purple", { 128, 0, 128, 1 } },
161+
{ "red", { 255, 0, 0, 1 } },
162+
{ "rosybrown", { 188, 143, 143, 1 } },
163+
{ "royalblue", { 65, 105, 225, 1 } },
164+
{ "saddlebrown", { 139, 69, 19, 1 } },
165+
{ "salmon", { 250, 128, 114, 1 } },
166+
{ "sandybrown", { 244, 164, 96, 1 } },
167+
{ "seagreen", { 46, 139, 87, 1 } },
168+
{ "seashell", { 255, 245, 238, 1 } },
169+
{ "sienna", { 160, 82, 45, 1 } },
170+
{ "silver", { 192, 192, 192, 1 } },
171+
{ "skyblue", { 135, 206, 235, 1 } },
172+
{ "slateblue", { 106, 90, 205, 1 } },
173+
{ "slategray", { 112, 128, 144, 1 } },
174+
{ "slategrey", { 112, 128, 144, 1 } },
175+
{ "snow", { 255, 250, 250, 1 } },
176+
{ "springgreen", { 0, 255, 127, 1 } },
177+
{ "steelblue", { 70, 130, 180, 1 } },
178+
{ "tan", { 210, 180, 140, 1 } },
179+
{ "teal", { 0, 128, 128, 1 } },
180+
{ "thistle", { 216, 191, 216, 1 } },
181+
{ "tomato", { 255, 99, 71, 1 } },
182+
{ "transparent", { 0, 0, 0, 0 } },
183+
{ "turquoise", { 64, 224, 208, 1 } },
184+
{ "violet", { 238, 130, 238, 1 } },
185+
{ "wheat", { 245, 222, 179, 1 } },
186+
{ "white", { 255, 255, 255, 1 } },
187+
{ "whitesmoke", { 245, 245, 245, 1 } },
188+
{ "yellow", { 255, 255, 0, 1 } },
189+
{ "yellowgreen", { 154, 205, 50, 1 } }
112190
};
113191

114192
const size_t namedColorCount = sizeof (namedColors) / sizeof (NamedColor);
@@ -189,13 +267,6 @@ Color CSSColorParser::parse(const std::string& css_str) {
189267
// Convert to lowercase.
190268
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
191269

192-
193-
for (size_t i = 0; i < namedColorCount; i++) {
194-
if (str == namedColors[i].name) {
195-
return namedColors[i].color;
196-
}
197-
}
198-
199270
// #abc and #abc123 syntax.
200271
if (str.length() && str.front() == '#') {
201272
if (str.length() == 4) {
@@ -286,5 +357,15 @@ Color CSSColorParser::parse(const std::string& css_str) {
286357
}
287358
}
288359

360+
NamedColor v{str.c_str(), {}};
361+
362+
auto end = (namedColors + namedColorCount);
363+
auto it = std::lower_bound(namedColors, end, v,
364+
[](const NamedColor& a, const NamedColor& b){
365+
return std::strcmp(a.name, b.name) < 0; });
366+
367+
if (it != end && std::strcmp(it->name, v.name) == 0)
368+
return it->color;
369+
289370
return {};
290371
}

0 commit comments

Comments
 (0)