1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

Merge branch 'master' into feat/new-fs-api

This commit is contained in:
Gabor Kiss-Vamosi 2020-08-04 16:41:52 +02:00
commit 068260925f
28 changed files with 576 additions and 419 deletions

2
.github/FUNDING.yml vendored
View File

@ -1 +1 @@
custom: ["https://littlevgl.com/donate"] custom: ["https://www.paypal.com/paypalme/my/profile"]

View File

@ -10,11 +10,21 @@
- Add `lv_task_get_next` - Add `lv_task_get_next`
- Add `lv_event_send_refresh`, `lv_event_send_refresh_recursive` to easily send `LV_EVENT_REFRESH` to object - Add `lv_event_send_refresh`, `lv_event_send_refresh_recursive` to easily send `LV_EVENT_REFRESH` to object
- Add `lv_tabview_set_tab_name()` function - used to change a tab's name - Add `lv_tabview_set_tab_name()` function - used to change a tab's name
- Add `LV_THEME_MATERIAL_FLAG_NO_TRANSITION` and `LV_THEME_MATERIAL_FLAG_NO_FOCUS` flags
- Reduce code size by adding: `LV_USE_FONT_COMPRESSED`, `LV_FONT_USE_SUBPX`, `LV_USE_OUTLINE`, `LV_USE_PATTERN`, `LV_USE_VALUE_STR` and applying some optimization
- Add `LV_MEMCPY_MEMSET_STD` to use standard `memcpy` and `memset`
### Bugfixes ### Bugfixes
- Do not print warning for missing glyph if its height OR width is zero. - Do not print warning for missing glyph if its height OR width is zero.
- Prevent duplicated sending of `LV_EVENT_INSERT` from text area - Prevent duplicated sending of `LV_EVENT_INSERT` from text area
- Tidy outer edges of cpicker widget.
- Remove duplicated lines from `lv_tabview_add_tab` - Remove duplicated lines from `lv_tabview_add_tab`
- btnmatrix: hadle combined states of buttons (e.g. chacked + disabled)
- textarea: fix typo in lv_textarea_set_sscrollbar_mode
- gauge: fix image needle drawing
- fix using freed memory in _lv_style_list_remove_style
## v7.2.0 (21.07.2020) ## v7.2.0 (21.07.2020)

View File

@ -78,7 +78,7 @@ Basically, every modern controller (which is able to drive a display) is suitabl
<tr> <tr>
<td> <strong>Heap</strong></td> <td> <strong>Heap</strong></td>
<td> &gt; 2 kB </td> <td> &gt; 2 kB </td>
<td> &gt; 16 kB</td> <td> &gt; 8 kB</td>
</tr> </tr>
<tr> <tr>
@ -145,7 +145,7 @@ void btn_event_cb(lv_obj_t * btn, lv_event_t event)
![LVGL button with label example](https://raw.githubusercontent.com/lvgl/docs/latest/misc/simple_button_example.gif) ![LVGL button with label example](https://raw.githubusercontent.com/lvgl/docs/latest/misc/simple_button_example.gif)
### LVGL from Micropython ### LVGL from Micropython
Learn more about [Micropython](https://docs.lvgl.io/en/html/get-started/micropython). Learn more about [Micropython](https://docs.lvgl.io/latest/en/html/get-started/micropython.html).
```python ```python
# Create a Button and a Label # Create a Button and a Label
scr = lv.obj() scr = lv.obj()

34
docs/ROADMAP.md Normal file
View File

@ -0,0 +1,34 @@
# Roadmap
This is a summary for thenew fatures of the major releases and a collection of ideas.
This list indicates only the current intention and can be changed.
## v8
Planned to September/October 2020
- New scrolling:
- See [feat/new-scroll](https://github.com/lvgl/lvgl/tree/feat/new-scroll) branch and [#1614](https://github.com/lvgl/lvgl/issues/1614)) issue.
- Remove `lv_page` and support scrolling on `lv_obj`
- Support "elastic" scrolling when scrolled in
- Support scroll chaining among any objects types (not only `lv_pages`s)
- Remove `lv_drag`. Similar effect can be achieved by setting the position in `LV_EVENT_PRESSING`
- Add snapping?
- Already working
- New layouts:
- See [#1615](https://github.com/lvgl/lvgl/issues/1615) issue
- [CSS Flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/)-like layout support
- Besides setting width/height in `px` add support to `partent percentage` and `screen percentage`.
- Work in progress
- Simplified File system interface ([feat/new_fs_api](https://github.com/lvgl/lvgl/tree/feat/new-fs-api) branch) to make porting easier
- Work in progress
- Add new label alignment modes
- See [#1656](https://github.com/lvgl/lvgl/issues/1656)
## Ideas
- Unit testing (gtest?). See [#1658](https://github.com/lvgl/lvgl/issues/1658)
- Benchmarking (gem5?). See [#1660](https://github.com/lvgl/lvgl/issues/1660)
- CPP binding. See [Forum](https://forum.lvgl.io/t/is-it-possible-to-officially-support-optional-cpp-api/2736)
- Optmize font decompression
- Switch to RGBA colors in styles
- Need coverage report for tests
- Need static analize (via coverity.io or somehing else).

View File

@ -1,6 +1,6 @@
{ {
"name": "lvgl", "name": "lvgl",
"version": "7.2.0", "version": "7.3.0",
"keywords": "graphics, gui, embedded, tft, lvgl", "keywords": "graphics, gui, embedded, tft, lvgl",
"description": "Graphics library to create embedded GUI with easy-to-use graphical elements, beautiful visual effects and low memory footprint. It offers anti-aliasing, opacity, and animations using only one frame buffer.", "description": "Graphics library to create embedded GUI with easy-to-use graphical elements, beautiful visual effects and low memory footprint. It offers anti-aliasing, opacity, and animations using only one frame buffer.",
"repository": { "repository": {

View File

@ -1,6 +1,6 @@
/** /**
* @file lv_conf.h * @file lv_conf.h
* Configuration file for LVGL v7.2.0 * Configuration file for LVGL v7.3.0
*/ */
/* /*
@ -97,6 +97,10 @@ typedef int16_t lv_coord_t;
# define LV_MEM_CUSTOM_FREE free /*Wrapper to free*/ # define LV_MEM_CUSTOM_FREE free /*Wrapper to free*/
#endif /*LV_MEM_CUSTOM*/ #endif /*LV_MEM_CUSTOM*/
/* Use the standard memcpy and memset instead of LVGL's own functions.
* The standard functions might or might not be faster depending on their implementation. */
#define LV_MEMCPY_MEMSET_STD 0
/* Garbage Collector settings /* Garbage Collector settings
* Used if lvgl is binded to higher level language and the memory is managed by that language */ * Used if lvgl is binded to higher level language and the memory is managed by that language */
#define LV_ENABLE_GC 0 #define LV_ENABLE_GC 0
@ -150,7 +154,7 @@ typedef void * lv_anim_user_data_t;
#endif #endif
/* 1: Enable shadow drawing*/ /* 1: Enable shadow drawing on rectangles*/
#define LV_USE_SHADOW 1 #define LV_USE_SHADOW 1
#if LV_USE_SHADOW #if LV_USE_SHADOW
/* Allow buffering some shadow calculation /* Allow buffering some shadow calculation
@ -160,6 +164,15 @@ typedef void * lv_anim_user_data_t;
#define LV_SHADOW_CACHE_SIZE 0 #define LV_SHADOW_CACHE_SIZE 0
#endif #endif
/*1: enable outline drawing on rectangles*/
#define LV_USE_OUTLINE 1
/*1: enable pattern drawing on rectangles*/
#define LV_USE_PATTERN 1
/*1: enable value string drawing on rectangles*/
#define LV_USE_VALUE_STR 1
/* 1: Use other blend modes than normal (`LV_BLEND_MODE_...`)*/ /* 1: Use other blend modes than normal (`LV_BLEND_MODE_...`)*/
#define LV_USE_BLEND_MODES 1 #define LV_USE_BLEND_MODES 1
@ -391,11 +404,20 @@ 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.*/ * but with > 10,000 characters if you see issues probably you need to enable it.*/
#define LV_FONT_FMT_TXT_LARGE 0 #define LV_FONT_FMT_TXT_LARGE 0
/* Enables/disables support for compressed fonts. If it's disabled, compressed
* glyphs cannot be processed by the library and won't be rendered.
*/
#define LV_USE_FONT_COMPRESSED 1
/* Enable subpixel rendering */
#define LV_USE_FONT_SUBPX 1
#if LV_USE_FONT_SUBPX
/* Set the pixel order of the display. /* Set the pixel order of the display.
* Important only if "subpx fonts" are used. * Important only if "subpx fonts" are used.
* With "normal" font it doesn't matter. * With "normal" font it doesn't matter.
*/ */
#define LV_FONT_SUBPX_BGR 0 #define LV_FONT_SUBPX_BGR 0
#endif
/*Declare the type of the user data of fonts (can be e.g. `void *`, `int`, `struct`)*/ /*Declare the type of the user data of fonts (can be e.g. `void *`, `int`, `struct`)*/
typedef void * lv_font_user_data_t; typedef void * lv_font_user_data_t;
@ -417,7 +439,10 @@ typedef void * lv_font_user_data_t;
/* A fast and impressive theme. /* A fast and impressive theme.
* Flags: * Flags:
* LV_THEME_MATERIAL_FLAG_LIGHT: light theme * LV_THEME_MATERIAL_FLAG_LIGHT: light theme
* LV_THEME_MATERIAL_FLAG_DARK: dark theme*/ * LV_THEME_MATERIAL_FLAG_DARK: dark theme
* LV_THEME_MATERIAL_FLAG_NO_TRANSITION: disable transitions (state change animations)
* LV_THEME_MATERIAL_FLAG_NO_FOCUS: disable indication of focused state)
* */
#define LV_USE_THEME_MATERIAL 1 #define LV_USE_THEME_MATERIAL 1
/* Mono-color theme for monochrome displays. /* Mono-color theme for monochrome displays.

2
lvgl.h
View File

@ -79,7 +79,7 @@ extern "C" {
#define LVGL_VERSION_MAJOR 7 #define LVGL_VERSION_MAJOR 7
#define LVGL_VERSION_MINOR 3 #define LVGL_VERSION_MINOR 3
#define LVGL_VERSION_PATCH 0 #define LVGL_VERSION_PATCH 0
#define LVGL_VERSION_INFO "dev" #define LVGL_VERSION_INFO ""
/********************** /**********************
* TYPEDEFS * TYPEDEFS

View File

@ -210,10 +210,19 @@ def docs_update_version(v):
cmd("git add conf.py") cmd("git add conf.py")
cmd('git ci -m "update conf.py to ' + v + '"') cmd('git ci -m "update conf.py to ' + v + '"')
def docs_merge_to_release_branch(v):
title("docs: merge to release branch")
cmd('git co release/v7 --')
cmd('git clean -fd .')
cmd('rm -f LVGL.pdf') #To avoide possible merge conflict
cmd('git merge latest')
cmd('git push origin release/v7')
def docs_build(): def docs_build():
title("docs: Build") title("docs: Build")
cmd("git checkout master") cmd("git checkout master")
cmd("./update.py latest") cmd("./update.py latest release/v7")
def clean_up(): def clean_up():
title("Clean up repos") title("Clean up repos")
@ -240,6 +249,7 @@ drivers_merge_to_release_branch(ver_str)
docs_clone() docs_clone()
docs_get_api() docs_get_api()
docs_update_version(ver_str) docs_update_version(ver_str)
docs_merge_to_release_branch(ver_str)
docs_build() docs_build()
clean_up() clean_up()

View File

@ -147,6 +147,12 @@
#endif #endif
#endif /*LV_MEM_CUSTOM*/ #endif /*LV_MEM_CUSTOM*/
/* Use the standard memcpy and memset instead of LVGL's own functions.
* The standard functions might or might not be faster depending on their implementation. */
#ifndef LV_MEMCPY_MEMSET_STD
#define LV_MEMCPY_MEMSET_STD 0
#endif
/* Garbage Collector settings /* Garbage Collector settings
* Used if lvgl is binded to higher level language and the memory is managed by that language */ * Used if lvgl is binded to higher level language and the memory is managed by that language */
#ifndef LV_ENABLE_GC #ifndef LV_ENABLE_GC
@ -223,7 +229,7 @@
#endif #endif
/* 1: Enable shadow drawing*/ /* 1: Enable shadow drawing on rectangles*/
#ifndef LV_USE_SHADOW #ifndef LV_USE_SHADOW
#define LV_USE_SHADOW 1 #define LV_USE_SHADOW 1
#endif #endif
@ -237,6 +243,21 @@
#endif #endif
#endif #endif
/*1: enable outline drawing on rectangles*/
#ifndef LV_USE_OUTLINE
#define LV_USE_OUTLINE 1
#endif
/*1: enable pattern drawing on rectangles*/
#ifndef LV_USE_PATTERN
#define LV_USE_PATTERN 1
#endif
/*1: enable value string drawing on rectangles*/
#ifndef LV_USE_VALUE_STR
#define LV_USE_VALUE_STR 1
#endif
/* 1: Use other blend modes than normal (`LV_BLEND_MODE_...`)*/ /* 1: Use other blend modes than normal (`LV_BLEND_MODE_...`)*/
#ifndef LV_USE_BLEND_MODES #ifndef LV_USE_BLEND_MODES
#define LV_USE_BLEND_MODES 1 #define LV_USE_BLEND_MODES 1
@ -589,6 +610,18 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h" */
#define LV_FONT_FMT_TXT_LARGE 0 #define LV_FONT_FMT_TXT_LARGE 0
#endif #endif
/* Enables/disables support for compressed fonts. If it's disabled, compressed
* glyphs cannot be processed by the library and won't be rendered.
*/
#ifndef LV_USE_FONT_COMPRESSED
#define LV_USE_FONT_COMPRESSED 1
#endif
/* Enable subpixel rendering */
#ifndef LV_USE_FONT_SUBPX
#define LV_USE_FONT_SUBPX 1
#endif
#if LV_USE_FONT_SUBPX
/* Set the pixel order of the display. /* Set the pixel order of the display.
* Important only if "subpx fonts" are used. * Important only if "subpx fonts" are used.
* With "normal" font it doesn't matter. * With "normal" font it doesn't matter.
@ -596,6 +629,7 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h" */
#ifndef LV_FONT_SUBPX_BGR #ifndef LV_FONT_SUBPX_BGR
#define LV_FONT_SUBPX_BGR 0 #define LV_FONT_SUBPX_BGR 0
#endif #endif
#endif
/*Declare the type of the user data of fonts (can be e.g. `void *`, `int`, `struct`)*/ /*Declare the type of the user data of fonts (can be e.g. `void *`, `int`, `struct`)*/
@ -620,7 +654,10 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h" */
/* A fast and impressive theme. /* A fast and impressive theme.
* Flags: * Flags:
* LV_THEME_MATERIAL_FLAG_LIGHT: light theme * LV_THEME_MATERIAL_FLAG_LIGHT: light theme
* LV_THEME_MATERIAL_FLAG_DARK: dark theme*/ * LV_THEME_MATERIAL_FLAG_DARK: dark theme
* LV_THEME_MATERIAL_FLAG_NO_TRANSITION: disable transitions (state change animations)
* LV_THEME_MATERIAL_FLAG_NO_FOCUS: disable indication of focused state)
* */
#ifndef LV_USE_THEME_MATERIAL #ifndef LV_USE_THEME_MATERIAL
#define LV_USE_THEME_MATERIAL 1 #define LV_USE_THEME_MATERIAL 1
#endif #endif

View File

@ -1783,7 +1783,8 @@ void lv_event_send_refresh_recursive(lv_obj_t * obj)
d = lv_disp_get_next(d); d = lv_disp_get_next(d);
} }
} else { }
else {
lv_res_t res = lv_event_send_refresh(obj); lv_res_t res = lv_event_send_refresh(obj);
if(res != LV_RES_OK) return; /*If invalid returned do not check the children*/ if(res != LV_RES_OK) return; /*If invalid returned do not check the children*/
@ -3157,7 +3158,7 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint8_t part, lv_draw_rect_dsc_t
} }
} }
#if LV_USE_OUTLINE
if(draw_dsc->outline_opa != LV_OPA_TRANSP) { if(draw_dsc->outline_opa != LV_OPA_TRANSP) {
draw_dsc->outline_width = lv_obj_get_style_outline_width(obj, part); draw_dsc->outline_width = lv_obj_get_style_outline_width(obj, part);
if(draw_dsc->outline_width) { if(draw_dsc->outline_width) {
@ -3171,7 +3172,9 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint8_t part, lv_draw_rect_dsc_t
#endif #endif
} }
} }
#endif
#if LV_USE_PATTERN
if(draw_dsc->pattern_opa != LV_OPA_TRANSP) { if(draw_dsc->pattern_opa != LV_OPA_TRANSP) {
draw_dsc->pattern_image = lv_obj_get_style_pattern_image(obj, part); draw_dsc->pattern_image = lv_obj_get_style_pattern_image(obj, part);
if(draw_dsc->pattern_image) { if(draw_dsc->pattern_image) {
@ -3192,6 +3195,8 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint8_t part, lv_draw_rect_dsc_t
} }
} }
} }
#endif
#if LV_USE_SHADOW #if LV_USE_SHADOW
if(draw_dsc->shadow_opa > LV_OPA_MIN) { if(draw_dsc->shadow_opa > LV_OPA_MIN) {
draw_dsc->shadow_width = lv_obj_get_style_shadow_width(obj, part); draw_dsc->shadow_width = lv_obj_get_style_shadow_width(obj, part);
@ -3210,6 +3215,7 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint8_t part, lv_draw_rect_dsc_t
} }
#endif #endif
#if LV_USE_VALUE_STR
if(draw_dsc->value_opa > LV_OPA_MIN) { if(draw_dsc->value_opa > LV_OPA_MIN) {
draw_dsc->value_str = lv_obj_get_style_value_str(obj, part); draw_dsc->value_str = lv_obj_get_style_value_str(obj, part);
if(draw_dsc->value_str) { if(draw_dsc->value_str) {
@ -3228,6 +3234,7 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint8_t part, lv_draw_rect_dsc_t
} }
} }
} }
#endif
#if LV_USE_OPA_SCALE #if LV_USE_OPA_SCALE
if(opa_scale < LV_OPA_MAX) { if(opa_scale < LV_OPA_MAX) {

View File

@ -257,7 +257,7 @@ void _lv_style_list_remove_style(lv_style_list_t * list, lv_style_t * style)
return; return;
} }
lv_style_t ** new_classes = lv_mem_realloc(list->style_list, sizeof(lv_style_t *) * (list->style_cnt - 1)); lv_style_t ** new_classes = lv_mem_alloc(sizeof(lv_style_t *) * (list->style_cnt - 1));
LV_ASSERT_MEM(new_classes); LV_ASSERT_MEM(new_classes);
if(new_classes == NULL) { if(new_classes == NULL) {
LV_LOG_WARN("lv_style_list_remove_style: couldn't reallocate class list"); LV_LOG_WARN("lv_style_list_remove_style: couldn't reallocate class list");
@ -271,6 +271,8 @@ void _lv_style_list_remove_style(lv_style_list_t * list, lv_style_t * style)
} }
lv_mem_free(list->style_list);
list->style_cnt--; list->style_cnt--;
list->style_list = new_classes; list->style_list = new_classes;
} }

View File

@ -570,7 +570,7 @@ bool lv_debug_check_style_list(const lv_style_list_t * list);
* lv_style_init(&my_style); * lv_style_init(&my_style);
* lv_style_copy(&my_style, &style_to_copy); * lv_style_copy(&my_style, &style_to_copy);
*/ */
#define LV_STYLE_CREATE(name, copy_p) static lv_style_t name; lv_style_init(&name); lv_style_copy(&name, copy); #define LV_STYLE_CREATE(name, copy_p) static lv_style_t name; lv_style_init(&name); lv_style_copy(&name, copy_p);

View File

@ -36,9 +36,11 @@ LV_ATTRIBUTE_FAST_MEM static void fill_normal(const lv_area_t * disp_area, lv_co
lv_color_t color, lv_opa_t opa, lv_color_t color, lv_opa_t opa,
const lv_opa_t * mask, lv_draw_mask_res_t mask_res); const lv_opa_t * mask, lv_draw_mask_res_t mask_res);
#if LV_USE_BLEND_MODES
static void fill_blended(const lv_area_t * disp_area, lv_color_t * disp_buf, const lv_area_t * draw_area, static void fill_blended(const lv_area_t * disp_area, lv_color_t * disp_buf, const lv_area_t * draw_area,
lv_color_t color, lv_opa_t opa, lv_color_t color, lv_opa_t opa,
const lv_opa_t * mask, lv_draw_mask_res_t mask_res, lv_blend_mode_t mode); const lv_opa_t * mask, lv_draw_mask_res_t mask_res, lv_blend_mode_t mode);
#endif
static void map_set_px(const lv_area_t * disp_area, lv_color_t * disp_buf, const lv_area_t * draw_area, static void map_set_px(const lv_area_t * disp_area, lv_color_t * disp_buf, const lv_area_t * draw_area,
const lv_area_t * map_area, const lv_color_t * map_buf, lv_opa_t opa, const lv_area_t * map_area, const lv_color_t * map_buf, lv_opa_t opa,
@ -49,12 +51,14 @@ LV_ATTRIBUTE_FAST_MEM static void map_normal(const lv_area_t * disp_area, lv_col
const lv_area_t * map_area, const lv_color_t * map_buf, lv_opa_t opa, const lv_area_t * map_area, const lv_color_t * map_buf, lv_opa_t opa,
const lv_opa_t * mask, lv_draw_mask_res_t mask_res); const lv_opa_t * mask, lv_draw_mask_res_t mask_res);
#if LV_USE_BLEND_MODES
static void map_blended(const lv_area_t * disp_area, lv_color_t * disp_buf, const lv_area_t * draw_area, static void map_blended(const lv_area_t * disp_area, lv_color_t * disp_buf, const lv_area_t * draw_area,
const lv_area_t * map_area, const lv_color_t * map_buf, lv_opa_t opa, const lv_area_t * map_area, const lv_color_t * map_buf, lv_opa_t opa,
const lv_opa_t * mask, lv_draw_mask_res_t mask_res, lv_blend_mode_t mode); const lv_opa_t * mask, lv_draw_mask_res_t mask_res, lv_blend_mode_t mode);
static inline lv_color_t color_blend_true_color_additive(lv_color_t fg, lv_color_t bg, lv_opa_t opa); static inline lv_color_t color_blend_true_color_additive(lv_color_t fg, lv_color_t bg, lv_opa_t opa);
static inline lv_color_t color_blend_true_color_subtractive(lv_color_t fg, lv_color_t bg, lv_opa_t opa); static inline lv_color_t color_blend_true_color_subtractive(lv_color_t fg, lv_color_t bg, lv_opa_t opa);
#endif
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
@ -167,9 +171,11 @@ LV_ATTRIBUTE_FAST_MEM void _lv_blend_fill(const lv_area_t * clip_area, const lv_
else if(mode == LV_BLEND_MODE_NORMAL) { else if(mode == LV_BLEND_MODE_NORMAL) {
fill_normal(disp_area, disp_buf, &draw_area, color, opa, mask, mask_res); fill_normal(disp_area, disp_buf, &draw_area, color, opa, mask, mask_res);
} }
#if LV_USE_BLEND_MODES
else { else {
fill_blended(disp_area, disp_buf, &draw_area, color, opa, mask, mask_res, mode); fill_blended(disp_area, disp_buf, &draw_area, color, opa, mask, mask_res, mode);
} }
#endif
} }
/** /**
@ -230,9 +236,11 @@ LV_ATTRIBUTE_FAST_MEM void _lv_blend_map(const lv_area_t * clip_area, const lv_a
else if(mode == LV_BLEND_MODE_NORMAL) { else if(mode == LV_BLEND_MODE_NORMAL) {
map_normal(disp_area, disp_buf, &draw_area, map_area, map_buf, opa, mask, mask_res); map_normal(disp_area, disp_buf, &draw_area, map_area, map_buf, opa, mask, mask_res);
} }
#if LV_USE_BLEND_MODES
else { else {
map_blended(disp_area, disp_buf, &draw_area, map_area, map_buf, opa, mask, mask_res, mode); map_blended(disp_area, disp_buf, &draw_area, map_area, map_buf, opa, mask, mask_res, mode);
} }
#endif
} }
@ -515,7 +523,7 @@ LV_ATTRIBUTE_FAST_MEM static void fill_normal(const lv_area_t * disp_area, lv_co
} }
} }
#if LV_USE_BLEND_MODES
/** /**
* Fill an area with a color but apply blending algorithms * Fill an area with a color but apply blending algorithms
* @param disp_area the current display area (destination area) * @param disp_area the current display area (destination area)
@ -606,6 +614,7 @@ static void fill_blended(const lv_area_t * disp_area, lv_color_t * disp_buf, co
} }
} }
} }
#endif
static void map_set_px(const lv_area_t * disp_area, lv_color_t * disp_buf, const lv_area_t * draw_area, static void map_set_px(const lv_area_t * disp_area, lv_color_t * disp_buf, const lv_area_t * draw_area,
const lv_area_t * map_area, const lv_color_t * map_buf, lv_opa_t opa, const lv_area_t * map_area, const lv_color_t * map_buf, lv_opa_t opa,
@ -845,7 +854,7 @@ LV_ATTRIBUTE_FAST_MEM static void map_normal(const lv_area_t * disp_area, lv_col
} }
} }
} }
#if LV_USE_BLEND_MODES
static void map_blended(const lv_area_t * disp_area, lv_color_t * disp_buf, const lv_area_t * draw_area, static void map_blended(const lv_area_t * disp_area, lv_color_t * disp_buf, const lv_area_t * draw_area,
const lv_area_t * map_area, const lv_color_t * map_buf, lv_opa_t opa, const lv_area_t * map_area, const lv_color_t * map_buf, lv_opa_t opa,
const lv_opa_t * mask, lv_draw_mask_res_t mask_res, lv_blend_mode_t mode) const lv_opa_t * mask, lv_draw_mask_res_t mask_res, lv_blend_mode_t mode)
@ -996,3 +1005,4 @@ static inline lv_color_t color_blend_true_color_subtractive(lv_color_t fg, lv_co
return lv_color_mix(fg, bg, opa); return lv_color_mix(fg, bg, opa);
} }
#endif

View File

@ -26,8 +26,10 @@ extern "C" {
**********************/ **********************/
enum { enum {
LV_BLEND_MODE_NORMAL, LV_BLEND_MODE_NORMAL,
#if LV_USE_BLEND_MODES
LV_BLEND_MODE_ADDITIVE, LV_BLEND_MODE_ADDITIVE,
LV_BLEND_MODE_SUBTRACTIVE, LV_BLEND_MODE_SUBTRACTIVE,
#endif
}; };
typedef uint8_t lv_blend_mode_t; typedef uint8_t lv_blend_mode_t;

View File

@ -607,6 +607,7 @@ LV_ATTRIBUTE_FAST_MEM static void draw_letter_normal(lv_coord_t pos_x, lv_coord_
static void draw_letter_subpx(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph_dsc_t * g, const lv_area_t * clip_area, static void draw_letter_subpx(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph_dsc_t * g, const lv_area_t * clip_area,
const uint8_t * map_p, lv_color_t color, lv_opa_t opa, lv_blend_mode_t blend_mode) const uint8_t * map_p, lv_color_t color, lv_opa_t opa, lv_blend_mode_t blend_mode)
{ {
#if LV_USE_FONT_SUBPX
const uint8_t * bpp_opa_table; const uint8_t * bpp_opa_table;
uint32_t bitmask_init; uint32_t bitmask_init;
uint32_t bitmask; uint32_t bitmask;
@ -806,6 +807,9 @@ static void draw_letter_subpx(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph_
_lv_mem_buf_release(mask_buf); _lv_mem_buf_release(mask_buf);
_lv_mem_buf_release(color_buf); _lv_mem_buf_release(color_buf);
#else
LV_LOG_WARN("Can't draw sub-pixel rendered letter because LV_USE_FONT_SUBPX == 0 in lv_conf.h");
#endif
} }

View File

@ -30,8 +30,10 @@
LV_ATTRIBUTE_FAST_MEM static void draw_bg(const lv_area_t * coords, const lv_area_t * clip, lv_draw_rect_dsc_t * dsc); LV_ATTRIBUTE_FAST_MEM static void draw_bg(const lv_area_t * coords, const lv_area_t * clip, lv_draw_rect_dsc_t * dsc);
LV_ATTRIBUTE_FAST_MEM static void draw_border(const lv_area_t * coords, const lv_area_t * clip, LV_ATTRIBUTE_FAST_MEM static void draw_border(const lv_area_t * coords, const lv_area_t * clip,
lv_draw_rect_dsc_t * dsc); lv_draw_rect_dsc_t * dsc);
static void draw_outline(const lv_area_t * coords, const lv_area_t * clip, lv_draw_rect_dsc_t * dsc);
LV_ATTRIBUTE_FAST_MEM static inline lv_color_t grad_get(lv_draw_rect_dsc_t * dsc, lv_coord_t s, lv_coord_t i); #if LV_USE_OUTLINE
static void draw_outline(const lv_area_t * coords, const lv_area_t * clip, lv_draw_rect_dsc_t * dsc);
#endif
#if LV_USE_SHADOW #if LV_USE_SHADOW
LV_ATTRIBUTE_FAST_MEM static void draw_shadow(const lv_area_t * coords, const lv_area_t * clip, LV_ATTRIBUTE_FAST_MEM static void draw_shadow(const lv_area_t * coords, const lv_area_t * clip,
lv_draw_rect_dsc_t * dsc); lv_draw_rect_dsc_t * dsc);
@ -39,8 +41,17 @@ LV_ATTRIBUTE_FAST_MEM static void shadow_draw_corner_buf(const lv_area_t * coord
lv_coord_t r); lv_coord_t r);
LV_ATTRIBUTE_FAST_MEM static void shadow_blur_corner(lv_coord_t size, lv_coord_t sw, uint16_t * sh_ups_buf); LV_ATTRIBUTE_FAST_MEM static void shadow_blur_corner(lv_coord_t size, lv_coord_t sw, uint16_t * sh_ups_buf);
#endif #endif
static void draw_pattern(const lv_area_t * coords, const lv_area_t * clip, lv_draw_rect_dsc_t * dsc);
static void draw_value(const lv_area_t * coords, const lv_area_t * clip, lv_draw_rect_dsc_t * dsc); #if LV_USE_PATTERN
static void draw_pattern(const lv_area_t * coords, const lv_area_t * clip, lv_draw_rect_dsc_t * dsc);
#endif
#if LV_USE_VALUE_STR
static void draw_value_str(const lv_area_t * coords, const lv_area_t * clip, lv_draw_rect_dsc_t * dsc);
#endif
static void draw_full_border(const lv_area_t * area_inner, const lv_area_t * area_outer, const lv_area_t * clip,
lv_coord_t radius, lv_color_t color, lv_opa_t opa, lv_blend_mode_t blend_mode);
LV_ATTRIBUTE_FAST_MEM static inline lv_color_t grad_get(lv_draw_rect_dsc_t * dsc, lv_coord_t s, lv_coord_t i);
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
@ -95,10 +106,19 @@ void lv_draw_rect(const lv_area_t * coords, const lv_area_t * clip, lv_draw_rect
#endif #endif
draw_bg(coords, clip, dsc); draw_bg(coords, clip, dsc);
#if LV_USE_PATTERN
draw_pattern(coords, clip, dsc); draw_pattern(coords, clip, dsc);
#endif
draw_border(coords, clip, dsc); draw_border(coords, clip, dsc);
draw_value(coords, clip, dsc);
#if LV_USE_VALUE_STR
draw_value_str(coords, clip, dsc);
#endif
#if LV_USE_OUTLINE
draw_outline(coords, clip, dsc); draw_outline(coords, clip, dsc);
#endif
LV_ASSERT_MEM_INTEGRITY(); LV_ASSERT_MEM_INTEGRITY();
} }
@ -370,8 +390,27 @@ LV_ATTRIBUTE_FAST_MEM static void draw_border(const lv_area_t * coords, const lv
if(dsc->border_width == 0) return; if(dsc->border_width == 0) return;
if(dsc->border_side == LV_BORDER_SIDE_NONE) return; if(dsc->border_side == LV_BORDER_SIDE_NONE) return;
lv_opa_t opa = dsc->border_opa; int32_t coords_w = lv_area_get_width(coords);
int32_t coords_h = lv_area_get_height(coords);
/*Get the real radius*/
int32_t rout = dsc->radius;
int32_t short_side = LV_MATH_MIN(coords_w, coords_h);
if(rout > short_side >> 1) rout = short_side >> 1;
/*Get the inner area*/
lv_area_t area_inner;
lv_area_copy(&area_inner, coords);
area_inner.x1 += ((dsc->border_side & LV_BORDER_SIDE_LEFT) ? dsc->border_width : - (dsc->border_width + rout));
area_inner.x2 -= ((dsc->border_side & LV_BORDER_SIDE_RIGHT) ? dsc->border_width : - (dsc->border_width + rout));
area_inner.y1 += ((dsc->border_side & LV_BORDER_SIDE_TOP) ? dsc->border_width : - (dsc->border_width + rout));
area_inner.y2 -= ((dsc->border_side & LV_BORDER_SIDE_BOTTOM) ? dsc->border_width : - (dsc->border_width + rout));
if(dsc->border_side == LV_BORDER_SIDE_FULL) {
draw_full_border(&area_inner, coords, clip, dsc->radius, dsc->border_color, dsc->border_opa, dsc->border_blend_mode);
}
else {
lv_opa_t opa = dsc->border_opa;
if(opa > LV_OPA_MAX) opa = LV_OPA_COVER; if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;
lv_disp_t * disp = _lv_refr_get_disp_refreshing(); lv_disp_t * disp = _lv_refr_get_disp_refreshing();
@ -398,43 +437,19 @@ LV_ATTRIBUTE_FAST_MEM static void draw_border(const lv_area_t * coords, const lv
/*Create a mask if there is a radius*/ /*Create a mask if there is a radius*/
lv_opa_t * mask_buf = _lv_mem_buf_get(draw_area_w); lv_opa_t * mask_buf = _lv_mem_buf_get(draw_area_w);
uint8_t other_mask_cnt = lv_draw_mask_get_cnt(); /*Create mask for the outer area*/
bool simple_mode = true;
if(other_mask_cnt) simple_mode = false;
else if(dsc->border_side != LV_BORDER_SIDE_FULL) simple_mode = false;
int16_t mask_rout_id = LV_MASK_ID_INV; int16_t mask_rout_id = LV_MASK_ID_INV;
int32_t coords_w = lv_area_get_width(coords);
int32_t coords_h = lv_area_get_height(coords);
/*Get the real radius*/
int32_t rout = dsc->radius;
int32_t short_side = LV_MATH_MIN(coords_w, coords_h);
if(rout > short_side >> 1) rout = short_side >> 1;
/*Get the outer area*/
lv_draw_mask_radius_param_t mask_rout_param; lv_draw_mask_radius_param_t mask_rout_param;
if(rout > 0) { if(rout > 0) {
lv_draw_mask_radius_init(&mask_rout_param, coords, rout, false); lv_draw_mask_radius_init(&mask_rout_param, coords, rout, false);
mask_rout_id = lv_draw_mask_add(&mask_rout_param, NULL); mask_rout_id = lv_draw_mask_add(&mask_rout_param, NULL);
} }
/*Get the inner radius*/ /*Create mask for the inner mask*/
int32_t rin = rout - dsc->border_width; int32_t rin = rout - dsc->border_width;
if(rin < 0) rin = 0; if(rin < 0) rin = 0;
/*Get the inner area*/
lv_area_t area_small;
lv_area_copy(&area_small, coords);
area_small.x1 += ((dsc->border_side & LV_BORDER_SIDE_LEFT) ? dsc->border_width : - (dsc->border_width + rout));
area_small.x2 -= ((dsc->border_side & LV_BORDER_SIDE_RIGHT) ? dsc->border_width : - (dsc->border_width + rout));
area_small.y1 += ((dsc->border_side & LV_BORDER_SIDE_TOP) ? dsc->border_width : - (dsc->border_width + rout));
area_small.y2 -= ((dsc->border_side & LV_BORDER_SIDE_BOTTOM) ? dsc->border_width : - (dsc->border_width + rout));
/*Create inner the mask*/
lv_draw_mask_radius_param_t mask_rin_param; lv_draw_mask_radius_param_t mask_rin_param;
lv_draw_mask_radius_init(&mask_rin_param, &area_small, rout - dsc->border_width, true); lv_draw_mask_radius_init(&mask_rin_param, &area_inner, rout - dsc->border_width, true);
int16_t mask_rin_id = lv_draw_mask_add(&mask_rin_param, NULL); int16_t mask_rin_id = lv_draw_mask_add(&mask_rin_param, NULL);
int32_t corner_size = LV_MATH_MAX(rout, dsc->border_width - 1); int32_t corner_size = LV_MATH_MAX(rout, dsc->border_width - 1);
@ -446,100 +461,6 @@ LV_ATTRIBUTE_FAST_MEM static void draw_border(const lv_area_t * coords, const lv
lv_color_t color = dsc->border_color; lv_color_t color = dsc->border_color;
lv_blend_mode_t blend_mode = dsc->border_blend_mode; lv_blend_mode_t blend_mode = dsc->border_blend_mode;
/*Apply some optimization if there is no other mask*/
if(simple_mode) {
/*Draw the upper corner area*/
int32_t upper_corner_end = coords->y1 - disp_area->y1 + corner_size;
upper_corner_end = LV_MATH_MIN(upper_corner_end, draw_area.y2);
fill_area.x1 = coords->x1;
fill_area.x2 = coords->x2;
fill_area.y1 = disp_area->y1 + draw_area.y1;
fill_area.y2 = fill_area.y1;
for(h = draw_area.y1; h <= upper_corner_end; h++) {
_lv_memset_ff(mask_buf, draw_area_w);
mask_res = lv_draw_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w);
lv_area_t fill_area2;
fill_area2.y1 = fill_area.y1;
fill_area2.y2 = fill_area.y2;
fill_area2.x1 = coords->x1;
fill_area2.x2 = coords->x1 + rout - 1;
_lv_blend_fill(clip, &fill_area2, color, mask_buf, mask_res, opa, blend_mode);
/*Draw the top horizontal line*/
if(fill_area2.y2 < coords->y1 + dsc->border_width) {
fill_area2.x1 = coords->x1 + rout;
fill_area2.x2 = coords->x2 - rout;
_lv_blend_fill(clip, &fill_area2, color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, blend_mode);
}
fill_area2.x1 = coords->x2 - rout + 1;
fill_area2.x2 = coords->x2;
int32_t mask_ofs = (coords->x2 - rout + 1) - (vdb->area.x1 + draw_area.x1);
if(mask_ofs < 0) mask_ofs = 0;
_lv_blend_fill(clip, &fill_area2, color, mask_buf + mask_ofs, mask_res, opa, blend_mode);
fill_area.y1++;
fill_area.y2++;
}
/*Draw the lower corner area */
int32_t lower_corner_end = coords->y2 - disp_area->y1 - corner_size;
lower_corner_end = LV_MATH_MAX(lower_corner_end, draw_area.y1);
if(lower_corner_end <= upper_corner_end) lower_corner_end = upper_corner_end + 1;
fill_area.y1 = disp_area->y1 + lower_corner_end;
fill_area.y2 = fill_area.y1;
for(h = lower_corner_end; h <= draw_area.y2; h++) {
_lv_memset_ff(mask_buf, draw_area_w);
mask_res = lv_draw_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w);
lv_area_t fill_area2;
fill_area2.x1 = coords->x1;
fill_area2.x2 = coords->x1 + rout - 1;
fill_area2.y1 = fill_area.y1;
fill_area2.y2 = fill_area.y2;
_lv_blend_fill(clip, &fill_area2, color, mask_buf, mask_res, opa, blend_mode);
/*Draw the bottom horizontal line*/
if(fill_area2.y2 > coords->y2 - dsc->border_width) {
fill_area2.x1 = coords->x1 + rout;
fill_area2.x2 = coords->x2 - rout;
_lv_blend_fill(clip, &fill_area2, color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, blend_mode);
}
fill_area2.x1 = coords->x2 - rout + 1;
fill_area2.x2 = coords->x2;
int32_t mask_ofs = (coords->x2 - rout + 1) - (vdb->area.x1 + draw_area.x1);
if(mask_ofs < 0) mask_ofs = 0;
_lv_blend_fill(clip, &fill_area2, color, mask_buf + mask_ofs, mask_res, opa, blend_mode);
fill_area.y1++;
fill_area.y2++;
}
/*Draw the left vertical border part*/
fill_area.y1 = coords->y1 + corner_size + 1;
fill_area.y2 = coords->y2 - corner_size - 1;
fill_area.x1 = coords->x1;
fill_area.x2 = coords->x1 + dsc->border_width - 1;
_lv_blend_fill(clip, &fill_area, color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, blend_mode);
/*Draw the right vertical border*/
fill_area.x1 = coords->x2 - dsc->border_width + 1;
fill_area.x2 = coords->x2;
_lv_blend_fill(clip, &fill_area, color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, blend_mode);
}
/*Process line by line if there is other mask too*/
else {
fill_area.x1 = coords->x1; fill_area.x1 = coords->x1;
fill_area.x2 = coords->x2; fill_area.x2 = coords->x2;
fill_area.y1 = disp_area->y1 + draw_area.y1; fill_area.y1 = disp_area->y1 + draw_area.y1;
@ -575,10 +496,10 @@ LV_ATTRIBUTE_FAST_MEM static void draw_border(const lv_area_t * coords, const lv
fill_area.y2++; fill_area.y2++;
} }
}
lv_draw_mask_remove_id(mask_rin_id); lv_draw_mask_remove_id(mask_rin_id);
lv_draw_mask_remove_id(mask_rout_id); lv_draw_mask_remove_id(mask_rout_id);
_lv_mem_buf_release(mask_buf); _lv_mem_buf_release(mask_buf);
}
} }
LV_ATTRIBUTE_FAST_MEM static inline lv_color_t grad_get(lv_draw_rect_dsc_t * dsc, lv_coord_t s, lv_coord_t i) LV_ATTRIBUTE_FAST_MEM static inline lv_color_t grad_get(lv_draw_rect_dsc_t * dsc, lv_coord_t s, lv_coord_t i)
@ -1226,6 +1147,7 @@ LV_ATTRIBUTE_FAST_MEM static void shadow_blur_corner(lv_coord_t size, lv_coord_t
#endif #endif
#if LV_USE_OUTLINE
static void draw_outline(const lv_area_t * coords, const lv_area_t * clip, lv_draw_rect_dsc_t * dsc) static void draw_outline(const lv_area_t * coords, const lv_area_t * clip, lv_draw_rect_dsc_t * dsc)
{ {
if(dsc->outline_opa <= LV_OPA_MIN) return; if(dsc->outline_opa <= LV_OPA_MIN) return;
@ -1235,10 +1157,6 @@ static void draw_outline(const lv_area_t * coords, const lv_area_t * clip, lv_dr
if(opa > LV_OPA_MAX) opa = LV_OPA_COVER; if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;
uint8_t other_mask_cnt = lv_draw_mask_get_cnt();
bool simple_mode = true;
if(other_mask_cnt) simple_mode = false;
/*Get the inner radius*/ /*Get the inner radius*/
lv_area_t area_inner; lv_area_t area_inner;
lv_area_copy(&area_inner, coords); lv_area_copy(&area_inner, coords);
@ -1247,16 +1165,6 @@ static void draw_outline(const lv_area_t * coords, const lv_area_t * clip, lv_dr
area_inner.x2 += dsc->outline_pad; area_inner.x2 += dsc->outline_pad;
area_inner.y2 += dsc->outline_pad; area_inner.y2 += dsc->outline_pad;
int32_t inner_w = lv_area_get_width(&area_inner);
int32_t inner_h = lv_area_get_height(&area_inner);
int32_t rin = dsc->radius;
int32_t short_side = LV_MATH_MIN(inner_w, inner_h);
if(rin > short_side >> 1) rin = short_side >> 1;
/*Get the outer area*/
int32_t rout = rin + dsc->outline_width;
lv_area_t area_outer; lv_area_t area_outer;
lv_area_copy(&area_outer, &area_inner); lv_area_copy(&area_outer, &area_inner);
@ -1265,165 +1173,13 @@ static void draw_outline(const lv_area_t * coords, const lv_area_t * clip, lv_dr
area_outer.y1 -= dsc->outline_width; area_outer.y1 -= dsc->outline_width;
area_outer.y2 += dsc->outline_width; area_outer.y2 += dsc->outline_width;
int32_t coords_out_w = lv_area_get_width(&area_outer); draw_full_border(&area_inner, &area_outer, clip, dsc->radius, dsc->outline_color, dsc->outline_opa,
int32_t coords_out_h = lv_area_get_height(&area_outer); dsc->outline_blend_mode);
short_side = LV_MATH_MIN(coords_out_w, coords_out_h);
if(rout > short_side >> 1) rout = short_side >> 1;
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
/* Get clipped fill area which is the real draw area.
* It is always the same or inside `fill_area` */
lv_area_t draw_area;
bool is_common;
is_common = _lv_area_intersect(&draw_area, &area_outer, clip);
if(is_common == false) return;
const lv_area_t * disp_area = &vdb->area;
/* Now `draw_area` has absolute coordinates.
* Make it relative to `disp_area` to simplify draw to `disp_buf`*/
draw_area.x1 -= disp_area->x1;
draw_area.y1 -= disp_area->y1;
draw_area.x2 -= disp_area->x1;
draw_area.y2 -= disp_area->y1;
int32_t draw_area_w = lv_area_get_width(&draw_area);
/*Create inner the mask*/
lv_draw_mask_radius_param_t mask_rin_param;
lv_draw_mask_radius_init(&mask_rin_param, &area_inner, rin, true);
int16_t mask_rin_id = lv_draw_mask_add(&mask_rin_param, NULL);
lv_draw_mask_radius_param_t mask_rout_param;
lv_draw_mask_radius_init(&mask_rout_param, &area_outer, rout, false);
int16_t mask_rout_id = lv_draw_mask_add(&mask_rout_param, NULL);
lv_opa_t * mask_buf = _lv_mem_buf_get(draw_area_w);
int32_t corner_size = LV_MATH_MAX(rout, dsc->outline_width - 1);
int32_t h;
lv_draw_mask_res_t mask_res;
lv_area_t fill_area;
lv_color_t color = dsc->outline_color;
lv_blend_mode_t blend_mode = dsc->outline_blend_mode;
/*Apply some optimization if there is no other mask*/
if(simple_mode) {
/*Draw the upper corner area*/
int32_t upper_corner_end = area_outer.y1 - disp_area->y1 + corner_size;
fill_area.x1 = area_outer.x1;
fill_area.x2 = area_outer.x2;
fill_area.y1 = disp_area->y1 + draw_area.y1;
fill_area.y2 = fill_area.y1;
for(h = draw_area.y1; h <= upper_corner_end; h++) {
_lv_memset_ff(mask_buf, draw_area_w);
mask_res = lv_draw_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w);
lv_area_t fill_area2;
fill_area2.y1 = fill_area.y1;
fill_area2.y2 = fill_area.y2;
fill_area2.x1 = area_outer.x1;
fill_area2.x2 = area_outer.x1 + rout - 1;
_lv_blend_fill(clip, &fill_area2, color, mask_buf, mask_res, opa, blend_mode);
/*Draw the top horizontal line*/
if(fill_area2.y2 < area_outer.y1 + dsc->outline_width) {
fill_area2.x1 = area_outer.x1 + rout;
fill_area2.x2 = area_outer.x2 - rout;
_lv_blend_fill(clip, &fill_area2, color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, blend_mode);
}
fill_area2.x1 = area_outer.x2 - rout + 1;
fill_area2.x2 = area_outer.x2;
int32_t mask_ofs = (area_outer.x2 - rout + 1) - (vdb->area.x1 + draw_area.x1);
if(mask_ofs < 0) mask_ofs = 0;
_lv_blend_fill(clip, &fill_area2, color, mask_buf + mask_ofs, mask_res, opa, blend_mode);
fill_area.y1++;
fill_area.y2++;
}
/*Draw the lower corner area */
int32_t lower_corner_end = area_outer.y2 - disp_area->y1 - corner_size;
if(lower_corner_end <= upper_corner_end) lower_corner_end = upper_corner_end + 1;
fill_area.y1 = disp_area->y1 + lower_corner_end;
fill_area.y2 = fill_area.y1;
for(h = lower_corner_end; h <= draw_area.y2; h++) {
_lv_memset_ff(mask_buf, draw_area_w);
mask_res = lv_draw_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w);
lv_area_t fill_area2;
fill_area2.x1 = area_outer.x1;
fill_area2.x2 = area_outer.x1 + rout - 1;
fill_area2.y1 = fill_area.y1;
fill_area2.y2 = fill_area.y2;
_lv_blend_fill(clip, &fill_area2, color, mask_buf, mask_res, opa, blend_mode);
/*Draw the bottom horizontal line*/
if(fill_area2.y2 > area_outer.y2 - dsc->outline_width) {
fill_area2.x1 = area_outer.x1 + rout;
fill_area2.x2 = area_outer.x2 - rout;
_lv_blend_fill(clip, &fill_area2, color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, blend_mode);
}
fill_area2.x1 = area_outer.x2 - rout + 1;
fill_area2.x2 = area_outer.x2;
int32_t mask_ofs = (area_outer.x2 - rout + 1) - (vdb->area.x1 + draw_area.x1);
if(mask_ofs < 0) mask_ofs = 0;
_lv_blend_fill(clip, &fill_area2, color, mask_buf + mask_ofs, mask_res, opa, blend_mode);
fill_area.y1++;
fill_area.y2++;
}
/*Draw the left vertical part*/
fill_area.y1 = area_outer.y1 + corner_size + 1;
fill_area.y2 = area_outer.y2 - corner_size - 1;
fill_area.x1 = area_outer.x1;
fill_area.x2 = area_outer.x1 + dsc->outline_width - 1;
_lv_blend_fill(clip, &fill_area, color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, blend_mode);
/*Draw the right vertical border*/
fill_area.x1 = area_outer.x2 - dsc->outline_width + 1;
fill_area.x2 = area_outer.x2;
_lv_blend_fill(clip, &fill_area, color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, blend_mode);
}
/*Process line by line if there is other mask too*/
else {
fill_area.x1 = area_outer.x1;
fill_area.x2 = area_outer.x2;
fill_area.y1 = disp_area->y1 + draw_area.y1;
fill_area.y2 = fill_area.y1;
for(h = draw_area.y1; h <= draw_area.y2; h++) {
_lv_memset_ff(mask_buf, draw_area_w);
mask_res = lv_draw_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w);
_lv_blend_fill(clip, &fill_area, color, mask_buf, mask_res, opa, blend_mode);
fill_area.y1++;
fill_area.y2++;
}
}
lv_draw_mask_remove_id(mask_rin_id);
lv_draw_mask_remove_id(mask_rout_id);
_lv_mem_buf_release(mask_buf);
} }
#endif
#if LV_USE_PATTERN
static void draw_pattern(const lv_area_t * coords, const lv_area_t * clip, lv_draw_rect_dsc_t * dsc) static void draw_pattern(const lv_area_t * coords, const lv_area_t * clip, lv_draw_rect_dsc_t * dsc)
{ {
if(dsc->pattern_image == NULL) return; if(dsc->pattern_image == NULL) return;
@ -1524,9 +1280,11 @@ static void draw_pattern(const lv_area_t * coords, const lv_area_t * clip, lv_dr
lv_draw_mask_remove_id(radius_mask_id); lv_draw_mask_remove_id(radius_mask_id);
} }
} }
#endif
static void draw_value(const lv_area_t * coords, const lv_area_t * clip, lv_draw_rect_dsc_t * dsc) #if LV_USE_VALUE_STR
static void draw_value_str(const lv_area_t * coords, const lv_area_t * clip, lv_draw_rect_dsc_t * dsc)
{ {
if(dsc->value_str == NULL) return; if(dsc->value_str == NULL) return;
if(dsc->value_opa <= LV_OPA_MIN) return; if(dsc->value_opa <= LV_OPA_MIN) return;
@ -1559,3 +1317,179 @@ static void draw_value(const lv_area_t * coords, const lv_area_t * clip, lv_draw
lv_draw_label(&value_area, clip, &label_dsc, dsc->value_str, NULL); lv_draw_label(&value_area, clip, &label_dsc, dsc->value_str, NULL);
} }
#endif
static void draw_full_border(const lv_area_t * area_inner, const lv_area_t * area_outer, const lv_area_t * clip,
lv_coord_t radius, lv_color_t color, lv_opa_t opa, lv_blend_mode_t blend_mode)
{
uint8_t other_mask_cnt = lv_draw_mask_get_cnt();
bool simple_mode = true;
if(other_mask_cnt) simple_mode = false;
int32_t inner_w = lv_area_get_width(area_inner);
int32_t inner_h = lv_area_get_height(area_inner);
lv_coord_t border_width = area_outer->x2 - area_inner->x2;
int32_t rin = radius;
int32_t short_side = LV_MATH_MIN(inner_w, inner_h);
if(rin > short_side >> 1) rin = short_side >> 1;
/*Get the outer area*/
int32_t rout = rin + border_width;
int32_t coords_out_w = lv_area_get_width(area_outer);
int32_t coords_out_h = lv_area_get_height(area_outer);
short_side = LV_MATH_MIN(coords_out_w, coords_out_h);
if(rout > short_side >> 1) rout = short_side >> 1;
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
/* Get clipped fill area which is the real draw area.
* It is always the same or inside `fill_area` */
lv_area_t draw_area;
bool is_common;
is_common = _lv_area_intersect(&draw_area, area_outer, clip);
if(is_common == false) return;
const lv_area_t * disp_area = &vdb->area;
/* Now `draw_area` has absolute coordinates.
* Make it relative to `disp_area` to simplify draw to `disp_buf`*/
draw_area.x1 -= disp_area->x1;
draw_area.y1 -= disp_area->y1;
draw_area.x2 -= disp_area->x1;
draw_area.y2 -= disp_area->y1;
int32_t draw_area_w = lv_area_get_width(&draw_area);
/*Create inner the mask*/
lv_draw_mask_radius_param_t mask_rin_param;
lv_draw_mask_radius_init(&mask_rin_param, area_inner, rin, true);
int16_t mask_rin_id = lv_draw_mask_add(&mask_rin_param, NULL);
lv_draw_mask_radius_param_t mask_rout_param;
lv_draw_mask_radius_init(&mask_rout_param, area_outer, rout, false);
int16_t mask_rout_id = lv_draw_mask_add(&mask_rout_param, NULL);
lv_opa_t * mask_buf = _lv_mem_buf_get(draw_area_w);
int32_t corner_size = LV_MATH_MAX(rout, border_width - 1);
int32_t h;
lv_draw_mask_res_t mask_res;
lv_area_t fill_area;
/*Apply some optimization if there is no other mask*/
if(simple_mode) {
/*Draw the upper corner area*/
int32_t upper_corner_end = area_outer->y1 - disp_area->y1 + corner_size;
fill_area.x1 = area_outer->x1;
fill_area.x2 = area_outer->x2;
fill_area.y1 = disp_area->y1 + draw_area.y1;
fill_area.y2 = fill_area.y1;
for(h = draw_area.y1; h <= upper_corner_end; h++) {
_lv_memset_ff(mask_buf, draw_area_w);
mask_res = lv_draw_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w);
lv_area_t fill_area2;
fill_area2.y1 = fill_area.y1;
fill_area2.y2 = fill_area.y2;
fill_area2.x1 = area_outer->x1;
fill_area2.x2 = area_outer->x1 + rout - 1;
_lv_blend_fill(clip, &fill_area2, color, mask_buf, mask_res, opa, blend_mode);
/*Draw the top horizontal line*/
if(fill_area2.y2 < area_outer->y1 + border_width) {
fill_area2.x1 = area_outer->x1 + rout;
fill_area2.x2 = area_outer->x2 - rout;
_lv_blend_fill(clip, &fill_area2, color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, blend_mode);
}
fill_area2.x1 = area_outer->x2 - rout + 1;
fill_area2.x2 = area_outer->x2;
int32_t mask_ofs = (area_outer->x2 - rout + 1) - (vdb->area.x1 + draw_area.x1);
if(mask_ofs < 0) mask_ofs = 0;
_lv_blend_fill(clip, &fill_area2, color, mask_buf + mask_ofs, mask_res, opa, blend_mode);
fill_area.y1++;
fill_area.y2++;
}
/*Draw the lower corner area */
int32_t lower_corner_end = area_outer->y2 - disp_area->y1 - corner_size;
if(lower_corner_end <= upper_corner_end) lower_corner_end = upper_corner_end + 1;
fill_area.y1 = disp_area->y1 + lower_corner_end;
fill_area.y2 = fill_area.y1;
for(h = lower_corner_end; h <= draw_area.y2; h++) {
_lv_memset_ff(mask_buf, draw_area_w);
mask_res = lv_draw_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w);
lv_area_t fill_area2;
fill_area2.x1 = area_outer->x1;
fill_area2.x2 = area_outer->x1 + rout - 1;
fill_area2.y1 = fill_area.y1;
fill_area2.y2 = fill_area.y2;
_lv_blend_fill(clip, &fill_area2, color, mask_buf, mask_res, opa, blend_mode);
/*Draw the bottom horizontal line*/
if(fill_area2.y2 > area_outer->y2 - border_width) {
fill_area2.x1 = area_outer->x1 + rout;
fill_area2.x2 = area_outer->x2 - rout;
_lv_blend_fill(clip, &fill_area2, color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, blend_mode);
}
fill_area2.x1 = area_outer->x2 - rout + 1;
fill_area2.x2 = area_outer->x2;
int32_t mask_ofs = (area_outer->x2 - rout + 1) - (vdb->area.x1 + draw_area.x1);
if(mask_ofs < 0) mask_ofs = 0;
_lv_blend_fill(clip, &fill_area2, color, mask_buf + mask_ofs, mask_res, opa, blend_mode);
fill_area.y1++;
fill_area.y2++;
}
/*Draw the left vertical part*/
fill_area.y1 = area_outer->y1 + corner_size + 1;
fill_area.y2 = area_outer->y2 - corner_size - 1;
fill_area.x1 = area_outer->x1;
fill_area.x2 = area_outer->x1 + border_width - 1;
_lv_blend_fill(clip, &fill_area, color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, blend_mode);
/*Draw the right vertical border*/
fill_area.x1 = area_outer->x2 - border_width + 1;
fill_area.x2 = area_outer->x2;
_lv_blend_fill(clip, &fill_area, color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, blend_mode);
}
/*Process line by line if there is other mask too*/
else {
fill_area.x1 = area_outer->x1;
fill_area.x2 = area_outer->x2;
fill_area.y1 = disp_area->y1 + draw_area.y1;
fill_area.y2 = fill_area.y1;
for(h = draw_area.y1; h <= draw_area.y2; h++) {
_lv_memset_ff(mask_buf, draw_area_w);
mask_res = lv_draw_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w);
_lv_blend_fill(clip, &fill_area, color, mask_buf, mask_res, opa, blend_mode);
fill_area.y1++;
fill_area.y2++;
}
}
lv_draw_mask_remove_id(mask_rin_id);
lv_draw_mask_remove_id(mask_rout_id);
_lv_mem_buf_release(mask_buf);
}

View File

@ -88,6 +88,7 @@ const uint8_t * lv_font_get_bitmap_fmt_txt(const lv_font_t * font, uint32_t unic
} }
/*Handle compressed bitmap*/ /*Handle compressed bitmap*/
else { else {
#if LV_USE_FONT_COMPRESSED
uint32_t gsize = gdsc->box_w * gdsc->box_h; uint32_t gsize = gdsc->box_w * gdsc->box_h;
if(gsize == 0) return NULL; if(gsize == 0) return NULL;
@ -118,6 +119,9 @@ const uint8_t * lv_font_get_bitmap_fmt_txt(const lv_font_t * font, uint32_t unic
decompress(&fdsc->glyph_bitmap[gdsc->bitmap_index], decompr_buf, gdsc->box_w, gdsc->box_h, (uint8_t)fdsc->bpp, decompress(&fdsc->glyph_bitmap[gdsc->bitmap_index], decompr_buf, gdsc->box_w, gdsc->box_h, (uint8_t)fdsc->bpp,
prefilter); prefilter);
return decompr_buf; return decompr_buf;
#else /* !LV_USE_FONT_COMPRESSED */
return NULL;
#endif
} }
/*If not returned earlier then the letter is not found in this font*/ /*If not returned earlier then the letter is not found in this font*/

View File

@ -586,6 +586,7 @@ void _lv_mem_buf_free_all(void)
} }
} }
#if LV_MEMCPY_MEMSET_STD == 0
/** /**
* Same as `memcpy` but optimized for 4 byte operation. * Same as `memcpy` but optimized for 4 byte operation.
* @param dst pointer to the destination buffer * @param dst pointer to the destination buffer
@ -652,7 +653,6 @@ LV_ATTRIBUTE_FAST_MEM void * _lv_memcpy(void * dst, const void * src, size_t len
/** /**
* Same as `memset` but optimized for 4 byte operation. * Same as `memset` but optimized for 4 byte operation.
* `dst` should be word aligned else normal `memcpy` will be used
* @param dst pointer to the destination buffer * @param dst pointer to the destination buffer
* @param v value to set [0..255] * @param v value to set [0..255]
* @param len number of byte to set * @param len number of byte to set
@ -707,7 +707,6 @@ LV_ATTRIBUTE_FAST_MEM void _lv_memset(void * dst, uint8_t v, size_t len)
/** /**
* Same as `memset(dst, 0x00, len)` but optimized for 4 byte operation. * Same as `memset(dst, 0x00, len)` but optimized for 4 byte operation.
* `dst` should be word aligned else normal `memcpy` will be used
* @param dst pointer to the destination buffer * @param dst pointer to the destination buffer
* @param len number of byte to set * @param len number of byte to set
*/ */
@ -757,7 +756,6 @@ LV_ATTRIBUTE_FAST_MEM void _lv_memset_00(void * dst, size_t len)
/** /**
* Same as `memset(dst, 0xFF, len)` but optimized for 4 byte operation. * Same as `memset(dst, 0xFF, len)` but optimized for 4 byte operation.
* `dst` should be word aligned else normal `memcpy` will be used
* @param dst pointer to the destination buffer * @param dst pointer to the destination buffer
* @param len number of byte to set * @param len number of byte to set
*/ */
@ -805,6 +803,7 @@ LV_ATTRIBUTE_FAST_MEM void _lv_memset_ff(void * dst, size_t len)
} }
} }
#endif /*LV_MEMCPY_MEMSET_STD*/
/********************** /**********************
* STATIC FUNCTIONS * STATIC FUNCTIONS

View File

@ -20,6 +20,10 @@ extern "C" {
#include "lv_log.h" #include "lv_log.h"
#include "lv_types.h" #include "lv_types.h"
#if LV_MEMCPY_MEMSET_STD
#include <string.h>
#endif
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
@ -137,6 +141,62 @@ void _lv_mem_buf_free_all(void);
//! @cond Doxygen_Suppress //! @cond Doxygen_Suppress
#if LV_MEMCPY_MEMSET_STD
/**
* Wrapper for the standard memcpy
* @param dst pointer to the destination buffer
* @param src pointer to the source buffer
* @param len number of byte to copy
*/
static inline void * _lv_memcpy(void * dst, const void * src, size_t len)
{
return memcpy(dst, src, len);
}
/**
* Wrapper for the standard memcpy
* @param dst pointer to the destination buffer
* @param src pointer to the source buffer
* @param len number of byte to copy
*/
static inline void * _lv_memcpy_small(void * dst, const void * src, size_t len)
{
return memcpy(dst, src, len);
}
/**
* Wrapper for the standard memset
* @param dst pointer to the destination buffer
* @param v value to set [0..255]
* @param len number of byte to set
*/
static inline void _lv_memset(void * dst, uint8_t v, size_t len)
{
memset(dst, v, len);
}
/**
* Wrapper for the standard memset with fixed 0x00 value
* @param dst pointer to the destination buffer
* @param len number of byte to set
*/
static inline void _lv_memset_00(void * dst, size_t len)
{
memset(dst, 0x00, len);
}
/**
* Wrapper for the standard memset with fixed 0xFF value
* @param dst pointer to the destination buffer
* @param len number of byte to set
*/
static inline void _lv_memset_ff(void * dst, size_t len)
{
memset(dst, 0xFF, len);
}
#else
/** /**
* Same as `memcpy` but optimized for 4 byte operation. * Same as `memcpy` but optimized for 4 byte operation.
* @param dst pointer to the destination buffer * @param dst pointer to the destination buffer
@ -168,7 +228,6 @@ LV_ATTRIBUTE_FAST_MEM static inline void * _lv_memcpy_small(void * dst, const vo
/** /**
* Same as `memset` but optimized for 4 byte operation. * Same as `memset` but optimized for 4 byte operation.
* `dst` should be word aligned else normal `memcpy` will be used
* @param dst pointer to the destination buffer * @param dst pointer to the destination buffer
* @param v value to set [0..255] * @param v value to set [0..255]
* @param len number of byte to set * @param len number of byte to set
@ -177,7 +236,6 @@ LV_ATTRIBUTE_FAST_MEM void _lv_memset(void * dst, uint8_t v, size_t len);
/** /**
* Same as `memset(dst, 0x00, len)` but optimized for 4 byte operation. * Same as `memset(dst, 0x00, len)` but optimized for 4 byte operation.
* `dst` should be word aligned else normal `memcpy` will be used
* @param dst pointer to the destination buffer * @param dst pointer to the destination buffer
* @param len number of byte to set * @param len number of byte to set
*/ */
@ -185,7 +243,6 @@ LV_ATTRIBUTE_FAST_MEM void _lv_memset_00(void * dst, size_t len);
/** /**
* Same as `memset(dst, 0xFF, len)` but optimized for 4 byte operation. * Same as `memset(dst, 0xFF, len)` but optimized for 4 byte operation.
* `dst` should be word aligned else normal `memcpy` will be used
* @param dst pointer to the destination buffer * @param dst pointer to the destination buffer
* @param len number of byte to set * @param len number of byte to set
*/ */
@ -193,6 +250,9 @@ LV_ATTRIBUTE_FAST_MEM void _lv_memset_ff(void * dst, size_t len);
//! @endcond //! @endcond
#endif
/********************** /**********************
* MACROS * MACROS
**********************/ **********************/

View File

@ -64,8 +64,9 @@
#define COLOR_BG_SEC_TEXT (IS_LIGHT ? lv_color_hex(0x31404f) : lv_color_hex(0xa5a8ad)) #define COLOR_BG_SEC_TEXT (IS_LIGHT ? lv_color_hex(0x31404f) : lv_color_hex(0xa5a8ad))
#define COLOR_BG_SEC_TEXT_DIS (IS_LIGHT ? lv_color_hex(0xaaaaaa) : lv_color_hex(0xa5a8ad)) #define COLOR_BG_SEC_TEXT_DIS (IS_LIGHT ? lv_color_hex(0xaaaaaa) : lv_color_hex(0xa5a8ad))
#define TRANSITION_TIME 150 #define TRANSITION_TIME ((theme.flags & LV_THEME_MATERIAL_FLAG_NO_TRANSITION) ? 0 : 150)
#define BORDER_WIDTH LV_DPX(2) #define BORDER_WIDTH LV_DPX(2)
#define OUTLINE_WIDTH ((theme.flags & LV_THEME_MATERIAL_FLAG_NO_FOCUS) ? 0 : LV_DPX(2))
#define IS_LIGHT (theme.flags & LV_THEME_MATERIAL_FLAG_LIGHT) #define IS_LIGHT (theme.flags & LV_THEME_MATERIAL_FLAG_LIGHT)
#define PAD_DEF (lv_disp_get_size_category(NULL) <= LV_DISP_SIZE_MEDIUM ? LV_DPX(15) : (LV_DPX(30))) #define PAD_DEF (lv_disp_get_size_category(NULL) <= LV_DISP_SIZE_MEDIUM ? LV_DPX(15) : (LV_DPX(30)))
@ -210,7 +211,8 @@ static void basic_init(void)
lv_style_set_bg_opa(&styles->bg, LV_STATE_DEFAULT, LV_OPA_COVER); lv_style_set_bg_opa(&styles->bg, LV_STATE_DEFAULT, LV_OPA_COVER);
lv_style_set_bg_color(&styles->bg, LV_STATE_DEFAULT, COLOR_BG); lv_style_set_bg_color(&styles->bg, LV_STATE_DEFAULT, COLOR_BG);
lv_style_set_border_color(&styles->bg, LV_STATE_DEFAULT, COLOR_BG_BORDER); lv_style_set_border_color(&styles->bg, LV_STATE_DEFAULT, COLOR_BG_BORDER);
lv_style_set_border_color(&styles->bg, LV_STATE_FOCUSED, theme.color_primary); if((theme.flags & LV_THEME_MATERIAL_FLAG_NO_FOCUS) == 0)lv_style_set_border_color(&styles->bg, LV_STATE_FOCUSED,
theme.color_primary);
lv_style_set_border_color(&styles->bg, LV_STATE_EDITED, theme.color_secondary); lv_style_set_border_color(&styles->bg, LV_STATE_EDITED, theme.color_secondary);
lv_style_set_border_width(&styles->bg, LV_STATE_DEFAULT, BORDER_WIDTH); lv_style_set_border_width(&styles->bg, LV_STATE_DEFAULT, BORDER_WIDTH);
lv_style_set_border_post(&styles->bg, LV_STATE_DEFAULT, true); lv_style_set_border_post(&styles->bg, LV_STATE_DEFAULT, true);
@ -298,7 +300,7 @@ static void basic_init(void)
lv_style_set_pad_top(&styles->btn, LV_STATE_DEFAULT, LV_DPX(15)); lv_style_set_pad_top(&styles->btn, LV_STATE_DEFAULT, LV_DPX(15));
lv_style_set_pad_bottom(&styles->btn, LV_STATE_DEFAULT, LV_DPX(15)); lv_style_set_pad_bottom(&styles->btn, LV_STATE_DEFAULT, LV_DPX(15));
lv_style_set_pad_inner(&styles->btn, LV_STATE_DEFAULT, LV_DPX(20)); lv_style_set_pad_inner(&styles->btn, LV_STATE_DEFAULT, LV_DPX(20));
lv_style_set_outline_width(&styles->btn, LV_STATE_DEFAULT, 3); lv_style_set_outline_width(&styles->btn, LV_STATE_DEFAULT, OUTLINE_WIDTH);
lv_style_set_outline_opa(&styles->btn, LV_STATE_DEFAULT, LV_OPA_0); lv_style_set_outline_opa(&styles->btn, LV_STATE_DEFAULT, LV_OPA_0);
lv_style_set_outline_opa(&styles->btn, LV_STATE_FOCUSED, LV_OPA_50); lv_style_set_outline_opa(&styles->btn, LV_STATE_FOCUSED, LV_OPA_50);
lv_style_set_outline_color(&styles->btn, LV_STATE_DEFAULT, theme.color_primary); lv_style_set_outline_color(&styles->btn, LV_STATE_DEFAULT, theme.color_primary);
@ -357,7 +359,7 @@ static void bar_init(void)
lv_style_set_outline_color(&styles->bar_bg, LV_STATE_EDITED, theme.color_secondary); lv_style_set_outline_color(&styles->bar_bg, LV_STATE_EDITED, theme.color_secondary);
lv_style_set_outline_opa(&styles->bar_bg, LV_STATE_DEFAULT, LV_OPA_TRANSP); lv_style_set_outline_opa(&styles->bar_bg, LV_STATE_DEFAULT, LV_OPA_TRANSP);
lv_style_set_outline_opa(&styles->bar_bg, LV_STATE_FOCUSED, LV_OPA_50); lv_style_set_outline_opa(&styles->bar_bg, LV_STATE_FOCUSED, LV_OPA_50);
lv_style_set_outline_width(&styles->bar_bg, LV_STATE_DEFAULT, 3); lv_style_set_outline_width(&styles->bar_bg, LV_STATE_DEFAULT, OUTLINE_WIDTH);
lv_style_set_transition_time(&styles->bar_bg, LV_STATE_DEFAULT, TRANSITION_TIME); lv_style_set_transition_time(&styles->bar_bg, LV_STATE_DEFAULT, TRANSITION_TIME);
lv_style_set_transition_prop_6(&styles->bar_bg, LV_STATE_DEFAULT, LV_STYLE_OUTLINE_OPA); lv_style_set_transition_prop_6(&styles->bar_bg, LV_STATE_DEFAULT, LV_STYLE_OUTLINE_OPA);
@ -608,7 +610,7 @@ static void checkbox_init(void)
lv_style_set_outline_color(&styles->cb_bg, LV_STATE_DEFAULT, theme.color_primary); lv_style_set_outline_color(&styles->cb_bg, LV_STATE_DEFAULT, theme.color_primary);
lv_style_set_outline_opa(&styles->cb_bg, LV_STATE_DEFAULT, LV_OPA_TRANSP); lv_style_set_outline_opa(&styles->cb_bg, LV_STATE_DEFAULT, LV_OPA_TRANSP);
lv_style_set_outline_opa(&styles->cb_bg, LV_STATE_FOCUSED, LV_OPA_50); lv_style_set_outline_opa(&styles->cb_bg, LV_STATE_FOCUSED, LV_OPA_50);
lv_style_set_outline_width(&styles->cb_bg, LV_STATE_DEFAULT, LV_DPX(3)); lv_style_set_outline_width(&styles->cb_bg, LV_STATE_DEFAULT, OUTLINE_WIDTH);
lv_style_set_outline_pad(&styles->cb_bg, LV_STATE_DEFAULT, LV_DPX(10)); lv_style_set_outline_pad(&styles->cb_bg, LV_STATE_DEFAULT, LV_DPX(10));
lv_style_set_transition_time(&styles->cb_bg, LV_STATE_DEFAULT, TRANSITION_TIME); lv_style_set_transition_time(&styles->cb_bg, LV_STATE_DEFAULT, TRANSITION_TIME);
lv_style_set_transition_prop_6(&styles->cb_bg, LV_STATE_DEFAULT, LV_STYLE_OUTLINE_OPA); lv_style_set_transition_prop_6(&styles->cb_bg, LV_STATE_DEFAULT, LV_STYLE_OUTLINE_OPA);
@ -738,7 +740,7 @@ static void list_init(void)
lv_style_set_border_width(&styles->list_btn, LV_STATE_DEFAULT, 1); lv_style_set_border_width(&styles->list_btn, LV_STATE_DEFAULT, 1);
lv_style_set_outline_color(&styles->list_btn, LV_STATE_FOCUSED, theme.color_secondary); lv_style_set_outline_color(&styles->list_btn, LV_STATE_FOCUSED, theme.color_secondary);
lv_style_set_outline_width(&styles->list_btn, LV_STATE_FOCUSED, BORDER_WIDTH); lv_style_set_outline_width(&styles->list_btn, LV_STATE_FOCUSED, OUTLINE_WIDTH);
lv_style_set_outline_pad(&styles->list_btn, LV_STATE_FOCUSED, -BORDER_WIDTH); lv_style_set_outline_pad(&styles->list_btn, LV_STATE_FOCUSED, -BORDER_WIDTH);
lv_style_set_pad_left(&styles->list_btn, LV_STATE_DEFAULT, PAD_DEF); lv_style_set_pad_left(&styles->list_btn, LV_STATE_DEFAULT, PAD_DEF);

View File

@ -24,6 +24,7 @@ typedef enum {
LV_THEME_MATERIAL_FLAG_DARK = 0x01, LV_THEME_MATERIAL_FLAG_DARK = 0x01,
LV_THEME_MATERIAL_FLAG_LIGHT = 0x02, LV_THEME_MATERIAL_FLAG_LIGHT = 0x02,
LV_THEME_MATERIAL_FLAG_NO_TRANSITION = 0x10, LV_THEME_MATERIAL_FLAG_NO_TRANSITION = 0x10,
LV_THEME_MATERIAL_FLAG_NO_FOCUS = 0x20,
} lv_theme_material_flag_t; } lv_theme_material_flag_t;
/********************** /**********************

View File

@ -658,7 +658,6 @@ static lv_design_res_t lv_btnmatrix_design(lv_obj_t * btnm, const lv_area_t * cl
lv_draw_rect_dsc_t draw_rect_tmp_dsc; lv_draw_rect_dsc_t draw_rect_tmp_dsc;
lv_draw_label_dsc_t draw_label_tmp_dsc; lv_draw_label_dsc_t draw_label_tmp_dsc;
/*The state changes without re-caching the styles, disable the use of cache*/
lv_state_t state_ori = btnm->state; lv_state_t state_ori = btnm->state;
btnm->state = LV_STATE_DEFAULT; btnm->state = LV_STATE_DEFAULT;
lv_draw_rect_dsc_init(&draw_rect_rel_dsc); lv_draw_rect_dsc_init(&draw_rect_rel_dsc);
@ -695,9 +694,20 @@ static lv_design_res_t lv_btnmatrix_design(lv_obj_t * btnm, const lv_area_t * cl
/*Choose the style*/ /*Choose the style*/
lv_draw_rect_dsc_t * draw_rect_dsc_act; lv_draw_rect_dsc_t * draw_rect_dsc_act;
lv_draw_label_dsc_t * draw_label_dsc_act; lv_draw_label_dsc_t * draw_label_dsc_act;
bool tgl_state = button_get_tgl_state(ext->ctrl_bits[btn_i]); lv_state_t btn_state = LV_STATE_DEFAULT;
if(button_get_tgl_state(ext->ctrl_bits[btn_i])) btn_state |= LV_STATE_CHECKED;
if(button_is_inactive(ext->ctrl_bits[btn_i])) btn_state |= LV_STATE_DISABLED;
if(btn_i == ext->btn_id_pr) btn_state |= LV_STATE_PRESSED;
if(btn_i == ext->btn_id_focused) {
btn_state |= LV_STATE_FOCUSED;
if(state_ori & LV_STATE_EDITED) btn_state |= LV_STATE_EDITED;
}
if(tgl_state) { if(btn_state == LV_STATE_DEFAULT) {
draw_rect_dsc_act = &draw_rect_rel_dsc;
draw_label_dsc_act = &draw_label_rel_dsc;
}
else if(btn_state == LV_STATE_CHECKED) {
if(!chk_inited) { if(!chk_inited) {
btnm->state = LV_STATE_CHECKED; btnm->state = LV_STATE_CHECKED;
lv_draw_rect_dsc_init(&draw_rect_chk_dsc); lv_draw_rect_dsc_init(&draw_rect_chk_dsc);
@ -708,9 +718,10 @@ static lv_design_res_t lv_btnmatrix_design(lv_obj_t * btnm, const lv_area_t * cl
btnm->state = state_ori; btnm->state = state_ori;
chk_inited = true; chk_inited = true;
} }
draw_rect_dsc_act = &draw_rect_chk_dsc;
draw_label_dsc_act = &draw_label_chk_dsc;
} }
else if(btn_state == LV_STATE_CHECKED) {
if(button_is_inactive(ext->ctrl_bits[btn_i])) {
if(!disabled_inited) { if(!disabled_inited) {
btnm->state = LV_STATE_DISABLED; btnm->state = LV_STATE_DISABLED;
lv_draw_rect_dsc_init(&draw_rect_ina_dsc); lv_draw_rect_dsc_init(&draw_rect_ina_dsc);
@ -724,21 +735,9 @@ static lv_design_res_t lv_btnmatrix_design(lv_obj_t * btnm, const lv_area_t * cl
draw_rect_dsc_act = &draw_rect_ina_dsc; draw_rect_dsc_act = &draw_rect_ina_dsc;
draw_label_dsc_act = &draw_label_ina_dsc; draw_label_dsc_act = &draw_label_ina_dsc;
} }
/*Simple released or checked buttons button*/ /*In other cases get the styles directly without caching them*/
else if(btn_i != ext->btn_id_pr && btn_i != ext->btn_id_focused) {
draw_rect_dsc_act = tgl_state ? &draw_rect_chk_dsc : &draw_rect_rel_dsc;
draw_label_dsc_act = tgl_state ? &draw_label_chk_dsc : &draw_label_rel_dsc;
}
/*Focused and/or pressed + checked or released button*/
else { else {
btnm->state = LV_STATE_DEFAULT; btnm->state = btn_state;
if(tgl_state) btnm->state = LV_STATE_CHECKED;
if(ext->btn_id_pr == btn_i) btnm->state |= LV_STATE_PRESSED;
if(ext->btn_id_focused == btn_i) {
btnm->state |= LV_STATE_FOCUSED;
if(state_ori & LV_STATE_EDITED) btnm->state |= LV_STATE_EDITED;
}
lv_draw_rect_dsc_init(&draw_rect_tmp_dsc); lv_draw_rect_dsc_init(&draw_rect_tmp_dsc);
lv_draw_label_dsc_init(&draw_label_tmp_dsc); lv_draw_label_dsc_init(&draw_label_tmp_dsc);
lv_obj_init_draw_rect_dsc(btnm, LV_BTNMATRIX_PART_BTN, &draw_rect_tmp_dsc); lv_obj_init_draw_rect_dsc(btnm, LV_BTNMATRIX_PART_BTN, &draw_rect_tmp_dsc);

View File

@ -48,6 +48,13 @@
#define TRI_OFFSET 2 #define TRI_OFFSET 2
/* The OUTER_MASK_WIDTH define is required to assist with the placing of a mask over the outer ring of the widget as when the
* multicoloured radial lines are calculated for the outer ring of the widget their lengths are jittering because of the
* integer based arithmetic. From tests the maximum delta was found to be 2 so the current value is set to 3 to achieve
* appropriate masking.
*/
#define OUTER_MASK_WIDTH 3
/********************** /**********************
* TYPEDEFS * TYPEDEFS
**********************/ **********************/
@ -483,6 +490,17 @@ static void draw_disc_grad(lv_obj_t * cpicker, const lv_area_t * mask)
uint16_t i; uint16_t i;
lv_coord_t cir_w = lv_obj_get_style_scale_width(cpicker, LV_CPICKER_PART_MAIN); lv_coord_t cir_w = lv_obj_get_style_scale_width(cpicker, LV_CPICKER_PART_MAIN);
/* Mask outer ring of widget to tidy up ragged edges of lines while drawing outer ring */
lv_area_t mask_area_out;
lv_area_copy(&mask_area_out, &cpicker->coords);
mask_area_out.x1 += OUTER_MASK_WIDTH;
mask_area_out.x2 -= OUTER_MASK_WIDTH;
mask_area_out.y1 += OUTER_MASK_WIDTH;
mask_area_out.y2 -= OUTER_MASK_WIDTH;
lv_draw_mask_radius_param_t mask_out_param;
lv_draw_mask_radius_init(&mask_out_param, &mask_area_out, LV_RADIUS_CIRCLE, false);
int16_t mask_out_id = lv_draw_mask_add(&mask_out_param, 0);
/* The inner line ends will be masked out. /* The inner line ends will be masked out.
* So make lines a little bit longer because the masking makes a more even result */ * So make lines a little bit longer because the masking makes a more even result */
lv_coord_t cir_w_extra = cir_w + line_dsc.width; lv_coord_t cir_w_extra = cir_w + line_dsc.width;
@ -498,7 +516,8 @@ static void draw_disc_grad(lv_obj_t * cpicker, const lv_area_t * mask)
lv_draw_line(&p[0], &p[1], mask, &line_dsc); lv_draw_line(&p[0], &p[1], mask, &line_dsc);
} }
/* Now remove mask to continue with inner part */
lv_draw_mask_remove_id(mask_out_id);
/*Mask out the inner area*/ /*Mask out the inner area*/
lv_draw_rect_dsc_t bg_dsc; lv_draw_rect_dsc_t bg_dsc;

View File

@ -589,15 +589,6 @@ static void lv_gauge_draw_needle(lv_obj_t * gauge, const lv_area_t * clip_area)
lv_draw_line_dsc_init(&line_dsc); lv_draw_line_dsc_init(&line_dsc);
lv_obj_init_draw_line_dsc(gauge, LV_GAUGE_PART_NEEDLE, &line_dsc); lv_obj_init_draw_line_dsc(gauge, LV_GAUGE_PART_NEEDLE, &line_dsc);
lv_draw_img_dsc_t img_dsc;
if(ext->needle_img == NULL) {
lv_draw_img_dsc_init(&img_dsc);
lv_obj_init_draw_img_dsc(gauge, LV_GAUGE_PART_MAIN, &img_dsc);
img_dsc.recolor_opa = LV_OPA_COVER;
img_dsc.pivot.x = ext->needle_img_pivot.x;
img_dsc.pivot.y = ext->needle_img_pivot.y;
}
p_mid.x = x_ofs; p_mid.x = x_ofs;
p_mid.y = y_ofs; p_mid.y = y_ofs;
for(i = 0; i < ext->needle_count; i++) { for(i = 0; i < ext->needle_count; i++) {
@ -625,10 +616,18 @@ static void lv_gauge_draw_needle(lv_obj_t * gauge, const lv_area_t * clip_area)
a.y1 = gauge->coords.y1 + lv_area_get_height(&gauge->coords) / 2 - ext->needle_img_pivot.y; a.y1 = gauge->coords.y1 + lv_area_get_height(&gauge->coords) / 2 - ext->needle_img_pivot.y;
a.x2 = a.x1 + info.w - 1; a.x2 = a.x1 + info.w - 1;
a.y2 = a.y1 + info.h - 1; a.y2 = a.y1 + info.h - 1;
lv_draw_img_dsc_t img_dsc;
lv_draw_img_dsc_init(&img_dsc);
lv_obj_init_draw_img_dsc(gauge, LV_GAUGE_PART_MAIN, &img_dsc);
img_dsc.recolor_opa = LV_OPA_COVER;
img_dsc.pivot.x = ext->needle_img_pivot.x;
img_dsc.pivot.y = ext->needle_img_pivot.y;
if(ext->needle_colors != NULL) if(ext->needle_colors != NULL)
img_dsc.recolor = ext->needle_colors[i]; img_dsc.recolor = ext->needle_colors[i];
needle_angle = (needle_angle * 10);
if(needle_angle > 3600) needle_angle -= 3600;
img_dsc.angle = needle_angle; img_dsc.angle = needle_angle;
lv_draw_img(&a, clip_area, ext->needle_img, &img_dsc); lv_draw_img(&a, clip_area, ext->needle_img, &img_dsc);
} }

View File

@ -495,7 +495,7 @@ uint16_t lv_list_get_size(const lv_obj_t * list)
lv_obj_t * btn = lv_list_get_next_btn(list, NULL); lv_obj_t * btn = lv_list_get_next_btn(list, NULL);
while(btn) { while(btn) {
size++; size++;
btn = lv_list_get_next_btn(list, NULL); btn = lv_list_get_next_btn(list, btn);
} }
return size; return size;
} }

View File

@ -440,18 +440,17 @@ void lv_tabview_set_tab_act(lv_obj_t * tabview, uint16_t id, lv_anim_enable_t an
* @param id index of the tab the name should be set * @param id index of the tab the name should be set
* @param name new tab name * @param name new tab name
*/ */
void lv_tabview_set_tab_name(lv_obj_t *tabview, uint16_t id, char *name) void lv_tabview_set_tab_name(lv_obj_t * tabview, uint16_t id, char * name)
{ {
LV_ASSERT_OBJ(tabview, LV_OBJX_NAME); LV_ASSERT_OBJ(tabview, LV_OBJX_NAME);
/* get tabview's ext pointer which contains the tab name pointer list */ /* get tabview's ext pointer which contains the tab name pointer list */
lv_tabview_ext_t *ext = lv_obj_get_ext_attr(tabview); lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview);
/* check for valid tab index */ /* check for valid tab index */
if (ext->tab_cnt > id) if(ext->tab_cnt > id) {
{
/* reallocate memory for new tab name (use reallocate due to mostly the size didn't change much) */ /* reallocate memory for new tab name (use reallocate due to mostly the size didn't change much) */
char *str = lv_mem_realloc((void *)ext->tab_name_ptr[id], strlen(name) + 1); char * str = lv_mem_realloc((void *)ext->tab_name_ptr[id], strlen(name) + 1);
LV_ASSERT_MEM(str); LV_ASSERT_MEM(str);
/* store new tab name at allocated memory */ /* store new tab name at allocated memory */

View File

@ -149,7 +149,7 @@ lv_obj_t * lv_textarea_create(lv_obj_t * par, const lv_obj_t * copy)
lv_label_set_text(ext->label, "Text area"); lv_label_set_text(ext->label, "Text area");
lv_obj_set_click(ext->label, false); lv_obj_set_click(ext->label, false);
lv_obj_set_size(ta, LV_TEXTAREA_DEF_WIDTH, LV_TEXTAREA_DEF_HEIGHT); lv_obj_set_size(ta, LV_TEXTAREA_DEF_WIDTH, LV_TEXTAREA_DEF_HEIGHT);
lv_textarea_set_sscrollbar_mode(ta, LV_SCROLLBAR_MODE_DRAG); lv_textarea_set_scrollbar_mode(ta, LV_SCROLLBAR_MODE_DRAG);
lv_obj_reset_style_list(ta, LV_PAGE_PART_SCROLLABLE); lv_obj_reset_style_list(ta, LV_PAGE_PART_SCROLLABLE);
lv_theme_apply(ta, LV_THEME_TEXTAREA); lv_theme_apply(ta, LV_THEME_TEXTAREA);

View File

@ -224,7 +224,7 @@ void lv_textarea_set_insert_replace(lv_obj_t * ta, const char * txt);
* @param ta pointer to a text area object * @param ta pointer to a text area object
* @param sb_mode the new mode from 'lv_scrollbar_mode_t' enum * @param sb_mode the new mode from 'lv_scrollbar_mode_t' enum
*/ */
static inline void lv_textarea_set_sscrollbar_mode(lv_obj_t * ta, lv_scrollbar_mode_t mode) static inline void lv_textarea_set_scrollbar_mode(lv_obj_t * ta, lv_scrollbar_mode_t mode)
{ {
lv_page_set_scrollbar_mode(ta, mode); lv_page_set_scrollbar_mode(ta, mode);
} }