mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-27 20:57:01 +08:00
Merge branch 'dev-6.1'
This commit is contained in:
@@ -188,8 +188,8 @@ Styles can be assigned to the objects to changed their appearance. A style descr
|
||||
|
||||
You can create a new style like this:
|
||||
```c
|
||||
static lv_style_t style1; /*Declare a new style. Should be `static`*/
|
||||
lv_style_copy(&style1, &lv_style_plain); /*Copy a buil-in style*/
|
||||
static lv_style_t style1; /*Declare a new style. Should be `static`*/
|
||||
lv_style_copy(&style1, &lv_style_plain); /*Copy a built-in style*/
|
||||
style1.body.main_color = LV_COLOR_RED; /*Main color*/
|
||||
style1.body.grad_color = lv_color_hex(0xffd83c) /*Gradient color (orange)*/
|
||||
style1.body.radius = 3;
|
||||
|
||||
@@ -43,6 +43,9 @@
|
||||
/*Images pixels with this color will not be drawn (with chroma keying)*/
|
||||
#define LV_COLOR_TRANSP LV_COLOR_LIME /*LV_COLOR_LIME: pure green*/
|
||||
|
||||
/* Enable chroma keying for indexed images. */
|
||||
#define LV_INDEXED_CHROMA 1
|
||||
|
||||
/* Enable anti-aliasing (lines, and radiuses will be smoothed) */
|
||||
#define LV_ANTIALIAS 1
|
||||
|
||||
@@ -193,6 +196,14 @@ typedef void * lv_img_decoder_user_data_t;
|
||||
* font's bitmaps */
|
||||
#define LV_ATTRIBUTE_LARGE_CONST
|
||||
|
||||
/* Export integer constant to binding.
|
||||
* This macro is used with constants in the form of LV_<CONST> that
|
||||
* should also appear on lvgl binding API such as Micropython
|
||||
*
|
||||
* The default value just prevents a GCC warning.
|
||||
*/
|
||||
#define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning
|
||||
|
||||
/*===================
|
||||
* HAL settings
|
||||
*==================*/
|
||||
@@ -229,6 +240,42 @@ typedef void * lv_indev_drv_user_data_t; /*Type of user data in the i
|
||||
# define LV_LOG_PRINTF 0
|
||||
#endif /*LV_USE_LOG*/
|
||||
|
||||
/*=================
|
||||
* Debug settings
|
||||
*================*/
|
||||
|
||||
/* If Debug is enabled LittelvGL validates the parameters of the functions.
|
||||
* If an invalid parameter is found an error log message is printed and
|
||||
* the MCU halts at the error. (`LV_USE_LOG` should be enabled)
|
||||
* If you are debugging the MCU you can pause
|
||||
* the debugger to see exactly where the issue is.
|
||||
*
|
||||
* The behavior of asserts can be overwritten by redefining them here.
|
||||
* E.g. #define LV_ASSERT_MEM(p) <my_assert_code>
|
||||
*/
|
||||
#define LV_USE_DEBUG 1
|
||||
#if LV_USE_DEBUG
|
||||
|
||||
/*Check if the parameter is NULL. (Quite fast) */
|
||||
#define LV_USE_ASSERT_NULL 1
|
||||
|
||||
/*Checks is the memory is successfully allocated or no. (Quite fast)*/
|
||||
#define LV_USE_ASSERT_MEM 1
|
||||
|
||||
/* Check the strings.
|
||||
* Search for NULL, very long strings, invalid characters, and unnatural repetitions. (Slow)
|
||||
* If disabled `LV_USE_ASSERT_NULL` will be performed instead (if it's enabled) */
|
||||
#define LV_USE_ASSERT_STR 0
|
||||
|
||||
/* Check NULL, the object's type and existence (e.g. not deleted). (Quite slow)
|
||||
* If disabled `LV_USE_ASSERT_NULL` will be performed instead (if it's enabled) */
|
||||
#define LV_USE_ASSERT_OBJ 0
|
||||
|
||||
/*Check if the styles are properly initialized. (Fast)*/
|
||||
#define LV_USE_ASSERT_STYLE 1
|
||||
|
||||
#endif /*LV_USE_DEBUG*/
|
||||
|
||||
/*================
|
||||
* THEME USAGE
|
||||
*================*/
|
||||
@@ -260,6 +307,10 @@ typedef void * lv_indev_drv_user_data_t; /*Type of user data in the i
|
||||
#define LV_FONT_ROBOTO_22 0
|
||||
#define LV_FONT_ROBOTO_28 0
|
||||
|
||||
/* Demonstrate special features */
|
||||
#define LV_FONT_ROBOTO_12_SUBPX 1
|
||||
#define LV_FONT_ROBOTO_28_COMPRESSED 1 /*bpp = 3*/
|
||||
|
||||
/*Pixel perfect monospace font
|
||||
* http://pelulamu.net/unscii/ */
|
||||
#define LV_FONT_UNSCII_8 0
|
||||
@@ -280,6 +331,12 @@ typedef void * lv_indev_drv_user_data_t; /*Type of user data in the i
|
||||
* but with > 10,000 characters if you see issues probably you need to enable it.*/
|
||||
#define LV_FONT_FMT_TXT_LARGE 0
|
||||
|
||||
/* Set the pixel order of the display.
|
||||
* Important only if "subpx fonts" are used.
|
||||
* With "normal" font it doesn't matter.
|
||||
*/
|
||||
#define LV_FONT_SUBPX_BGR 0
|
||||
|
||||
/*Declare the type of the user data of fonts (can be e.g. `void *`, `int`, `struct`)*/
|
||||
typedef void * lv_font_user_data_t;
|
||||
|
||||
@@ -297,6 +354,42 @@ typedef void * lv_font_user_data_t;
|
||||
/*Can break (wrap) texts on these chars*/
|
||||
#define LV_TXT_BREAK_CHARS " ,.;:-_"
|
||||
|
||||
/* If a word is at least this long, will break wherever "prettiest"
|
||||
* To disable, set to a value <= 0 */
|
||||
#define LV_TXT_LINE_BREAK_LONG_LEN 12
|
||||
|
||||
/* Minimum number of characters in a long word to put on a line before a break.
|
||||
* Depends on LV_TXT_LINE_BREAK_LONG_LEN. */
|
||||
#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3
|
||||
|
||||
/* Minimum number of characters in a long word to put on a line after a break.
|
||||
* Depends on LV_TXT_LINE_BREAK_LONG_LEN. */
|
||||
#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3
|
||||
|
||||
/* The control character to use for signalling text recoloring. */
|
||||
#define LV_TXT_COLOR_CMD "#"
|
||||
|
||||
/* Support bidirectional texts.
|
||||
* Allows mixing Left-to-Right and Right-to-Left texts.
|
||||
* The direction will be processed according to the Unicode Bidirectioanl Algorithm:
|
||||
* https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/
|
||||
#define LV_USE_BIDI 0
|
||||
#if LV_USE_BIDI
|
||||
/* Set the default direction. Supported values:
|
||||
* `LV_BIDI_DIR_LTR` Left-to-Right
|
||||
* `LV_BIDI_DIR_RTL` Right-to-Left
|
||||
* `LV_BIDI_DIR_AUTO` detect texts base direction */
|
||||
#define LV_BIDI_BASE_DIR_DEF LV_BIDI_DIR_AUTO
|
||||
#endif
|
||||
|
||||
/*Change the built in (v)snprintf functions*/
|
||||
#define LV_SPRINTF_CUSTOM 0
|
||||
#if LV_SPRINTF_CUSTOM
|
||||
# define LV_SPRINTF_INCLUDE <stdio.h>
|
||||
# define lv_snprintf snprintf
|
||||
# define lv_vsnprintf vsnprintf
|
||||
#endif /*LV_SPRINTF_CUSTOM*/
|
||||
|
||||
/*===================
|
||||
* LV_OBJ SETTINGS
|
||||
*==================*/
|
||||
@@ -355,6 +448,9 @@ typedef void * lv_obj_user_data_t;
|
||||
/*Container (dependencies: -*/
|
||||
#define LV_USE_CONT 1
|
||||
|
||||
/*Color picker (dependencies: -*/
|
||||
#define LV_USE_CPICKER 1
|
||||
|
||||
/*Drop down list (dependencies: lv_page, lv_label, lv_symbol_def.h)*/
|
||||
#define LV_USE_DDLIST 1
|
||||
#if LV_USE_DDLIST != 0
|
||||
|
||||
@@ -29,11 +29,14 @@ extern "C" {
|
||||
|
||||
#include "src/lv_core/lv_refr.h"
|
||||
#include "src/lv_core/lv_disp.h"
|
||||
#include "src/lv_core/lv_debug.h"
|
||||
|
||||
#include "src/lv_themes/lv_theme.h"
|
||||
|
||||
#include "src/lv_font/lv_font.h"
|
||||
#include "src/lv_font/lv_font_fmt_txt.h"
|
||||
#include "src/lv_misc/lv_bidi.h"
|
||||
#include "src/lv_misc/lv_printf.h"
|
||||
|
||||
#include "src/lv_objx/lv_btn.h"
|
||||
#include "src/lv_objx/lv_imgbtn.h"
|
||||
@@ -46,6 +49,7 @@ extern "C" {
|
||||
#include "src/lv_objx/lv_chart.h"
|
||||
#include "src/lv_objx/lv_table.h"
|
||||
#include "src/lv_objx/lv_cb.h"
|
||||
#include "src/lv_objx/lv_cpicker.h"
|
||||
#include "src/lv_objx/lv_bar.h"
|
||||
#include "src/lv_objx/lv_slider.h"
|
||||
#include "src/lv_objx/lv_led.h"
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -40,8 +40,8 @@ else:
|
||||
compr = ""
|
||||
|
||||
#Built in symbols
|
||||
syms = "61441,61448,61451,61452,61453,61457,61459,61460,61461,61465,61468,61473,61478,61479,61480,61502,61504,61512,61515,61516,61517,61521,61522,61523,61524,61543,61544,61553,61556,61559,61560,61561,61563,61587,61589,61636,61637,61639,61671,61683,61724,61732,61787,61931,62016,62017,62018,62019,62020,62099"
|
||||
syms = "61441,61448,61451,61452,61452,61453,61457,61459,61461,61465,61468,61473,61478,61479,61480,61502,61512,61515,61516,61517,61521,61522,61523,61524,61543,61544,61550,61552,61553,61556,61559,61560,61561,61563,61587,61589,61636,61637,61639,61671,61674,61683,61724,61732,61787,61931,62016,62017,62018,62019,62020,62087,62099,62212,62189,62810,63426,63650"
|
||||
|
||||
#Run the command
|
||||
cmd = "lv_font_conv {} --bpp {} --size {} --font ./Roboto-Regular.woff -r {} --font FontAwesome.ttf -r {} --format lvgl -o {} --force-fast-kern-format".format(compr, args.bpp, args.size, args.range[0], syms, args.output)
|
||||
cmd = "lv_font_conv {} --bpp {} --size {} --font Roboto-Regular.woff -r {} --font FontAwesome5-Solid+Brands+Regular.woff -r {} --format lvgl -o {} --force-fast-kern-format".format(compr, args.bpp, args.size, args.range[0], syms, args.output)
|
||||
os.system(cmd)
|
||||
|
||||
Regular → Executable
+5
-1
@@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3.6
|
||||
|
||||
'''
|
||||
Generates a checker file for lv_conf.h from lv_conf_templ.h define all the not defined values
|
||||
'''
|
||||
@@ -34,9 +36,11 @@ for i in fin.read().splitlines():
|
||||
if '/*--END OF LV_CONF_H--*/' in i: break
|
||||
|
||||
r = re.search(r'^ *# *define ([^\s]+).*$', i)
|
||||
|
||||
if r:
|
||||
line = re.sub('\(.*?\)', '', r[1], 1) #remove parentheses from macros
|
||||
fout.write(
|
||||
f'#ifndef {r[1]}\n'
|
||||
f'#ifndef {line}\n'
|
||||
f'{i}\n'
|
||||
'#endif\n'
|
||||
)
|
||||
|
||||
+141
-1
@@ -50,6 +50,11 @@
|
||||
#define LV_COLOR_TRANSP LV_COLOR_LIME /*LV_COLOR_LIME: pure green*/
|
||||
#endif
|
||||
|
||||
/* Enable chroma keying for indexed images. */
|
||||
#ifndef LV_INDEXED_CHROMA
|
||||
#define LV_INDEXED_CHROMA 1
|
||||
#endif
|
||||
|
||||
/* Enable anti-aliasing (lines, and radiuses will be smoothed) */
|
||||
#ifndef LV_ANTIALIAS
|
||||
#define LV_ANTIALIAS 1
|
||||
@@ -261,6 +266,16 @@
|
||||
#define LV_ATTRIBUTE_LARGE_CONST
|
||||
#endif
|
||||
|
||||
/* Export integer constant to binding.
|
||||
* This macro is used with constants in the form of LV_<CONST> that
|
||||
* should also appear on lvgl binding API such as Micropython
|
||||
*
|
||||
* The default value just prevents a GCC warning.
|
||||
*/
|
||||
#ifndef LV_EXPORT_CONST_INT
|
||||
#define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning
|
||||
#endif
|
||||
|
||||
/*===================
|
||||
* HAL settings
|
||||
*==================*/
|
||||
@@ -301,12 +316,60 @@
|
||||
#endif
|
||||
|
||||
/* 1: Print the log with 'printf';
|
||||
* 0: user need to register a callback with `lv_log_register_print`*/
|
||||
* 0: user need to register a callback with `lv_log_register_print_cb`*/
|
||||
#ifndef LV_LOG_PRINTF
|
||||
# define LV_LOG_PRINTF 0
|
||||
#endif
|
||||
#endif /*LV_USE_LOG*/
|
||||
|
||||
/*=================
|
||||
* Debug settings
|
||||
*================*/
|
||||
|
||||
/* If Debug is enabled LittelvGL validates the parameters of the functions.
|
||||
* If an invalid parameter is found an error log message is printed and
|
||||
* the MCU halts at the error. (`LV_USE_LOG` should be enabled)
|
||||
* If you are debugging the MCU you can pause
|
||||
* the debugger to see exactly where the issue is.
|
||||
*
|
||||
* The behavior of asserts can be overwritten by redefining them here.
|
||||
* E.g. #define LV_ASSERT_MEM(p) <my_assert_code>
|
||||
*/
|
||||
#ifndef LV_USE_DEBUG
|
||||
#define LV_USE_DEBUG 1
|
||||
#endif
|
||||
#if LV_USE_DEBUG
|
||||
|
||||
/*Check if the parameter is NULL. (Quite fast) */
|
||||
#ifndef LV_USE_ASSERT_NULL
|
||||
#define LV_USE_ASSERT_NULL 1
|
||||
#endif
|
||||
|
||||
/*Checks is the memory is successfully allocated or no. (Quite fast)*/
|
||||
#ifndef LV_USE_ASSERT_MEM
|
||||
#define LV_USE_ASSERT_MEM 1
|
||||
#endif
|
||||
|
||||
/* Check the strings.
|
||||
* Search for NULL, very long strings, invalid characters, and unnatural repetitions. (Slow)
|
||||
* If disabled `LV_USE_ASSERT_NULL` will be performed instead (if it's enabled) */
|
||||
#ifndef LV_USE_ASSERT_STR
|
||||
#define LV_USE_ASSERT_STR 0
|
||||
#endif
|
||||
|
||||
/* Check NULL, the object's type and existence (e.g. not deleted). (Quite slow)
|
||||
* If disabled `LV_USE_ASSERT_NULL` will be performed instead (if it's enabled) */
|
||||
#ifndef LV_USE_ASSERT_OBJ
|
||||
#define LV_USE_ASSERT_OBJ 0
|
||||
#endif
|
||||
|
||||
/*Check if the styles are properly initialized. (Fast)*/
|
||||
#ifndef LV_USE_ASSERT_STYLE
|
||||
#define LV_USE_ASSERT_STYLE 1
|
||||
#endif
|
||||
|
||||
#endif /*LV_USE_DEBUG*/
|
||||
|
||||
/*================
|
||||
* THEME USAGE
|
||||
*================*/
|
||||
@@ -364,6 +427,14 @@
|
||||
#define LV_FONT_ROBOTO_28 0
|
||||
#endif
|
||||
|
||||
/* Demonstrate special features */
|
||||
#ifndef LV_FONT_ROBOTO_12_SUBPX
|
||||
#define LV_FONT_ROBOTO_12_SUBPX 1
|
||||
#endif
|
||||
#ifndef LV_FONT_ROBOTO_28_COMPRESSED
|
||||
#define LV_FONT_ROBOTO_28_COMPRESSED 1 /*bpp = 3*/
|
||||
#endif
|
||||
|
||||
/*Pixel perfect monospace font
|
||||
* http://pelulamu.net/unscii/ */
|
||||
#ifndef LV_FONT_UNSCII_8
|
||||
@@ -392,6 +463,14 @@
|
||||
#define LV_FONT_FMT_TXT_LARGE 0
|
||||
#endif
|
||||
|
||||
/* Set the pixel order of the display.
|
||||
* Important only if "subpx fonts" are used.
|
||||
* With "normal" font it doesn't matter.
|
||||
*/
|
||||
#ifndef LV_FONT_SUBPX_BGR
|
||||
#define LV_FONT_SUBPX_BGR 0
|
||||
#endif
|
||||
|
||||
/*Declare the type of the user data of fonts (can be e.g. `void *`, `int`, `struct`)*/
|
||||
|
||||
/*=================
|
||||
@@ -412,6 +491,62 @@
|
||||
#define LV_TXT_BREAK_CHARS " ,.;:-_"
|
||||
#endif
|
||||
|
||||
/* If a word is at least this long, will break wherever "prettiest"
|
||||
* To disable, set to a value <= 0 */
|
||||
#ifndef LV_TXT_LINE_BREAK_LONG_LEN
|
||||
#define LV_TXT_LINE_BREAK_LONG_LEN 12
|
||||
#endif
|
||||
|
||||
/* Minimum number of characters in a long word to put on a line before a break.
|
||||
* Depends on LV_TXT_LINE_BREAK_LONG_LEN. */
|
||||
#ifndef LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN
|
||||
#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3
|
||||
#endif
|
||||
|
||||
/* Minimum number of characters in a long word to put on a line after a break.
|
||||
* Depends on LV_TXT_LINE_BREAK_LONG_LEN. */
|
||||
#ifndef LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN
|
||||
#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3
|
||||
#endif
|
||||
|
||||
/* The control character to use for signalling text recoloring. */
|
||||
#ifndef LV_TXT_COLOR_CMD
|
||||
#define LV_TXT_COLOR_CMD "#"
|
||||
#endif
|
||||
|
||||
/* Support bidirectional texts.
|
||||
* Allows mixing Left-to-Right and Right-to-Left texts.
|
||||
* The direction will be processed according to the Unicode Bidirectioanl Algorithm:
|
||||
* https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/
|
||||
#ifndef LV_USE_BIDI
|
||||
#define LV_USE_BIDI 0
|
||||
#endif
|
||||
#if LV_USE_BIDI
|
||||
/* Set the default direction. Supported values:
|
||||
* `LV_BIDI_DIR_LTR` Left-to-Right
|
||||
* `LV_BIDI_DIR_RTL` Right-to-Left
|
||||
* `LV_BIDI_DIR_AUTO` detect texts base direction */
|
||||
#ifndef LV_BIDI_BASE_DIR_DEF
|
||||
#define LV_BIDI_BASE_DIR_DEF LV_BIDI_DIR_AUTO
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Change the built in (v)snprintf functions*/
|
||||
#ifndef LV_SPRINTF_CUSTOM
|
||||
#define LV_SPRINTF_CUSTOM 0
|
||||
#endif
|
||||
#if LV_SPRINTF_CUSTOM
|
||||
#ifndef LV_SPRINTF_INCLUDE
|
||||
# define LV_SPRINTF_INCLUDE <stdio.h>
|
||||
#endif
|
||||
#ifndef lv_snprintf
|
||||
# define lv_snprintf snprintf
|
||||
#endif
|
||||
#ifndef lv_vsnprintf
|
||||
# define lv_vsnprintf vsnprintf
|
||||
#endif
|
||||
#endif /*LV_SPRINTF_CUSTOM*/
|
||||
|
||||
/*===================
|
||||
* LV_OBJ SETTINGS
|
||||
*==================*/
|
||||
@@ -495,6 +630,11 @@
|
||||
#define LV_USE_CONT 1
|
||||
#endif
|
||||
|
||||
/*Color picker (dependencies: -*/
|
||||
#ifndef LV_USE_CPICKER
|
||||
#define LV_USE_CPICKER 1
|
||||
#endif
|
||||
|
||||
/*Drop down list (dependencies: lv_page, lv_label, lv_symbol_def.h)*/
|
||||
#ifndef LV_USE_DDLIST
|
||||
#define LV_USE_DDLIST 1
|
||||
|
||||
@@ -4,6 +4,7 @@ CSRCS += lv_disp.c
|
||||
CSRCS += lv_obj.c
|
||||
CSRCS += lv_refr.c
|
||||
CSRCS += lv_style.c
|
||||
CSRCS += lv_debug.c
|
||||
|
||||
DEPPATH += --dep-path $(LVGL_DIR)/lvgl/src/lv_core
|
||||
VPATH += :$(LVGL_DIR)/lvgl/src/lv_core
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
/**
|
||||
* @file lv_debug.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_obj.h"
|
||||
#include "lv_debug.h"
|
||||
|
||||
#if LV_USE_DEBUG
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#ifndef LV_DEBUG_STR_MAX_LENGTH
|
||||
#define LV_DEBUG_STR_MAX_LENGTH (1024 * 8)
|
||||
#endif
|
||||
|
||||
#ifndef LV_DEBUG_STR_MAX_REPEAT
|
||||
#define LV_DEBUG_STR_MAX_REPEAT 8
|
||||
#endif
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_find);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
bool lv_debug_check_null(const void * p)
|
||||
{
|
||||
if(p) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool lv_debug_check_obj_type(const lv_obj_t * obj, const char * obj_type)
|
||||
{
|
||||
if(obj_type[0] == '\0') return true;
|
||||
|
||||
lv_obj_type_t types;
|
||||
lv_obj_get_type((lv_obj_t *)obj, &types);
|
||||
|
||||
uint8_t i;
|
||||
for(i = 0; i < LV_MAX_ANCESTOR_NUM; i++) {
|
||||
if(strcmp(types.type[i], obj_type) == 0) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool lv_debug_check_obj_valid(const lv_obj_t * obj)
|
||||
{
|
||||
lv_disp_t * disp = lv_disp_get_next(NULL);
|
||||
while(disp) {
|
||||
lv_obj_t * scr;
|
||||
LV_LL_READ(disp->scr_ll, scr) {
|
||||
|
||||
if(scr == obj) return true;
|
||||
bool found = obj_valid_child(scr, obj);
|
||||
if(found) return true;
|
||||
}
|
||||
|
||||
disp = lv_disp_get_next(disp);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool lv_debug_check_style(const lv_style_t * style)
|
||||
{
|
||||
if(style == NULL) return true; /*NULL style is still valid*/
|
||||
|
||||
#if LV_USE_ASSERT_STYLE
|
||||
if(style->debug_sentinel != LV_STYLE_DEGUG_SENTINEL_VALUE) {
|
||||
LV_LOG_WARN("Invalid style (local variable or not initialized?)");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lv_debug_check_str(const void * str)
|
||||
{
|
||||
const uint8_t * s = (const uint8_t *)str;
|
||||
uint8_t last_byte = 0;
|
||||
uint32_t rep = 0;
|
||||
uint32_t i;
|
||||
|
||||
for(i = 0; s[i] != '\0' && i < LV_DEBUG_STR_MAX_LENGTH; i++) {
|
||||
if(s[i] != last_byte) {
|
||||
last_byte = s[i];
|
||||
rep = 1;
|
||||
} else if(s[i] > 0x7F){
|
||||
rep++;
|
||||
if(rep > LV_DEBUG_STR_MAX_REPEAT) {
|
||||
LV_LOG_WARN("lv_debug_check_str: a non-ASCII char has repeated more than LV_DEBUG_STR_MAX_REPEAT times)");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(s[i] < 10) {
|
||||
LV_LOG_WARN("lv_debug_check_str: invalid char in the string (< 10 value)");
|
||||
return false; /*Shouldn't occur in strings*/
|
||||
}
|
||||
}
|
||||
|
||||
if(s[i] == '\0') return true;
|
||||
|
||||
LV_LOG_WARN("lv_debug_check_str: string is longer than LV_DEBUG_STR_MAX_LENGTH");
|
||||
return false;
|
||||
}
|
||||
|
||||
void lv_debug_log_error(const char * msg, uint64_t value)
|
||||
{
|
||||
static const char hex[] = "0123456789ABCDEF";
|
||||
|
||||
uint32_t msg_len = strlen(msg);
|
||||
uint32_t value_len = sizeof(unsigned long int);
|
||||
|
||||
if(msg_len < 230) {
|
||||
char buf[255];
|
||||
char * bufp = buf;
|
||||
|
||||
/*Add the function name*/
|
||||
memcpy(bufp, msg, msg_len);
|
||||
bufp += msg_len;
|
||||
|
||||
/*Add value in hey*/
|
||||
*bufp = ' ';
|
||||
bufp ++;
|
||||
*bufp = '(';
|
||||
bufp ++;
|
||||
*bufp = '0';
|
||||
bufp ++;
|
||||
*bufp = 'x';
|
||||
bufp ++;
|
||||
|
||||
int8_t i;
|
||||
for(i = value_len * 2 - 1; i >= 0; i--) {
|
||||
uint8_t x = (unsigned long int)((unsigned long int)value >> (i * 4)) & 0xF;
|
||||
|
||||
*bufp = hex[x];
|
||||
bufp++;
|
||||
}
|
||||
|
||||
*bufp = ')';
|
||||
bufp ++;
|
||||
|
||||
*bufp = '\0';
|
||||
LV_LOG_ERROR(buf);
|
||||
} else {
|
||||
LV_LOG_ERROR(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_find)
|
||||
{
|
||||
/*Check all children of `parent`*/
|
||||
lv_obj_t * child;
|
||||
LV_LL_READ(parent->child_ll, child) {
|
||||
if(child == obj_to_find) return true;
|
||||
|
||||
/*Check the children*/
|
||||
bool found = obj_valid_child(child, obj_to_find);
|
||||
if(found) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DEBUG*/
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @file lv_debug.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DEBUG_H
|
||||
#define LV_DEBUG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_obj.h"
|
||||
|
||||
#if LV_USE_DEBUG
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
bool lv_debug_check_null(const void * p);
|
||||
|
||||
bool lv_debug_check_obj_type(const lv_obj_t * obj, const char * obj_type);
|
||||
|
||||
bool lv_debug_check_obj_valid(const lv_obj_t * obj);
|
||||
|
||||
bool lv_debug_check_style(const lv_style_t * style);
|
||||
|
||||
bool lv_debug_check_str(const void * str);
|
||||
|
||||
void lv_debug_log_error(const char * msg, uint64_t value);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifndef LV_DEBUG_ASSERT
|
||||
#define LV_DEBUG_ASSERT(expr, msg, value) \
|
||||
{ \
|
||||
if(!(expr)) { \
|
||||
LV_LOG_ERROR(__func__); \
|
||||
lv_debug_log_error(msg, (unsigned long int)value); \
|
||||
while(1); \
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*----------------
|
||||
* CHECKS
|
||||
*----------------*/
|
||||
|
||||
#ifndef LV_DEBUG_IS_NULL
|
||||
#define LV_DEBUG_IS_NULL(p) (lv_debug_check_null(p))
|
||||
#endif
|
||||
|
||||
#ifndef LV_DEBUG_IS_STR
|
||||
#define LV_DEBUG_IS_STR(str) (lv_debug_check_null(str) && \
|
||||
lv_debug_check_str(str))
|
||||
#endif
|
||||
|
||||
#ifndef LV_DEBUG_IS_OBJ
|
||||
#define LV_DEBUG_IS_OBJ(obj_p, obj_type) (lv_debug_check_null(obj_p) && \
|
||||
lv_debug_check_obj_valid(obj_p) && \
|
||||
lv_debug_check_obj_type(obj_p, obj_type))
|
||||
#endif
|
||||
|
||||
#ifndef LV_DEBUG_IS_STYLE
|
||||
#define LV_DEBUG_IS_STYLE(style_p) (lv_debug_check_style(style_p))
|
||||
#endif
|
||||
|
||||
/*-----------------
|
||||
* ASSERTS
|
||||
*-----------------*/
|
||||
|
||||
/*clang-format off*/
|
||||
|
||||
#if LV_USE_ASSERT_NULL
|
||||
# ifndef LV_ASSERT_NULL
|
||||
# define LV_ASSERT_NULL(p) LV_DEBUG_ASSERT(LV_DEBUG_IS_NULL(p), "NULL pointer", p);
|
||||
# endif
|
||||
#else
|
||||
# define LV_ASSERT_NULL(p) true
|
||||
#endif
|
||||
|
||||
#if LV_USE_ASSERT_MEM
|
||||
# ifndef LV_ASSERT_MEM
|
||||
# define LV_ASSERT_MEM(p) LV_DEBUG_ASSERT(LV_DEBUG_IS_NULL(p), "Out of memory", p);
|
||||
# endif
|
||||
#else
|
||||
# define LV_ASSERT_MEM(p) true
|
||||
#endif
|
||||
|
||||
#if LV_USE_ASSERT_STR
|
||||
# ifndef LV_ASSERT_STR
|
||||
# define LV_ASSERT_STR(str) LV_DEBUG_ASSERT(LV_DEBUG_IS_STR(str), "Strange or invalid string", str);
|
||||
# endif
|
||||
#else /* LV_USE_ASSERT_OBJ == 0 */
|
||||
# if LV_USE_ASSERT_NULL /*Use at least LV_ASSERT_NULL if enabled*/
|
||||
# define LV_ASSERT_STR(str) LV_ASSERT_NULL(str)
|
||||
# else
|
||||
# define LV_ASSERT_STR(str) true
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#if LV_USE_ASSERT_OBJ
|
||||
# ifndef LV_ASSERT_OBJ
|
||||
# define LV_ASSERT_OBJ(obj_p, obj_type) LV_DEBUG_ASSERT(LV_DEBUG_IS_OBJ(obj_p, obj_type), "Invalid object", obj_p);
|
||||
# endif
|
||||
#else /* LV_USE_ASSERT_OBJ == 0 */
|
||||
# if LV_USE_ASSERT_NULL /*Use at least LV_ASSERT_NULL if enabled*/
|
||||
# define LV_ASSERT_OBJ(obj_p, obj_type) LV_ASSERT_NULL(obj_p)
|
||||
# else
|
||||
# define LV_ASSERT_OBJ(obj_p, obj_type) true
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#if LV_USE_ASSERT_STYLE
|
||||
# ifndef LV_ASSERT_STYLE
|
||||
# define LV_ASSERT_STYLE(style_p) LV_DEBUG_ASSERT(LV_DEBUG_IS_STYLE(style_p), "Invalid style", style_p);
|
||||
# endif
|
||||
#else
|
||||
# define LV_ASSERT_STYLE(style) true
|
||||
#endif
|
||||
|
||||
#else /* LV_USE_DEBUG == 0 */
|
||||
|
||||
#define LV_DEBUG_ASSERT(expr, msg, value) do{}while(0)
|
||||
|
||||
#define LV_ASSERT_NULL(p) true
|
||||
#define LV_ASSERT_MEM(p) true
|
||||
#define LV_ASSERT_STR(p) true
|
||||
#define LV_ASSERT_OBJ(obj, obj_type) true
|
||||
#define LV_ASSERT_STYLE(p) true
|
||||
|
||||
#endif /* LV_USE_DEBUG */
|
||||
/*clang-format on*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_DEBUG_H*/
|
||||
@@ -8,8 +8,9 @@
|
||||
*********************/
|
||||
#include "lv_group.h"
|
||||
#if LV_USE_GROUP != 0
|
||||
#include "../lv_themes/lv_theme.h"
|
||||
#include <stddef.h>
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "../lv_themes/lv_theme.h"
|
||||
#include "../lv_misc/lv_gc.h"
|
||||
|
||||
#if defined(LV_GC_INCLUDE)
|
||||
@@ -62,7 +63,7 @@ void lv_group_init(void)
|
||||
lv_group_t * lv_group_create(void)
|
||||
{
|
||||
lv_group_t * group = lv_ll_ins_head(&LV_GC_ROOT(_lv_group_ll));
|
||||
lv_mem_assert(group);
|
||||
LV_ASSERT_MEM(group);
|
||||
if(group == NULL) return NULL;
|
||||
lv_ll_init(&group->obj_ll, sizeof(lv_obj_t *));
|
||||
|
||||
@@ -138,7 +139,7 @@ void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj)
|
||||
|
||||
obj->group_p = group;
|
||||
lv_obj_t ** next = lv_ll_ins_tail(&group->obj_ll);
|
||||
lv_mem_assert(next);
|
||||
LV_ASSERT_MEM(next);
|
||||
if(next == NULL) return;
|
||||
*next = obj;
|
||||
|
||||
|
||||
+320
-38
File diff suppressed because it is too large
Load Diff
+23
-3
@@ -28,6 +28,7 @@ extern "C" {
|
||||
#include "../lv_misc/lv_ll.h"
|
||||
#include "../lv_misc/lv_color.h"
|
||||
#include "../lv_misc/lv_log.h"
|
||||
#include "../lv_misc/lv_bidi.h"
|
||||
#include "../lv_hal/lv_hal.h"
|
||||
|
||||
/*********************
|
||||
@@ -111,7 +112,8 @@ enum {
|
||||
LV_SIGNAL_CHILD_CHG, /**< Child was removed/added */
|
||||
LV_SIGNAL_CORD_CHG, /**< Object coordinates/size have changed */
|
||||
LV_SIGNAL_PARENT_SIZE_CHG, /**< Parent's size has changed */
|
||||
LV_SIGNAL_STYLE_CHG, /**< Object's style has changed */
|
||||
LV_SIGNAL_STYLE_CHG, /**< Object's style has changed */
|
||||
LV_SIGNAL_BASE_DIR_CHG, /**<The base dir has changed*/
|
||||
LV_SIGNAL_REFR_EXT_DRAW_PAD, /**< Object's extra padding has changed */
|
||||
LV_SIGNAL_GET_TYPE, /**< LittlevGL needs to retrieve the object's type */
|
||||
|
||||
@@ -123,7 +125,8 @@ enum {
|
||||
LV_SIGNAL_LONG_PRESS, /**< Object has been pressed for at least `LV_INDEV_LONG_PRESS_TIME`. Not called if dragged.*/
|
||||
LV_SIGNAL_LONG_PRESS_REP, /**< Called after `LV_INDEV_LONG_PRESS_TIME` in every `LV_INDEV_LONG_PRESS_REP_TIME` ms. Not called if dragged.*/
|
||||
LV_SIGNAL_DRAG_BEGIN,
|
||||
LV_SIGNAL_DRAG_END,
|
||||
LV_SIGNAL_DRAG_END,
|
||||
|
||||
/*Group related*/
|
||||
LV_SIGNAL_FOCUS,
|
||||
LV_SIGNAL_DEFOCUS,
|
||||
@@ -218,7 +221,8 @@ typedef struct _lv_obj_t
|
||||
uint8_t opa_scale_en : 1; /**< 1: opa_scale is set*/
|
||||
uint8_t parent_event : 1; /**< 1: Send the object's events to the parent too. */
|
||||
lv_drag_dir_t drag_dir : 2; /**< Which directions the object can be dragged in */
|
||||
uint8_t reserved : 6; /**< Reserved for future use*/
|
||||
lv_bidi_dir_t base_dir : 2; /**< Base direction of texts related to this object */
|
||||
uint8_t reserved : 3; /**< Reserved for future use*/
|
||||
uint8_t protect; /**< Automatically happening actions can be prevented. 'OR'ed values from
|
||||
`lv_protect_t`*/
|
||||
lv_opa_t opa_scale; /**< Scale down the opacity by this factor. Effects all children as well*/
|
||||
@@ -510,6 +514,7 @@ void lv_obj_set_drag_parent(lv_obj_t * obj, bool en);
|
||||
*/
|
||||
void lv_obj_set_parent_event(lv_obj_t * obj, bool en);
|
||||
|
||||
void lv_obj_set_base_dir(lv_obj_t * obj, lv_bidi_dir_t dir);
|
||||
/**
|
||||
* Set the opa scale enable parameter (required to set opa_scale with `lv_obj_set_opa_scale()`)
|
||||
* @param obj pointer to an object
|
||||
@@ -849,6 +854,9 @@ bool lv_obj_get_drag_parent(const lv_obj_t * obj);
|
||||
*/
|
||||
bool lv_obj_get_parent_event(const lv_obj_t * obj);
|
||||
|
||||
|
||||
lv_bidi_dir_t lv_obj_get_base_dir(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the opa scale enable parameter
|
||||
* @param obj pointer to an object
|
||||
@@ -960,6 +968,18 @@ bool lv_obj_is_focused(const lv_obj_t * obj);
|
||||
|
||||
#endif
|
||||
|
||||
/*-------------------
|
||||
* OTHER FUNCTIONS
|
||||
*------------------*/
|
||||
|
||||
/**
|
||||
* Used in the signal callback to handle `LV_SIGNAL_GET_TYPE` signal
|
||||
* @param buf pointer to `lv_obj_type_t`. (`param` i nteh signal callback)
|
||||
* @param name name of the object. E.g. "lv_btn". (Only teh pointer is saved)
|
||||
* @return LV_RES_OK
|
||||
*/
|
||||
lv_res_t lv_obj_handle_get_type_signal(lv_obj_type_t * buf, const char * name);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
@@ -318,19 +318,19 @@ static void lv_refr_area(const lv_area_t * area_p)
|
||||
tmp.x2 = 0;
|
||||
tmp.y1 = 0;
|
||||
|
||||
lv_coord_t y_tmp = max_row - 1;
|
||||
lv_coord_t h_tmp = max_row;
|
||||
do {
|
||||
tmp.y2 = y_tmp;
|
||||
tmp.y2 = h_tmp - 1;
|
||||
disp_refr->driver.rounder_cb(&disp_refr->driver, &tmp);
|
||||
|
||||
/*If this height fits into `max_row` then fine*/
|
||||
if(lv_area_get_height(&tmp) <= max_row) break;
|
||||
|
||||
/*Decrement the height of the area until it fits into `max_row` after rounding*/
|
||||
y_tmp--;
|
||||
} while(y_tmp != 0);
|
||||
h_tmp--;
|
||||
} while(h_tmp > 0);
|
||||
|
||||
if(y_tmp == 0) {
|
||||
if(h_tmp <= 0) {
|
||||
LV_LOG_WARN("Can't set VDB height using the round function. (Wrong round_cb or to "
|
||||
"small VDB)");
|
||||
return;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_obj.h"
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "../lv_misc/lv_mem.h"
|
||||
#include "../lv_misc/lv_anim.h"
|
||||
|
||||
@@ -106,6 +107,12 @@ void lv_style_init(void)
|
||||
lv_style_scr.line.width = 2;
|
||||
lv_style_scr.line.rounded = 0;
|
||||
|
||||
#if LV_USE_DEBUG
|
||||
#if LV_USE_ASSERT_STYLE
|
||||
lv_style_scr.debug_sentinel = LV_STYLE_DEGUG_SENTINEL_VALUE;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Plain style (by default near the same as the screen style)*/
|
||||
lv_style_copy(&lv_style_plain, &lv_style_scr);
|
||||
lv_style_plain.body.padding.left = LV_DPI / 20;
|
||||
@@ -287,7 +294,7 @@ void lv_style_anim_init(lv_anim_t * a)
|
||||
|
||||
lv_style_anim_dsc_t * dsc;
|
||||
dsc = lv_mem_alloc(sizeof(lv_style_anim_dsc_t));
|
||||
lv_mem_assert(dsc);
|
||||
LV_ASSERT_MEM(dsc);
|
||||
if(dsc == NULL) return;
|
||||
dsc->ready_cb = NULL;
|
||||
dsc->style_anim = NULL;
|
||||
|
||||
+23
-1
@@ -23,6 +23,9 @@ extern "C" {
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_RADIUS_CIRCLE (LV_COORD_MAX) /**< A very big radius to always draw as circle*/
|
||||
#define LV_STYLE_DEGUG_SENTINEL_VALUE 0x12345678
|
||||
|
||||
LV_EXPORT_CONST_INT(LV_RADIUS_CIRCLE);
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@@ -119,6 +122,13 @@ typedef struct
|
||||
lv_opa_t opa;
|
||||
uint8_t rounded : 1; /**< 1: rounded line endings*/
|
||||
} line;
|
||||
|
||||
#if LV_USE_DEBUG
|
||||
#if LV_USE_ASSERT_STYLE
|
||||
uint32_t debug_sentinel; /**<Should `LV_STYLE_DEGUG_SENTINEL_VALUE` to indicate that the style is valid*/
|
||||
#endif
|
||||
#endif
|
||||
|
||||
} lv_style_t;
|
||||
|
||||
#if LV_USE_ANIMATION
|
||||
@@ -186,7 +196,7 @@ void lv_style_anim_set_styles(lv_anim_t * a, lv_style_t * to_anim, const lv_styl
|
||||
* @param duration duration of the animation in milliseconds
|
||||
* @param delay delay before the animation in milliseconds
|
||||
*/
|
||||
static inline void lv_style_anim_set_time(lv_anim_t * a, uint16_t duration, uint16_t delay)
|
||||
static inline void lv_style_anim_set_time(lv_anim_t * a, uint16_t duration, int16_t delay)
|
||||
{
|
||||
lv_anim_set_time(a, duration, delay);
|
||||
}
|
||||
@@ -272,6 +282,18 @@ extern lv_style_t lv_style_btn_ina;
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create and initialize a `static` style
|
||||
* Example:
|
||||
* LV_STYLE_CREATE(my_style, &lv_style_plain);
|
||||
* is equivalent to
|
||||
* static lv_style_t my_style;
|
||||
* lv_style_copy(my_style, &lv_style_plain);
|
||||
*
|
||||
* If the style to copy is `NULL` `lv_style_plain` will be used.
|
||||
*/
|
||||
#define LV_STYLE_CREATE(name, copy_p) static lv_style_t name; lv_style_copy(&name, copy_p == NULL ? &lv_style_plain : copy_p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include "lv_draw.h"
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
#include "../lv_misc/lv_log.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
@@ -60,12 +61,12 @@ void * lv_draw_get_buf(uint32_t size)
|
||||
|
||||
if(LV_GC_ROOT(_lv_draw_buf) == NULL) {
|
||||
LV_GC_ROOT(_lv_draw_buf) = lv_mem_alloc(size);
|
||||
lv_mem_assert(LV_GC_ROOT(_lv_draw_buf));
|
||||
LV_ASSERT_MEM(LV_GC_ROOT(_lv_draw_buf));
|
||||
return LV_GC_ROOT(_lv_draw_buf);
|
||||
}
|
||||
|
||||
LV_GC_ROOT(_lv_draw_buf) = lv_mem_realloc(LV_GC_ROOT(_lv_draw_buf), size);
|
||||
lv_mem_assert(LV_GC_ROOT(_lv_draw_buf));
|
||||
LV_ASSERT_MEM(LV_GC_ROOT(_lv_draw_buf));
|
||||
return LV_GC_ROOT(_lv_draw_buf);
|
||||
}
|
||||
|
||||
|
||||
+69
-89
@@ -20,7 +20,6 @@
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static uint16_t fast_atan2(int x, int y);
|
||||
static void ver_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coord_t len, lv_color_t color,
|
||||
lv_opa_t opa);
|
||||
static void hor_line(lv_coord_t x, lv_coord_t y, const lv_area_t * mask, lv_coord_t len, lv_color_t color,
|
||||
@@ -57,6 +56,11 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, cons
|
||||
lv_coord_t thickness = style->line.width;
|
||||
if(thickness > radius) thickness = radius;
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
thickness--;
|
||||
radius--;
|
||||
#endif
|
||||
|
||||
lv_coord_t r_out = radius;
|
||||
lv_coord_t r_in = r_out - thickness;
|
||||
int16_t deg_base;
|
||||
@@ -73,17 +77,26 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, cons
|
||||
else
|
||||
deg_test = deg_test_inv;
|
||||
|
||||
int middle_r_out = r_out;
|
||||
#if !LV_ANTIALIAS
|
||||
thickness--;
|
||||
middle_r_out = r_out - 1;
|
||||
#endif
|
||||
if(deg_test(270, start_angle, end_angle))
|
||||
hor_line(center_x - r_out + 1, center_y, mask, thickness - 1, color, opa); /*Left Middle*/
|
||||
hor_line(center_x - middle_r_out, center_y, mask, thickness, color, opa); /*Left Middle*/
|
||||
if(deg_test(90, start_angle, end_angle))
|
||||
hor_line(center_x + r_in, center_y, mask, thickness - 1, color, opa); /*Right Middle*/
|
||||
hor_line(center_x + r_in, center_y, mask, thickness, color, opa); /*Right Middle*/
|
||||
if(deg_test(180, start_angle, end_angle))
|
||||
ver_line(center_x, center_y - r_out + 1, mask, thickness - 1, color, opa); /*Top Middle*/
|
||||
ver_line(center_x, center_y - middle_r_out, mask, thickness, color, opa); /*Top Middle*/
|
||||
if(deg_test(0, start_angle, end_angle))
|
||||
ver_line(center_x, center_y + r_in, mask, thickness - 1, color, opa); /*Bottom middle*/
|
||||
ver_line(center_x, center_y + r_in, mask, thickness, color, opa); /*Bottom middle*/
|
||||
|
||||
uint32_t r_out_sqr = r_out * r_out;
|
||||
uint32_t r_in_sqr = r_in * r_in;
|
||||
#if LV_ANTIALIAS
|
||||
uint32_t r_out_aa_sqr = (r_out + 1) * (r_out + 1);
|
||||
uint32_t r_in_aa_sqr = (r_in - 1) * (r_in - 1);
|
||||
#endif
|
||||
int16_t xi;
|
||||
int16_t yi;
|
||||
for(yi = -r_out; yi < 0; yi++) {
|
||||
@@ -95,12 +108,55 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, cons
|
||||
x_end[1] = LV_COORD_MIN;
|
||||
x_end[2] = LV_COORD_MIN;
|
||||
x_end[3] = LV_COORD_MIN;
|
||||
int xe = 0;
|
||||
for(xi = -r_out; xi < 0; xi++) {
|
||||
|
||||
uint32_t r_act_sqr = xi * xi + yi * yi;
|
||||
#if LV_ANTIALIAS
|
||||
if(r_act_sqr > r_out_aa_sqr) {
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
if(r_act_sqr > r_out_sqr) continue;
|
||||
#endif
|
||||
|
||||
deg_base = fast_atan2(xi, yi) - 180;
|
||||
deg_base = lv_atan2(xi, yi) - 180;
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
int opa2 = -1;
|
||||
if(r_act_sqr > r_out_sqr) {
|
||||
opa2 = LV_OPA_100 * (r_out + 1) - lv_sqrt(LV_OPA_100 * LV_OPA_100 * r_act_sqr);
|
||||
if(opa2 < LV_OPA_0)
|
||||
opa2 = LV_OPA_0;
|
||||
else if(opa2 > LV_OPA_100)
|
||||
opa2 = LV_OPA_100;
|
||||
} else if(r_act_sqr < r_in_sqr) {
|
||||
if(xe == 0) xe = xi;
|
||||
opa2 = lv_sqrt(LV_OPA_100 * LV_OPA_100 * r_act_sqr) - LV_OPA_100 * (r_in - 1);
|
||||
if(opa2 < LV_OPA_0)
|
||||
opa2 = LV_OPA_0;
|
||||
else if(opa2 > LV_OPA_100)
|
||||
opa2 = LV_OPA_100;
|
||||
if(r_act_sqr < r_in_aa_sqr)
|
||||
break; /*No need to continue the iteration in x once we found the inner edge of the
|
||||
arc*/
|
||||
}
|
||||
if(opa2 != -1) {
|
||||
if(deg_test(180 + deg_base, start_angle, end_angle)) {
|
||||
lv_draw_px(center_x + xi, center_y + yi, mask, color, opa2);
|
||||
}
|
||||
if(deg_test(360 - deg_base, start_angle, end_angle)) {
|
||||
lv_draw_px(center_x + xi, center_y - yi, mask, color, opa2);
|
||||
}
|
||||
if(deg_test(180 - deg_base, start_angle, end_angle)) {
|
||||
lv_draw_px(center_x - xi, center_y + yi, mask, color, opa2);
|
||||
}
|
||||
if(deg_test(deg_base, start_angle, end_angle)) {
|
||||
lv_draw_px(center_x - xi, center_y - yi, mask, color, opa2);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
deg = 180 + deg_base;
|
||||
if(deg_test(deg, start_angle, end_angle)) {
|
||||
@@ -130,111 +186,35 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, cons
|
||||
x_end[3] = xi - 1;
|
||||
}
|
||||
|
||||
if(r_act_sqr < r_in_sqr)
|
||||
if(r_act_sqr < r_in_sqr) {
|
||||
xe = xi;
|
||||
break; /*No need to continue the iteration in x once we found the inner edge of the
|
||||
arc*/
|
||||
}
|
||||
}
|
||||
|
||||
if(x_start[0] != LV_COORD_MIN) {
|
||||
if(x_end[0] == LV_COORD_MIN) x_end[0] = xi - 1;
|
||||
if(x_end[0] == LV_COORD_MIN) x_end[0] = xe - 1;
|
||||
hor_line(center_x + x_start[0], center_y + yi, mask, x_end[0] - x_start[0], color, opa);
|
||||
}
|
||||
|
||||
if(x_start[1] != LV_COORD_MIN) {
|
||||
if(x_end[1] == LV_COORD_MIN) x_end[1] = xi - 1;
|
||||
if(x_end[1] == LV_COORD_MIN) x_end[1] = xe - 1;
|
||||
hor_line(center_x + x_start[1], center_y - yi, mask, x_end[1] - x_start[1], color, opa);
|
||||
}
|
||||
|
||||
if(x_start[2] != LV_COORD_MIN) {
|
||||
if(x_end[2] == LV_COORD_MIN) x_end[2] = xi - 1;
|
||||
if(x_end[2] == LV_COORD_MIN) x_end[2] = xe - 1;
|
||||
hor_line(center_x - x_end[2], center_y + yi, mask, LV_MATH_ABS(x_end[2] - x_start[2]), color, opa);
|
||||
}
|
||||
|
||||
if(x_start[3] != LV_COORD_MIN) {
|
||||
if(x_end[3] == LV_COORD_MIN) x_end[3] = xi - 1;
|
||||
if(x_end[3] == LV_COORD_MIN) x_end[3] = xe - 1;
|
||||
hor_line(center_x - x_end[3], center_y - yi, mask, LV_MATH_ABS(x_end[3] - x_start[3]), color, opa);
|
||||
}
|
||||
|
||||
#if LV_ANTIALIAS
|
||||
/*TODO*/
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t fast_atan2(int x, int y)
|
||||
{
|
||||
// Fast XY vector to integer degree algorithm - Jan 2011 www.RomanBlack.com
|
||||
// Converts any XY values including 0 to a degree value that should be
|
||||
// within +/- 1 degree of the accurate value without needing
|
||||
// large slow trig functions like ArcTan() or ArcCos().
|
||||
// NOTE! at least one of the X or Y values must be non-zero!
|
||||
// This is the full version, for all 4 quadrants and will generate
|
||||
// the angle in integer degrees from 0-360.
|
||||
// Any values of X and Y are usable including negative values provided
|
||||
// they are between -1456 and 1456 so the 16bit multiply does not overflow.
|
||||
|
||||
unsigned char negflag;
|
||||
unsigned char tempdegree;
|
||||
unsigned char comp;
|
||||
unsigned int degree; /*this will hold the result*/
|
||||
unsigned int ux;
|
||||
unsigned int uy;
|
||||
|
||||
/*Save the sign flags then remove signs and get XY as unsigned ints*/
|
||||
negflag = 0;
|
||||
if(x < 0) {
|
||||
negflag += 0x01; /*x flag bit*/
|
||||
x = (0 - x); /*is now +*/
|
||||
}
|
||||
ux = x; /*copy to unsigned var before multiply*/
|
||||
if(y < 0) {
|
||||
negflag += 0x02; /*y flag bit*/
|
||||
y = (0 - y); /*is now +*/
|
||||
}
|
||||
uy = y; /*copy to unsigned var before multiply*/
|
||||
|
||||
/*1. Calc the scaled "degrees"*/
|
||||
if(ux > uy) {
|
||||
degree = (uy * 45) / ux; /*degree result will be 0-45 range*/
|
||||
negflag += 0x10; /*octant flag bit*/
|
||||
} else {
|
||||
degree = (ux * 45) / uy; /*degree result will be 0-45 range*/
|
||||
}
|
||||
|
||||
/*2. Compensate for the 4 degree error curve*/
|
||||
comp = 0;
|
||||
tempdegree = degree; /*use an unsigned char for speed!*/
|
||||
if(tempdegree > 22) { /*if top half of range*/
|
||||
if(tempdegree <= 44) comp++;
|
||||
if(tempdegree <= 41) comp++;
|
||||
if(tempdegree <= 37) comp++;
|
||||
if(tempdegree <= 32) comp++; /*max is 4 degrees compensated*/
|
||||
} else { /*else is lower half of range*/
|
||||
if(tempdegree >= 2) comp++;
|
||||
if(tempdegree >= 6) comp++;
|
||||
if(tempdegree >= 10) comp++;
|
||||
if(tempdegree >= 15) comp++; /*max is 4 degrees compensated*/
|
||||
}
|
||||
degree += comp; /*degree is now accurate to +/- 1 degree!*/
|
||||
|
||||
/*Invert degree if it was X>Y octant, makes 0-45 into 90-45*/
|
||||
if(negflag & 0x10) degree = (90 - degree);
|
||||
|
||||
/*3. Degree is now 0-90 range for this quadrant,*/
|
||||
/*need to invert it for whichever quadrant it was in*/
|
||||
if(negflag & 0x02) { /*if -Y*/
|
||||
if(negflag & 0x01) /*if -Y -X*/
|
||||
degree = (180 + degree);
|
||||
else /*else is -Y +X*/
|
||||
degree = (180 - degree);
|
||||
} else { /*else is +Y*/
|
||||
if(negflag & 0x01) /*if +Y -X*/
|
||||
degree = (360 - degree);
|
||||
}
|
||||
return degree;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
+101
-25
@@ -252,6 +252,7 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p, const lv
|
||||
bool g_ret = lv_font_get_glyph_dsc(font_p, &g, letter, '\0');
|
||||
if(g_ret == false) return;
|
||||
|
||||
|
||||
lv_coord_t pos_x = pos_p->x + g.ofs_x;
|
||||
lv_coord_t pos_y = pos_p->y + (font_p->line_height - font_p->base_line) - g.box_h - g.ofs_y;
|
||||
|
||||
@@ -259,6 +260,9 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p, const lv
|
||||
uint8_t bitmask_init;
|
||||
uint8_t bitmask;
|
||||
|
||||
/*bpp = 3 should be converted to bpp = 4 in lv_font_get_glyph_bitmap */
|
||||
if(g.bpp == 3) g.bpp = 4;
|
||||
|
||||
switch(g.bpp) {
|
||||
case 1:
|
||||
bpp_opa_table = bpp1_opa_table;
|
||||
@@ -297,17 +301,32 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p, const lv
|
||||
if(g.box_w & 0x7) width_byte_scr++;
|
||||
uint16_t width_bit = g.box_w * g.bpp; /*Letter width in bits*/
|
||||
|
||||
bool subpx = font_p->subpx == LV_FONT_SUBPX_NONE ? false : true;
|
||||
|
||||
/* Calculate the col/row start/end on the map*/
|
||||
lv_coord_t col_start = pos_x >= mask_p->x1 ? 0 : mask_p->x1 - pos_x;
|
||||
lv_coord_t col_end = pos_x + g.box_w <= mask_p->x2 ? g.box_w : mask_p->x2 - pos_x + 1;
|
||||
lv_coord_t row_start = pos_y >= mask_p->y1 ? 0 : mask_p->y1 - pos_y;
|
||||
lv_coord_t row_end = pos_y + g.box_h <= mask_p->y2 ? g.box_h : mask_p->y2 - pos_y + 1;
|
||||
lv_coord_t col_start;
|
||||
lv_coord_t col_end;
|
||||
lv_coord_t row_start;
|
||||
lv_coord_t row_end;
|
||||
|
||||
if(subpx == false) {
|
||||
col_start = pos_x >= mask_p->x1 ? 0 : mask_p->x1 - pos_x;
|
||||
col_end = pos_x + g.box_w <= mask_p->x2 ? g.box_w : mask_p->x2 - pos_x + 1;
|
||||
row_start = pos_y >= mask_p->y1 ? 0 : mask_p->y1 - pos_y;
|
||||
row_end = pos_y + g.box_h <= mask_p->y2 ? g.box_h : mask_p->y2 - pos_y + 1;
|
||||
} else {
|
||||
col_start = pos_x >= mask_p->x1 ? 0 : (mask_p->x1 - pos_x) * 3;
|
||||
col_end = pos_x + g.box_w / 3 <= mask_p->x2 ? g.box_w : (mask_p->x2 - pos_x + 1) * 3;
|
||||
row_start = pos_y >= mask_p->y1 ? 0 : mask_p->y1 - pos_y;
|
||||
row_end = pos_y + g.box_h <= mask_p->y2 ? g.box_h : mask_p->y2 - pos_y + 1;
|
||||
}
|
||||
|
||||
/*Set a pointer on VDB to the first pixel of the letter*/
|
||||
vdb_buf_tmp += ((pos_y - vdb->area.y1) * vdb_width) + pos_x - vdb->area.x1;
|
||||
|
||||
/*If the letter is partially out of mask the move there on VDB*/
|
||||
vdb_buf_tmp += (row_start * vdb_width) + col_start;
|
||||
if(subpx) vdb_buf_tmp += (row_start * vdb_width) + col_start / 3;
|
||||
else vdb_buf_tmp += (row_start * vdb_width) + col_start;
|
||||
|
||||
/*Move on the map too*/
|
||||
uint32_t bit_ofs = (row_start * width_bit) + (col_start * g.bpp);
|
||||
@@ -323,37 +342,90 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p, const lv
|
||||
scr_transp = disp->driver.screen_transp;
|
||||
#endif
|
||||
|
||||
uint8_t font_rgb[3];
|
||||
uint8_t txt_rgb[3] = {LV_COLOR_GET_R(color), LV_COLOR_GET_G(color), LV_COLOR_GET_B(color)};
|
||||
|
||||
for(row = row_start; row < row_end; row++) {
|
||||
bitmask = bitmask_init >> col_bit;
|
||||
uint8_t sub_px_cnt = 0;
|
||||
for(col = col_start; col < col_end; col++) {
|
||||
letter_px = (*map_p & bitmask) >> (8 - col_bit - g.bpp);
|
||||
if(letter_px != 0) {
|
||||
if(opa == LV_OPA_COVER) {
|
||||
px_opa = g.bpp == 8 ? letter_px : bpp_opa_table[letter_px];
|
||||
} else {
|
||||
px_opa = g.bpp == 8 ? (uint16_t)((uint16_t)letter_px * opa) >> 8
|
||||
: (uint16_t)((uint16_t)bpp_opa_table[letter_px] * opa) >> 8;
|
||||
}
|
||||
|
||||
if(disp->driver.set_px_cb) {
|
||||
disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width,
|
||||
(col + pos_x) - vdb->area.x1, (row + pos_y) - vdb->area.y1, color, px_opa);
|
||||
} else if(vdb_buf_tmp->full != color.full) {
|
||||
if(px_opa > LV_OPA_MAX)
|
||||
*vdb_buf_tmp = color;
|
||||
else if(px_opa > LV_OPA_MIN) {
|
||||
if(scr_transp == false) {
|
||||
*vdb_buf_tmp = lv_color_mix(color, *vdb_buf_tmp, px_opa);
|
||||
} else {
|
||||
/*subpx == 0*/
|
||||
if(subpx == false) {
|
||||
if(letter_px != 0) {
|
||||
if(opa == LV_OPA_COVER) {
|
||||
px_opa = g.bpp == 8 ? letter_px : bpp_opa_table[letter_px];
|
||||
} else {
|
||||
px_opa = g.bpp == 8 ? (uint16_t)((uint16_t)letter_px * opa) >> 8
|
||||
: (uint16_t)((uint16_t)bpp_opa_table[letter_px] * opa) >> 8;
|
||||
}
|
||||
|
||||
if(disp->driver.set_px_cb) {
|
||||
disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width,
|
||||
(col + pos_x) - vdb->area.x1, (row + pos_y) - vdb->area.y1, color, px_opa);
|
||||
} else if(vdb_buf_tmp->full != color.full) {
|
||||
if(px_opa > LV_OPA_MAX) {
|
||||
*vdb_buf_tmp = color;
|
||||
} else if(px_opa > LV_OPA_MIN) {
|
||||
if(scr_transp == false) {
|
||||
*vdb_buf_tmp = lv_color_mix(color, *vdb_buf_tmp, px_opa);
|
||||
} else {
|
||||
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
|
||||
*vdb_buf_tmp = color_mix_2_alpha(*vdb_buf_tmp, (*vdb_buf_tmp).ch.alpha, color, px_opa);
|
||||
*vdb_buf_tmp = color_mix_2_alpha(*vdb_buf_tmp, (*vdb_buf_tmp).ch.alpha, color, px_opa);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
vdb_buf_tmp++;
|
||||
}
|
||||
/*Handle subpx drawing*/
|
||||
else {
|
||||
if(letter_px != 0) {
|
||||
if(opa == LV_OPA_COVER) {
|
||||
px_opa = g.bpp == 8 ? letter_px : bpp_opa_table[letter_px];
|
||||
} else {
|
||||
px_opa = g.bpp == 8 ? (uint16_t)((uint16_t)letter_px * opa) >> 8
|
||||
: (uint16_t)((uint16_t)bpp_opa_table[letter_px] * opa) >> 8;
|
||||
}
|
||||
|
||||
font_rgb[sub_px_cnt] = px_opa;
|
||||
} else {
|
||||
font_rgb[sub_px_cnt] = 0;
|
||||
}
|
||||
sub_px_cnt ++;
|
||||
|
||||
if(sub_px_cnt == 3) {
|
||||
lv_color_t res_color;
|
||||
|
||||
if(font_rgb[0] == 0 && font_rgb[1] == 0 && font_rgb[2] == 0) {
|
||||
res_color = *vdb_buf_tmp;
|
||||
} else {
|
||||
|
||||
uint8_t bg_rgb[3] = {LV_COLOR_GET_R(*vdb_buf_tmp), LV_COLOR_GET_G(*vdb_buf_tmp), LV_COLOR_GET_B(*vdb_buf_tmp)};
|
||||
|
||||
#if LV_FONT_SUBPX_BGR
|
||||
LV_COLOR_SET_B(res_color, (uint16_t)((uint16_t)txt_rgb[0] * font_rgb[0] + (bg_rgb[2] * (255 - font_rgb[0]))) >> 8);
|
||||
LV_COLOR_SET_R(res_color, (uint16_t)((uint16_t)txt_rgb[2] * font_rgb[2] + (bg_rgb[0] * (255 - font_rgb[2]))) >> 8);
|
||||
#else
|
||||
LV_COLOR_SET_R(res_color, (uint16_t)((uint16_t)txt_rgb[0] * font_rgb[0] + (bg_rgb[0] * (255 - font_rgb[0]))) >> 8);
|
||||
LV_COLOR_SET_B(res_color, (uint16_t)((uint16_t)txt_rgb[2] * font_rgb[2] + (bg_rgb[2] * (255 - font_rgb[2]))) >> 8);
|
||||
#endif
|
||||
LV_COLOR_SET_G(res_color, (uint16_t)((uint16_t)txt_rgb[1] * font_rgb[1] + (bg_rgb[1] * (255 - font_rgb[1]))) >> 8);
|
||||
}
|
||||
if(scr_transp == false) {
|
||||
vdb_buf_tmp->full = res_color.full;
|
||||
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
|
||||
} else {
|
||||
*vdb_buf_tmp = color_mix_2_alpha(*vdb_buf_tmp, (*vdb_buf_tmp).ch.alpha, color, px_opa);
|
||||
#endif
|
||||
}
|
||||
sub_px_cnt = 0;
|
||||
vdb_buf_tmp++;
|
||||
}
|
||||
}
|
||||
|
||||
vdb_buf_tmp++;
|
||||
|
||||
if(col_bit < 8 - g.bpp) {
|
||||
col_bit += g.bpp;
|
||||
@@ -364,11 +436,15 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p, const lv
|
||||
map_p++;
|
||||
}
|
||||
}
|
||||
|
||||
col_bit += ((g.box_w - col_end) + col_start) * g.bpp;
|
||||
|
||||
map_p += (col_bit >> 3);
|
||||
col_bit = col_bit & 0x7;
|
||||
vdb_buf_tmp += vdb_width - (col_end - col_start); /*Next row in VDB*/
|
||||
|
||||
/*Next row in VDB*/
|
||||
if(subpx) vdb_buf_tmp += vdb_width - (col_end - col_start) / 3;
|
||||
else vdb_buf_tmp += vdb_width - (col_end - col_start);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "lv_draw_img.h"
|
||||
#include "lv_img_cache.h"
|
||||
#include "../lv_misc/lv_log.h"
|
||||
#include "../lv_misc/lv_mem.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -50,7 +51,7 @@ void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void *
|
||||
if(src == NULL) {
|
||||
LV_LOG_WARN("Image draw: src is NULL");
|
||||
lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER);
|
||||
lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL, -1, -1, NULL);
|
||||
lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL, NULL, NULL, LV_BIDI_DIR_LTR);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -60,7 +61,7 @@ void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void *
|
||||
if(res == LV_RES_INV) {
|
||||
LV_LOG_WARN("Image draw error");
|
||||
lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER);
|
||||
lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL, -1, -1, NULL);
|
||||
lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, "No\ndata", LV_TXT_FLAG_NONE, NULL, NULL, NULL, LV_BIDI_DIR_LTR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -401,10 +402,14 @@ bool lv_img_color_format_is_chroma_keyed(lv_img_cf_t cf)
|
||||
switch(cf) {
|
||||
case LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED:
|
||||
case LV_IMG_CF_RAW_CHROMA_KEYED:
|
||||
#if LV_INDEXED_CHROMA
|
||||
case LV_IMG_CF_INDEXED_1BIT:
|
||||
case LV_IMG_CF_INDEXED_2BIT:
|
||||
case LV_IMG_CF_INDEXED_4BIT:
|
||||
case LV_IMG_CF_INDEXED_8BIT: is_chroma_keyed = true; break;
|
||||
case LV_IMG_CF_INDEXED_8BIT:
|
||||
#endif
|
||||
is_chroma_keyed = true; break;
|
||||
|
||||
default: is_chroma_keyed = false; break;
|
||||
}
|
||||
|
||||
@@ -423,6 +428,10 @@ bool lv_img_color_format_has_alpha(lv_img_cf_t cf)
|
||||
switch(cf) {
|
||||
case LV_IMG_CF_TRUE_COLOR_ALPHA:
|
||||
case LV_IMG_CF_RAW_ALPHA:
|
||||
case LV_IMG_CF_INDEXED_1BIT:
|
||||
case LV_IMG_CF_INDEXED_2BIT:
|
||||
case LV_IMG_CF_INDEXED_4BIT:
|
||||
case LV_IMG_CF_INDEXED_8BIT:
|
||||
case LV_IMG_CF_ALPHA_1BIT:
|
||||
case LV_IMG_CF_ALPHA_2BIT:
|
||||
case LV_IMG_CF_ALPHA_4BIT:
|
||||
@@ -464,6 +473,66 @@ lv_img_src_t lv_img_src_get_type(const void * src)
|
||||
return img_src_type;
|
||||
}
|
||||
|
||||
lv_img_dsc_t *lv_img_buf_alloc(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf)
|
||||
{
|
||||
/* Allocate image descriptor */
|
||||
lv_img_dsc_t *dsc = lv_mem_alloc(sizeof(lv_img_dsc_t));
|
||||
if(dsc == NULL)
|
||||
return NULL;
|
||||
|
||||
memset(dsc, 0, sizeof(lv_img_dsc_t));
|
||||
|
||||
/* Get image data size */
|
||||
dsc->data_size = lv_img_buf_get_img_size(w, h, cf);
|
||||
if(dsc->data_size == 0) {
|
||||
lv_mem_free(dsc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate raw buffer */
|
||||
dsc->data = lv_mem_alloc(dsc->data_size);
|
||||
if(dsc->data == NULL) {
|
||||
lv_mem_free(dsc);
|
||||
return NULL;
|
||||
}
|
||||
memset((uint8_t *)dsc->data, 0, dsc->data_size);
|
||||
|
||||
/* Fill in header */
|
||||
dsc->header.always_zero = 0;
|
||||
dsc->header.w = w;
|
||||
dsc->header.h = h;
|
||||
dsc->header.cf = cf;
|
||||
return dsc;
|
||||
}
|
||||
|
||||
void lv_img_buf_free(lv_img_dsc_t *dsc)
|
||||
{
|
||||
if(dsc != NULL) {
|
||||
if(dsc->data != NULL)
|
||||
lv_mem_free(dsc->data);
|
||||
|
||||
lv_mem_free(dsc);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t lv_img_buf_get_img_size(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf)
|
||||
{
|
||||
switch(cf) {
|
||||
case LV_IMG_CF_TRUE_COLOR: return LV_IMG_BUF_SIZE_TRUE_COLOR(w, h);
|
||||
case LV_IMG_CF_TRUE_COLOR_ALPHA: return LV_IMG_BUF_SIZE_TRUE_COLOR_ALPHA(w, h);
|
||||
case LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED: return LV_IMG_BUF_SIZE_TRUE_COLOR_CHROMA_KEYED(w, h);
|
||||
case LV_IMG_CF_ALPHA_1BIT: return LV_IMG_BUF_SIZE_ALPHA_1BIT(w, h);
|
||||
case LV_IMG_CF_ALPHA_2BIT: return LV_IMG_BUF_SIZE_ALPHA_2BIT(w, h);
|
||||
case LV_IMG_CF_ALPHA_4BIT: return LV_IMG_BUF_SIZE_ALPHA_4BIT(w, h);
|
||||
case LV_IMG_CF_ALPHA_8BIT: return LV_IMG_BUF_SIZE_ALPHA_8BIT(w, h);
|
||||
case LV_IMG_CF_INDEXED_1BIT: return LV_IMG_BUF_SIZE_INDEXED_1BIT(w, h);
|
||||
case LV_IMG_CF_INDEXED_2BIT: return LV_IMG_BUF_SIZE_INDEXED_2BIT(w, h);
|
||||
case LV_IMG_CF_INDEXED_4BIT: return LV_IMG_BUF_SIZE_INDEXED_4BIT(w, h);
|
||||
case LV_IMG_CF_INDEXED_8BIT: return LV_IMG_BUF_SIZE_INDEXED_8BIT(w, h);
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
@@ -493,8 +562,7 @@ static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mas
|
||||
if(cdsc->dec_dsc.error_msg != NULL) {
|
||||
LV_LOG_WARN("Image draw error");
|
||||
lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER);
|
||||
lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, cdsc->dec_dsc.error_msg, LV_TXT_FLAG_NONE, NULL, -1,
|
||||
-1, NULL);
|
||||
lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, cdsc->dec_dsc.error_msg, LV_TXT_FLAG_NONE, NULL, NULL, NULL, LV_BIDI_DIR_LTR);
|
||||
}
|
||||
/* The decoder open could open the image and gave the entire uncompressed image.
|
||||
* Just draw it!*/
|
||||
@@ -506,7 +574,7 @@ static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mas
|
||||
else {
|
||||
lv_coord_t width = lv_area_get_width(&mask_com);
|
||||
|
||||
uint8_t * buf = lv_draw_get_buf(lv_area_get_width(&mask_com) * ((LV_COLOR_DEPTH >> 3) + 1)); /*+1 because of the possible alpha byte*/
|
||||
uint8_t * buf = lv_draw_get_buf(lv_area_get_width(&mask_com) * LV_IMG_PX_SIZE_ALPHA_BYTE); /*space for the possible alpha byte*/
|
||||
|
||||
lv_area_t line;
|
||||
lv_area_copy(&line, &mask_com);
|
||||
|
||||
@@ -20,6 +20,26 @@ extern "C" {
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#define LV_IMG_BUF_SIZE_TRUE_COLOR(w, h) ((LV_COLOR_SIZE / 8) * w * h)
|
||||
#define LV_IMG_BUF_SIZE_TRUE_COLOR_CHROMA_KEYED(w, h) ((LV_COLOR_SIZE / 8) * w * h)
|
||||
#define LV_IMG_BUF_SIZE_TRUE_COLOR_ALPHA(w, h) (LV_IMG_PX_SIZE_ALPHA_BYTE * w * h)
|
||||
|
||||
/*+ 1: to be sure no fractional row*/
|
||||
#define LV_IMG_BUF_SIZE_ALPHA_1BIT(w, h) ((((w / 8) + 1) * h))
|
||||
#define LV_IMG_BUF_SIZE_ALPHA_2BIT(w, h) ((((w / 4) + 1) * h))
|
||||
#define LV_IMG_BUF_SIZE_ALPHA_4BIT(w, h) ((((w / 2) + 1) * h))
|
||||
#define LV_IMG_BUF_SIZE_ALPHA_8BIT(w, h) ((w * h))
|
||||
|
||||
/*4 * X: for palette*/
|
||||
#define LV_IMG_BUF_SIZE_INDEXED_1BIT(w, h) (LV_IMG_BUF_SIZE_ALPHA_1BIT(w, h) + 4 * 2)
|
||||
#define LV_IMG_BUF_SIZE_INDEXED_2BIT(w, h) (LV_IMG_BUF_SIZE_ALPHA_2BIT(w, h) + 4 * 4)
|
||||
#define LV_IMG_BUF_SIZE_INDEXED_4BIT(w, h) (LV_IMG_BUF_SIZE_ALPHA_4BIT(w, h) + 4 * 16)
|
||||
#define LV_IMG_BUF_SIZE_INDEXED_8BIT(w, h) (LV_IMG_BUF_SIZE_ALPHA_8BIT(w, h) + 4 * 256)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
@@ -120,9 +140,30 @@ bool lv_img_color_format_is_chroma_keyed(lv_img_cf_t cf);
|
||||
*/
|
||||
bool lv_img_color_format_has_alpha(lv_img_cf_t cf);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
/**
|
||||
* Allocate an image buffer in RAM
|
||||
* @param w width of image
|
||||
* @param h height of image
|
||||
* @param cf a color format (`LV_IMG_CF_...`)
|
||||
* @return an allocated image, or NULL on failure
|
||||
*/
|
||||
lv_img_dsc_t *lv_img_buf_alloc(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf);
|
||||
|
||||
/**
|
||||
* Free an allocated image buffer
|
||||
* @param dsc image buffer to free
|
||||
*/
|
||||
void lv_img_buf_free(lv_img_dsc_t *dsc);
|
||||
|
||||
/**
|
||||
* Get the memory consumption of a raw bitmap, given color format and dimensions.
|
||||
* @param w width
|
||||
* @param h height
|
||||
* @param cf color format
|
||||
* @return size in bytes
|
||||
*/
|
||||
uint32_t lv_img_buf_get_img_size(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
+57
-22
@@ -8,6 +8,7 @@
|
||||
*********************/
|
||||
#include "lv_draw_label.h"
|
||||
#include "../lv_misc/lv_math.h"
|
||||
#include "../lv_misc/lv_bidi.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -51,15 +52,18 @@ static uint8_t hex_char_to_num(char hex);
|
||||
* @param txt 0 terminated text to write
|
||||
* @param flag settings for the text from 'txt_flag_t' enum
|
||||
* @param offset text offset in x and y direction (NULL if unused)
|
||||
* @param sel_start start index of selected area (`LV_LABEL_TXT_SEL_OFF` if none)
|
||||
* @param sel_end end index of selected area (`LV_LABEL_TXT_SEL_OFF` if none)
|
||||
* @param sel make the text selected in the range by drawing a background there
|
||||
*/
|
||||
void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale,
|
||||
const char * txt, lv_txt_flag_t flag, lv_point_t * offset, uint16_t sel_start, uint16_t sel_end,
|
||||
lv_draw_label_hint_t * hint)
|
||||
const char * txt, lv_txt_flag_t flag, lv_point_t * offset, lv_draw_label_txt_sel_t * sel,
|
||||
lv_draw_label_hint_t * hint, lv_bidi_dir_t bidi_dir)
|
||||
{
|
||||
const lv_font_t * font = style->text.font;
|
||||
lv_coord_t w;
|
||||
|
||||
/*No need to waste processor time if string is empty*/
|
||||
if (txt[0] == '\0') return;
|
||||
|
||||
if((flag & LV_TXT_FLAG_EXPAND) == 0) {
|
||||
/*Normally use the label's width as width*/
|
||||
w = lv_area_get_width(coords);
|
||||
@@ -67,7 +71,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
|
||||
/*If EXAPND is enabled then not limit the text's width to the object's width*/
|
||||
lv_point_t p;
|
||||
lv_txt_get_size(&p, txt, style->text.font, style->text.letter_space, style->text.line_space, LV_COORD_MAX,
|
||||
flag);
|
||||
flag);
|
||||
w = p.x;
|
||||
}
|
||||
|
||||
@@ -105,6 +109,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
|
||||
pos.y += hint->y;
|
||||
}
|
||||
|
||||
|
||||
uint32_t line_end = line_start + lv_txt_get_next_line(&txt[line_start], font, style->text.letter_space, w, flag);
|
||||
|
||||
/*Go the first visible line*/
|
||||
@@ -139,6 +144,18 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
|
||||
|
||||
lv_opa_t opa = opa_scale == LV_OPA_COVER ? style->text.opa : (uint16_t)((uint16_t)style->text.opa * opa_scale) >> 8;
|
||||
|
||||
uint16_t sel_start = 0xFFFF;
|
||||
uint16_t sel_end = 0xFFFF;
|
||||
if(sel) {
|
||||
sel_start = sel->start;
|
||||
sel_end = sel->end;
|
||||
if(sel_start > sel_end) {
|
||||
uint16_t tmp = sel_start;
|
||||
sel_start = sel_end;
|
||||
sel_end = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
cmd_state_t cmd_state = CMD_STATE_WAIT;
|
||||
uint32_t i;
|
||||
uint16_t par_start = 0;
|
||||
@@ -155,12 +172,31 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
|
||||
}
|
||||
/*Write all letter of a line*/
|
||||
cmd_state = CMD_STATE_WAIT;
|
||||
i = line_start;
|
||||
i = 0;
|
||||
uint32_t letter;
|
||||
uint32_t letter_next;
|
||||
while(i < line_end) {
|
||||
letter = lv_txt_encoded_next(txt, &i);
|
||||
letter_next = lv_txt_encoded_next(&txt[i], NULL);
|
||||
#if LV_USE_BIDI
|
||||
char *bidi_txt = lv_draw_get_buf(line_end - line_start + 1);
|
||||
lv_bidi_process_paragraph(txt + line_start, bidi_txt, line_end - line_start, bidi_dir, NULL, 0);
|
||||
#else
|
||||
const char *bidi_txt = txt + line_start;
|
||||
#endif
|
||||
|
||||
while(i < line_end - line_start) {
|
||||
uint16_t logical_char_pos = 0;
|
||||
if(sel_start != 0xFFFF && sel_end != 0xFFFF) {
|
||||
#if LV_USE_BIDI
|
||||
logical_char_pos = lv_txt_encoded_get_char_id(txt, line_start);
|
||||
uint16_t t = lv_txt_encoded_get_char_id(bidi_txt, i);
|
||||
logical_char_pos += lv_bidi_get_logical_pos(bidi_txt, NULL, line_end - line_start, bidi_dir, t, NULL);
|
||||
#else
|
||||
logical_char_pos = lv_txt_encoded_get_char_id(txt, line_start + i);
|
||||
#endif
|
||||
}
|
||||
|
||||
letter = lv_txt_encoded_next(bidi_txt, &i);
|
||||
letter_next = lv_txt_encoded_next(&bidi_txt[i], NULL);
|
||||
|
||||
|
||||
/*Handle the re-color command*/
|
||||
if((flag & LV_TXT_FLAG_RECOLOR) != 0) {
|
||||
@@ -183,7 +219,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
|
||||
/*Get the parameter*/
|
||||
if(i - par_start == LABEL_RECOLOR_PAR_LENGTH + 1) {
|
||||
char buf[LABEL_RECOLOR_PAR_LENGTH + 1];
|
||||
memcpy(buf, &txt[par_start], LABEL_RECOLOR_PAR_LENGTH);
|
||||
memcpy(buf, &bidi_txt[par_start], LABEL_RECOLOR_PAR_LENGTH);
|
||||
buf[LABEL_RECOLOR_PAR_LENGTH] = '\0';
|
||||
int r, g, b;
|
||||
r = (hex_char_to_num(buf[0]) << 4) + hex_char_to_num(buf[1]);
|
||||
@@ -206,9 +242,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
|
||||
letter_w = lv_font_get_glyph_width(font, letter, letter_next);
|
||||
|
||||
if(sel_start != 0xFFFF && sel_end != 0xFFFF) {
|
||||
int char_ind = lv_encoded_get_char_id(txt, i);
|
||||
/*Do not draw the rectangle on the character at `sel_start`.*/
|
||||
if(char_ind > sel_start && char_ind <= sel_end) {
|
||||
if(logical_char_pos >= sel_start && logical_char_pos < sel_end) {
|
||||
lv_area_t sel_coords;
|
||||
sel_coords.x1 = pos.x;
|
||||
sel_coords.y1 = pos.y;
|
||||
@@ -217,6 +251,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
|
||||
lv_draw_rect(&sel_coords, mask, &sel_style, opa);
|
||||
}
|
||||
}
|
||||
|
||||
lv_draw_letter(&pos, mask, font, letter, color, opa);
|
||||
|
||||
if(letter_w > 0) {
|
||||
@@ -231,7 +266,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
|
||||
/*Align to middle*/
|
||||
if(flag & LV_TXT_FLAG_CENTER) {
|
||||
line_width =
|
||||
lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag);
|
||||
lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag);
|
||||
|
||||
pos.x += (lv_area_get_width(coords) - line_width) / 2;
|
||||
|
||||
@@ -239,7 +274,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
|
||||
/*Align to the right*/
|
||||
else if(flag & LV_TXT_FLAG_RIGHT) {
|
||||
line_width =
|
||||
lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag);
|
||||
lv_txt_get_width(&txt[line_start], line_end - line_start, font, style->text.letter_space, flag);
|
||||
pos.x += lv_area_get_width(coords) - line_width;
|
||||
}
|
||||
|
||||
@@ -269,13 +304,13 @@ static uint8_t hex_char_to_num(char hex)
|
||||
if(hex >= 'a') hex -= 'a' - 'A'; /*Convert to upper case*/
|
||||
|
||||
switch(hex) {
|
||||
case 'A': result = 10; break;
|
||||
case 'B': result = 11; break;
|
||||
case 'C': result = 12; break;
|
||||
case 'D': result = 13; break;
|
||||
case 'E': result = 14; break;
|
||||
case 'F': result = 15; break;
|
||||
default: result = 0; break;
|
||||
case 'A': result = 10; break;
|
||||
case 'B': result = 11; break;
|
||||
case 'C': result = 12; break;
|
||||
case 'D': result = 13; break;
|
||||
case 'E': result = 14; break;
|
||||
case 'F': result = 15; break;
|
||||
default: result = 0; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,15 +14,24 @@ extern "C" {
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw.h"
|
||||
#include "../lv_misc/lv_bidi.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_DRAW_LABEL_NO_TXT_SEL (0xFFFF)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t start;
|
||||
uint16_t end;
|
||||
}lv_draw_label_txt_sel_t;
|
||||
|
||||
|
||||
/** Store some info to speed up drawing of very large texts
|
||||
* It takes a lot of time to get the first visible character because
|
||||
* all the previous characters needs to be checked to calculate the positions.
|
||||
@@ -54,11 +63,11 @@ typedef struct {
|
||||
* @param flag settings for the text from 'txt_flag_t' enum
|
||||
* @param offset text offset in x and y direction (NULL if unused)
|
||||
* @param sel_start start index of selected area (`LV_LABEL_TXT_SEL_OFF` if none)
|
||||
* @param sel_end end index of selected area (`LV_LABEL_TXT_SEL_OFF` if none)
|
||||
* @param bidi_dir base direction of the text
|
||||
*/
|
||||
void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale,
|
||||
const char * txt, lv_txt_flag_t flag, lv_point_t * offset, uint16_t sel_start, uint16_t sel_end,
|
||||
lv_draw_label_hint_t * hint);
|
||||
const char * txt, lv_txt_flag_t flag, lv_point_t * offset, lv_draw_label_txt_sel_t * sel,
|
||||
lv_draw_label_hint_t * hint, lv_bidi_dir_t bidi_dir);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
||||
@@ -45,8 +45,7 @@ static void point_swap(lv_point_t * p1, lv_point_t * p2);
|
||||
*/
|
||||
void lv_draw_triangle(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale)
|
||||
{
|
||||
|
||||
/*Return is the triangle is degenerated*/
|
||||
/*Return if the triangle is degenerated*/
|
||||
if(points[0].x == points[1].x && points[0].y == points[1].y) return;
|
||||
if(points[1].x == points[2].x && points[1].y == points[2].y) return;
|
||||
if(points[0].x == points[2].x && points[0].y == points[2].y) return;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "lv_img_cache.h"
|
||||
#include "lv_img_decoder.h"
|
||||
#include "lv_draw_img.h"
|
||||
@@ -162,7 +163,7 @@ void lv_img_cache_set_size(uint16_t new_entry_cnt)
|
||||
|
||||
/*Reallocate the cache*/
|
||||
LV_GC_ROOT(_lv_img_cache_array) = lv_mem_alloc(sizeof(lv_img_cache_entry_t) * new_entry_cnt);
|
||||
lv_mem_assert(LV_GC_ROOT(_lv_img_cache_array));
|
||||
LV_ASSERT_MEM(LV_GC_ROOT(_lv_img_cache_array));
|
||||
if(LV_GC_ROOT(_lv_img_cache_array) == NULL) {
|
||||
entry_cnt = 0;
|
||||
return;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_img_decoder.h"
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "../lv_draw/lv_draw_img.h"
|
||||
#include "../lv_misc/lv_ll.h"
|
||||
#include "../lv_misc/lv_color.h"
|
||||
@@ -31,6 +32,7 @@ typedef struct
|
||||
lv_fs_file_t * f;
|
||||
#endif
|
||||
lv_color_t * palette;
|
||||
lv_opa_t * opa;
|
||||
} lv_img_decoder_built_in_data_t;
|
||||
|
||||
/**********************
|
||||
@@ -68,7 +70,7 @@ void lv_img_decoder_init(void)
|
||||
decoder = lv_img_decoder_create();
|
||||
if(decoder == NULL) {
|
||||
LV_LOG_WARN("lv_img_decoder_init: out of memory");
|
||||
lv_mem_assert(decoder);
|
||||
LV_ASSERT_MEM(decoder);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -198,7 +200,7 @@ lv_img_decoder_t * lv_img_decoder_create(void)
|
||||
{
|
||||
lv_img_decoder_t * decoder;
|
||||
decoder = lv_ll_ins_head(&LV_GC_ROOT(_lv_img_defoder_ll));
|
||||
lv_mem_assert(decoder);
|
||||
LV_ASSERT_MEM(decoder);
|
||||
if(decoder == NULL) return NULL;
|
||||
|
||||
memset(decoder, 0, sizeof(lv_img_decoder_t));
|
||||
@@ -333,7 +335,7 @@ lv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder
|
||||
dsc->user_data = lv_mem_alloc(sizeof(lv_img_decoder_built_in_data_t));
|
||||
if(dsc->user_data == NULL) {
|
||||
LV_LOG_ERROR("img_decoder_built_in_open: out of memory");
|
||||
lv_mem_assert(dsc->user_data);
|
||||
LV_ASSERT_MEM(dsc->user_data);
|
||||
}
|
||||
memset(dsc->user_data, 0, sizeof(lv_img_decoder_built_in_data_t));
|
||||
}
|
||||
@@ -342,7 +344,7 @@ lv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder
|
||||
user_data->f = lv_mem_alloc(sizeof(f));
|
||||
if(user_data->f == NULL) {
|
||||
LV_LOG_ERROR("img_decoder_built_in_open: out of memory");
|
||||
lv_mem_assert(user_data->f);
|
||||
LV_ASSERT_MEM(user_data->f);
|
||||
}
|
||||
|
||||
memcpy(user_data->f, &f, sizeof(f));
|
||||
@@ -380,17 +382,18 @@ lv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder
|
||||
dsc->user_data = lv_mem_alloc(sizeof(lv_img_decoder_built_in_data_t));
|
||||
if(dsc->user_data == NULL) {
|
||||
LV_LOG_ERROR("img_decoder_built_in_open: out of memory");
|
||||
lv_mem_assert(dsc->user_data);
|
||||
LV_ASSERT_MEM(dsc->user_data);
|
||||
}
|
||||
memset(dsc->user_data, 0, sizeof(lv_img_decoder_built_in_data_t));
|
||||
}
|
||||
|
||||
lv_img_decoder_built_in_data_t * user_data = dsc->user_data;
|
||||
user_data->palette = lv_mem_alloc(palette_size * sizeof(lv_color_t));
|
||||
if(user_data->palette == NULL) {
|
||||
user_data->opa = lv_mem_alloc(palette_size * sizeof(lv_opa_t));
|
||||
if(user_data->palette == NULL || user_data->opa == NULL) {
|
||||
LV_LOG_ERROR("img_decoder_built_in_open: out of memory");
|
||||
#if LV_USE_FILESYSTEM
|
||||
lv_mem_assert(user_data->f);
|
||||
LV_ASSERT_MEM(user_data->f);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -398,7 +401,13 @@ lv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder
|
||||
/*Read the palette from file*/
|
||||
#if LV_USE_FILESYSTEM
|
||||
lv_fs_seek(user_data->f, 4); /*Skip the header*/
|
||||
lv_fs_read(user_data->f, user_data->palette, palette_size * sizeof(lv_color_t), NULL);
|
||||
lv_color32_t cur_color;
|
||||
uint32_t i;
|
||||
for(i = 0; i < palette_size; i++) {
|
||||
lv_fs_read(user_data->f, &cur_color, sizeof(lv_color32_t), NULL);
|
||||
user_data->palette[i] = lv_color_make(cur_color.ch.red, cur_color.ch.green, cur_color.ch.blue);
|
||||
user_data->opa[i] = cur_color.ch.alpha;
|
||||
}
|
||||
#else
|
||||
LV_LOG_WARN("Image built-in decoder can read the palette because LV_USE_FILESYSTEM = 0");
|
||||
return LV_RES_INV;
|
||||
@@ -410,6 +419,7 @@ lv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder
|
||||
uint32_t i;
|
||||
for(i = 0; i < palette_size; i++) {
|
||||
user_data->palette[i] = lv_color_make(palette_p[i].ch.red, palette_p[i].ch.green, palette_p[i].ch.blue);
|
||||
user_data->opa[i] = palette_p[i].ch.alpha;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -711,13 +721,24 @@ static lv_res_t lv_img_decoder_built_in_line_indexed(lv_img_decoder_dsc_t * dsc,
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t byte_act = 0;
|
||||
uint8_t val_act;
|
||||
lv_coord_t i;
|
||||
lv_color_t * cbuf = (lv_color_t *)buf;
|
||||
for(i = 0; i < len; i++) {
|
||||
val_act = (data_tmp[byte_act] & (mask << pos)) >> pos;
|
||||
cbuf[i] = user_data->palette[val_act];
|
||||
val_act = (*data_tmp & (mask << pos)) >> pos;
|
||||
|
||||
lv_color_t color = user_data->palette[val_act];
|
||||
#if LV_COLOR_DEPTH == 8 || LV_COLOR_DEPTH == 1
|
||||
buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE] = color.full;
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
/*Because of Alpha byte 16 bit color can start on odd address which can cause crash*/
|
||||
buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE] = color.full & 0xFF;
|
||||
buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE + 1] = (color.full >> 8) & 0xFF;
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
*((uint32_t *)&buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE]) = color.full;
|
||||
#else
|
||||
#error "Invalid LV_COLOR_DEPTH. Check it in lv_conf.h"
|
||||
#endif
|
||||
buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE + LV_IMG_PX_SIZE_ALPHA_BYTE - 1] = user_data->opa[val_act];
|
||||
|
||||
pos -= px_size;
|
||||
if(pos < 0) {
|
||||
|
||||
+15
-1
@@ -53,7 +53,18 @@ typedef struct
|
||||
uint8_t bpp; /**< Bit-per-pixel: 1, 2, 4, 8*/
|
||||
}lv_font_glyph_dsc_t;
|
||||
|
||||
/*Describe the properties of a font*/
|
||||
|
||||
/** The bitmaps might be upscaled by 3 to achieve subpixel rendering. */
|
||||
enum {
|
||||
LV_FONT_SUBPX_NONE,
|
||||
LV_FONT_SUBPX_HOR,
|
||||
LV_FONT_SUBPX_VER,
|
||||
LV_FONT_SUBPX_BOTH,
|
||||
};
|
||||
|
||||
typedef uint8_t lv_font_subpx_t;
|
||||
|
||||
/** Describe the properties of a font*/
|
||||
typedef struct _lv_font_struct
|
||||
{
|
||||
/** Get a glyph's descriptor from a font*/
|
||||
@@ -65,10 +76,13 @@ typedef struct _lv_font_struct
|
||||
/*Pointer to the font in a font pack (must have the same line height)*/
|
||||
uint8_t line_height; /**< The real line height where any text fits*/
|
||||
uint8_t base_line; /**< Base line measured from the top of the line_height*/
|
||||
uint8_t subpx :2; /**< An element of `lv_font_subpx_t`*/
|
||||
void * dsc; /**< Store implementation specific data here*/
|
||||
#if LV_USE_USER_DATA
|
||||
lv_font_user_data_t user_data; /**< Custom user data for font. */
|
||||
#endif
|
||||
|
||||
|
||||
} lv_font_t;
|
||||
|
||||
/**********************
|
||||
|
||||
@@ -8,9 +8,12 @@
|
||||
*********************/
|
||||
#include "lv_font.h"
|
||||
#include "lv_font_fmt_txt.h"
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "../lv_draw/lv_draw.h"
|
||||
#include "../lv_misc/lv_types.h"
|
||||
#include "../lv_misc/lv_log.h"
|
||||
#include "../lv_misc/lv_utils.h"
|
||||
#include "../lv_misc/lv_mem.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -19,6 +22,11 @@
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef enum {
|
||||
RLE_STATE_SINGLE = 0,
|
||||
RLE_STATE_REPEATE,
|
||||
RLE_STATE_COUNTER,
|
||||
}rle_state_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
@@ -29,10 +37,25 @@ static int32_t unicode_list_compare(const void * ref, const void * element);
|
||||
static int32_t kern_pair_8_compare(const void * ref, const void * element);
|
||||
static int32_t kern_pair_16_compare(const void * ref, const void * element);
|
||||
|
||||
static void decompress(const uint8_t * in, uint8_t * out, lv_coord_t w, lv_coord_t h, uint8_t bpp);
|
||||
static void decompress_line(uint8_t * out, lv_coord_t w);
|
||||
static uint8_t get_bits(const uint8_t * in, uint32_t bit_pos, uint8_t len);
|
||||
static void bits_write(uint8_t * out, uint32_t bit_pos, uint8_t val, uint8_t len);
|
||||
static void rle_init(const uint8_t * in, uint8_t bpp);
|
||||
static uint8_t rle_next(void);
|
||||
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
static uint32_t rle_rdp;
|
||||
static const uint8_t * rle_in;
|
||||
static uint8_t rle_bpp;
|
||||
static uint8_t rle_prev_v;
|
||||
static uint8_t rle_cnt;
|
||||
static rle_state_t rle_state;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
@@ -59,7 +82,34 @@ const uint8_t * lv_font_get_bitmap_fmt_txt(const lv_font_t * font, uint32_t unic
|
||||
|
||||
const lv_font_fmt_txt_glyph_dsc_t * gdsc = &fdsc->glyph_dsc[gid];
|
||||
|
||||
if(gdsc) return &fdsc->glyph_bitmap[gdsc->bitmap_index];
|
||||
if(fdsc->bitmap_format == LV_FONT_FMT_TXT_PLAIN) {
|
||||
if(gdsc) return &fdsc->glyph_bitmap[gdsc->bitmap_index];
|
||||
}
|
||||
/*Handle compressed bitmap*/
|
||||
else
|
||||
{
|
||||
static uint8_t * buf = NULL;
|
||||
|
||||
uint32_t gsize = gdsc->box_w * gdsc->box_h;
|
||||
if(gsize == 0) return NULL;
|
||||
|
||||
uint32_t buf_size = gsize;
|
||||
switch(fdsc->bpp) {
|
||||
case 1: buf_size = gsize >> 3; break;
|
||||
case 2: buf_size = gsize >> 2; break;
|
||||
case 3: buf_size = gsize >> 1; break;
|
||||
case 4: buf_size = gsize >> 1; break;
|
||||
}
|
||||
|
||||
if(lv_mem_get_size(buf) < buf_size) {
|
||||
buf = lv_mem_realloc(buf, buf_size);
|
||||
LV_ASSERT_MEM(buf);
|
||||
if(buf == NULL) return NULL;
|
||||
}
|
||||
|
||||
decompress(&fdsc->glyph_bitmap[gdsc->bitmap_index], buf, gdsc->box_w , gdsc->box_h, fdsc->bpp);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*If not returned earlier then the letter is not found in this font*/
|
||||
return NULL;
|
||||
@@ -90,7 +140,9 @@ bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_glyph_dsc_t *
|
||||
/*Put together a glyph dsc*/
|
||||
const lv_font_fmt_txt_glyph_dsc_t * gdsc = &fdsc->glyph_dsc[gid];
|
||||
|
||||
uint32_t adv_w = gdsc->adv_w + ((int32_t)((int32_t)kvalue * fdsc->kern_scale) >> 4);
|
||||
int32_t kv = ((int32_t)((int32_t)kvalue * fdsc->kern_scale) >> 4);
|
||||
|
||||
uint32_t adv_w = gdsc->adv_w + kv;
|
||||
adv_w = (adv_w + (1 << 3)) >> 4;
|
||||
|
||||
dsc_out->adv_w = adv_w;
|
||||
@@ -238,6 +290,176 @@ static int32_t kern_pair_16_compare(const void * ref, const void * element)
|
||||
else return (int32_t) ref16_p[1] - element16_p[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* The compress a glyph's bitmap
|
||||
* @param in the compressed bitmap
|
||||
* @param out buffer to store the result
|
||||
* @param px_num number of pixels in the glyph (width * height)
|
||||
* @param bpp bit per pixel (bpp = 3 will be converted to bpp = 4)
|
||||
*/
|
||||
static void decompress(const uint8_t * in, uint8_t * out, lv_coord_t w, lv_coord_t h, uint8_t bpp)
|
||||
{
|
||||
uint32_t wrp = 0;
|
||||
uint8_t wr_size = bpp;
|
||||
if(bpp == 3) wr_size = 4;
|
||||
|
||||
rle_init(in, bpp);
|
||||
|
||||
uint8_t * line_buf = lv_draw_get_buf(w * 2);
|
||||
uint8_t * line_buf1 = line_buf;
|
||||
uint8_t * line_buf2 = line_buf + w;
|
||||
|
||||
decompress_line(line_buf1, w);
|
||||
|
||||
lv_coord_t y;
|
||||
lv_coord_t x;
|
||||
for(x = 0; x < w; x++) {
|
||||
bits_write(out,wrp, line_buf1[x], bpp);
|
||||
wrp += wr_size;
|
||||
}
|
||||
|
||||
for(y = 1; y < h; y++) {
|
||||
decompress_line(line_buf2, w);
|
||||
|
||||
for(x = 0; x < w; x++) {
|
||||
line_buf1[x] = line_buf2[x] ^ line_buf1[x];
|
||||
bits_write(out,wrp, line_buf1[x], bpp);
|
||||
wrp += wr_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decompress one line. Store one pixel per byte
|
||||
* @param out output buffer
|
||||
* @param w width of the line in pixel count
|
||||
*/
|
||||
static void decompress_line(uint8_t * out, lv_coord_t w)
|
||||
{
|
||||
lv_coord_t i;
|
||||
for(i = 0; i < w; i++) {
|
||||
out[i] = rle_next();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read bits from an input buffer. The read can cross byte boundary.
|
||||
* @param in the input buffer to read from.
|
||||
* @param bit_pos index of teh first bit to read.
|
||||
* @param len number of bits to read (must be <= 8).
|
||||
* @return the read bits
|
||||
*/
|
||||
static uint8_t get_bits(const uint8_t * in, uint32_t bit_pos, uint8_t len)
|
||||
{
|
||||
uint8_t res = 0;
|
||||
uint32_t byte_pos = bit_pos >> 3;
|
||||
bit_pos = bit_pos & 0x7;
|
||||
uint8_t bit_mask = (uint16_t)((uint16_t) 1 << len) - 1;
|
||||
uint16_t in16 = (in[byte_pos] << 8) + in[byte_pos + 1];
|
||||
|
||||
res = (in16 >> (16 - bit_pos - len)) & bit_mask;
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write `val` data to `bit_pos` position of `out`. The write can NOT cross byte boundary.
|
||||
* @param out buffer where to write
|
||||
* @param bit_pos bit index to write
|
||||
* @param val value to write
|
||||
* @param len length of bits to write from `val`. (Counted from the LSB).
|
||||
* @note `len == 3` will be converted to `len = 4` and `val` will be upscaled too
|
||||
*/
|
||||
static void bits_write(uint8_t * out, uint32_t bit_pos, uint8_t val, uint8_t len)
|
||||
{
|
||||
if(len == 3) {
|
||||
len = 4;
|
||||
switch(val) {
|
||||
case 0: val = 0; break;
|
||||
case 1: val = 2; break;
|
||||
case 2: val = 4; break;
|
||||
case 3: val = 6; break;
|
||||
case 4: val = 9; break;
|
||||
case 5: val = 11; break;
|
||||
case 6: val = 13; break;
|
||||
case 7: val = 15; break;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t byte_pos = bit_pos >> 3;
|
||||
bit_pos = bit_pos & 0x7;
|
||||
bit_pos = 8 - bit_pos - len;
|
||||
|
||||
uint8_t bit_mask = (uint16_t)((uint16_t) 1 << len) - 1;
|
||||
out[byte_pos] &= ((~bit_mask) << bit_pos);
|
||||
out[byte_pos] |= (val << bit_pos);
|
||||
}
|
||||
|
||||
static void rle_init(const uint8_t * in, uint8_t bpp)
|
||||
{
|
||||
rle_in = in;
|
||||
rle_bpp = bpp;
|
||||
rle_state = RLE_STATE_SINGLE;
|
||||
rle_rdp = 0;
|
||||
rle_prev_v = 0;
|
||||
rle_cnt = 0;
|
||||
}
|
||||
|
||||
static uint8_t rle_next(void)
|
||||
{
|
||||
uint8_t v = 0;
|
||||
uint8_t ret = 0;
|
||||
|
||||
if(rle_state == RLE_STATE_SINGLE) {
|
||||
ret = get_bits(rle_in, rle_rdp, rle_bpp);
|
||||
if(rle_rdp != 0 && rle_prev_v == ret) {
|
||||
rle_cnt = 0;
|
||||
rle_state = RLE_STATE_REPEATE;
|
||||
}
|
||||
|
||||
rle_prev_v = ret;
|
||||
rle_rdp += rle_bpp;
|
||||
}
|
||||
else if(rle_state == RLE_STATE_REPEATE) {
|
||||
v = get_bits(rle_in, rle_rdp, 1);
|
||||
rle_cnt++;
|
||||
rle_rdp += 1;
|
||||
if(v == 1) {
|
||||
ret = rle_prev_v;
|
||||
if(rle_cnt == 11) {
|
||||
rle_cnt = get_bits(rle_in, rle_rdp, 6);
|
||||
rle_rdp += 6;
|
||||
if(rle_cnt != 0) {
|
||||
rle_state = RLE_STATE_COUNTER;
|
||||
} else {
|
||||
ret = get_bits(rle_in, rle_rdp, rle_bpp);
|
||||
rle_prev_v = ret;
|
||||
rle_rdp += rle_bpp;
|
||||
rle_state = RLE_STATE_SINGLE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret = get_bits(rle_in, rle_rdp, rle_bpp);
|
||||
rle_prev_v = ret;
|
||||
rle_rdp += rle_bpp;
|
||||
rle_state = RLE_STATE_SINGLE;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else if(rle_state == RLE_STATE_COUNTER) {
|
||||
ret = rle_prev_v;
|
||||
rle_cnt--;
|
||||
if(rle_cnt == 0) {
|
||||
ret = get_bits(rle_in, rle_rdp, rle_bpp);
|
||||
rle_prev_v = ret;
|
||||
rle_rdp += rle_bpp;
|
||||
rle_state = RLE_STATE_SINGLE;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Code Comparator.
|
||||
*
|
||||
* Compares the value of both input arguments.
|
||||
|
||||
@@ -45,7 +45,7 @@ typedef struct
|
||||
uint8_t box_w; /**< Width of the glyph's bounding box*/
|
||||
uint8_t box_h; /**< Height of the glyph's bounding box*/
|
||||
int8_t ofs_x; /**< x offset of the bounding box*/
|
||||
uint8_t ofs_y; /**< y offset of the bounding box. Measured from the top of the line*/
|
||||
int8_t ofs_y; /**< y offset of the bounding box. Measured from the top of the line*/
|
||||
}lv_font_fmt_txt_glyph_dsc_t;
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ typedef struct {
|
||||
3. value = class_pair_values[(left_class-1)*right_class_cnt + (righ_class-1)]
|
||||
*/
|
||||
|
||||
const uint8_t * class_pair_values; /*left_class_num * right_class_num value*/
|
||||
const int8_t * class_pair_values; /*left_class_num * right_class_num value*/
|
||||
const uint8_t * left_class_mapping; /*Map the glyph_ids to classes: index -> glyph_id -> class_id*/
|
||||
const uint8_t * right_class_mapping; /*Map the glyph_ids to classes: index -> glyph_id -> class_id*/
|
||||
uint8_t left_class_cnt;
|
||||
@@ -180,7 +180,7 @@ typedef struct {
|
||||
/*Number of cmap tables*/
|
||||
uint16_t cmap_num :10;
|
||||
|
||||
/*Bit per pixel: 1, 2, 4 or 8*/
|
||||
/*Bit per pixel: 1, 2, 3, 4*/
|
||||
uint16_t bpp :3;
|
||||
|
||||
/*Type of `kern_dsc`*/
|
||||
@@ -191,6 +191,7 @@ typedef struct {
|
||||
* from `lv_font_fmt_txt_bitmap_format_t`
|
||||
*/
|
||||
uint16_t bitmap_format :2;
|
||||
uint16_t subpx :1;
|
||||
|
||||
/*Cache the last letter and is glyph id*/
|
||||
uint32_t last_letter;
|
||||
|
||||
+1251
-1426
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+1738
-1887
File diff suppressed because it is too large
Load Diff
+2874
-2831
File diff suppressed because it is too large
Load Diff
+4083
-3769
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+65
-50
@@ -11,57 +11,72 @@ extern "C" {
|
||||
#include "../../../lv_conf.h"
|
||||
#endif
|
||||
|
||||
/* In the font converter use this list as range:
|
||||
61441, 61448, 61451, 61452, 61452, 61453, 61457, 61459, 61461, 61465,
|
||||
61468, 61473, 61478, 61479, 61480, 61502, 61512, 61515, 61516, 61517,
|
||||
61521, 61522, 61523, 61524, 61543, 61544, 61550, 61552, 61553, 61556,
|
||||
61559, 61560, 61561, 61563, 61587, 61589, 61636, 61637, 61639, 61671,
|
||||
61674, 61683, 61724, 61732, 61787, 61931, 62016, 62017, 62018, 62019,
|
||||
62020, 62087, 62099, 62212, 62189, 62810, 63426, 63650
|
||||
*/
|
||||
|
||||
#define LV_SYMBOL_AUDIO "\xef\x80\x81"
|
||||
#define LV_SYMBOL_VIDEO "\xef\x80\x88"
|
||||
#define LV_SYMBOL_LIST "\xef\x80\x8b"
|
||||
#define LV_SYMBOL_OK "\xef\x80\x8c"
|
||||
#define LV_SYMBOL_CLOSE "\xef\x80\x8d"
|
||||
#define LV_SYMBOL_POWER "\xef\x80\x91"
|
||||
#define LV_SYMBOL_SETTINGS "\xef\x80\x93"
|
||||
#define LV_SYMBOL_TRASH "\xef\x80\x94"
|
||||
#define LV_SYMBOL_HOME "\xef\x80\x95"
|
||||
#define LV_SYMBOL_DOWNLOAD "\xef\x80\x99"
|
||||
#define LV_SYMBOL_DRIVE "\xef\x80\x9c"
|
||||
#define LV_SYMBOL_REFRESH "\xef\x80\xa1"
|
||||
#define LV_SYMBOL_MUTE "\xef\x80\xa6"
|
||||
#define LV_SYMBOL_VOLUME_MID "\xef\x80\xa7"
|
||||
#define LV_SYMBOL_VOLUME_MAX "\xef\x80\xa8"
|
||||
#define LV_SYMBOL_IMAGE "\xef\x80\xbe"
|
||||
#define LV_SYMBOL_EDIT "\xef\x81\x80"
|
||||
#define LV_SYMBOL_PREV "\xef\x81\x88"
|
||||
#define LV_SYMBOL_PLAY "\xef\x81\x8b"
|
||||
#define LV_SYMBOL_PAUSE "\xef\x81\x8c"
|
||||
#define LV_SYMBOL_STOP "\xef\x81\x8d"
|
||||
#define LV_SYMBOL_NEXT "\xef\x81\x91"
|
||||
#define LV_SYMBOL_EJECT "\xef\x81\x92"
|
||||
#define LV_SYMBOL_LEFT "\xef\x81\x93"
|
||||
#define LV_SYMBOL_RIGHT "\xef\x81\x94"
|
||||
#define LV_SYMBOL_PLUS "\xef\x81\xa7"
|
||||
#define LV_SYMBOL_MINUS "\xef\x81\xa8"
|
||||
#define LV_SYMBOL_WARNING "\xef\x81\xb1"
|
||||
#define LV_SYMBOL_SHUFFLE "\xef\x81\xb4"
|
||||
#define LV_SYMBOL_UP "\xef\x81\xb7"
|
||||
#define LV_SYMBOL_DOWN "\xef\x81\xb8"
|
||||
#define LV_SYMBOL_LOOP "\xef\x81\xb9"
|
||||
#define LV_SYMBOL_DIRECTORY "\xef\x81\xbb"
|
||||
#define LV_SYMBOL_UPLOAD "\xef\x82\x93"
|
||||
#define LV_SYMBOL_CALL "\xef\x82\x95"
|
||||
#define LV_SYMBOL_CUT "\xef\x83\x84"
|
||||
#define LV_SYMBOL_COPY "\xef\x83\x85"
|
||||
#define LV_SYMBOL_SAVE "\xef\x83\x87"
|
||||
#define LV_SYMBOL_CHARGE "\xef\x83\xa7"
|
||||
#define LV_SYMBOL_BELL "\xef\x83\xb3"
|
||||
#define LV_SYMBOL_KEYBOARD "\xef\x84\x9c"
|
||||
#define LV_SYMBOL_GPS "\xef\x84\xa4"
|
||||
#define LV_SYMBOL_FILE "\xef\x85\x9b"
|
||||
#define LV_SYMBOL_WIFI "\xef\x87\xab"
|
||||
#define LV_SYMBOL_BATTERY_FULL "\xef\x89\x80"
|
||||
#define LV_SYMBOL_BATTERY_3 "\xef\x89\x81"
|
||||
#define LV_SYMBOL_BATTERY_2 "\xef\x89\x82"
|
||||
#define LV_SYMBOL_BATTERY_1 "\xef\x89\x83"
|
||||
#define LV_SYMBOL_BATTERY_EMPTY "\xef\x89\x84"
|
||||
#define LV_SYMBOL_BLUETOOTH "\xef\x8a\x93"
|
||||
#define LV_SYMBOL_AUDIO "\xef\x80\x81" /*61441, 0xF001*/
|
||||
#define LV_SYMBOL_VIDEO "\xef\x80\x88" /*61448, 0xF008*/
|
||||
#define LV_SYMBOL_LIST "\xef\x80\x8b" /*61451, 0xF00B*/
|
||||
#define LV_SYMBOL_OK "\xef\x80\x8c" /*61452, 0xF00C*/
|
||||
#define LV_SYMBOL_CLOSE "\xef\x80\x8d" /*61453, 0xF00D*/
|
||||
#define LV_SYMBOL_POWER "\xef\x80\x91" /*61457, 0xF011*/
|
||||
#define LV_SYMBOL_SETTINGS "\xef\x80\x93" /*61459, 0xF013*/
|
||||
#define LV_SYMBOL_HOME "\xef\x80\x95" /*61461, 0xF015*/
|
||||
#define LV_SYMBOL_DOWNLOAD "\xef\x80\x99" /*61465, 0xF019*/
|
||||
#define LV_SYMBOL_DRIVE "\xef\x80\x9c" /*61468, 0xF01C*/
|
||||
#define LV_SYMBOL_REFRESH "\xef\x80\xa1" /*61473, 0xF021*/
|
||||
#define LV_SYMBOL_MUTE "\xef\x80\xa6" /*61478, 0xF026*/
|
||||
#define LV_SYMBOL_VOLUME_MID "\xef\x80\xa7" /*61479, 0xF027*/
|
||||
#define LV_SYMBOL_VOLUME_MAX "\xef\x80\xa8" /*61480, 0xF028*/
|
||||
#define LV_SYMBOL_IMAGE "\xef\x80\xbe" /*61502, 0xF03E*/
|
||||
#define LV_SYMBOL_EDIT "\xef\x8C\x84" /*62212, 0xF304*/
|
||||
#define LV_SYMBOL_PREV "\xef\x81\x88" /*61512, 0xF048*/
|
||||
#define LV_SYMBOL_PLAY "\xef\x81\x8b" /*61515, 0xF04B*/
|
||||
#define LV_SYMBOL_PAUSE "\xef\x81\x8c" /*61516, 0xF04C*/
|
||||
#define LV_SYMBOL_STOP "\xef\x81\x8d" /*61517, 0xF04D*/
|
||||
#define LV_SYMBOL_NEXT "\xef\x81\x91" /*61521, 0xF051*/
|
||||
#define LV_SYMBOL_EJECT "\xef\x81\x92" /*61522, 0xF052*/
|
||||
#define LV_SYMBOL_LEFT "\xef\x81\x93" /*61523, 0xF053*/
|
||||
#define LV_SYMBOL_RIGHT "\xef\x81\x94" /*61524, 0xF054*/
|
||||
#define LV_SYMBOL_PLUS "\xef\x81\xa7" /*61543, 0xF067*/
|
||||
#define LV_SYMBOL_MINUS "\xef\x81\xa8" /*61544, 0xF068*/
|
||||
#define LV_SYMBOL_EYE_OPEN "\xef\x81\xae" /*61550, 0xF06E*/
|
||||
#define LV_SYMBOL_EYE_CLOSE "\xef\x81\xb0" /*61552, 0xF070*/
|
||||
#define LV_SYMBOL_WARNING "\xef\x81\xb1" /*61553, 0xF071*/
|
||||
#define LV_SYMBOL_SHUFFLE "\xef\x81\xb4" /*61556, 0xF074*/
|
||||
#define LV_SYMBOL_UP "\xef\x81\xb7" /*61559, 0xF077*/
|
||||
#define LV_SYMBOL_DOWN "\xef\x81\xb8" /*61560, 0xF078*/
|
||||
#define LV_SYMBOL_LOOP "\xef\x81\xb9" /*61561, 0xF079*/
|
||||
#define LV_SYMBOL_DIRECTORY "\xef\x81\xbb" /*61563, 0xF07B*/
|
||||
#define LV_SYMBOL_UPLOAD "\xef\x82\x93" /*61587, 0xF093*/
|
||||
#define LV_SYMBOL_CALL "\xef\x82\x95" /*61589, 0xF095*/
|
||||
#define LV_SYMBOL_CUT "\xef\x83\x84" /*61636, 0xF0C4*/
|
||||
#define LV_SYMBOL_COPY "\xef\x83\x85" /*61637, 0xF0C5*/
|
||||
#define LV_SYMBOL_SAVE "\xef\x83\x87" /*61639, 0xF0C7*/
|
||||
#define LV_SYMBOL_CHARGE "\xef\x83\xa7" /*61671, 0xF0E7*/
|
||||
#define LV_SYMBOL_PASTE "\xef\x83\xAA" /*61674, 0xF0EA*/
|
||||
#define LV_SYMBOL_BELL "\xef\x83\xb3" /*61683, 0xF0F3*/
|
||||
#define LV_SYMBOL_KEYBOARD "\xef\x84\x9c" /*61724, 0xF11C*/
|
||||
#define LV_SYMBOL_GPS "\xef\x84\xa4" /*61732, 0xF124*/
|
||||
#define LV_SYMBOL_FILE "\xef\x85\x9b" /*61787, 0xF158*/
|
||||
#define LV_SYMBOL_WIFI "\xef\x87\xab" /*61931, 0xF1EB*/
|
||||
#define LV_SYMBOL_BATTERY_FULL "\xef\x89\x80" /*62016, 0xF240*/
|
||||
#define LV_SYMBOL_BATTERY_3 "\xef\x89\x81" /*62017, 0xF241*/
|
||||
#define LV_SYMBOL_BATTERY_2 "\xef\x89\x82" /*62018, 0xF242*/
|
||||
#define LV_SYMBOL_BATTERY_1 "\xef\x89\x83" /*62019, 0xF243*/
|
||||
#define LV_SYMBOL_BATTERY_EMPTY "\xef\x89\x84" /*62020, 0xF244*/
|
||||
#define LV_SYMBOL_USB "\xef\x8a\x87" /*62087, 0xF287*/
|
||||
#define LV_SYMBOL_BLUETOOTH "\xef\x8a\x93" /*62099, 0xF293*/
|
||||
#define LV_SYMBOL_TRASH "\xef\x8B\xAD" /*62189, 0xF2ED*/
|
||||
#define LV_SYMBOL_BACKSPACE "\xef\x95\x9A" /*62810, 0xF55A*/
|
||||
#define LV_SYMBOL_SD_CARD "\xef\x9F\x82" /*63426, 0xF7C2*/
|
||||
#define LV_SYMBOL_NEW_LINE "\xef\xA2\xA2" /*63650, 0xF8A2*/
|
||||
|
||||
/** Invalid symbol at (U+F8FF). If written before a string then `lv_img` will show it as a label*/
|
||||
#define LV_SYMBOL_DUMMY "\xEF\xA3\xBF"
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "lv_hal.h"
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "../lv_misc/lv_mem.h"
|
||||
#include "../lv_core/lv_obj.h"
|
||||
#include "../lv_core/lv_refr.h"
|
||||
@@ -118,7 +119,7 @@ lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
|
||||
{
|
||||
lv_disp_t * disp = lv_ll_ins_head(&LV_GC_ROOT(_lv_disp_ll));
|
||||
if(!disp) {
|
||||
lv_mem_assert(disp);
|
||||
LV_ASSERT_MEM(disp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -147,7 +148,7 @@ lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
|
||||
|
||||
/*Create a refresh task*/
|
||||
disp->refr_task = lv_task_create(lv_disp_refr_task, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, disp);
|
||||
lv_mem_assert(disp->refr_task);
|
||||
LV_ASSERT_MEM(disp->refr_task);
|
||||
if(disp->refr_task == NULL) return NULL;
|
||||
|
||||
lv_task_ready(disp->refr_task); /*Be sure the screen will be refreshed immediately on start up*/
|
||||
@@ -267,14 +268,14 @@ bool lv_disp_get_antialiasing(lv_disp_t * disp)
|
||||
*/
|
||||
LV_ATTRIBUTE_FLUSH_READY void lv_disp_flush_ready(lv_disp_drv_t * disp_drv)
|
||||
{
|
||||
disp_drv->buffer->flushing = 0;
|
||||
|
||||
/*If the screen is transparent initialize it when the flushing is ready*/
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
if(disp_drv->screen_transp) {
|
||||
memset(disp_drv->buffer->buf_act, 0x00, disp_drv->buffer->size * sizeof(lv_color32_t));
|
||||
}
|
||||
#endif
|
||||
|
||||
disp_drv->buffer->flushing = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "../lv_hal/lv_hal_indev.h"
|
||||
#include "../lv_core/lv_indev.h"
|
||||
#include "../lv_misc/lv_mem.h"
|
||||
@@ -77,7 +78,7 @@ lv_indev_t * lv_indev_drv_register(lv_indev_drv_t * driver)
|
||||
|
||||
lv_indev_t * indev = lv_ll_ins_head(&LV_GC_ROOT(_lv_indev_ll));
|
||||
if(!indev) {
|
||||
lv_mem_assert(indev);
|
||||
LV_ASSERT_MEM(indev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#if LV_USE_ANIMATION
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "../lv_hal/lv_hal_tick.h"
|
||||
#include "lv_task.h"
|
||||
#include "lv_math.h"
|
||||
@@ -89,7 +90,7 @@ void lv_anim_create(lv_anim_t * a)
|
||||
|
||||
/*Add the new animation to the animation linked list*/
|
||||
lv_anim_t * new_anim = lv_ll_ins_head(&LV_GC_ROOT(_lv_anim_ll));
|
||||
lv_mem_assert(new_anim);
|
||||
LV_ASSERT_MEM(new_anim);
|
||||
if(new_anim == NULL) return;
|
||||
|
||||
/*Initialize the animation descriptor*/
|
||||
|
||||
@@ -129,10 +129,10 @@ static inline void lv_anim_set_exec_cb(lv_anim_t * a, void * var, lv_anim_exec_x
|
||||
* @param duration duration of the animation in milliseconds
|
||||
* @param delay delay before the animation in milliseconds
|
||||
*/
|
||||
static inline void lv_anim_set_time(lv_anim_t * a, uint16_t duration, uint16_t delay)
|
||||
static inline void lv_anim_set_time(lv_anim_t * a, uint16_t duration, int16_t delay)
|
||||
{
|
||||
a->time = duration;
|
||||
a->act_time = -delay;
|
||||
a->act_time = (int16_t)(-delay);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -192,6 +192,19 @@ bool lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p)
|
||||
return is_in;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment or decrement an area's size by a single amount
|
||||
* @param a_p pointer to an area to grow
|
||||
* @param amount amount to increment the area, or negative to decrement
|
||||
*/
|
||||
void lv_area_increment(lv_area_t * a_p, const lv_coord_t amount)
|
||||
{
|
||||
a_p->x1 -= amount;
|
||||
a_p->y1 -= amount;
|
||||
a_p->x2 += amount;
|
||||
a_p->y2 += amount;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
+12
-2
@@ -29,6 +29,9 @@ extern "C" {
|
||||
#define LV_COORD_MAX ((lv_coord_t)((uint32_t)((uint32_t)1 << (8 * sizeof(lv_coord_t) - 1)) - 1000))
|
||||
#define LV_COORD_MIN (-LV_COORD_MAX)
|
||||
|
||||
LV_EXPORT_CONST_INT(LV_COORD_MAX);
|
||||
LV_EXPORT_CONST_INT(LV_COORD_MIN);
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
@@ -82,7 +85,7 @@ inline static void lv_area_copy(lv_area_t * dest, const lv_area_t * src)
|
||||
*/
|
||||
static inline lv_coord_t lv_area_get_width(const lv_area_t * area_p)
|
||||
{
|
||||
return area_p->x2 - area_p->x1 + 1;
|
||||
return (lv_coord_t)(area_p->x2 - area_p->x1 + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,7 +95,7 @@ static inline lv_coord_t lv_area_get_width(const lv_area_t * area_p)
|
||||
*/
|
||||
static inline lv_coord_t lv_area_get_height(const lv_area_t * area_p)
|
||||
{
|
||||
return area_p->y2 - area_p->y1 + 1;
|
||||
return (lv_coord_t)(area_p->y2 - area_p->y1 + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,6 +168,13 @@ bool lv_area_is_on(const lv_area_t * a1_p, const lv_area_t * a2_p);
|
||||
*/
|
||||
bool lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p);
|
||||
|
||||
/**
|
||||
* Increment or decrement an area's size by a single amount
|
||||
* @param a_p pointer to an area to grow
|
||||
* @param amount amount to increment the area, or negative to decrement
|
||||
*/
|
||||
void lv_area_increment(lv_area_t * a_p, const lv_coord_t amount);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* @file lv_bifi.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_BIDI_H
|
||||
#define LV_BIDI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#ifdef LV_CONF_INCLUDE_SIMPLE
|
||||
#include "lv_conf.h"
|
||||
#else
|
||||
#include "../../../lv_conf.h"
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
/* Special non printable strong characters.
|
||||
* They can be inserted to texts to affect the run's direction*/
|
||||
#define LV_BIDI_LRO "\xE2\x80\xAD" /*U+202D*/
|
||||
#define LV_BIDI_RLO "\xE2\x80\xAE" /*U+202E*/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
enum
|
||||
{
|
||||
/*The first 4 values are stored in `lv_obj_t` on 2 bits*/
|
||||
LV_BIDI_DIR_LTR = 0x00,
|
||||
LV_BIDI_DIR_RTL = 0x01,
|
||||
LV_BIDI_DIR_AUTO = 0x02,
|
||||
LV_BIDI_DIR_INHERIT = 0x03,
|
||||
|
||||
LV_BIDI_DIR_NEUTRAL = 0x20,
|
||||
LV_BIDI_DIR_WEAK = 0x21,
|
||||
};
|
||||
|
||||
typedef uint8_t lv_bidi_dir_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
#if LV_USE_BIDI
|
||||
|
||||
void lv_bidi_process(const char * str_in, char * str_out, lv_bidi_dir_t base_dir);
|
||||
void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_bidi_dir_t base_dir, uint16_t *pos_conv_out, uint16_t pos_conv_len);
|
||||
uint32_t lv_bidi_get_next_paragraph(const char * txt);
|
||||
lv_bidi_dir_t lv_bidi_detect_base_dir(const char * txt);
|
||||
lv_bidi_dir_t lv_bidi_get_letter_dir(uint32_t letter);
|
||||
bool lv_bidi_letter_is_weak(uint32_t letter);
|
||||
bool lv_bidi_letter_is_rtl(uint32_t letter);
|
||||
bool lv_bidi_letter_is_neutral(uint32_t letter);
|
||||
uint16_t lv_bidi_get_logical_pos(const char * str_in, char **bidi_txt, uint32_t len, lv_bidi_dir_t base_dir, uint32_t visual_pos, bool *is_rtl);
|
||||
uint16_t lv_bidi_get_visual_pos(const char * str_in, char **bidi_txt, uint16_t len, lv_bidi_dir_t base_dir, uint32_t logical_pos, bool *is_rtl);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_BIDI*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /*LV_BIDI_H*/
|
||||
+44
-16
@@ -7,6 +7,7 @@
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_color.h"
|
||||
#include "lv_math.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -105,39 +106,66 @@ lv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v)
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an RGB color to HSV
|
||||
* @param r red
|
||||
* @param g green
|
||||
* @param b blue
|
||||
* @return the given RGB color n HSV
|
||||
* Convert a 32-bit RGB color to HSV
|
||||
* @param r8 8-bit red
|
||||
* @param g8 8-bit green
|
||||
* @param b8 8-bit blue
|
||||
* @return the given RGB color in HSV
|
||||
*/
|
||||
lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r, uint8_t g, uint8_t b)
|
||||
lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r8, uint8_t g8, uint8_t b8)
|
||||
{
|
||||
uint16_t r = ((uint32_t)r8 << 10) / 255;
|
||||
uint16_t g = ((uint32_t)g8 << 10) / 255;
|
||||
uint16_t b = ((uint32_t)b8 << 10) / 255;
|
||||
|
||||
uint16_t rgbMin = r < g ? (r < b ? r : b) : (g < b ? g : b);
|
||||
uint16_t rgbMax = r > g ? (r > b ? r : b) : (g > b ? g : b);
|
||||
|
||||
lv_color_hsv_t hsv;
|
||||
uint8_t rgbMin, rgbMax;
|
||||
|
||||
rgbMin = r < g ? (r < b ? r : b) : (g < b ? g : b);
|
||||
rgbMax = r > g ? (r > b ? r : b) : (g > b ? g : b);
|
||||
// https://en.wikipedia.org/wiki/HSL_and_HSV#Lightness
|
||||
hsv.v = (100 * rgbMax) >> 10;
|
||||
|
||||
hsv.v = rgbMax;
|
||||
if(hsv.v == 0) {
|
||||
int32_t delta = rgbMax - rgbMin;
|
||||
if (LV_MATH_ABS(delta) < 3) {
|
||||
hsv.h = 0;
|
||||
hsv.s = 0;
|
||||
return hsv;
|
||||
}
|
||||
|
||||
hsv.s = 255 * (long)(rgbMax - rgbMin) / hsv.v;
|
||||
if(hsv.s == 0) {
|
||||
// https://en.wikipedia.org/wiki/HSL_and_HSV#Saturation
|
||||
hsv.s = 100 * delta / rgbMax;
|
||||
if(hsv.s < 3) {
|
||||
hsv.h = 0;
|
||||
return hsv;
|
||||
}
|
||||
|
||||
// https://en.wikipedia.org/wiki/HSL_and_HSV#Hue_and_chroma
|
||||
int32_t h;
|
||||
if(rgbMax == r)
|
||||
hsv.h = 0 + 43 * (g - b) / (rgbMax - rgbMin);
|
||||
h = (((g - b) << 10) / delta) + (g < b ? (6 << 10) : 0); // between yellow & magenta
|
||||
else if(rgbMax == g)
|
||||
hsv.h = 85 + 43 * (b - r) / (rgbMax - rgbMin);
|
||||
h = (((b - r) << 10) / delta) + (2 << 10); // between cyan & yellow
|
||||
else if(rgbMax == b)
|
||||
h = (((r - g) << 10) / delta) + (4 << 10); // between magenta & cyan
|
||||
else
|
||||
hsv.h = 171 + 43 * (r - g) / (rgbMax - rgbMin);
|
||||
h = 0;
|
||||
h *= 60;
|
||||
h >>= 10;
|
||||
if (h < 0) h += 360;
|
||||
|
||||
hsv.h = h;
|
||||
return hsv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a color to HSV
|
||||
* @param color color
|
||||
* @return the given color in HSV
|
||||
*/
|
||||
lv_color_hsv_t lv_color_to_hsv(lv_color_t color)
|
||||
{
|
||||
lv_color32_t color32;
|
||||
color32.full = lv_color_to32(color);
|
||||
return lv_color_rgb_to_hsv(color32.ch.red, color32.ch.green, color32.ch.blue);
|
||||
}
|
||||
|
||||
+194
-123
@@ -90,16 +90,123 @@ enum {
|
||||
#error "Invalid LV_COLOR_DEPTH in lv_conf.h! Set it to 1, 8, 16 or 32!"
|
||||
#endif
|
||||
|
||||
/*---------------------------------------
|
||||
* Macros for all existing color depths
|
||||
* to set/get values of the color channels
|
||||
*------------------------------------------*/
|
||||
# define LV_COLOR_SET_R1(c, v) (c).ch.red = (uint8_t)((v) & 0x1);
|
||||
# define LV_COLOR_SET_G1(c, v) (c).ch.green = (uint8_t)((v) & 0x1);
|
||||
# define LV_COLOR_SET_B1(c, v) (c).ch.blue = (uint8_t)((v) & 0x1);
|
||||
# define LV_COLOR_SET_A1(c, v)
|
||||
|
||||
# define LV_COLOR_GET_R1(c) (c).ch.red
|
||||
# define LV_COLOR_GET_G1(c) (c).ch.green
|
||||
# define LV_COLOR_GET_B1(c) (c).ch.blue
|
||||
# define LV_COLOR_GET_A1(c) 1
|
||||
|
||||
# define LV_COLOR_SET_R8(c, v) (c).ch.red = (uint8_t)((v) & 0x7);
|
||||
# define LV_COLOR_SET_G8(c, v) (c).ch.green = (uint8_t)((v) & 0x7);
|
||||
# define LV_COLOR_SET_B8(c, v) (c).ch.blue = (uint8_t)((v) & 0x3);
|
||||
# define LV_COLOR_SET_A8(c, v) do {} while(0)
|
||||
|
||||
# define LV_COLOR_GET_R8(c) (c).ch.red
|
||||
# define LV_COLOR_GET_G8(c) (c).ch.green
|
||||
# define LV_COLOR_GET_B8(c) (c).ch.blue
|
||||
# define LV_COLOR_GET_A8(c) 0xFF
|
||||
|
||||
# define LV_COLOR_SET_R16(c, v) (c).ch.red = (uint8_t)(((uint8_t)(v)) & 0x1F);
|
||||
# define LV_COLOR_SET_G16(c, v) (c).ch.green = (uint8_t)((v) & 0x3F);
|
||||
# define LV_COLOR_SET_G16_SWAP(c, v) {(c).ch.green_h = (uint8_t)(((v) >> 3) & 0x7); (c).ch.green_l = (uint8_t)((v) & 0x7);}
|
||||
# define LV_COLOR_SET_B16(c, v) (c).ch.blue = (uint8_t)((v) & 0x1F);
|
||||
# define LV_COLOR_SET_A16(c, v) do {} while(0)
|
||||
|
||||
# define LV_COLOR_GET_R16(c) (c).ch.red
|
||||
# define LV_COLOR_GET_G16(c) (c).ch.green
|
||||
# define LV_COLOR_GET_G16_SWAP(c) (((c).ch.green_h << 3) + (c).ch.green_l)
|
||||
# define LV_COLOR_GET_B16(c) (c).ch.blue
|
||||
# define LV_COLOR_GET_A16(c) 0xFF
|
||||
|
||||
# define LV_COLOR_SET_R32(c, v) (c).ch.red = (uint32_t)((v) & 0xFF);
|
||||
# define LV_COLOR_SET_G32(c, v) (c).ch.green = (uint32_t)((v) & 0xFF);
|
||||
# define LV_COLOR_SET_B32(c, v) (c).ch.blue = (uint32_t)((v) & 0xFF);
|
||||
# define LV_COLOR_SET_A32(c, v) (c).ch.alpha = (uint32_t)((v) & 0xFF);
|
||||
|
||||
# define LV_COLOR_GET_R32(c) (c).ch.red
|
||||
# define LV_COLOR_GET_G32(c) (c).ch.green
|
||||
# define LV_COLOR_GET_B32(c) (c).ch.blue
|
||||
# define LV_COLOR_GET_A32(c) (c).ch.alpha
|
||||
|
||||
|
||||
/*---------------------------------------
|
||||
* Macros for the current color depth
|
||||
* to set/get values of the color channels
|
||||
*------------------------------------------*/
|
||||
#if LV_COLOR_DEPTH == 1
|
||||
# define LV_COLOR_SET_R(c, v) LV_COLOR_SET_R1(c,v)
|
||||
# define LV_COLOR_SET_G(c, v) LV_COLOR_SET_G1(c,v)
|
||||
# define LV_COLOR_SET_B(c, v) LV_COLOR_SET_B1(c,v)
|
||||
# define LV_COLOR_SET_A(c, v) LV_COLOR_SET_A1(c,v)
|
||||
|
||||
# define LV_COLOR_GET_R(c) LV_COLOR_GET_R1(c)
|
||||
# define LV_COLOR_GET_G(c) LV_COLOR_GET_G1(c)
|
||||
# define LV_COLOR_GET_B(c) LV_COLOR_GET_B1(c)
|
||||
# define LV_COLOR_GET_A(c) LV_COLOR_GET_A1(c)
|
||||
|
||||
#elif LV_COLOR_DEPTH == 8
|
||||
# define LV_COLOR_SET_R(c, v) LV_COLOR_SET_R8(c,v)
|
||||
# define LV_COLOR_SET_G(c, v) LV_COLOR_SET_G8(c,v)
|
||||
# define LV_COLOR_SET_B(c, v) LV_COLOR_SET_B8(c,v)
|
||||
# define LV_COLOR_SET_A(c, v) LV_COLOR_SET_A8(c,v)
|
||||
|
||||
# define LV_COLOR_GET_R(c) LV_COLOR_GET_R8(c)
|
||||
# define LV_COLOR_GET_G(c) LV_COLOR_GET_G8(c)
|
||||
# define LV_COLOR_GET_B(c) LV_COLOR_GET_B8(c)
|
||||
# define LV_COLOR_GET_A(c) LV_COLOR_GET_A8(c)
|
||||
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
# define LV_COLOR_SET_R(c, v) LV_COLOR_SET_R16(c,v)
|
||||
# if LV_COLOR_16_SWAP == 0
|
||||
# define LV_COLOR_SET_G(c, v) LV_COLOR_SET_G16(c,v)
|
||||
# else
|
||||
# define LV_COLOR_SET_G(c, v) LV_COLOR_SET_G16_SWAP(c,v)
|
||||
# endif
|
||||
# define LV_COLOR_SET_B(c, v) LV_COLOR_SET_B16(c,v)
|
||||
# define LV_COLOR_SET_A(c, v) LV_COLOR_SET_A16(c,v)
|
||||
|
||||
# define LV_COLOR_GET_R(c) LV_COLOR_GET_R16(c)
|
||||
# if LV_COLOR_16_SWAP == 0
|
||||
# define LV_COLOR_GET_G(c) LV_COLOR_GET_G16(c)
|
||||
# else
|
||||
# define LV_COLOR_GET_G(c) LV_COLOR_GET_G16_SWAP(c)
|
||||
# endif
|
||||
# define LV_COLOR_GET_B(c) LV_COLOR_GET_B16(c)
|
||||
# define LV_COLOR_GET_A(c) LV_COLOR_GET_A16(c)
|
||||
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
# define LV_COLOR_SET_R(c, v) LV_COLOR_SET_R32(c,v)
|
||||
# define LV_COLOR_SET_G(c, v) LV_COLOR_SET_G32(c,v)
|
||||
# define LV_COLOR_SET_B(c, v) LV_COLOR_SET_B32(c,v)
|
||||
# define LV_COLOR_SET_A(c, v) LV_COLOR_SET_A32(c,v)
|
||||
|
||||
# define LV_COLOR_GET_R(c) LV_COLOR_GET_R32(c)
|
||||
# define LV_COLOR_GET_G(c) LV_COLOR_GET_G32(c)
|
||||
# define LV_COLOR_GET_B(c) LV_COLOR_GET_B32(c)
|
||||
# define LV_COLOR_GET_A(c) LV_COLOR_GET_A32(c)
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef union
|
||||
{
|
||||
uint8_t blue : 1;
|
||||
uint8_t green : 1;
|
||||
uint8_t red : 1;
|
||||
uint8_t full : 1;
|
||||
struct
|
||||
{
|
||||
uint8_t blue : 1;
|
||||
uint8_t green : 1;
|
||||
uint8_t red : 1;
|
||||
} ch;
|
||||
uint8_t full;
|
||||
} lv_color1_t;
|
||||
|
||||
typedef union
|
||||
@@ -191,24 +298,19 @@ static inline uint8_t lv_color_to1(lv_color_t color)
|
||||
#if LV_COLOR_DEPTH == 1
|
||||
return color.full;
|
||||
#elif LV_COLOR_DEPTH == 8
|
||||
if((color.ch.red & 0x4) || (color.ch.green & 0x4) || (color.ch.blue & 0x2)) {
|
||||
if((LV_COLOR_GET_R(color) & 0x4) || (LV_COLOR_GET_G(color) & 0x4) || (LV_COLOR_GET_B(color) & 0x2)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
#if LV_COLOR_16_SWAP == 0
|
||||
if((color.ch.red & 0x10) || (color.ch.green & 0x20) || (color.ch.blue & 0x10)) {
|
||||
if((LV_COLOR_GET_R(color) & 0x10) || (LV_COLOR_GET_G(color) & 0x20) || (LV_COLOR_GET_B(color) & 0x10)) {
|
||||
return 1;
|
||||
#else
|
||||
if((color.ch.red & 0x10) || (color.ch.green_h & 0x20) || (color.ch.blue & 0x10)) {
|
||||
return 1;
|
||||
#endif
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
if((color.ch.red & 0x80) || (color.ch.green & 0x80) || (color.ch.blue & 0x80)) {
|
||||
if((LV_COLOR_GET_R(color) & 0x80) || (LV_COLOR_GET_G(color) & 0x80) || (LV_COLOR_GET_B(color) & 0x80)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
@@ -226,31 +328,23 @@ static inline uint8_t lv_color_to8(lv_color_t color)
|
||||
#elif LV_COLOR_DEPTH == 8
|
||||
return color.full;
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
|
||||
#if LV_COLOR_16_SWAP == 0
|
||||
lv_color8_t ret;
|
||||
ret.ch.red = color.ch.red >> 2; /* 5 - 3 = 2*/
|
||||
ret.ch.green = color.ch.green >> 3; /* 6 - 3 = 3*/
|
||||
ret.ch.blue = color.ch.blue >> 3; /* 5 - 2 = 3*/
|
||||
LV_COLOR_SET_R8(ret, LV_COLOR_GET_R(color) >> 2); /* 5 - 3 = 2*/
|
||||
LV_COLOR_SET_G8(ret, LV_COLOR_GET_G(color) >> 3); /* 6 - 3 = 3*/
|
||||
LV_COLOR_SET_B8(ret, LV_COLOR_GET_B(color) >> 3); /* 5 - 2 = 3*/
|
||||
return ret.full;
|
||||
#else
|
||||
lv_color8_t ret;
|
||||
ret.ch.red = color.ch.red >> 2; /* 5 - 3 = 2*/
|
||||
ret.ch.green = color.ch.green_h; /* 6 - 3 = 3*/
|
||||
ret.ch.blue = color.ch.blue >> 3; /* 5 - 2 = 3*/
|
||||
return ret.full;
|
||||
#endif
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
lv_color8_t ret;
|
||||
ret.ch.red = color.ch.red >> 5; /* 8 - 3 = 5*/
|
||||
ret.ch.green = color.ch.green >> 5; /* 8 - 3 = 5*/
|
||||
ret.ch.blue = color.ch.blue >> 6; /* 8 - 2 = 6*/
|
||||
LV_COLOR_SET_R8(ret, LV_COLOR_GET_R(color) >> 5); /* 8 - 3 = 5*/
|
||||
LV_COLOR_SET_G8(ret, LV_COLOR_GET_G(color) >> 5); /* 8 - 3 = 5*/
|
||||
LV_COLOR_SET_B8(ret, LV_COLOR_GET_B(color) >> 6); /* 8 - 2 = 6*/
|
||||
return ret.full;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint16_t lv_color_to16(lv_color_t color)
|
||||
{
|
||||
|
||||
#if LV_COLOR_DEPTH == 1
|
||||
if(color.full == 0)
|
||||
return 0;
|
||||
@@ -258,34 +352,30 @@ static inline uint16_t lv_color_to16(lv_color_t color)
|
||||
return 0xFFFF;
|
||||
#elif LV_COLOR_DEPTH == 8
|
||||
lv_color16_t ret;
|
||||
LV_COLOR_SET_R16(ret, LV_COLOR_GET_R(color) * 4); /*(2^5 - 1)/(2^3 - 1) = 31/7 = 4*/
|
||||
#if LV_COLOR_16_SWAP == 0
|
||||
ret.ch.red = color.ch.red * 4; /*(2^5 - 1)/(2^3 - 1) = 31/7 = 4*/
|
||||
ret.ch.green = color.ch.green * 9; /*(2^6 - 1)/(2^3 - 1) = 63/7 = 9*/
|
||||
ret.ch.blue = color.ch.blue * 10; /*(2^5 - 1)/(2^2 - 1) = 31/3 = 10*/
|
||||
LV_COLOR_SET_G16(ret, LV_COLOR_GET_G(color) * 9); /*(2^6 - 1)/(2^3 - 1) = 63/7 = 9*/
|
||||
#else
|
||||
ret.red = color.ch.red * 4;
|
||||
uint8_t g_tmp = color.ch.green * 9;
|
||||
ret.ch.green_h = (g_tmp & 0x1F) >> 3;
|
||||
ret.ch.green_l = g_tmp & 0x07;
|
||||
ret.ch.blue = color.ch.blue * 10;
|
||||
LV_COLOR_SET_G16_SWAP(ret, (LV_COLOR_GET_G(color) * 9)); /*(2^6 - 1)/(2^3 - 1) = 63/7 = 9*/
|
||||
#endif
|
||||
LV_COLOR_SET_B16(ret, LV_COLOR_GET_B(color) * 10); /*(2^5 - 1)/(2^2 - 1) = 31/3 = 10*/
|
||||
return ret.full;
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
return color.full;
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
lv_color16_t ret;
|
||||
LV_COLOR_SET_R16(ret, LV_COLOR_GET_R(color) >> 3); /* 8 - 5 = 3*/
|
||||
|
||||
#if LV_COLOR_16_SWAP == 0
|
||||
ret.ch.red = color.ch.red >> 3; /* 8 - 5 = 3*/
|
||||
ret.ch.green = color.ch.green >> 2; /* 8 - 6 = 2*/
|
||||
ret.ch.blue = color.ch.blue >> 3; /* 8 - 5 = 3*/
|
||||
LV_COLOR_SET_G16(ret, LV_COLOR_GET_G(color) >> 2); /* 8 - 6 = 2*/
|
||||
#else
|
||||
ret.ch.red = color.ch.red >> 3;
|
||||
ret.ch.green_h = (color.ch.green & 0xE0) >> 5;
|
||||
ret.ch.green_l = (color.ch.green & 0x1C) >> 2;
|
||||
ret.ch.blue = color.ch.blue >> 3;
|
||||
LV_COLOR_SET_G16_SWAP(ret, ret.ch.green_h = (LV_COLOR_GET_G(color) >> 2); /*(2^6 - 1)/(2^3 - 1) = 63/7 = 9*/
|
||||
#endif
|
||||
LV_COLOR_SET_B16(ret, LV_COLOR_GET_B(color) >> 3); /* 8 - 5 = 3*/
|
||||
return ret.full;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline uint32_t lv_color_to32(lv_color_t color)
|
||||
@@ -297,27 +387,46 @@ static inline uint32_t lv_color_to32(lv_color_t color)
|
||||
return 0xFFFFFFFF;
|
||||
#elif LV_COLOR_DEPTH == 8
|
||||
lv_color32_t ret;
|
||||
ret.ch.red = color.ch.red * 36; /*(2^8 - 1)/(2^3 - 1) = 255/7 = 36*/
|
||||
ret.ch.green = color.ch.green * 36; /*(2^8 - 1)/(2^3 - 1) = 255/7 = 36*/
|
||||
ret.ch.blue = color.ch.blue * 85; /*(2^8 - 1)/(2^2 - 1) = 255/3 = 85*/
|
||||
ret.ch.alpha = 0xFF;
|
||||
LV_COLOR_SET_R32(ret, LV_COLOR_GET_R(color) * 36); /*(2^8 - 1)/(2^3 - 1) = 255/7 = 36*/
|
||||
LV_COLOR_SET_G32(ret, LV_COLOR_GET_G(color) * 36); /*(2^8 - 1)/(2^3 - 1) = 255/7 = 36*/
|
||||
LV_COLOR_SET_B32(ret, LV_COLOR_GET_B(color) * 85); /*(2^8 - 1)/(2^2 - 1) = 255/3 = 85*/
|
||||
LV_COLOR_SET_A32(color, 0xFF);
|
||||
return ret.full;
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
#if LV_COLOR_16_SWAP == 0
|
||||
/**
|
||||
* The floating point math for conversion is:
|
||||
* valueto = valuefrom * ( (2^bitsto - 1) / (float)(2^bitsfrom - 1) )
|
||||
* The faster integer math for conversion is:
|
||||
* valueto = ( valuefrom * multiplier + adder ) >> divisor
|
||||
* multiplier = FLOOR( ( (2^bitsto - 1) << divisor ) / (float)(2^bitsfrom - 1) )
|
||||
*
|
||||
* Find the first divisor where ( adder >> divisor ) <= 0
|
||||
*
|
||||
* 5-bit to 8-bit: ( 31 * multiplier + adder ) >> divisor = 255
|
||||
* divisor multiplier adder min (0) max (31)
|
||||
* 0 8 7 7 255
|
||||
* 1 16 14 7 255
|
||||
* 2 32 28 7 255
|
||||
* 3 65 25 3 255
|
||||
* 4 131 19 1 255
|
||||
* 5 263 7 0 255
|
||||
*
|
||||
* 6-bit to 8-bit: 255 = ( 63 * multiplier + adder ) >> divisor
|
||||
* divisor multiplier adder min (0) max (63)
|
||||
* 0 4 3 3 255
|
||||
* 1 8 6 3 255
|
||||
* 2 16 12 3 255
|
||||
* 3 32 24 3 255
|
||||
* 4 64 48 3 255
|
||||
* 5 129 33 1 255
|
||||
* 6 259 3 0 255
|
||||
*/
|
||||
lv_color32_t ret;
|
||||
ret.ch.red = color.ch.red * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
|
||||
ret.ch.green = color.ch.green * 4; /*(2^8 - 1)/(2^6 - 1) = 255/63 = 4*/
|
||||
ret.ch.blue = color.ch.blue * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
|
||||
ret.ch.alpha = 0xFF;
|
||||
LV_COLOR_SET_R32(ret, (LV_COLOR_GET_R(color) * 263 + 7 ) >> 5);
|
||||
LV_COLOR_SET_G32(ret, (LV_COLOR_GET_G(color) * 259 + 3 ) >> 6);
|
||||
LV_COLOR_SET_B32(ret, (LV_COLOR_GET_B(color) * 263 + 7 ) >> 5);
|
||||
LV_COLOR_SET_A32(ret, 0xFF);
|
||||
return ret.full;
|
||||
#else
|
||||
lv_color32_t ret;
|
||||
ret.ch.red = color.ch.red * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
|
||||
ret.ch.green = ((color.ch.green_h << 3) + color.ch.green_l) * 4; /*(2^8 - 1)/(2^6 - 1) = 255/63 = 4*/
|
||||
ret.ch.blue = color.ch.blue * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
|
||||
ret.ch.alpha = 0xFF;
|
||||
return ret.full;
|
||||
#endif
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
return color.full;
|
||||
#endif
|
||||
@@ -328,21 +437,10 @@ static inline lv_color_t lv_color_mix(lv_color_t c1, lv_color_t c2, uint8_t mix)
|
||||
lv_color_t ret;
|
||||
#if LV_COLOR_DEPTH != 1
|
||||
/*LV_COLOR_DEPTH == 8, 16 or 32*/
|
||||
ret.ch.red = (uint16_t)((uint16_t)c1.ch.red * mix + (c2.ch.red * (255 - mix))) >> 8;
|
||||
#if LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP
|
||||
/*If swapped Green is in 2 parts*/
|
||||
uint16_t g_1 = (c1.ch.green_h << 3) + c1.ch.green_l;
|
||||
uint16_t g_2 = (c2.ch.green_h << 3) + c2.ch.green_l;
|
||||
uint16_t g_out = (uint16_t)((uint16_t)g_1 * mix + (g_2 * (255 - mix))) >> 8;
|
||||
ret.ch.green_h = g_out >> 3;
|
||||
ret.ch.green_l = g_out & 0x7;
|
||||
#else
|
||||
ret.ch.green = (uint16_t)((uint16_t)c1.ch.green * mix + (c2.ch.green * (255 - mix))) >> 8;
|
||||
#endif
|
||||
ret.ch.blue = (uint16_t)((uint16_t)c1.ch.blue * mix + (c2.ch.blue * (255 - mix))) >> 8;
|
||||
#if LV_COLOR_DEPTH == 32
|
||||
ret.ch.alpha = 0xFF;
|
||||
#endif
|
||||
LV_COLOR_SET_R(ret, (uint16_t)((uint16_t) LV_COLOR_GET_R(c1) * mix + LV_COLOR_GET_R(c2) * (255 - mix)) >> 8);
|
||||
LV_COLOR_SET_G(ret, (uint16_t)((uint16_t) LV_COLOR_GET_G(c1) * mix + LV_COLOR_GET_G(c2) * (255 - mix)) >> 8);
|
||||
LV_COLOR_SET_B(ret, (uint16_t)((uint16_t) LV_COLOR_GET_B(c1) * mix + LV_COLOR_GET_B(c2) * (255 - mix)) >> 8);
|
||||
LV_COLOR_SET_A(ret, 0xFF);
|
||||
#else
|
||||
/*LV_COLOR_DEPTH == 1*/
|
||||
ret.full = mix > LV_OPA_50 ? c1.full : c2.full;
|
||||
@@ -360,65 +458,31 @@ static inline uint8_t lv_color_brightness(lv_color_t color)
|
||||
{
|
||||
lv_color32_t c32;
|
||||
c32.full = lv_color_to32(color);
|
||||
uint16_t bright = 3 * c32.ch.red + c32.ch.blue + 4 * c32.ch.green;
|
||||
return (uint16_t)bright >> 3;
|
||||
uint16_t bright = (uint16_t)(3u * LV_COLOR_GET_R32(c32) + LV_COLOR_GET_B32(c32) + 4u * LV_COLOR_GET_G32(c32));
|
||||
return (uint8_t)(bright >> 3);
|
||||
}
|
||||
|
||||
/* The most simple macro to create a color from R,G and B values */
|
||||
#if LV_COLOR_DEPTH == 1
|
||||
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){(b8 >> 7 | g8 >> 7 | r8 >> 7)})
|
||||
static inline lv_color_t lv_color_make(int r8, int g8, int b8)
|
||||
{
|
||||
lv_color_t color;
|
||||
color.full = (b8 >> 7 | g8 >> 7 | r8 >> 7);
|
||||
return color;
|
||||
}
|
||||
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){.full = (b8 >> 7 | g8 >> 7 | r8 >> 7)})
|
||||
#elif LV_COLOR_DEPTH == 8
|
||||
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8 >> 6, g8 >> 5, r8 >> 5}})
|
||||
static inline lv_color_t lv_color_make(uint8_t r8, int g8, int b8)
|
||||
{
|
||||
lv_color_t color;
|
||||
color.ch.blue = b8 >> 6;
|
||||
color.ch.green = g8 >> 5;
|
||||
color.ch.red = r8 >> 5;
|
||||
return color;
|
||||
}
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
#if LV_COLOR_16_SWAP == 0
|
||||
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8 >> 3, g8 >> 2, r8 >> 3}})
|
||||
static inline lv_color_t lv_color_make(uint8_t r8, uint8_t g8, uint8_t b8)
|
||||
{
|
||||
lv_color_t color;
|
||||
color.ch.blue = (uint16_t)(b8 >> 3);
|
||||
color.ch.green = (uint16_t)(g8 >> 2);
|
||||
color.ch.red = (uint16_t)(r8 >> 3);
|
||||
return color;
|
||||
}
|
||||
#else
|
||||
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{g8 >> 5, r8 >> 3, b8 >> 3, (g8 >> 2) & 0x7}})
|
||||
static inline lv_color_t lv_color_make(uint8_t r8, uint8_t g8, uint8_t b8)
|
||||
{
|
||||
lv_color_t color;
|
||||
color.ch.green_h = (uint16_t)(g8 >> 5);
|
||||
color.ch.red = (uint16_t)(r8 >> 3);
|
||||
color.ch.blue = (uint16_t)(b8 >> 3);
|
||||
color.ch.green_l = (uint16_t)((g8 >> 2) & 0x7);
|
||||
return color;
|
||||
}
|
||||
#endif
|
||||
static inline lv_color_t lv_color_make(uint8_t r8, uint8_t g8, uint8_t b8)
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8, g8, r8, 0xff}}) /*Fix 0xff alpha*/
|
||||
static inline lv_color_t lv_color_make(uint8_t r8, uint8_t g8, uint8_t b8)
|
||||
{
|
||||
lv_color_t color;
|
||||
color.ch.blue = b8;
|
||||
color.ch.green = g8;
|
||||
color.ch.red = r8;
|
||||
color.ch.alpha = 0xff;
|
||||
return color;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline lv_color_t lv_color_make(uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
return LV_COLOR_MAKE(r, g, b);
|
||||
}
|
||||
|
||||
static inline lv_color_t lv_color_hex(uint32_t c)
|
||||
{
|
||||
return lv_color_make((uint8_t)((c >> 16) & 0xFF), (uint8_t)((c >> 8) & 0xFF), (uint8_t)(c & 0xFF));
|
||||
@@ -440,13 +504,20 @@ static inline lv_color_t lv_color_hex3(uint32_t c)
|
||||
lv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v);
|
||||
|
||||
/**
|
||||
* Convert an RGB color to HSV
|
||||
* @param r red
|
||||
* @param g green
|
||||
* @param b blue
|
||||
* @return the given RGB color n HSV
|
||||
* Convert a 32-bit RGB color to HSV
|
||||
* @param r8 8-bit red
|
||||
* @param g8 8-bit green
|
||||
* @param b8 8-bit blue
|
||||
* @return the given RGB color in HSV
|
||||
*/
|
||||
lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r, uint8_t g, uint8_t b);
|
||||
lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r8, uint8_t g8, uint8_t b8);
|
||||
|
||||
/**
|
||||
* Convert a color to HSV
|
||||
* @param color color
|
||||
* @return the given color in HSV
|
||||
*/
|
||||
lv_color_hsv_t lv_color_to_hsv(lv_color_t color);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
||||
+4
-3
@@ -9,6 +9,7 @@
|
||||
#include "lv_fs.h"
|
||||
#if LV_USE_FILESYSTEM
|
||||
|
||||
#include "../lv_core/lv_debug.h"
|
||||
#include "lv_ll.h"
|
||||
#include <string.h>
|
||||
#include "lv_gc.h"
|
||||
@@ -107,7 +108,7 @@ lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mo
|
||||
}
|
||||
|
||||
file_p->file_d = lv_mem_alloc(file_p->drv->file_size);
|
||||
lv_mem_assert(file_p->file_d);
|
||||
LV_ASSERT_MEM(file_p->file_d);
|
||||
if(file_p->file_d == NULL) {
|
||||
file_p->drv = NULL;
|
||||
return LV_FS_RES_OUT_OF_MEM; /* Out of memory */
|
||||
@@ -367,7 +368,7 @@ lv_fs_res_t lv_fs_dir_open(lv_fs_dir_t * rddir_p, const char * path)
|
||||
}
|
||||
|
||||
rddir_p->dir_d = lv_mem_alloc(rddir_p->drv->rddir_size);
|
||||
lv_mem_assert(rddir_p->dir_d);
|
||||
LV_ASSERT_MEM(rddir_p->dir_d);
|
||||
if(rddir_p->dir_d == NULL) {
|
||||
rddir_p->dir_d = NULL;
|
||||
return LV_FS_RES_OUT_OF_MEM; /* Out of memory */
|
||||
@@ -486,7 +487,7 @@ void lv_fs_drv_register(lv_fs_drv_t * drv_p)
|
||||
/*Save the new driver*/
|
||||
lv_fs_drv_t * new_drv;
|
||||
new_drv = lv_ll_ins_head(&LV_GC_ROOT(_lv_drv_ll));
|
||||
lv_mem_assert(new_drv);
|
||||
LV_ASSERT_MEM(new_drv);
|
||||
if(new_drv == NULL) return;
|
||||
|
||||
memcpy(new_drv, drv_p, sizeof(lv_fs_drv_t));
|
||||
|
||||
@@ -29,6 +29,7 @@ extern "C" {
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_FS_MAX_FN_LENGTH 64
|
||||
#define LV_FS_MAX_PATH_LENGTH 256
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#if LV_LOG_PRINTF
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user