diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-08-05 10:44:52 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-08-05 10:44:52 +0300 |
commit | ddb3dd5c4278f4ecfbd76351cb1651581dd9ec49 (patch) | |
tree | 316839d72f77e7e0e50b8ff2cb7ddfb3070a9c76 /src/ui/color.c | |
parent | 84909b4deba7ed90eed591cefe457be482628ecf (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.c | 135 |
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 | ||
5 | static const iColor transparent_; | 5 | static const iColor transparent_; |
6 | 6 | ||
7 | static 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 | |||
7 | iColor get_Color(int color) { | 25 | iColor 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 }, | 33 | void 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 | |||
39 | iLocalDef iFloat4 normalize_(iColor d) { | ||
40 | return divf_F4(init_F4(d.r, d.g, d.b, d.a), 255.0f); | ||
41 | } | ||
42 | |||
43 | iLocalDef 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 | |||
51 | iHSLColor 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 | |||
94 | static 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 | |||
103 | iColor 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 | ||
33 | const char *escape_Color(int color) { | 120 | const 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; |