summaryrefslogtreecommitdiff
path: root/src/ui/color.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-08-05 10:44:52 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-08-05 10:44:52 +0300
commitddb3dd5c4278f4ecfbd76351cb1651581dd9ec49 (patch)
tree316839d72f77e7e0e50b8ff2cb7ddfb3070a9c76 /src/ui/color.c
parent84909b4deba7ed90eed591cefe457be482628ecf (diff)
Color: Added HSL conversions
Removed the extra 15/88 grays from the UI palette.
Diffstat (limited to 'src/ui/color.c')
-rw-r--r--src/ui/color.c135
1 files changed, 110 insertions, 25 deletions
diff --git a/src/ui/color.c b/src/ui/color.c
index 46d8a71f..0402d0fb 100644
--- a/src/ui/color.c
+++ b/src/ui/color.c
@@ -4,40 +4,125 @@
4 4
5static const iColor transparent_; 5static const iColor transparent_;
6 6
7static iColor palette_[max_ColorId] = {
8 { 0, 0, 0, 255 },
9 { 40, 40, 40, 255 },
10 { 80, 80, 80, 255 },
11 { 160, 160, 160, 255 },
12 { 255, 255, 255, 255 },
13 { 106, 80, 0, 255 },
14 { 255, 192, 0, 255 },
15 { 0, 96, 128, 255 },
16 { 0, 192, 255, 255 },
17 { 255, 255, 32, 255 },
18 { 255, 64, 64, 255 },
19 { 255, 0, 255, 255 },
20 { 132, 132, 255, 255 },
21 { 0, 200, 0, 255 },
22 /* theme colors left black until theme is seeded */
23};
24
7iColor get_Color(int color) { 25iColor get_Color(int color) {
8 static const iColor palette[] = { 26 const iColor *rgba = &transparent_;
9 { 0, 0, 0, 255 }, 27 if (color >= 0 && color < max_ColorId) {
10 { 24, 24, 24, 255 }, 28 rgba = &palette_[color];
11 { 40, 40, 40, 255 }, 29 }
12 { 80, 80, 80, 255 }, 30 return *rgba;
13 { 160, 160, 160, 255 }, 31}
14 { 208, 208, 208, 255 }, 32
15 { 255, 255, 255, 255 }, 33void set_Color(int color, iColor rgba) {
16 { 106, 80, 0, 255 }, 34 if (color >= tmFirst_ColorId && color < max_ColorId) {
17 { 255, 192, 0, 255 }, 35 palette_[color] = rgba;
18 { 0, 96, 128, 255 },
19 { 0, 192, 255, 255 },
20 { 255, 255, 32, 255 },
21 { 255, 64, 64, 255 },
22 { 255, 0, 255, 255 },
23 { 132, 132, 255, 255 },
24 { 0, 200, 0, 255 },
25 };
26 const iColor *clr = &transparent_;
27 if (color >= 0 && color < (int) iElemCount(palette)) {
28 clr = &palette[color];
29 } 36 }
30 return *clr; 37}
38
39iLocalDef iFloat4 normalize_(iColor d) {
40 return divf_F4(init_F4(d.r, d.g, d.b, d.a), 255.0f);
41}
42
43iLocalDef iColor toColor_(iFloat4 d) {
44 const iFloat4 i = addf_F4(mulf_F4(d, 255.0f), 0.5f);
45 return (iColor){ (uint8_t) x_F4(i),
46 (uint8_t) y_F4(i),
47 (uint8_t) z_F4(i),
48 (uint8_t) w_F4(i) };
49}
50
51iHSLColor hsl_Color(iColor color) {
52 float rgb[4];
53 store_F4(normalize_(color), rgb);
54 int compMax, compMin;
55 if (rgb[0] >= rgb[1] && rgb[0] >= rgb[2]) {
56 compMax = 0;
57 }
58 else if (rgb[1] >= rgb[0] && rgb[1] >= rgb[2]) {
59 compMax = 1;
60 }
61 else {
62 compMax = 2;
63 }
64 if (rgb[0] <= rgb[1] && rgb[0] <= rgb[2]) {
65 compMin = 0;
66 }
67 else if (rgb[1] <= rgb[0] && rgb[1] <= rgb[2]) {
68 compMin = 1;
69 }
70 else {
71 compMin = 2;
72 }
73 const float rgbMax = rgb[compMax];
74 const float rgbMin = rgb[compMin];
75 const float lum = (rgbMax + rgbMin) / 2.0f;
76 float hue = 0.0f;
77 float sat = 0.0f;
78 if (fabsf(rgbMax - rgbMin) > 0.00001f) {
79 float chr = rgbMax - rgbMin;
80 sat = chr / (1.0f - fabsf(2.0f * lum - 1.0f));
81 if (compMax == 0) {
82 hue = (rgb[1] - rgb[2]) / chr + (rgb[1] < rgb[2] ? 6 : 0);
83 }
84 else if (compMax == 1) {
85 hue = (rgb[2] - rgb[0]) / chr + 2;
86 }
87 else {
88 hue = (rgb[0] - rgb[1]) / chr + 4;
89 }
90 }
91 return (iHSLColor){ hue * 60, sat, lum, rgb[3] }; /* hue in degrees */
92}
93
94static float hueToRgb_(float p, float q, float t) {
95 if (t < 0.0f) t += 1.0f;
96 if (t > 1.0f) t -= 1.0f;
97 if (t < 1.0f / 6.0f) return p + (q - p) * 6.0f * t;
98 if (t < 1.0f / 2.0f) return q;
99 if (t < 2.0f / 3.0f) return p + (q - p) * (2.0f / 3.0f - t) * 6.0f;
100 return p;
101}
102
103iColor fromHsl_Color(iHSLColor hsl) {
104 float r, g, b;
105 hsl.hue /= 360.0f;
106 if (hsl.sat < 0.00001f) {
107 r = g = b = hsl.lum;
108 }
109 else {
110 const float q = hsl.lum < 0.5f ? hsl.lum * (1 + hsl.sat)
111 : (hsl.lum + hsl.sat - hsl.lum * hsl.sat);
112 const float p = 2 * hsl.lum - q;
113 r = hueToRgb_(p, q, hsl.hue + 1.0f / 3.0f);
114 g = hueToRgb_(p, q, hsl.hue);
115 b = hueToRgb_(p, q, hsl.hue - 1.0f / 3.0f);
116 }
117 return toColor_(init_F4(r, g, b, hsl.a));
31} 118}
32 119
33const char *escape_Color(int color) { 120const char *escape_Color(int color) {
34 static const char *esc[] = { 121 static const char *esc[] = {
35 black_ColorEscape, 122 black_ColorEscape,
36 gray15_ColorEscape,
37 gray25_ColorEscape, 123 gray25_ColorEscape,
38 gray50_ColorEscape, 124 gray50_ColorEscape,
39 gray75_ColorEscape, 125 gray75_ColorEscape,
40 gray88_ColorEscape,
41 white_ColorEscape, 126 white_ColorEscape,
42 brown_ColorEscape, 127 brown_ColorEscape,
43 orange_ColorEscape, 128 orange_ColorEscape,
@@ -49,7 +134,7 @@ const char *escape_Color(int color) {
49 blue_ColorEscape, 134 blue_ColorEscape,
50 green_ColorEscape, 135 green_ColorEscape,
51 }; 136 };
52 if (color >= 0 && color < max_ColorId) { 137 if (color >= 0 && color < (int) iElemCount(esc)) {
53 return esc[color]; 138 return esc[color];
54 } 139 }
55 return white_ColorEscape; 140 return white_ColorEscape;