summaryrefslogtreecommitdiff
path: root/src/ui
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
parent84909b4deba7ed90eed591cefe457be482628ecf (diff)
Color: Added HSL conversions
Removed the extra 15/88 grays from the UI palette.
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/color.c135
-rw-r--r--src/ui/color.h79
2 files changed, 171 insertions, 43 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;
diff --git a/src/ui/color.h b/src/ui/color.h
index 01e49c9c..11feb63e 100644
--- a/src/ui/color.h
+++ b/src/ui/color.h
@@ -1,15 +1,14 @@
1#pragma once 1#pragma once
2 2
3#include <the_Foundation/range.h> 3#include <the_Foundation/range.h>
4#include <the_Foundation/math.h>
4 5
5enum iColorId { 6enum iColorId {
6 none_ColorId = -1, 7 none_ColorId = -1,
7 black_ColorId, 8 black_ColorId,
8 gray15_ColorId,
9 gray25_ColorId, 9 gray25_ColorId,
10 gray50_ColorId, 10 gray50_ColorId,
11 gray75_ColorId, 11 gray75_ColorId,
12 gray88_ColorId,
13 white_ColorId, 12 white_ColorId,
14 brown_ColorId, 13 brown_ColorId,
15 orange_ColorId, 14 orange_ColorId,
@@ -20,35 +19,79 @@ enum iColorId {
20 magenta_ColorId, 19 magenta_ColorId,
21 blue_ColorId, 20 blue_ColorId,
22 green_ColorId, 21 green_ColorId,
22 /* content theme colors */
23 tmFirst_ColorId,
24 tmBackground_ColorId = tmFirst_ColorId,
25 tmParagraph_ColorId,
26 tmFirstParagraph_ColorId,
27 tmQuote_ColorId,
28 tmPreformatted_ColorId,
29 tmHeader1_ColorId,
30 tmHeader2_ColorId,
31 tmHeader3_ColorId,
32
33 tmLinkIcon_ColorId,
34 tmLinkIconVisited_ColorId,
35 tmLinkText_ColorId,
36 tmLinkTextHover_ColorId,
37 tmLinkDomain_ColorId,
38 tmLinkLastVisitDate_ColorId,
39
40 tmHypertextLinkIcon_ColorId,
41 tmHypertextLinkIconVisited_ColorId,
42 tmHypertextLinkText_ColorId,
43 tmHypertextLinkTextHover_ColorId,
44 tmHypertextLinkDomain_ColorId,
45 tmHypertextLinkLastVisitDate_ColorId,
46
47 tmGopherLinkIcon_ColorId,
48 tmGopherLinkIconVisited_ColorId,
49 tmGopherLinkText_ColorId,
50 tmGopherLinkTextHover_ColorId,
51 tmGopherLinkDomain_ColorId,
52 tmGopherLinkLastVisitDate_ColorId,
53
54 tmInlineContentMetadata_ColorId,
55 tmBannerBackground_ColorId,
56 tmBannerTitle_ColorId,
57 tmBannerIcon_ColorId,
23 max_ColorId 58 max_ColorId
24}; 59};
25 60
26#define mask_ColorId 0x0f 61#define mask_ColorId 0x3f
27#define permanent_ColorId 0x80 /* cannot be changed via escapes */ 62#define permanent_ColorId 0x80 /* cannot be changed via escapes */
28 63
29#define black_ColorEscape "\r0" 64#define black_ColorEscape "\r0"
30#define gray15_ColorEscape "\r1" 65#define gray25_ColorEscape "\r1"
31#define gray25_ColorEscape "\r2" 66#define gray50_ColorEscape "\r2"
32#define gray50_ColorEscape "\r3" 67#define gray75_ColorEscape "\r3"
33#define gray75_ColorEscape "\r4" 68#define white_ColorEscape "\r4"
34#define gray88_ColorEscape "\r5" 69#define brown_ColorEscape "\r5"
35#define white_ColorEscape "\r6" 70#define orange_ColorEscape "\r6"
36#define brown_ColorEscape "\r7" 71#define teal_ColorEscape "\r7"
37#define orange_ColorEscape "\r8" 72#define cyan_ColorEscape "\r8"
38#define teal_ColorEscape "\r9" 73#define yellow_ColorEscape "\r9"
39#define cyan_ColorEscape "\r:" 74#define red_ColorEscape "\r:"
40#define yellow_ColorEscape "\r;" 75#define magenta_ColorEscape "\r;"
41#define red_ColorEscape "\r<" 76#define blue_ColorEscape "\r<"
42#define magenta_ColorEscape "\r=" 77#define green_ColorEscape "\r="
43#define blue_ColorEscape "\r>"
44#define green_ColorEscape "\r?"
45 78
46iDeclareType(Color) 79iDeclareType(Color)
80iDeclareType(HSLColor)
47 81
48struct Impl_Color { 82struct Impl_Color {
49 uint8_t r, g, b, a; 83 uint8_t r, g, b, a;
50}; 84};
51 85
86struct Impl_HSLColor {
87 float hue, sat, lum, a;
88};
89
52iColor get_Color (int color); 90iColor get_Color (int color);
91void set_Color (int color, iColor rgba);
92
93iHSLColor hsl_Color (iColor rgba);
94iColor fromHsl_Color (iHSLColor hsl);
95
53iColor ansi_Color (iRangecc escapeSequence, int fallback); 96iColor ansi_Color (iRangecc escapeSequence, int fallback);
54const char * escape_Color (int color); 97const char * escape_Color (int color);