Merge branch 'dev-6.1'

This commit is contained in:
Gabor Kiss-Vamosi
2019-11-25 13:17:35 +01:00
115 changed files with 23039 additions and 11047 deletions
+2 -2
View File
@@ -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;
+96
View File
@@ -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
+4
View File
@@ -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.
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
+1
View File
@@ -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
+193
View File
@@ -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*/
+154
View File
@@ -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*/
+4 -3
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+23 -3
View File
@@ -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
**********************/
+5 -5
View File
@@ -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;
+8 -1
View File
@@ -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
View File
@@ -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
+3 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
}
+74 -6
View File
@@ -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);
+44 -3
View File
@@ -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
View File
@@ -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;
}
}
+12 -3
View File
@@ -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
+1 -2
View File
@@ -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;
+2 -1
View File
@@ -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;
+33 -12
View File
@@ -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
View File
@@ -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;
/**********************
+224 -2
View File
@@ -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.
+4 -3
View File
@@ -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;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+65 -50
View File
@@ -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"
+5 -4
View File
@@ -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;
}
/**
+2 -1
View File
@@ -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;
}
+2 -1
View File
@@ -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*/
+2 -2
View File
@@ -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);
}
/**
+13
View File
@@ -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
View File
@@ -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
+76
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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));
+1
View File
@@ -29,6 +29,7 @@ extern "C" {
* DEFINES
*********************/
#define LV_FS_MAX_FN_LENGTH 64
#define LV_FS_MAX_PATH_LENGTH 256
/**********************
* TYPEDEFS
+1
View File
@@ -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