izzi
SVG SUBSET C++ API
Loading...
Searching...
No Matches
a60-svg-color-palette.h
Go to the documentation of this file.
1// svg custom palette-*- mode: C++ -*-
2
3// alpha60
4// bittorrent x scrape x data + analytics
5
6// Copyright (c) 2024, Benjamin De Kosnik <b.dekosnik@gmail.com>
7
8// This file is part of the alpha60 library. This library is free
9// software; you can redistribute it and/or modify it under the terms
10// of the GNU General Public License as published by the Free Software
11// Foundation; either version 3, or (at your option) any later
12// version.
13
14// This library is distributed in the hope that it will be useful, but
15// WITHOUT ANY WARRANTY; without even the implied warranty of
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17// General Public License for more details.
18
19#ifndef MiL_SVG_COLOR_PALETTE_H
20#define MiL_SVG_COLOR_PALETTE_H 1
21
22//#include "a60-svg-color.h"
23
24
25namespace svg {
26
27/// Palette, finite set of colors used. Must end with color::none.
28template<typename T, std::size_t N>
29using palette = std::array<T, N>;
30
31template<std::size_t N>
33
34template<std::size_t N>
36
37/// Default colors for izzi.
39{
40 // black to gray to white in 10% and 25% increments
46
48
49 // yellow
54
55 // orange
59
60 // red
67
68 // brown
72
73 // green
80
81 // blue
92
93 // purple (magenta, violet, pink)
103
105};
106
107/// Only color no black and white or gray
109{
110 // yellow
115
116 // orange
120
121 // red
128
129 // brown
133
134 // green
141
142 // blue
153
154 // purple (magenta, violet, pink)
164
166};
167
168/// Japan colors (118)
169/// https://en.wikipedia.org/wiki/Traditional_colors_of_Japan
171{
172 color_qi(240,143,144), color_qi(219,90,107), color_qi(252,201,185),
173 color_qi(242,102,108), color_qi(245,143,132), color_qi(185,87,84),
174 color_qi(157,41,51), color_qi(247,102,90), color_qi(151,100,90),
175 color_qi(195,39,43), color_qi(103,36,34), color_qi(94,40,36),
176 color_qi(250,123,98), color_qi(220,48,35), color_qi(147,67,55),
177 color_qi(145,50,40), color_qi(53,30,28), color_qi(211,78,54),
178 color_qi(161,61,45), color_qi(117,46,35), color_qi(255,121,82),
179 color_qi(230,131,100), color_qi(227,92,56), color_qi(179,92,68),
180 color_qi(155,83,63), color_qi(96,40,30), color_qi(76,34,27),
181 color_qi(255,53,0), color_qi(159,116,98), color_qi(89,43,31),
182 color_qi(245,127,79), color_qi(159,82,51), color_qi(152,85,56),
183 color_qi(255,162,107), color_qi(255,137,54), color_qi(251,129,54),
184 color_qi(46,33,27), color_qi(202,105,36), color_qi(213,120,53),
185 color_qi(169,98,50), color_qi(140,89,57), color_qi(89,58,39),
186 color_qi(190,127,81), color_qi(183,112,45), color_qi(219,132,73),
187 color_qi(247,187,125), color_qi(255,166,49), color_qi(203,126,31),
188 color_qi(120,94,73), color_qi(250,169,69), color_qi(187,129,65),
189 color_qi(255,185,78), color_qi(230,155,58), color_qi(176,146,122),
190 color_qi(127,107,93), color_qi(102,83,67), color_qi(161,121,23),
191 color_qi(92,72,39), color_qi(226,177,60), color_qi(211,177,125),
192 color_qi(149,123,56), color_qi(100,85,48), color_qi(189,169,40),
193 color_qi(156,138,77), color_qi(71,63,45), color_qi(82,75,42),
194 color_qi(133,124,85), color_qi(122,148,46), color_qi(188,181,140),
195 color_qi(140,158,94), color_qi(82,89,59), color_qi(140,156,118),
196 color_qi(129,123,105), color_qi(55,66,49), color_qi(165,186,147),
197 color_qi(64,122,82), color_qi(61,64,53), color_qi(101,98,85),
198 color_qi(45,68,54), color_qi(90,100,87), color_qi(129,156,139),
199 color_qi(58,64,59), color_qi(53,78,75), color_qi(117,125,117),
200 color_qi(43,55,54), color_qi(106,127,122), color_qi(72,146,155),
201 color_qi(69,88,89), color_qi(38,67,72), color_qi(29,105,124),
202 color_qi(77,100,108), color_qi(52,77,86), color_qi(77,143,172),
203 color_qi(93,140,174), color_qi(24,27,38), color_qi(0,49,113),
204 color_qi(120,119,155), color_qi(118,105,128), color_qi(137,114,158),
205 color_qi(135,95,154), color_qi(151,110,154), color_qi(43,32,40),
206 color_qi(168,124,160), color_qi(91,50,86), color_qi(35,25,30),
207 color_qi(187,119,150), color_qi(117,93,91), color_qi(109,43,80),
208 color_qi(164,52,93), color_qi(67,36,42), color_qi(126,38,57),
209 color_qi(68,49,46), color_qi(255,221,202), color_qi(151,134,124),
210 color_qi(75,60,57), color_qi(53,41,37), color_qi(23,20,18),
212};
213
214
215/// ColorBrewer 2.0
216/// https://colorbrewer2.org
217
218/// Single hue 3-class sequential, low to high
220{
221 /// red
222 color_qi(254,224,210), color_qi(252,146,114), color_qi(222,45,38),
223
224 /// orange
225 color_qi(254,230,206), color_qi(253,174,107), color_qi(230,85,13),
226
227 /// green
228 color_qi(229,245,224), color_qi(161,217,155), color_qi(49,163,84),
229
230 /// blue
231 color_qi(222,235,247), color_qi(158,202,225), color_qi(49,130,189),
232
233 /// purple
234 color_qi(239,237,245), color_qi(188,189,220), color_qi(117,107,177),
235
236 /// gray
237 color_qi(240,240,240), color_qi(189,189,189), color_qi(99,99,99),
239};
240
241/// Single hue 9-class sequential, low to high
243{
244 /// reds
245 color_qi(255,245,240), color_qi(254,224,210), color_qi(252,187,161),
246 color_qi(252,146,114), color_qi(251,106,74), color_qi(239,59,44),
247 color_qi(203,24,29), color_qi(165,15,21), color_qi(103,0,13),
248
249 /// orange
250 color_qi(255,245,235), color_qi(254,230,206), color_qi(253,208,162),
251 color_qi(253,174,107), color_qi(253,141,60), color_qi(241,105,19),
252 color_qi(217,72,1), color_qi(166,54,3), color_qi(127,39,4),
253
254 /// green
255 color_qi(247,252,245), color_qi(229,245,224), color_qi(199,233,192),
256 color_qi(161,217,155), color_qi(116,217,155), color_qi(65,171,93),
257 color_qi(35,139,69), color_qi(0,109,44), color_qi(0,68,27),
258
259 /// blue
260 color_qi(247,251,255), color_qi(222,235,247), color_qi(198,219,239),
261 color_qi(158,202,225), color_qi(107,174,214), color_qi(66,146,198),
262 color_qi(33,113,181), color_qi(8,81,156), color_qi(8,48,107),
263
264 /// purple
265 color_qi(252,251,253), color_qi(239,237,245), color_qi(218,218,235),
266 color_qi(188,189,220), color_qi(158,154,200), color_qi(128,125,186),
267 color_qi(106,81,163), color_qi(84,39,143), color_qi(63,0,125),
268
269 /// gray
270 color_qi(255,255,255), color_qi(240,240,240), color_qi(217,217,217),
271 color_qi(189,189,189), color_qi(150,150,150), color_qi(115,115,115),
272 color_qi(82,82,82), color_qi(37,37,37), color_qi(0,0,0),
273
275};
276
277/// Single hue 7-class sequential, low to high
279{
280 /// orange
281 color_qi(254,237,222), color_qi(253,208,162), color_qi(253,174,107),
282 color_qi(253,141,60), color_qi(241,105,19), color_qi(217,72,1),
283 color_qi(140,45,4),
284
285 /// reds
286 color_qi(254,229,217), color_qi(252,187,161), color_qi(252,146,114),
287 color_qi(251,106,74), color_qi(239,59,44), color_qi(203,24,29),
288 color_qi(153,0,13),
289
290 /// purple
291 color_qi(242,240,247), color_qi(218,218,235), color_qi(188,189,220),
292 color_qi(158,154,200), color_qi(128,125,186), color_qi(106,81,163),
293 color_qi(74,20,134),
294
295 /// blue
296 color_qi(239,243,255), color_qi(198,219,239), color_qi(158,202,225),
297 color_qi(107,174,214), color_qi(66,146,198), color_qi(33,113,181),
298 color_qi(8,69,148),
299
300 /// green
301 color_qi(237,248,233), color_qi(199,233,192), color_qi(161,217,155),
302 color_qi(116,196,118), color_qi(65,171,93), color_qi(35,139,69),
303 color_qi(0,90,50),
304
305 /// gray
306 color_qi(247,247,247), color_qi(217,217,217), color_qi(189,189,189),
307 color_qi(150,150,150), color_qi(115,115,115), color_qi(82,82,82),
308 color_qi(37,37,37),
309
311};
312
313
314/**
315 CIECAM02-UCS color space, perceptually different colors, equally spaced out.
316
317 Hand-picked values for a 67-68 BTIHA, aka cyberwar.
318 Start with color constraints, generate 264 options, hand-pick to n=68.
319 http://jnnnnn.github.io/category-colors-constrained.html
320*/
322{
323 // SE, red to orange/yellow (18)
324 color_qi(251,225,217), color_qi(254,231,192), color_qi(253,196,189),
325 color_qi(212,130,149), color_qi(253,225,137), color_qi(252,205,149),
326 color_qi(217,167,66), color_qi(254,205,15), color_qi(246,166,2),
327 color_qi(205,129,38), color_qi(233,112,10), color_qi(208,73,7),
328 color_qi(253,65,9), color_qi(243,28,78), color_qi(201,8,10),
329 color_qi(202,105,73), color_qi(242,92,88), color_qi(175,77,68),
330 /*
331 color_qi(253,176,130), color_qi(253,162,71), color_qi(246,131,146),
332 color_qi(254,103,148), color_qi(250,45,142), color_qi(213,9,126),
333 */
334
335 // SW, yellow, chartreuse, green, aquamarine (18)
336 color_qi(204,246,233), color_qi(155,254,227), color_qi(253,233,69),
337 color_qi(214,222,15), color_qi(211,254,20), color_qi(158,247,24),
338 color_qi(10,216,17), color_qi(10,235,101), color_qi(27,232,149),
339 color_qi(46,246,197), color_qi(224,248,106), color_qi(183,255,128),
340 color_qi(97,189,41), color_qi(163,238,148), color_qi(207,229,137),
341 color_qi(129,255,173), color_qi(158,227,189), color_qi(206,248,196),
342
343 // NE lavender to red violet (18)
344 color_qi(91,90,208), color_qi(125,91,240), color_qi(167,26,253),
345 color_qi(181,157,251), color_qi(214,202,254), color_qi(178,86,249),
346 color_qi(214,148,253), color_qi(188,121,216), color_qi(159,32,195),
347 color_qi(245,17,253), color_qi(251,80,225), color_qi(206,98,203),
348 color_qi(252,18,201), color_qi(235,125,171), color_qi(252,184,211),
349 color_qi(255,226,241), color_qi(254,199,248), color_qi(221,177,238),
350
351 // NW sky blue to indigo (18)
352 color_qi(11,240,233), color_qi(16,224,248), color_qi(152,252,255),
353 color_qi(199,236,249), color_qi(231,234,253), color_qi(187,217,253),
354 color_qi(126,216,254), color_qi(95,153,253), color_qi(57,87,255),
355 color_qi(22,130,251), color_qi(16,176,255), color_qi(48,199,253),
356 color_qi(5,169,209), color_qi(204,214,228), color_qi(100,214,203),
357 color_qi(146,166,254), color_qi(123,159,212), color_qi(105,154,179),
358
360};
361
362/// Oklab
363/// https://bottosson.github.io/posts/oklab/
364
365/// Set and Get working spectrum, aka default palette.
366/// NB: If colorbands are being used, palette has to be izzi or
367/// izzi_hue, and cannot be sorted (as color bands use colors arranged
368/// in a fixed order with offsets in hue.
369auto&
370active_spectrum(const bool sortbyhuep = false)
371{
372 //static auto spectrum = izzi_palette;
373 static auto spectrum = izzi_hue_palette;
374 //static auto spectrum = jp_palette;
375 //static auto spectrum = ciecam02_palette;
376 //static auto spectrum = colorbrewer2s3s_palette;
377 //static auto spectrum = colorbrewer2s9s_palette;
378
379 static bool initp(false);
380 if (sortbyhuep && !initp)
381 {
382 std::sort(spectrum.begin(), spectrum.end(), svg::color_qf_lt);
383 std::reverse(spectrum.begin(), spectrum.end());
384 initp = true;
385 }
386 return spectrum;
387}
388
389
390/// Random entry from array above.
391color_qi
392random_color(const uint startoffset = 0)
393{
394 auto& spectrum = active_spectrum();
395 const uint maxc = spectrum.size();
396 static std::mt19937_64 rg(std::random_device{}());
397 auto disti = std::uniform_int_distribution<>(startoffset, maxc - 1);
398 uint index = disti(rg);
399 return spectrum[index];
400}
401
402template<typename _Spectrm>
403color_qi
404random_color(const _Spectrm& spectrm, const uint startoffset = 0)
405{
406 const uint maxc = spectrm.size();
407 static std::mt19937_64 rg(std::random_device{}());
408 auto disti = std::uniform_int_distribution<>(startoffset, maxc - 1);
409 uint index = disti(rg);
410 return spectrm[index];
411}
412
413/// Loop through color array starting at position c.
414/// Iff klr is not found, return color::none as the next color.
415color_qi
417{
418 auto& spectrum = active_spectrum();
419 color_qi cnext = color::none;
420 auto itr = std::find(spectrum.begin(), spectrum.end(), klr);
421 if (itr != spectrum.end())
422 {
423 ++itr;
424 if (itr == spectrum.end())
425 itr = spectrum.begin();
426 cnext = *itr;
427 }
428 return cnext;
429}
430
431/// Start at specified color bar entry point.
432color_qi
434{
435 static color_qi _S_klr = klr;
436 color_qi retk = _S_klr;
437 _S_klr = next_color(_S_klr);
438 return retk;
439}
440
441} // namespace svg
442
443#endif
constexpr uint color_max_size
Total number of enumerated colors.
palette< color_qi, N > palette_qi
static const palette_qi< 118 > jp_palette
Japan colors (118) https://en.wikipedia.org/wiki/Traditional_colors_of_Japan.
palette< color_qf, N > palette_qf
static const palette_qi< 73 > ciecam02_palette
color_qi next_color(const color_qi klr)
Loop through color array starting at position c. Iff klr is not found, return color::none as the next...
static const palette_qi< 43 > colorbrewer2s7s_palette
Single hue 7-class sequential, low to high.
auto & active_spectrum(const bool sortbyhuep=false)
Oklab https://bottosson.github.io/posts/oklab/.
static const palette_qi< 55 > colorbrewer2s9s_palette
Single hue 9-class sequential, low to high.
color_qi random_color(const uint startoffset=0)
Random entry from array above.
static const palette_qi< color_max_size - 4 > izzi_palette
Default colors for izzi.
color_qi start_at_color(const color_qi klr)
Start at specified color bar entry point.
bool color_qf_lt(const color_qf &k1, const color_qf &k2)
Forwarding function.
unsigned int uint
Definition a60-svg.h:57
static const palette_qi< color_max_size - 20 > izzi_hue_palette
Only color no black and white or gray.
std::array< T, N > palette
Palette, finite set of colors used. Must end with color::none.
static const palette_qi< 19 > colorbrewer2s3s_palette
ColorBrewer 2.0 https://colorbrewer2.org.
Color quantified as integral RGB components in the range [0,255]. aka like Scalar in OpenCV.