1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-14 06:42:58 +08:00
lvgl/lv_misc/lv_color.h

352 lines
9.4 KiB
C
Raw Normal View History

2017-11-23 20:42:14 +01:00
/**
2017-11-23 21:28:36 +01:00
* @file lv_color.h
2018-06-19 09:49:58 +02:00
*
2017-11-23 20:42:14 +01:00
*/
2017-11-26 11:38:28 +01:00
#ifndef LV_COLOR_H
#define LV_COLOR_H
2017-11-23 20:42:14 +01:00
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#ifdef LV_CONF_INCLUDE_SIMPLE
#include "lv_conf.h"
#else
2017-11-26 23:57:39 +01:00
#include "../../lv_conf.h"
#endif
2017-11-23 20:42:14 +01:00
#include <stdint.h>
/*********************
* DEFINES
*********************/
2017-11-23 21:28:36 +01:00
#define LV_COLOR_BLACK LV_COLOR_MAKE(0x00,0x00,0x00)
#define LV_COLOR_WHITE LV_COLOR_MAKE(0xFF,0xFF,0xFF)
#define LV_COLOR_RED LV_COLOR_MAKE(0xFF,0x00,0x00)
#define LV_COLOR_LIME LV_COLOR_MAKE(0x00,0xFF,0x00)
#define LV_COLOR_BLUE LV_COLOR_MAKE(0x00,0x00,0xFF)
#define LV_COLOR_YELLOW LV_COLOR_MAKE(0xFF,0xFF,0x00)
#define LV_COLOR_CYAN LV_COLOR_MAKE(0x00,0xFF,0xFF)
#define LV_COLOR_AQUA LV_COLOR_CYAN
#define LV_COLOR_MAGENTA LV_COLOR_MAKE(0xFF,0x00,0xFF)
#define LV_COLOR_SILVER LV_COLOR_MAKE(0xC0,0xC0,0xC0)
#define LV_COLOR_GRAY LV_COLOR_MAKE(0x80,0x80,0x80)
#define LV_COLOR_MARRON LV_COLOR_MAKE(0x80,0x00,0x00)
#define LV_COLOR_OLIVE LV_COLOR_MAKE(0x80,0x80,0x00)
#define LV_COLOR_GREEN LV_COLOR_MAKE(0x00,0x80,0x00)
#define LV_COLOR_PURPLE LV_COLOR_MAKE(0x80,0x00,0x80)
#define LV_COLOR_TEAL LV_COLOR_MAKE(0x00,0x80,0x80)
#define LV_COLOR_NAVY LV_COLOR_MAKE(0x00,0x00,0x80)
#define LV_COLOR_ORANGE LV_COLOR_MAKE(0xFF,0xA5,0x00)
#define LV_OPA_TRANSP 0
#define LV_OPA_0 0
#define LV_OPA_10 25
#define LV_OPA_20 51
#define LV_OPA_30 76
#define LV_OPA_40 102
#define LV_OPA_50 127
#define LV_OPA_60 153
#define LV_OPA_70 178
#define LV_OPA_80 204
#define LV_OPA_90 229
#define LV_OPA_100 255
#define LV_OPA_COVER 255
2017-11-23 20:42:14 +01:00
#if LV_COLOR_DEPTH == 1
#define LV_COLOR_SIZE 8
#elif LV_COLOR_DEPTH == 8
#define LV_COLOR_SIZE 8
#elif LV_COLOR_DEPTH == 16
#define LV_COLOR_SIZE 16
#elif LV_COLOR_DEPTH == 24
#define LV_COLOR_SIZE 32
#else
#error "Invalid color depth (LV_COLOR_DEPTH in lv_conf.h)"
#endif
2017-11-23 20:42:14 +01:00
/**********************
* TYPEDEFS
**********************/
typedef union
{
uint8_t blue :1;
uint8_t green :1;
uint8_t red :1;
uint8_t full :1;
2018-06-19 09:49:58 +02:00
} lv_color1_t;
2017-11-23 20:42:14 +01:00
typedef union
{
struct
{
uint8_t blue :2;
uint8_t green :3;
uint8_t red :3;
};
uint8_t full;
2018-06-19 09:49:58 +02:00
} lv_color8_t;
2017-11-23 20:42:14 +01:00
typedef union
{
struct
{
uint16_t blue :5;
uint16_t green :6;
uint16_t red :5;
};
uint16_t full;
2018-06-19 09:49:58 +02:00
} lv_color16_t;
2017-11-23 20:42:14 +01:00
typedef union
{
struct
{
uint8_t blue;
uint8_t green;
uint8_t red;
uint8_t alpha;
2017-11-23 20:42:14 +01:00
};
uint32_t full;
2018-06-19 09:49:58 +02:00
} lv_color24_t;
2017-11-23 20:42:14 +01:00
2017-11-23 21:28:36 +01:00
#if LV_COLOR_DEPTH == 1
2017-12-01 19:40:12 +01:00
typedef uint8_t lv_color_int_t;
2017-11-23 21:28:36 +01:00
typedef lv_color1_t lv_color_t;
#elif LV_COLOR_DEPTH == 8
2017-12-01 19:40:12 +01:00
typedef uint8_t lv_color_int_t;
2017-11-23 21:28:36 +01:00
typedef lv_color8_t lv_color_t;
#elif LV_COLOR_DEPTH == 16
2017-12-01 19:40:12 +01:00
typedef uint16_t lv_color_int_t;
2017-11-23 21:28:36 +01:00
typedef lv_color16_t lv_color_t;
#elif LV_COLOR_DEPTH == 24
2017-12-01 19:40:12 +01:00
typedef uint32_t lv_color_int_t;
2017-11-23 21:28:36 +01:00
typedef lv_color24_t lv_color_t;
2017-11-23 20:42:14 +01:00
#else
2017-11-23 21:28:36 +01:00
#error "Invalid LV_COLOR_DEPTH in misc_conf.h! Set it to 1, 8, 16 or 24!"
2017-11-23 20:42:14 +01:00
#endif
2017-11-23 21:28:36 +01:00
typedef uint8_t lv_opa_t;
2017-11-23 20:42:14 +01:00
typedef struct
{
uint16_t h;
uint8_t s;
uint8_t v;
2017-11-23 21:28:36 +01:00
} lv_color_hsv_t;
2017-11-23 20:42:14 +01:00
/**********************
* GLOBAL PROTOTYPES
**********************/
/*In color conversations:
2018-06-19 09:49:58 +02:00
* - When converting to bigger color type the LSB weight of 1 LSB is calculated
2017-11-23 20:42:14 +01:00
* E.g. 16 bit Red has 5 bits
* 8 bit Red has 2 bits
* ----------------------
* 8 bit red LSB = (2^5 - 1) / (2^2 - 1) = 31 / 3 = 10
2018-06-19 09:49:58 +02:00
*
2017-11-23 20:42:14 +01:00
* - When calculating to smaller color type simply shift out the LSBs
2018-06-19 09:49:58 +02:00
* E.g. 8 bit Red has 2 bits
2017-11-23 20:42:14 +01:00
* 16 bit Red has 5 bits
* ----------------------
* Shift right with 5 - 3 = 2
*/
2017-11-23 21:28:36 +01:00
static inline uint8_t lv_color_to1(lv_color_t color)
2017-11-23 20:42:14 +01:00
{
2017-11-23 21:28:36 +01:00
#if LV_COLOR_DEPTH == 1
2018-06-19 09:49:58 +02:00
return color.full;
2017-11-23 21:28:36 +01:00
#elif LV_COLOR_DEPTH == 8
if((color.red & 0x4) ||
2018-06-19 09:49:58 +02:00
(color.green & 0x4) ||
(color.blue & 0x2)) {
return 1;
2017-11-23 20:42:14 +01:00
} else {
2018-06-19 09:49:58 +02:00
return 0;
2017-11-23 20:42:14 +01:00
}
2017-11-23 21:28:36 +01:00
#elif LV_COLOR_DEPTH == 16
if((color.red & 0x10) ||
2018-06-19 09:49:58 +02:00
(color.green & 0x20) ||
(color.blue & 0x10)) {
return 1;
2017-11-23 20:42:14 +01:00
} else {
2018-06-19 09:49:58 +02:00
return 0;
2017-11-23 20:42:14 +01:00
}
2017-11-23 21:28:36 +01:00
#elif LV_COLOR_DEPTH == 24
2017-11-23 20:42:14 +01:00
if((color.red & 0x80) ||
2018-06-19 09:49:58 +02:00
(color.green & 0x80) ||
(color.blue & 0x80)) {
return 1;
2017-11-23 20:42:14 +01:00
} else {
2018-06-19 09:49:58 +02:00
return 0;
2017-11-23 20:42:14 +01:00
}
#endif
}
2017-11-23 21:28:36 +01:00
static inline uint8_t lv_color_to8(lv_color_t color)
2017-11-23 20:42:14 +01:00
{
2017-11-23 21:28:36 +01:00
#if LV_COLOR_DEPTH == 1
2017-11-23 20:42:14 +01:00
if(color.full == 0) return 0;
else return 0xFF;
2017-11-23 21:28:36 +01:00
#elif LV_COLOR_DEPTH == 8
2017-11-23 20:42:14 +01:00
return color.full;
2017-11-23 21:28:36 +01:00
#elif LV_COLOR_DEPTH == 16
lv_color8_t ret;
2017-11-23 20:42:14 +01:00
ret.red = color.red >> 2; /* 5 - 3 = 2*/
ret.green = color.green >> 3; /* 6 - 3 = 3*/
ret.blue = color.blue >> 3; /* 5 - 2 = 3*/
return ret.full;
2017-11-23 21:28:36 +01:00
#elif LV_COLOR_DEPTH == 24
lv_color8_t ret;
2017-11-23 20:42:14 +01:00
ret.red = color.red >> 5; /* 8 - 3 = 5*/
ret.green = color.green >> 5; /* 8 - 3 = 5*/
ret.blue = color.blue >> 6; /* 8 - 2 = 6*/
return ret.full;
#endif
}
2017-11-23 21:28:36 +01:00
static inline uint16_t lv_color_to16(lv_color_t color)
2017-11-23 20:42:14 +01:00
{
2017-11-23 21:28:36 +01:00
#if LV_COLOR_DEPTH == 1
2017-11-23 20:42:14 +01:00
if(color.full == 0) return 0;
else return 0xFFFF;
2017-11-23 21:28:36 +01:00
#elif LV_COLOR_DEPTH == 8
lv_color16_t ret;
2017-11-23 20:42:14 +01:00
ret.red = color.red * 4; /*(2^5 - 1)/(2^3 - 1) = 31/7 = 4*/
ret.green = color.green * 9; /*(2^6 - 1)/(2^3 - 1) = 63/7 = 9*/
ret.blue = color.blue * 10; /*(2^5 - 1)/(2^2 - 1) = 31/3 = 10*/
return ret.full;
2017-11-23 21:28:36 +01:00
#elif LV_COLOR_DEPTH == 16
2017-11-23 20:42:14 +01:00
return color.full;
2017-11-23 21:28:36 +01:00
#elif LV_COLOR_DEPTH == 24
lv_color16_t ret;
2017-11-23 20:42:14 +01:00
ret.red = color.red >> 3; /* 8 - 5 = 3*/
ret.green = color.green >> 2; /* 8 - 6 = 2*/
ret.blue = color.blue >> 3; /* 8 - 5 = 3*/
return ret.full;
#endif
}
2017-11-23 21:28:36 +01:00
static inline uint32_t lv_color_to24(lv_color_t color)
2017-11-23 20:42:14 +01:00
{
2017-11-23 21:28:36 +01:00
#if LV_COLOR_DEPTH == 1
2017-11-23 20:42:14 +01:00
if(color.full == 0) return 0;
else return 0xFFFFFFFF;
2017-11-23 21:28:36 +01:00
#elif LV_COLOR_DEPTH == 8
lv_color24_t ret;
2017-11-23 20:42:14 +01:00
ret.red = color.red * 36; /*(2^8 - 1)/(2^3 - 1) = 255/7 = 36*/
ret.green = color.green * 36; /*(2^8 - 1)/(2^3 - 1) = 255/7 = 36*/
ret.blue = color.blue * 85; /*(2^8 - 1)/(2^2 - 1) = 255/3 = 85*/
ret.alpha = 0xFF;
2017-11-23 20:42:14 +01:00
return ret.full;
2017-11-23 21:28:36 +01:00
#elif LV_COLOR_DEPTH == 16
lv_color24_t ret;
2017-11-23 20:42:14 +01:00
ret.red = color.red * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
ret.green = color.green * 4; /*(2^8 - 1)/(2^6 - 1) = 255/63 = 4*/
ret.blue = color.blue * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
ret.alpha = 0xFF;
2017-11-23 20:42:14 +01:00
return ret.full;
2017-11-23 21:28:36 +01:00
#elif LV_COLOR_DEPTH == 24
2017-11-23 20:42:14 +01:00
return color.full;
#endif
}
2017-11-23 21:28:36 +01:00
static inline lv_color_t lv_color_mix(lv_color_t c1, lv_color_t c2, uint8_t mix)
2017-11-23 20:42:14 +01:00
{
2017-11-23 21:28:36 +01:00
lv_color_t ret;
#if LV_COLOR_DEPTH != 1
2017-11-23 20:42:14 +01:00
ret.red = (uint16_t)((uint16_t) c1.red * mix + (c2.red * (255 - mix))) >> 8;
ret.green = (uint16_t)((uint16_t) c1.green * mix + (c2.green * (255 - mix))) >> 8;
ret.blue = (uint16_t)((uint16_t) c1.blue * mix + (c2.blue * (255 - mix))) >> 8;
# if LV_COLOR_DEPTH == 24
ret.alpha = 0xFF;
# endif
#else
ret.full = mix > LV_OPA_50 ? c1.full : c2.full;
#endif
2017-11-23 20:42:14 +01:00
return ret;
}
/**
* Get the brightness of a color
* @param color a color
* @return the brightness [0..255]
*/
2018-06-19 09:49:58 +02:00
static inline uint8_t lv_color_brightness(lv_color_t color)
2017-11-23 20:42:14 +01:00
{
2017-11-23 21:28:36 +01:00
lv_color24_t c24;
c24.full = lv_color_to24(color);
2017-11-23 20:42:14 +01:00
uint16_t bright = 3 * c24.red + c24.blue + 4 * c24.green;
return (uint16_t) bright >> 3;
}
/* The most simple macro to create a color from R,G and B values
* The order of bit field is different on Big-endian and Little-endian machines*/
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
2017-11-23 21:28:36 +01:00
#if LV_COLOR_DEPTH == 1
2017-12-17 01:54:09 +01:00
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){(b8 >> 7 | g8 >> 7 | r8 >> 7)})
2017-11-23 21:28:36 +01:00
#elif LV_COLOR_DEPTH == 8
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8 >> 6, g8 >> 5, r8 >> 5}})
#elif LV_COLOR_DEPTH == 16
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8 >> 3, g8 >> 2, r8 >> 3}})
#elif LV_COLOR_DEPTH == 24
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8, g8, r8, 0xff}}) /*Fix 0xff alpha*/
2017-11-23 20:42:14 +01:00
#endif
#else
#if LV_COLOR_DEPTH == 1
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){(r8 >> 7 | g8 >> 7 | b8 >> 7)})
#elif LV_COLOR_DEPTH == 8
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{r8 >> 6, g8 >> 5, b8 >> 5}})
#elif LV_COLOR_DEPTH == 16
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{r8 >> 3, g8 >> 2, b8 >> 3}})
#elif LV_COLOR_DEPTH == 24
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{0xff, r8, g8, b8}}) /*Fix 0xff alpha*/
#endif
#endif
2017-11-23 20:42:14 +01:00
2017-11-23 21:28:36 +01:00
#define LV_COLOR_HEX(c) LV_COLOR_MAKE(((uint32_t)((uint32_t)c >> 16) & 0xFF), \
2017-11-23 20:42:14 +01:00
((uint32_t)((uint32_t)c >> 8) & 0xFF), \
((uint32_t) c & 0xFF))
2017-11-23 21:28:36 +01:00
/*Usage LV_COLOR_HEX3(0x16C) which means LV_COLOR_HEX(0x1166CC)*/
#define LV_COLOR_HEX3(c) LV_COLOR_MAKE((((c >> 4) & 0xF0) | ((c >> 8) & 0xF)), \
2017-11-23 20:42:14 +01:00
((uint32_t)(c & 0xF0) | ((c & 0xF0) >> 4)), \
((uint32_t)(c & 0xF) | ((c & 0xF) << 4)))
/**
* Convert a HSV color to RGB
* @param h hue [0..359]
* @param s saturation [0..100]
* @param v value [0..100]
2017-11-23 21:28:36 +01:00
* @return the given RGB color in RGB (with LV_COLOR_DEPTH depth)
2017-11-23 20:42:14 +01:00
*/
2017-11-23 21:28:36 +01:00
lv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v);
2017-11-23 20:42:14 +01:00
/**
* Convert an RGB color to HSV
* @param r red
* @param g green
* @param b blue
* @return the given RGB color n HSV
*/
2017-11-23 21:28:36 +01:00
lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r, uint8_t g, uint8_t b);
2017-11-23 20:42:14 +01:00
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /* extern "C" */
#endif
2017-11-26 23:57:39 +01:00
#endif /*USE_COLOR*/