LittlevGL  3.20.00.19
lv_color.h
Go to the documentation of this file.
1 
6 #ifndef LV_COLOR_H
7 #define LV_COLOR_H
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 /*********************
14  * INCLUDES
15  *********************/
16 #ifdef LV_CONF_INCLUDE_SIMPLE
17 #include "lv_conf.h"
18 #else
19 #include "../../../lv_conf.h"
20 #endif
21 
22 /*Error checking*/
23 #if LV_COLOR_DEPTH == 24
24 #error "LV_COLOR_DEPTH 24 is deprecated. Use LV_COLOR_DEPTH 32 instead (lv_conf.h)"
25 #endif
26 
27 #if LV_COLOR_DEPTH != 32 && LV_COLOR_SCREEN_TRANSP != 0
28 #error "LV_COLOR_SCREEN_TRANSP requires LV_COLOR_DEPTH == 32. Set it in lv_conf.h"
29 #endif
30 
31 #if LV_COLOR_DEPTH != 16 && LV_COLOR_16_SWAP != 0
32 #error "LV_COLOR_16_SWAP requires LV_COLOR_DEPTH == 16. Set it in lv_conf.h"
33 #endif
34 
35 #include <stdint.h>
36 
37 /*********************
38  * DEFINES
39  *********************/
40 #define LV_COLOR_WHITE LV_COLOR_MAKE(0xFF, 0xFF, 0xFF)
41 #define LV_COLOR_SILVER LV_COLOR_MAKE(0xC0, 0xC0, 0xC0)
42 #define LV_COLOR_GRAY LV_COLOR_MAKE(0x80, 0x80, 0x80)
43 #define LV_COLOR_BLACK LV_COLOR_MAKE(0x00, 0x00, 0x00)
44 #define LV_COLOR_RED LV_COLOR_MAKE(0xFF, 0x00, 0x00)
45 #define LV_COLOR_MAROON LV_COLOR_MAKE(0x80, 0x00, 0x00)
46 #define LV_COLOR_YELLOW LV_COLOR_MAKE(0xFF, 0xFF, 0x00)
47 #define LV_COLOR_OLIVE LV_COLOR_MAKE(0x80, 0x80, 0x00)
48 #define LV_COLOR_LIME LV_COLOR_MAKE(0x00, 0xFF, 0x00)
49 #define LV_COLOR_GREEN LV_COLOR_MAKE(0x00, 0x80, 0x00)
50 #define LV_COLOR_CYAN LV_COLOR_MAKE(0x00, 0xFF, 0xFF)
51 #define LV_COLOR_AQUA LV_COLOR_CYAN
52 #define LV_COLOR_TEAL LV_COLOR_MAKE(0x00, 0x80, 0x80)
53 #define LV_COLOR_BLUE LV_COLOR_MAKE(0x00, 0x00, 0xFF)
54 #define LV_COLOR_NAVY LV_COLOR_MAKE(0x00, 0x00, 0x80)
55 #define LV_COLOR_MAGENTA LV_COLOR_MAKE(0xFF, 0x00, 0xFF)
56 #define LV_COLOR_PURPLE LV_COLOR_MAKE(0x80, 0x00, 0x80)
57 #define LV_COLOR_ORANGE LV_COLOR_MAKE(0xFF, 0xA5, 0x00)
58 
62 enum {
64  LV_OPA_0 = 0,
65  LV_OPA_10 = 25,
66  LV_OPA_20 = 51,
67  LV_OPA_30 = 76,
68  LV_OPA_40 = 102,
69  LV_OPA_50 = 127,
70  LV_OPA_60 = 153,
71  LV_OPA_70 = 178,
72  LV_OPA_80 = 204,
73  LV_OPA_90 = 229,
74  LV_OPA_100 = 255,
75  LV_OPA_COVER = 255,
76 };
77 
78 #define LV_OPA_MIN 16 /*Opacities below this will be transparent*/
79 #define LV_OPA_MAX 251 /*Opacities above this will fully cover*/
80 
81 #if LV_COLOR_DEPTH == 1
82 #define LV_COLOR_SIZE 8
83 #elif LV_COLOR_DEPTH == 8
84 #define LV_COLOR_SIZE 8
85 #elif LV_COLOR_DEPTH == 16
86 #define LV_COLOR_SIZE 16
87 #elif LV_COLOR_DEPTH == 32
88 #define LV_COLOR_SIZE 32
89 #else
90 #error "Invalid LV_COLOR_DEPTH in lv_conf.h! Set it to 1, 8, 16 or 32!"
91 #endif
92 
93 /**********************
94  * TYPEDEFS
95  **********************/
96 
97 typedef union
98 {
99  uint8_t blue : 1;
100  uint8_t green : 1;
101  uint8_t red : 1;
102  uint8_t full : 1;
103 } lv_color1_t;
104 
105 typedef union
106 {
107  struct
108  {
109  uint8_t blue : 2;
110  uint8_t green : 3;
111  uint8_t red : 3;
112  } ch;
113  uint8_t full;
114 } lv_color8_t;
115 
116 typedef union
117 {
118  struct
119  {
120 #if LV_COLOR_16_SWAP == 0
121  uint16_t blue : 5;
122  uint16_t green : 6;
123  uint16_t red : 5;
124 #else
125  uint16_t green_h : 3;
126  uint16_t red : 5;
127  uint16_t blue : 5;
128  uint16_t green_l : 3;
129 #endif
130  } ch;
131  uint16_t full;
132 } lv_color16_t;
133 
134 typedef union
135 {
136  struct
137  {
138  uint8_t blue;
139  uint8_t green;
140  uint8_t red;
141  uint8_t alpha;
142  } ch;
143  uint32_t full;
144 } lv_color32_t;
145 
146 #if LV_COLOR_DEPTH == 1
147 typedef uint8_t lv_color_int_t;
148 typedef lv_color1_t lv_color_t;
149 #elif LV_COLOR_DEPTH == 8
150 typedef uint8_t lv_color_int_t;
151 typedef lv_color8_t lv_color_t;
152 #elif LV_COLOR_DEPTH == 16
153 typedef uint16_t lv_color_int_t;
154 typedef lv_color16_t lv_color_t;
155 #elif LV_COLOR_DEPTH == 32
156 typedef uint32_t lv_color_int_t;
157 typedef lv_color32_t lv_color_t;
158 #else
159 #error "Invalid LV_COLOR_DEPTH in lv_conf.h! Set it to 1, 8, 16 or 32!"
160 #endif
161 
162 typedef uint8_t lv_opa_t;
163 
164 typedef struct
165 {
166  uint16_t h;
167  uint8_t s;
168  uint8_t v;
170 
171 /**********************
172  * GLOBAL PROTOTYPES
173  **********************/
174 
175 /*In color conversations:
176  * - When converting to bigger color type the LSB weight of 1 LSB is calculated
177  * E.g. 16 bit Red has 5 bits
178  * 8 bit Red has 2 bits
179  * ----------------------
180  * 8 bit red LSB = (2^5 - 1) / (2^2 - 1) = 31 / 3 = 10
181  *
182  * - When calculating to smaller color type simply shift out the LSBs
183  * E.g. 8 bit Red has 2 bits
184  * 16 bit Red has 5 bits
185  * ----------------------
186  * Shift right with 5 - 3 = 2
187  */
188 
189 static inline uint8_t lv_color_to1(lv_color_t color)
190 {
191 #if LV_COLOR_DEPTH == 1
192  return color.full;
193 #elif LV_COLOR_DEPTH == 8
194  if((color.ch.red & 0x4) || (color.ch.green & 0x4) || (color.ch.blue & 0x2)) {
195  return 1;
196  } else {
197  return 0;
198  }
199 #elif LV_COLOR_DEPTH == 16
200 #if LV_COLOR_16_SWAP == 0
201  if((color.ch.red & 0x10) || (color.ch.green & 0x20) || (color.ch.blue & 0x10)) {
202  return 1;
203 #else
204  if((color.ch.red & 0x10) || (color.ch.green_h & 0x20) || (color.ch.blue & 0x10)) {
205  return 1;
206 #endif
207  } else {
208  return 0;
209  }
210 #elif LV_COLOR_DEPTH == 32
211  if((color.ch.red & 0x80) || (color.ch.green & 0x80) || (color.ch.blue & 0x80)) {
212  return 1;
213  } else {
214  return 0;
215  }
216 #endif
217 }
218 
219 static inline uint8_t lv_color_to8(lv_color_t color)
220 {
221 #if LV_COLOR_DEPTH == 1
222  if(color.full == 0)
223  return 0;
224  else
225  return 0xFF;
226 #elif LV_COLOR_DEPTH == 8
227  return color.full;
228 #elif LV_COLOR_DEPTH == 16
229 
230 #if LV_COLOR_16_SWAP == 0
231  lv_color8_t ret;
232  ret.ch.red = color.ch.red >> 2; /* 5 - 3 = 2*/
233  ret.ch.green = color.ch.green >> 3; /* 6 - 3 = 3*/
234  ret.ch.blue = color.ch.blue >> 3; /* 5 - 2 = 3*/
235  return ret.full;
236 #else
237  lv_color8_t ret;
238  ret.ch.red = color.ch.red >> 2; /* 5 - 3 = 2*/
239  ret.ch.green = color.ch.green_h; /* 6 - 3 = 3*/
240  ret.ch.blue = color.ch.blue >> 3; /* 5 - 2 = 3*/
241  return ret.full;
242 #endif
243 #elif LV_COLOR_DEPTH == 32
244  lv_color8_t ret;
245  ret.ch.red = color.ch.red >> 5; /* 8 - 3 = 5*/
246  ret.ch.green = color.ch.green >> 5; /* 8 - 3 = 5*/
247  ret.ch.blue = color.ch.blue >> 6; /* 8 - 2 = 6*/
248  return ret.full;
249 #endif
250 }
251 
252 static inline uint16_t lv_color_to16(lv_color_t color)
253 {
254 #if LV_COLOR_DEPTH == 1
255  if(color.full == 0)
256  return 0;
257  else
258  return 0xFFFF;
259 #elif LV_COLOR_DEPTH == 8
260  lv_color16_t ret;
261 #if LV_COLOR_16_SWAP == 0
262  ret.ch.red = color.ch.red * 4; /*(2^5 - 1)/(2^3 - 1) = 31/7 = 4*/
263  ret.ch.green = color.ch.green * 9; /*(2^6 - 1)/(2^3 - 1) = 63/7 = 9*/
264  ret.ch.blue = color.ch.blue * 10; /*(2^5 - 1)/(2^2 - 1) = 31/3 = 10*/
265 #else
266  ret.red = color.ch.red * 4;
267  uint8_t g_tmp = color.ch.green * 9;
268  ret.ch.green_h = (g_tmp & 0x1F) >> 3;
269  ret.ch.green_l = g_tmp & 0x07;
270  ret.ch.blue = color.ch.blue * 10;
271 #endif
272  return ret.full;
273 #elif LV_COLOR_DEPTH == 16
274  return color.full;
275 #elif LV_COLOR_DEPTH == 32
276  lv_color16_t ret;
277 #if LV_COLOR_16_SWAP == 0
278  ret.ch.red = color.ch.red >> 3; /* 8 - 5 = 3*/
279  ret.ch.green = color.ch.green >> 2; /* 8 - 6 = 2*/
280  ret.ch.blue = color.ch.blue >> 3; /* 8 - 5 = 3*/
281 #else
282  ret.ch.red = color.ch.red >> 3;
283  ret.ch.green_h = (color.ch.green & 0xE0) >> 5;
284  ret.ch.green_l = (color.ch.green & 0x1C) >> 2;
285  ret.ch.blue = color.ch.blue >> 3;
286 #endif
287  return ret.full;
288 #endif
289 }
290 
291 static inline uint32_t lv_color_to32(lv_color_t color)
292 {
293 #if LV_COLOR_DEPTH == 1
294  if(color.full == 0)
295  return 0;
296  else
297  return 0xFFFFFFFF;
298 #elif LV_COLOR_DEPTH == 8
299  lv_color32_t ret;
300  ret.ch.red = color.ch.red * 36; /*(2^8 - 1)/(2^3 - 1) = 255/7 = 36*/
301  ret.ch.green = color.ch.green * 36; /*(2^8 - 1)/(2^3 - 1) = 255/7 = 36*/
302  ret.ch.blue = color.ch.blue * 85; /*(2^8 - 1)/(2^2 - 1) = 255/3 = 85*/
303  ret.ch.alpha = 0xFF;
304  return ret.full;
305 #elif LV_COLOR_DEPTH == 16
306 #if LV_COLOR_16_SWAP == 0
307  lv_color32_t ret;
308  ret.ch.red = color.ch.red * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
309  ret.ch.green = color.ch.green * 4; /*(2^8 - 1)/(2^6 - 1) = 255/63 = 4*/
310  ret.ch.blue = color.ch.blue * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
311  ret.ch.alpha = 0xFF;
312  return ret.full;
313 #else
314  lv_color32_t ret;
315  ret.ch.red = color.ch.red * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
316  ret.ch.green = ((color.ch.green_h << 3) + color.ch.green_l) * 4; /*(2^8 - 1)/(2^6 - 1) = 255/63 = 4*/
317  ret.ch.blue = color.ch.blue * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
318  ret.ch.alpha = 0xFF;
319  return ret.full;
320 #endif
321 #elif LV_COLOR_DEPTH == 32
322  return color.full;
323 #endif
324 }
325 
326 static inline lv_color_t lv_color_mix(lv_color_t c1, lv_color_t c2, uint8_t mix)
327 {
328  lv_color_t ret;
329 #if LV_COLOR_DEPTH != 1
330  /*LV_COLOR_DEPTH == 8, 16 or 32*/
331  ret.ch.red = (uint16_t)((uint16_t)c1.ch.red * mix + (c2.ch.red * (255 - mix))) >> 8;
332 #if LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP
333  /*If swapped Green is in 2 parts*/
334  uint16_t g_1 = (c1.ch.green_h << 3) + c1.ch.green_l;
335  uint16_t g_2 = (c2.ch.green_h << 3) + c2.ch.green_l;
336  uint16_t g_out = (uint16_t)((uint16_t)g_1 * mix + (g_2 * (255 - mix))) >> 8;
337  ret.ch.green_h = g_out >> 3;
338  ret.ch.green_l = g_out & 0x7;
339 #else
340  ret.ch.green = (uint16_t)((uint16_t)c1.ch.green * mix + (c2.ch.green * (255 - mix))) >> 8;
341 #endif
342  ret.ch.blue = (uint16_t)((uint16_t)c1.ch.blue * mix + (c2.ch.blue * (255 - mix))) >> 8;
343 #if LV_COLOR_DEPTH == 32
344  ret.ch.alpha = 0xFF;
345 #endif
346 #else
347  /*LV_COLOR_DEPTH == 1*/
348  ret.full = mix > LV_OPA_50 ? c1.full : c2.full;
349 #endif
350 
351  return ret;
352 }
353 
359 static inline uint8_t lv_color_brightness(lv_color_t color)
360 {
361  lv_color32_t c32;
362  c32.full = lv_color_to32(color);
363  uint16_t bright = 3 * c32.ch.red + c32.ch.blue + 4 * c32.ch.green;
364  return (uint16_t)bright >> 3;
365 }
366 
367 /* The most simple macro to create a color from R,G and B values */
368 #if LV_COLOR_DEPTH == 1
369 #define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){(b8 >> 7 | g8 >> 7 | r8 >> 7)})
370 static inline lv_color_t lv_color_make(int r8, int g8, int b8)
371 {
372  lv_color_t color;
373  color.full = (b8 >> 7 | g8 >> 7 | r8 >> 7);
374  return color;
375 }
376 #elif LV_COLOR_DEPTH == 8
377 #define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8 >> 6, g8 >> 5, r8 >> 5}})
378 static inline lv_color_t lv_color_make(uint8_t r8, int g8, int b8)
379 {
380  lv_color_t color;
381  color.ch.blue = b8 >> 6;
382  color.ch.green = g8 >> 5;
383  color.ch.red = r8 >> 5;
384  return color;
385 }
386 #elif LV_COLOR_DEPTH == 16
387 #if LV_COLOR_16_SWAP == 0
388 #define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8 >> 3, g8 >> 2, r8 >> 3}})
389 static inline lv_color_t lv_color_make(uint8_t r8, uint8_t g8, uint8_t b8)
390 {
391  lv_color_t color;
392  color.ch.blue = (uint16_t)(b8 >> 3);
393  color.ch.green = (uint16_t)(g8 >> 2);
394  color.ch.red = (uint16_t)(r8 >> 3);
395  return color;
396 }
397 #else
398 #define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{g8 >> 5, r8 >> 3, b8 >> 3, (g8 >> 2) & 0x7}})
399 static inline lv_color_t lv_color_make(uint8_t r8, uint8_t g8, uint8_t b8)
400 {
401  lv_color_t color;
402  color.ch.green_h = (uint16_t)(g8 >> 5);
403  color.ch.red = (uint16_t)(r8 >> 3);
404  color.ch.blue = (uint16_t)(b8 >> 3);
405  color.ch.green_l = (uint16_t)((g8 >> 2) & 0x7);
406  return color;
407 }
408 #endif
409 #elif LV_COLOR_DEPTH == 32
410 #define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8, g8, r8, 0xff}}) /*Fix 0xff alpha*/
411 static inline lv_color_t lv_color_make(uint8_t r8, uint8_t g8, uint8_t b8)
412 {
413  lv_color_t color;
414  color.ch.blue = b8;
415  color.ch.green = g8;
416  color.ch.red = r8;
417  color.ch.alpha = 0xff;
418  return color;
419 }
420 #endif
421 
422 static inline lv_color_t lv_color_hex(uint32_t c)
423 {
424  return lv_color_make((uint8_t)((c >> 16) & 0xFF), (uint8_t)((c >> 8) & 0xFF), (uint8_t)(c & 0xFF));
425 }
426 
427 static inline lv_color_t lv_color_hex3(uint32_t c)
428 {
429  return lv_color_make((uint8_t)(((c >> 4) & 0xF0) | ((c >> 8) & 0xF)), (uint8_t)((c & 0xF0) | ((c & 0xF0) >> 4)),
430  (uint8_t)((c & 0xF) | ((c & 0xF) << 4)));
431 }
432 
440 lv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v);
441 
449 lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r, uint8_t g, uint8_t b);
450 
451 /**********************
452  * MACROS
453  **********************/
454 
455 #ifdef __cplusplus
456 } /* extern "C" */
457 #endif
458 
459 #endif /*USE_COLOR*/
struct lv_color16_t::@28 ch
Definition: lv_color.h:65
Definition: lv_color.h:69
Definition: lv_color.h:105
Definition: lv_color.h:66
uint8_t blue
Definition: lv_color.h:109
Definition: lv_color.h:134
uint8_t red
Definition: lv_color.h:140
Definition: lv_color.h:97
uint8_t alpha
Definition: lv_color.h:141
uint8_t v
Definition: lv_color.h:168
struct lv_color8_t::@27 ch
Definition: lv_color.h:64
lv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v)
Definition: lv_color.h:73
Definition: lv_color.h:164
Definition: lv_color.h:68
uint16_t green
Definition: lv_color.h:122
lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r, uint8_t g, uint8_t b)
uint16_t blue
Definition: lv_color.h:121
Definition: lv_color.h:116
uint16_t full
Definition: lv_color.h:131
uint16_t red
Definition: lv_color.h:123
Definition: lv_color.h:70
uint8_t lv_opa_t
Definition: lv_color.h:162
uint8_t red
Definition: lv_color.h:111
Definition: lv_color.h:72
uint8_t blue
Definition: lv_color.h:138
Definition: lv_color.h:71
uint8_t s
Definition: lv_color.h:167
Definition: lv_color.h:63
uint8_t green
Definition: lv_color.h:110
uint8_t green
Definition: lv_color.h:139
Definition: lv_color.h:75
Definition: lv_color.h:67
uint32_t full
Definition: lv_color.h:143
Definition: lv_color.h:74
uint8_t full
Definition: lv_color.h:113
struct lv_color32_t::@29 ch
uint16_t h
Definition: lv_color.h:166
© Copyright 1995-2019, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale