1 /**
2 * @file lv_color.c
3 *
4 */
5
6 /*********************
7 * INCLUDES
8 *********************/
9 #include "lv_color.h"
10 #include "lv_log.h"
11
12 /*********************
13 * DEFINES
14 *********************/
15
16 /**********************
17 * TYPEDEFS
18 **********************/
19
20 /**********************
21 * STATIC PROTOTYPES
22 **********************/
23
24 /**********************
25 * STATIC VARIABLES
26 **********************/
27
28 /**********************
29 * MACROS
30 **********************/
31
32 /**********************
33 * GLOBAL FUNCTIONS
34 **********************/
35
lv_color_fill(lv_color_t * buf,lv_color_t color,uint32_t px_num)36 void LV_ATTRIBUTE_FAST_MEM lv_color_fill(lv_color_t * buf, lv_color_t color, uint32_t px_num)
37 {
38 #if LV_COLOR_DEPTH == 16
39 uintptr_t buf_int = (uintptr_t)buf;
40 if(buf_int & 0x3) {
41 *buf = color;
42 buf++;
43 px_num--;
44 }
45
46 uint32_t c32 = (uint32_t)color.full + ((uint32_t)color.full << 16);
47 uint32_t * buf32 = (uint32_t *)buf;
48
49 while(px_num > 16) {
50 *buf32 = c32;
51 buf32++;
52 *buf32 = c32;
53 buf32++;
54 *buf32 = c32;
55 buf32++;
56 *buf32 = c32;
57 buf32++;
58
59 *buf32 = c32;
60 buf32++;
61 *buf32 = c32;
62 buf32++;
63 *buf32 = c32;
64 buf32++;
65 *buf32 = c32;
66 buf32++;
67
68 px_num -= 16;
69 }
70
71 buf = (lv_color_t *)buf32;
72
73 while(px_num) {
74 *buf = color;
75 buf++;
76 px_num--;
77 }
78 #else
79 while(px_num > 16) {
80 *buf = color;
81 buf++;
82 *buf = color;
83 buf++;
84 *buf = color;
85 buf++;
86 *buf = color;
87 buf++;
88
89 *buf = color;
90 buf++;
91 *buf = color;
92 buf++;
93 *buf = color;
94 buf++;
95 *buf = color;
96 buf++;
97
98 *buf = color;
99 buf++;
100 *buf = color;
101 buf++;
102 *buf = color;
103 buf++;
104 *buf = color;
105 buf++;
106
107 *buf = color;
108 buf++;
109 *buf = color;
110 buf++;
111 *buf = color;
112 buf++;
113 *buf = color;
114 buf++;
115
116 px_num -= 16;
117 }
118 while(px_num) {
119 *buf = color;
120 buf++;
121 px_num--;
122 }
123 #endif
124 }
125
lv_color_lighten(lv_color_t c,lv_opa_t lvl)126 lv_color_t lv_color_lighten(lv_color_t c, lv_opa_t lvl)
127 {
128 return lv_color_mix(lv_color_white(), c, lvl);
129 }
130
lv_color_darken(lv_color_t c,lv_opa_t lvl)131 lv_color_t lv_color_darken(lv_color_t c, lv_opa_t lvl)
132 {
133 return lv_color_mix(lv_color_black(), c, lvl);
134 }
135
lv_color_change_lightness(lv_color_t c,lv_opa_t lvl)136 lv_color_t lv_color_change_lightness(lv_color_t c, lv_opa_t lvl)
137 {
138 /*It'd be better to convert the color to HSL, change L and convert back to RGB.*/
139 if(lvl == LV_OPA_50) return c;
140 else if(lvl < LV_OPA_50) return lv_color_darken(c, (LV_OPA_50 - lvl) * 2);
141 else return lv_color_lighten(c, (lvl - LV_OPA_50) * 2);
142 }
143
144 /**
145 * Convert a HSV color to RGB
146 * @param h hue [0..359]
147 * @param s saturation [0..100]
148 * @param v value [0..100]
149 * @return the given RGB color in RGB (with LV_COLOR_DEPTH depth)
150 */
lv_color_hsv_to_rgb(uint16_t h,uint8_t s,uint8_t v)151 lv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v)
152 {
153 h = (uint32_t)((uint32_t)h * 255) / 360;
154 s = (uint16_t)((uint16_t)s * 255) / 100;
155 v = (uint16_t)((uint16_t)v * 255) / 100;
156
157 uint8_t r, g, b;
158
159 uint8_t region, remainder, p, q, t;
160
161 if(s == 0) {
162 return lv_color_make(v, v, v);
163 }
164
165 region = h / 43;
166 remainder = (h - (region * 43)) * 6;
167
168 p = (v * (255 - s)) >> 8;
169 q = (v * (255 - ((s * remainder) >> 8))) >> 8;
170 t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8;
171
172 switch(region) {
173 case 0:
174 r = v;
175 g = t;
176 b = p;
177 break;
178 case 1:
179 r = q;
180 g = v;
181 b = p;
182 break;
183 case 2:
184 r = p;
185 g = v;
186 b = t;
187 break;
188 case 3:
189 r = p;
190 g = q;
191 b = v;
192 break;
193 case 4:
194 r = t;
195 g = p;
196 b = v;
197 break;
198 default:
199 r = v;
200 g = p;
201 b = q;
202 break;
203 }
204
205 lv_color_t result = lv_color_make(r, g, b);
206 return result;
207 }
208
209 /**
210 * Convert a 32-bit RGB color to HSV
211 * @param r8 8-bit red
212 * @param g8 8-bit green
213 * @param b8 8-bit blue
214 * @return the given RGB color in HSV
215 */
lv_color_rgb_to_hsv(uint8_t r8,uint8_t g8,uint8_t b8)216 lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r8, uint8_t g8, uint8_t b8)
217 {
218 uint16_t r = ((uint32_t)r8 << 10) / 255;
219 uint16_t g = ((uint32_t)g8 << 10) / 255;
220 uint16_t b = ((uint32_t)b8 << 10) / 255;
221
222 uint16_t rgbMin = r < g ? (r < b ? r : b) : (g < b ? g : b);
223 uint16_t rgbMax = r > g ? (r > b ? r : b) : (g > b ? g : b);
224
225 lv_color_hsv_t hsv;
226
227 // https://en.wikipedia.org/wiki/HSL_and_HSV#Lightness
228 hsv.v = (100 * rgbMax) >> 10;
229
230 int32_t delta = rgbMax - rgbMin;
231 if(delta < 3) {
232 hsv.h = 0;
233 hsv.s = 0;
234 return hsv;
235 }
236
237 // https://en.wikipedia.org/wiki/HSL_and_HSV#Saturation
238 hsv.s = 100 * delta / rgbMax;
239 if(hsv.s < 3) {
240 hsv.h = 0;
241 return hsv;
242 }
243
244 // https://en.wikipedia.org/wiki/HSL_and_HSV#Hue_and_chroma
245 int32_t h;
246 if(rgbMax == r)
247 h = (((g - b) << 10) / delta) + (g < b ? (6 << 10) : 0); // between yellow & magenta
248 else if(rgbMax == g)
249 h = (((b - r) << 10) / delta) + (2 << 10); // between cyan & yellow
250 else if(rgbMax == b)
251 h = (((r - g) << 10) / delta) + (4 << 10); // between magenta & cyan
252 else
253 h = 0;
254 h *= 60;
255 h >>= 10;
256 if(h < 0) h += 360;
257
258 hsv.h = h;
259 return hsv;
260 }
261
262 /**
263 * Convert a color to HSV
264 * @param color color
265 * @return the given color in HSV
266 */
lv_color_to_hsv(lv_color_t color)267 lv_color_hsv_t lv_color_to_hsv(lv_color_t color)
268 {
269 lv_color32_t color32;
270 color32.full = lv_color_to32(color);
271 return lv_color_rgb_to_hsv(color32.ch.red, color32.ch.green, color32.ch.blue);
272 }
273
lv_palette_main(lv_palette_t p)274 lv_color_t lv_palette_main(lv_palette_t p)
275 {
276 static const lv_color_t colors[] = {
277 LV_COLOR_MAKE(0xF4, 0x43, 0x36), LV_COLOR_MAKE(0xE9, 0x1E, 0x63), LV_COLOR_MAKE(0x9C, 0x27, 0xB0), LV_COLOR_MAKE(0x67, 0x3A, 0xB7),
278 LV_COLOR_MAKE(0x3F, 0x51, 0xB5), LV_COLOR_MAKE(0x21, 0x96, 0xF3), LV_COLOR_MAKE(0x03, 0xA9, 0xF4), LV_COLOR_MAKE(0x00, 0xBC, 0xD4),
279 LV_COLOR_MAKE(0x00, 0x96, 0x88), LV_COLOR_MAKE(0x4C, 0xAF, 0x50), LV_COLOR_MAKE(0x8B, 0xC3, 0x4A), LV_COLOR_MAKE(0xCD, 0xDC, 0x39),
280 LV_COLOR_MAKE(0xFF, 0xEB, 0x3B), LV_COLOR_MAKE(0xFF, 0xC1, 0x07), LV_COLOR_MAKE(0xFF, 0x98, 0x00), LV_COLOR_MAKE(0xFF, 0x57, 0x22),
281 LV_COLOR_MAKE(0x79, 0x55, 0x48), LV_COLOR_MAKE(0x60, 0x7D, 0x8B), LV_COLOR_MAKE(0x9E, 0x9E, 0x9E)
282 };
283
284 if(p >= _LV_PALETTE_LAST) {
285 LV_LOG_WARN("Invalid palette: %d", p);
286 return lv_color_black();
287 }
288
289 return colors[p];
290
291 }
292
lv_palette_lighten(lv_palette_t p,uint8_t lvl)293 lv_color_t lv_palette_lighten(lv_palette_t p, uint8_t lvl)
294 {
295 static const lv_color_t colors[][5] = {
296 {LV_COLOR_MAKE(0xEF, 0x53, 0x50), LV_COLOR_MAKE(0xE5, 0x73, 0x73), LV_COLOR_MAKE(0xEF, 0x9A, 0x9A), LV_COLOR_MAKE(0xFF, 0xCD, 0xD2), LV_COLOR_MAKE(0xFF, 0xEB, 0xEE)},
297 {LV_COLOR_MAKE(0xEC, 0x40, 0x7A), LV_COLOR_MAKE(0xF0, 0x62, 0x92), LV_COLOR_MAKE(0xF4, 0x8F, 0xB1), LV_COLOR_MAKE(0xF8, 0xBB, 0xD0), LV_COLOR_MAKE(0xFC, 0xE4, 0xEC)},
298 {LV_COLOR_MAKE(0xAB, 0x47, 0xBC), LV_COLOR_MAKE(0xBA, 0x68, 0xC8), LV_COLOR_MAKE(0xCE, 0x93, 0xD8), LV_COLOR_MAKE(0xE1, 0xBE, 0xE7), LV_COLOR_MAKE(0xF3, 0xE5, 0xF5)},
299 {LV_COLOR_MAKE(0x7E, 0x57, 0xC2), LV_COLOR_MAKE(0x95, 0x75, 0xCD), LV_COLOR_MAKE(0xB3, 0x9D, 0xDB), LV_COLOR_MAKE(0xD1, 0xC4, 0xE9), LV_COLOR_MAKE(0xED, 0xE7, 0xF6)},
300 {LV_COLOR_MAKE(0x5C, 0x6B, 0xC0), LV_COLOR_MAKE(0x79, 0x86, 0xCB), LV_COLOR_MAKE(0x9F, 0xA8, 0xDA), LV_COLOR_MAKE(0xC5, 0xCA, 0xE9), LV_COLOR_MAKE(0xE8, 0xEA, 0xF6)},
301 {LV_COLOR_MAKE(0x42, 0xA5, 0xF5), LV_COLOR_MAKE(0x64, 0xB5, 0xF6), LV_COLOR_MAKE(0x90, 0xCA, 0xF9), LV_COLOR_MAKE(0xBB, 0xDE, 0xFB), LV_COLOR_MAKE(0xE3, 0xF2, 0xFD)},
302 {LV_COLOR_MAKE(0x29, 0xB6, 0xF6), LV_COLOR_MAKE(0x4F, 0xC3, 0xF7), LV_COLOR_MAKE(0x81, 0xD4, 0xFA), LV_COLOR_MAKE(0xB3, 0xE5, 0xFC), LV_COLOR_MAKE(0xE1, 0xF5, 0xFE)},
303 {LV_COLOR_MAKE(0x26, 0xC6, 0xDA), LV_COLOR_MAKE(0x4D, 0xD0, 0xE1), LV_COLOR_MAKE(0x80, 0xDE, 0xEA), LV_COLOR_MAKE(0xB2, 0xEB, 0xF2), LV_COLOR_MAKE(0xE0, 0xF7, 0xFA)},
304 {LV_COLOR_MAKE(0x26, 0xA6, 0x9A), LV_COLOR_MAKE(0x4D, 0xB6, 0xAC), LV_COLOR_MAKE(0x80, 0xCB, 0xC4), LV_COLOR_MAKE(0xB2, 0xDF, 0xDB), LV_COLOR_MAKE(0xE0, 0xF2, 0xF1)},
305 {LV_COLOR_MAKE(0x66, 0xBB, 0x6A), LV_COLOR_MAKE(0x81, 0xC7, 0x84), LV_COLOR_MAKE(0xA5, 0xD6, 0xA7), LV_COLOR_MAKE(0xC8, 0xE6, 0xC9), LV_COLOR_MAKE(0xE8, 0xF5, 0xE9)},
306 {LV_COLOR_MAKE(0x9C, 0xCC, 0x65), LV_COLOR_MAKE(0xAE, 0xD5, 0x81), LV_COLOR_MAKE(0xC5, 0xE1, 0xA5), LV_COLOR_MAKE(0xDC, 0xED, 0xC8), LV_COLOR_MAKE(0xF1, 0xF8, 0xE9)},
307 {LV_COLOR_MAKE(0xD4, 0xE1, 0x57), LV_COLOR_MAKE(0xDC, 0xE7, 0x75), LV_COLOR_MAKE(0xE6, 0xEE, 0x9C), LV_COLOR_MAKE(0xF0, 0xF4, 0xC3), LV_COLOR_MAKE(0xF9, 0xFB, 0xE7)},
308 {LV_COLOR_MAKE(0xFF, 0xEE, 0x58), LV_COLOR_MAKE(0xFF, 0xF1, 0x76), LV_COLOR_MAKE(0xFF, 0xF5, 0x9D), LV_COLOR_MAKE(0xFF, 0xF9, 0xC4), LV_COLOR_MAKE(0xFF, 0xFD, 0xE7)},
309 {LV_COLOR_MAKE(0xFF, 0xCA, 0x28), LV_COLOR_MAKE(0xFF, 0xD5, 0x4F), LV_COLOR_MAKE(0xFF, 0xE0, 0x82), LV_COLOR_MAKE(0xFF, 0xEC, 0xB3), LV_COLOR_MAKE(0xFF, 0xF8, 0xE1)},
310 {LV_COLOR_MAKE(0xFF, 0xA7, 0x26), LV_COLOR_MAKE(0xFF, 0xB7, 0x4D), LV_COLOR_MAKE(0xFF, 0xCC, 0x80), LV_COLOR_MAKE(0xFF, 0xE0, 0xB2), LV_COLOR_MAKE(0xFF, 0xF3, 0xE0)},
311 {LV_COLOR_MAKE(0xFF, 0x70, 0x43), LV_COLOR_MAKE(0xFF, 0x8A, 0x65), LV_COLOR_MAKE(0xFF, 0xAB, 0x91), LV_COLOR_MAKE(0xFF, 0xCC, 0xBC), LV_COLOR_MAKE(0xFB, 0xE9, 0xE7)},
312 {LV_COLOR_MAKE(0x8D, 0x6E, 0x63), LV_COLOR_MAKE(0xA1, 0x88, 0x7F), LV_COLOR_MAKE(0xBC, 0xAA, 0xA4), LV_COLOR_MAKE(0xD7, 0xCC, 0xC8), LV_COLOR_MAKE(0xEF, 0xEB, 0xE9)},
313 {LV_COLOR_MAKE(0x78, 0x90, 0x9C), LV_COLOR_MAKE(0x90, 0xA4, 0xAE), LV_COLOR_MAKE(0xB0, 0xBE, 0xC5), LV_COLOR_MAKE(0xCF, 0xD8, 0xDC), LV_COLOR_MAKE(0xEC, 0xEF, 0xF1)},
314 {LV_COLOR_MAKE(0xBD, 0xBD, 0xBD), LV_COLOR_MAKE(0xE0, 0xE0, 0xE0), LV_COLOR_MAKE(0xEE, 0xEE, 0xEE), LV_COLOR_MAKE(0xF5, 0xF5, 0xF5), LV_COLOR_MAKE(0xFA, 0xFA, 0xFA)},
315 };
316
317 if(p >= _LV_PALETTE_LAST) {
318 LV_LOG_WARN("Invalid palette: %d", p);
319 return lv_color_black();
320 }
321
322 if(lvl == 0 || lvl > 5) {
323 LV_LOG_WARN("Invalid level: %d. Must be 1..5", lvl);
324 return lv_color_black();
325 }
326
327 lvl--;
328
329 return colors[p][lvl];
330 }
331
lv_palette_darken(lv_palette_t p,uint8_t lvl)332 lv_color_t lv_palette_darken(lv_palette_t p, uint8_t lvl)
333 {
334 static const lv_color_t colors[][4] = {
335 {LV_COLOR_MAKE(0xE5, 0x39, 0x35), LV_COLOR_MAKE(0xD3, 0x2F, 0x2F), LV_COLOR_MAKE(0xC6, 0x28, 0x28), LV_COLOR_MAKE(0xB7, 0x1C, 0x1C)},
336 {LV_COLOR_MAKE(0xD8, 0x1B, 0x60), LV_COLOR_MAKE(0xC2, 0x18, 0x5B), LV_COLOR_MAKE(0xAD, 0x14, 0x57), LV_COLOR_MAKE(0x88, 0x0E, 0x4F)},
337 {LV_COLOR_MAKE(0x8E, 0x24, 0xAA), LV_COLOR_MAKE(0x7B, 0x1F, 0xA2), LV_COLOR_MAKE(0x6A, 0x1B, 0x9A), LV_COLOR_MAKE(0x4A, 0x14, 0x8C)},
338 {LV_COLOR_MAKE(0x5E, 0x35, 0xB1), LV_COLOR_MAKE(0x51, 0x2D, 0xA8), LV_COLOR_MAKE(0x45, 0x27, 0xA0), LV_COLOR_MAKE(0x31, 0x1B, 0x92)},
339 {LV_COLOR_MAKE(0x39, 0x49, 0xAB), LV_COLOR_MAKE(0x30, 0x3F, 0x9F), LV_COLOR_MAKE(0x28, 0x35, 0x93), LV_COLOR_MAKE(0x1A, 0x23, 0x7E)},
340 {LV_COLOR_MAKE(0x1E, 0x88, 0xE5), LV_COLOR_MAKE(0x19, 0x76, 0xD2), LV_COLOR_MAKE(0x15, 0x65, 0xC0), LV_COLOR_MAKE(0x0D, 0x47, 0xA1)},
341 {LV_COLOR_MAKE(0x03, 0x9B, 0xE5), LV_COLOR_MAKE(0x02, 0x88, 0xD1), LV_COLOR_MAKE(0x02, 0x77, 0xBD), LV_COLOR_MAKE(0x01, 0x57, 0x9B)},
342 {LV_COLOR_MAKE(0x00, 0xAC, 0xC1), LV_COLOR_MAKE(0x00, 0x97, 0xA7), LV_COLOR_MAKE(0x00, 0x83, 0x8F), LV_COLOR_MAKE(0x00, 0x60, 0x64)},
343 {LV_COLOR_MAKE(0x00, 0x89, 0x7B), LV_COLOR_MAKE(0x00, 0x79, 0x6B), LV_COLOR_MAKE(0x00, 0x69, 0x5C), LV_COLOR_MAKE(0x00, 0x4D, 0x40)},
344 {LV_COLOR_MAKE(0x43, 0xA0, 0x47), LV_COLOR_MAKE(0x38, 0x8E, 0x3C), LV_COLOR_MAKE(0x2E, 0x7D, 0x32), LV_COLOR_MAKE(0x1B, 0x5E, 0x20)},
345 {LV_COLOR_MAKE(0x7C, 0xB3, 0x42), LV_COLOR_MAKE(0x68, 0x9F, 0x38), LV_COLOR_MAKE(0x55, 0x8B, 0x2F), LV_COLOR_MAKE(0x33, 0x69, 0x1E)},
346 {LV_COLOR_MAKE(0xC0, 0xCA, 0x33), LV_COLOR_MAKE(0xAF, 0xB4, 0x2B), LV_COLOR_MAKE(0x9E, 0x9D, 0x24), LV_COLOR_MAKE(0x82, 0x77, 0x17)},
347 {LV_COLOR_MAKE(0xFD, 0xD8, 0x35), LV_COLOR_MAKE(0xFB, 0xC0, 0x2D), LV_COLOR_MAKE(0xF9, 0xA8, 0x25), LV_COLOR_MAKE(0xF5, 0x7F, 0x17)},
348 {LV_COLOR_MAKE(0xFF, 0xB3, 0x00), LV_COLOR_MAKE(0xFF, 0xA0, 0x00), LV_COLOR_MAKE(0xFF, 0x8F, 0x00), LV_COLOR_MAKE(0xFF, 0x6F, 0x00)},
349 {LV_COLOR_MAKE(0xFB, 0x8C, 0x00), LV_COLOR_MAKE(0xF5, 0x7C, 0x00), LV_COLOR_MAKE(0xEF, 0x6C, 0x00), LV_COLOR_MAKE(0xE6, 0x51, 0x00)},
350 {LV_COLOR_MAKE(0xF4, 0x51, 0x1E), LV_COLOR_MAKE(0xE6, 0x4A, 0x19), LV_COLOR_MAKE(0xD8, 0x43, 0x15), LV_COLOR_MAKE(0xBF, 0x36, 0x0C)},
351 {LV_COLOR_MAKE(0x6D, 0x4C, 0x41), LV_COLOR_MAKE(0x5D, 0x40, 0x37), LV_COLOR_MAKE(0x4E, 0x34, 0x2E), LV_COLOR_MAKE(0x3E, 0x27, 0x23)},
352 {LV_COLOR_MAKE(0x54, 0x6E, 0x7A), LV_COLOR_MAKE(0x45, 0x5A, 0x64), LV_COLOR_MAKE(0x37, 0x47, 0x4F), LV_COLOR_MAKE(0x26, 0x32, 0x38)},
353 {LV_COLOR_MAKE(0x75, 0x75, 0x75), LV_COLOR_MAKE(0x61, 0x61, 0x61), LV_COLOR_MAKE(0x42, 0x42, 0x42), LV_COLOR_MAKE(0x21, 0x21, 0x21)},
354 };
355
356 if(p >= _LV_PALETTE_LAST) {
357 LV_LOG_WARN("Invalid palette: %d", p);
358 return lv_color_black();
359 }
360
361 if(lvl == 0 || lvl > 4) {
362 LV_LOG_WARN("Invalid level: %d. Must be 1..4", lvl);
363 return lv_color_black();
364 }
365
366 lvl--;
367
368 return colors[p][lvl];
369 }
370