ESP32 LVGL library from v9.2.0 to v9.2.2 (#22385)

This commit is contained in:
s-hadinger 2024-10-30 19:50:43 +01:00 committed by GitHub
parent 3f4b2331ee
commit 0ba0b8dada
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
89 changed files with 675 additions and 323 deletions

View File

@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file.
### Changed ### Changed
- ESP32 Platform from 2024.10.30 to 2024.11.30, Framework (Arduino Core) from v3.1.0.241023 to v3.1.0.241030 and IDF to 5.3.1.241024 (#22384) - ESP32 Platform from 2024.10.30 to 2024.11.30, Framework (Arduino Core) from v3.1.0.241023 to v3.1.0.241030 and IDF to 5.3.1.241024 (#22384)
- ESP32 LVGL library from v9.2.0 to v9.2.2
### Fixed ### Fixed
- ESP32 Arduino Core IPv6 zones used by Matter (#22378) - ESP32 Arduino Core IPv6 zones used by Matter (#22378)

View File

@ -1501,6 +1501,7 @@ set_button_text|lv.obj, string||[lv_list_set_button_text](https://docs.lvgl.io/9
Method|Arguments|Return type|LVGL equivalent Method|Arguments|Return type|LVGL equivalent
:---|:---|:---|:--- :---|:---|:---|:---
get_anim||lv.anim|[lv_animimg_get_anim](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_get_anim)
get_duration||int|[lv_animimg_get_duration](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_get_duration) get_duration||int|[lv_animimg_get_duration](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_get_duration)
get_repeat_count||int|[lv_animimg_get_repeat_count](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_get_repeat_count) get_repeat_count||int|[lv_animimg_get_repeat_count](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_get_repeat_count)
get_src_count||int|[lv_animimg_get_src_count](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_get_src_count) get_src_count||int|[lv_animimg_get_src_count](https://docs.lvgl.io/9.0/search.html?q=lv_animimg_get_src_count)

View File

@ -818,6 +818,7 @@ const be_ntv_func_def_t lv_timer_func[] = {
/* `lv_animimg` methods */ /* `lv_animimg` methods */
#ifdef BE_LV_WIDGET_ANIMIMG #ifdef BE_LV_WIDGET_ANIMIMG
const be_ntv_func_def_t lv_animimg_func[] = { const be_ntv_func_def_t lv_animimg_func[] = {
{ "get_anim", { (const void*) &lv_animimg_get_anim, "lv.anim", "(lv.obj)" } },
{ "get_duration", { (const void*) &lv_animimg_get_duration, "i", "(lv.obj)" } }, { "get_duration", { (const void*) &lv_animimg_get_duration, "i", "(lv.obj)" } },
{ "get_repeat_count", { (const void*) &lv_animimg_get_repeat_count, "i", "(lv.obj)" } }, { "get_repeat_count", { (const void*) &lv_animimg_get_repeat_count, "i", "(lv.obj)" } },
{ "get_src_count", { (const void*) &lv_animimg_get_src_count, "i", "(lv.obj)" } }, { "get_src_count", { (const void*) &lv_animimg_get_src_count, "i", "(lv.obj)" } },

View File

@ -1013,6 +1013,7 @@ const void ** lv_animimg_get_src(lv_obj_t * img)
uint8_t lv_animimg_get_src_count(lv_obj_t * img) uint8_t lv_animimg_get_src_count(lv_obj_t * img)
uint32_t lv_animimg_get_duration(lv_obj_t * img) uint32_t lv_animimg_get_duration(lv_obj_t * img)
uint32_t lv_animimg_get_repeat_count(lv_obj_t * img) uint32_t lv_animimg_get_repeat_count(lv_obj_t * img)
lv_anim_t * lv_animimg_get_anim(lv_obj_t * img)
// ../../lvgl/src/widgets/arc/lv_arc.h // ../../lvgl/src/widgets/arc/lv_arc.h
lv_obj_t * lv_arc_create(lv_obj_t * parent) lv_obj_t * lv_arc_create(lv_obj_t * parent)
@ -1061,7 +1062,7 @@ lv_obj_t * lv_button_create(lv_obj_t * parent)
// ../../lvgl/src/widgets/buttonmatrix/lv_buttonmatrix.h // ../../lvgl/src/widgets/buttonmatrix/lv_buttonmatrix.h
lv_obj_t * lv_buttonmatrix_create(lv_obj_t * parent) lv_obj_t * lv_buttonmatrix_create(lv_obj_t * parent)
void lv_buttonmatrix_set_map(lv_obj_t * obj, const char * map[]) void lv_buttonmatrix_set_map(lv_obj_t * obj, const char * const map[])
void lv_buttonmatrix_set_ctrl_map(lv_obj_t * obj, const lv_buttonmatrix_ctrl_t ctrl_map[]) void lv_buttonmatrix_set_ctrl_map(lv_obj_t * obj, const lv_buttonmatrix_ctrl_t ctrl_map[])
void lv_buttonmatrix_set_selected_button(lv_obj_t * obj, uint32_t btn_id) void lv_buttonmatrix_set_selected_button(lv_obj_t * obj, uint32_t btn_id)
void lv_buttonmatrix_set_button_ctrl(lv_obj_t * obj, uint32_t btn_id, lv_buttonmatrix_ctrl_t ctrl) void lv_buttonmatrix_set_button_ctrl(lv_obj_t * obj, uint32_t btn_id, lv_buttonmatrix_ctrl_t ctrl)
@ -1070,7 +1071,7 @@ void lv_buttonmatrix_set_button_ctrl_all(lv_obj_t * obj, lv_buttonmatrix_ctrl_t
void lv_buttonmatrix_clear_button_ctrl_all(lv_obj_t * obj, lv_buttonmatrix_ctrl_t ctrl) void lv_buttonmatrix_clear_button_ctrl_all(lv_obj_t * obj, lv_buttonmatrix_ctrl_t ctrl)
void lv_buttonmatrix_set_button_width(lv_obj_t * obj, uint32_t btn_id, uint32_t width) void lv_buttonmatrix_set_button_width(lv_obj_t * obj, uint32_t btn_id, uint32_t width)
void lv_buttonmatrix_set_one_checked(lv_obj_t * obj, bool en) void lv_buttonmatrix_set_one_checked(lv_obj_t * obj, bool en)
const char ** lv_buttonmatrix_get_map(const lv_obj_t * obj) const char * const * lv_buttonmatrix_get_map(const lv_obj_t * obj)
uint32_t lv_buttonmatrix_get_selected_button(const lv_obj_t * obj) uint32_t lv_buttonmatrix_get_selected_button(const lv_obj_t * obj)
const char * lv_buttonmatrix_get_button_text(const lv_obj_t * obj, uint32_t btn_id) const char * lv_buttonmatrix_get_button_text(const lv_obj_t * obj, uint32_t btn_id)
bool lv_buttonmatrix_has_button_ctrl(lv_obj_t * obj, uint32_t btn_id, lv_buttonmatrix_ctrl_t ctrl) bool lv_buttonmatrix_has_button_ctrl(lv_obj_t * obj, uint32_t btn_id, lv_buttonmatrix_ctrl_t ctrl)
@ -1092,7 +1093,7 @@ lv_result_t lv_calendar_get_pressed_date(const lv_obj_t * calendar, lv_calendar_
// ../../lvgl/src/widgets/calendar/lv_calendar_chinese.h // ../../lvgl/src/widgets/calendar/lv_calendar_chinese.h
void lv_calendar_set_chinese_mode(lv_obj_t * obj, bool en) void lv_calendar_set_chinese_mode(lv_obj_t * obj, bool en)
const char * lv_calendar_get_day_name(lv_calendar_date_t * gregorian) const char * lv_calendar_get_day_name(lv_calendar_date_t * gregorian)
lv_calendar_chinese_t lv_calendar_gregorian_to_chinese(lv_calendar_date_t * gregorian) void lv_calendar_gregorian_to_chinese(lv_calendar_date_t * gregorian_time, lv_calendar_chinese_t * chinese_time)
// ../../lvgl/src/widgets/calendar/lv_calendar_header_arrow.h // ../../lvgl/src/widgets/calendar/lv_calendar_header_arrow.h
lv_obj_t * lv_calendar_header_arrow_create(lv_obj_t * parent) lv_obj_t * lv_calendar_header_arrow_create(lv_obj_t * parent)
@ -1220,11 +1221,11 @@ lv_obj_t * lv_keyboard_create(lv_obj_t * parent)
void lv_keyboard_set_textarea(lv_obj_t * kb, lv_obj_t * ta) void lv_keyboard_set_textarea(lv_obj_t * kb, lv_obj_t * ta)
void lv_keyboard_set_mode(lv_obj_t * kb, lv_keyboard_mode_t mode) void lv_keyboard_set_mode(lv_obj_t * kb, lv_keyboard_mode_t mode)
void lv_keyboard_set_popovers(lv_obj_t * kb, bool en) void lv_keyboard_set_popovers(lv_obj_t * kb, bool en)
void lv_keyboard_set_map(lv_obj_t * kb, lv_keyboard_mode_t mode, const char * map[], const lv_buttonmatrix_ctrl_t ctrl_map[]) void lv_keyboard_set_map(lv_obj_t * kb, lv_keyboard_mode_t mode, const char * const map[], const lv_buttonmatrix_ctrl_t ctrl_map[])
lv_obj_t * lv_keyboard_get_textarea(const lv_obj_t * kb) lv_obj_t * lv_keyboard_get_textarea(const lv_obj_t * kb)
lv_keyboard_mode_t lv_keyboard_get_mode(const lv_obj_t * kb) lv_keyboard_mode_t lv_keyboard_get_mode(const lv_obj_t * kb)
bool lv_keyboard_get_popovers(const lv_obj_t * obj) bool lv_keyboard_get_popovers(const lv_obj_t * obj)
const char ** lv_keyboard_get_map_array(const lv_obj_t * kb) const char * const * lv_keyboard_get_map_array(const lv_obj_t * kb)
uint32_t lv_keyboard_get_selected_button(const lv_obj_t * obj) uint32_t lv_keyboard_get_selected_button(const lv_obj_t * obj)
const char * lv_keyboard_get_button_text(const lv_obj_t * obj, uint32_t btn_id) const char * lv_keyboard_get_button_text(const lv_obj_t * obj, uint32_t btn_id)

View File

@ -407,7 +407,7 @@ class type_mapper_class:
"lv_roller_mode_t": "i", "lv_roller_mode_t": "i",
"lv_table_cell_ctrl_t": "i", "lv_table_cell_ctrl_t": "i",
"lv_calendar_chinese_t": "c", # "lv_calendar_chinese_t": "c",
# adding ad-hoc colorwheel from LVGL8 to LVGL9 # adding ad-hoc colorwheel from LVGL8 to LVGL9
"lv_colorwheel_mode_t": "i", "lv_colorwheel_mode_t": "i",
@ -459,6 +459,7 @@ class type_mapper_class:
# "char **": "lv_str_arr", # treat as a simple pointer, decoding needs to be done at Berry level # "char **": "lv_str_arr", # treat as a simple pointer, decoding needs to be done at Berry level
"constchar **": "c", # treat as a simple pointer, decoding needs to be done at Berry level "constchar **": "c", # treat as a simple pointer, decoding needs to be done at Berry level
"void * []": "c", # treat as a simple pointer, decoding needs to be done at Berry level "void * []": "c", # treat as a simple pointer, decoding needs to be done at Berry level
"constchar * *": "c",
# callbacks # callbacks
"lv_group_focus_cb_t": "lv_group_focus_cb", "lv_group_focus_cb_t": "lv_group_focus_cb",

View File

@ -1,6 +1,6 @@
{ {
"name": "lvgl", "name": "lvgl",
"version": "9.2.0", "version": "9.2.2",
"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,5 +1,5 @@
name=lvgl name=lvgl
version=9.2.0 version=9.2.2
author=kisvegabor author=kisvegabor
maintainer=kisvegabor,embeddedt,pete-pjb maintainer=kisvegabor,embeddedt,pete-pjb
sentence=Full-featured Graphics Library for Embedded Systems sentence=Full-featured Graphics Library for Embedded Systems

View File

@ -1,6 +1,6 @@
/** /**
* @file lv_conf.h * @file lv_conf.h
* Configuration file for v9.2.0 * Configuration file for v9.2.2
*/ */
/* /*
@ -95,6 +95,14 @@
#if LV_USE_OS == LV_OS_CUSTOM #if LV_USE_OS == LV_OS_CUSTOM
#define LV_OS_CUSTOM_INCLUDE <stdint.h> #define LV_OS_CUSTOM_INCLUDE <stdint.h>
#endif #endif
#if LV_USE_OS == LV_OS_FREERTOS
/*
* Unblocking an RTOS task with a direct notification is 45% faster and uses less RAM
* than unblocking a task using an intermediary object such as a binary semaphore.
* RTOS task notifications can only be used when there is only one task that can be the recipient of the event.
*/
#define LV_USE_FREERTOS_TASK_NOTIFY 1
#endif
/*======================== /*========================
* RENDERING CONFIGURATION * RENDERING CONFIGURATION
@ -205,10 +213,16 @@
#endif #endif
/* Use NXP's PXP on iMX RTxxx platforms. */ /* Use NXP's PXP on iMX RTxxx platforms. */
#define LV_USE_DRAW_PXP 0 #define LV_USE_PXP 0
#if LV_USE_DRAW_PXP #if LV_USE_PXP
#if LV_USE_OS /* Use PXP for drawing.*/
#define LV_USE_DRAW_PXP 1
/* Use PXP to rotate display.*/
#define LV_USE_ROTATE_PXP 0
#if LV_USE_DRAW_PXP && LV_USE_OS
/* Use additional draw thread for PXP processing.*/ /* Use additional draw thread for PXP processing.*/
#define LV_USE_PXP_DRAW_THREAD 1 #define LV_USE_PXP_DRAW_THREAD 1
#endif #endif

View File

@ -8,7 +8,7 @@
#define LVGL_VERSION_MAJOR 9 #define LVGL_VERSION_MAJOR 9
#define LVGL_VERSION_MINOR 2 #define LVGL_VERSION_MINOR 2
#define LVGL_VERSION_PATCH 0 #define LVGL_VERSION_PATCH 2
#define LVGL_VERSION_INFO "" #define LVGL_VERSION_INFO ""
#endif /* LVGL_VERSION_H */ #endif /* LVGL_VERSION_H */

View File

@ -306,7 +306,7 @@ void lv_obj_add_state(lv_obj_t * obj, lv_state_t state)
lv_state_t new_state = obj->state | state; lv_state_t new_state = obj->state | state;
if(obj->state != new_state) { if(obj->state != new_state) {
if(new_state & LV_STATE_DISABLED) { if(new_state & ~obj->state & LV_STATE_DISABLED) {
lv_indev_reset(NULL, obj); lv_indev_reset(NULL, obj);
} }

View File

@ -1046,7 +1046,7 @@ static int32_t calc_content_width(lv_obj_t * obj)
default: default:
/* Consider other cases only if x=0 and use the width of the object. /* Consider other cases only if x=0 and use the width of the object.
* With x!=0 circular dependency could occur. */ * With x!=0 circular dependency could occur. */
if(lv_obj_get_style_y(child, 0) == 0) { if(lv_obj_get_style_x(child, 0) == 0) {
child_res_tmp = lv_area_get_width(&child->coords) + space_left; child_res_tmp = lv_area_get_width(&child->coords) + space_left;
child_res_tmp += lv_obj_get_style_margin_right(child, LV_PART_MAIN); child_res_tmp += lv_obj_get_style_margin_right(child, LV_PART_MAIN);
} }

View File

@ -44,7 +44,7 @@ typedef lv_result_t (*lv_property_getter_t)(const lv_obj_t *, lv_prop_id_t, lv_p
**********************/ **********************/
static lv_result_t obj_property(lv_obj_t * obj, lv_prop_id_t id, lv_property_t * value, bool set); static lv_result_t obj_property(lv_obj_t * obj, lv_prop_id_t id, lv_property_t * value, bool set);
static int32_t property_name_compare(const void * ref, const void * element); static int property_name_compare(const void * ref, const void * element);
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
@ -121,7 +121,7 @@ lv_property_t lv_obj_get_style_property(lv_obj_t * obj, lv_prop_id_t id, uint32_
uint32_t index = LV_PROPERTY_ID_INDEX(id); uint32_t index = LV_PROPERTY_ID_INDEX(id);
if(index == LV_PROPERTY_ID_INVALID || index >= LV_PROPERTY_ID_START) { if(index == LV_PROPERTY_ID_INVALID || index >= LV_PROPERTY_ID_START) {
LV_LOG_WARN("invalid style property id %d", id); LV_LOG_WARN("invalid style property id 0x%" LV_PRIx32, id);
value.id = LV_PROPERTY_ID_INVALID; value.id = LV_PROPERTY_ID_INVALID;
value.num = 0; value.num = 0;
return value; return value;
@ -232,7 +232,7 @@ static lv_result_t obj_property(lv_obj_t * obj, lv_prop_id_t id, lv_property_t *
/*id matched but we got null pointer to functions*/ /*id matched but we got null pointer to functions*/
if(set ? prop->setter == NULL : prop->getter == NULL) { if(set ? prop->setter == NULL : prop->getter == NULL) {
LV_LOG_WARN("NULL %s provided, id: %d", set ? "setter" : "getter", id); LV_LOG_WARN("NULL %s provided, id: 0x%" LV_PRIx32, set ? "setter" : "getter", id);
return LV_RESULT_INVALID; return LV_RESULT_INVALID;
} }
@ -278,7 +278,7 @@ static lv_result_t obj_property(lv_obj_t * obj, lv_prop_id_t id, lv_property_t *
break; break;
} }
default: { default: {
LV_LOG_WARN("Unknown property id: 0x%08x", prop->id); LV_LOG_WARN("Unknown property id: 0x%08" LV_PRIx32, prop->id);
return LV_RESULT_INVALID; return LV_RESULT_INVALID;
} }
} }
@ -289,7 +289,7 @@ static lv_result_t obj_property(lv_obj_t * obj, lv_prop_id_t id, lv_property_t *
/*If no setter found, try base class then*/ /*If no setter found, try base class then*/
} }
LV_LOG_WARN("Unknown property id: 0x%08x", id); LV_LOG_WARN("Unknown property id: 0x%08" LV_PRIx32, id);
return LV_RESULT_INVALID; return LV_RESULT_INVALID;
} }

View File

@ -353,6 +353,9 @@ bool lv_obj_has_style_prop(const lv_obj_t * obj, lv_style_selector_t selector, l
void lv_obj_set_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t value, void lv_obj_set_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t value,
lv_style_selector_t selector) lv_style_selector_t selector)
{ {
/*Stop running transitions wit this property */
trans_delete(obj, lv_obj_style_get_selector_part(selector), prop, NULL);
lv_style_t * style = get_local_style(obj, selector); lv_style_t * style = get_local_style(obj, selector);
if(selector == LV_PART_MAIN && lv_style_prop_has_flag(prop, LV_STYLE_PROP_FLAG_TRANSFORM)) { if(selector == LV_PART_MAIN && lv_style_prop_has_flag(prop, LV_STYLE_PROP_FLAG_TRANSFORM)) {
lv_obj_invalidate(obj); lv_obj_invalidate(obj);

View File

@ -355,7 +355,7 @@ void lv_display_refr_timer(lv_timer_t * tmr)
/* Ensure the timer does not run again automatically. /* Ensure the timer does not run again automatically.
* This is done before refreshing in case refreshing invalidates something else. * This is done before refreshing in case refreshing invalidates something else.
* However if the performance monitor is enabled keep the timer running to count the FPS.*/ * However if the performance monitor is enabled keep the timer running to count the FPS.*/
#if LV_USE_PERF_MONITOR #if !LV_USE_PERF_MONITOR
lv_timer_pause(tmr); lv_timer_pause(tmr);
#endif #endif
} }

View File

@ -141,8 +141,7 @@ struct lv_display_t {
lv_event_list_t event_list; lv_event_list_t event_list;
uint32_t sw_rotate : 1; /**< 1: use software rotation (slower)*/ uint32_t rotation : 3; /**< Element of lv_display_rotation_t*/
uint32_t rotation : 2; /**< Element of lv_display_rotation_t*/
lv_theme_t * theme; /**< The theme assigned to the screen*/ lv_theme_t * theme; /**< The theme assigned to the screen*/

View File

@ -179,8 +179,7 @@ void lv_draw_dispatch(void)
while(disp) { while(disp) {
lv_layer_t * layer = disp->layer_head; lv_layer_t * layer = disp->layer_head;
while(layer) { while(layer) {
/* If there are no tasks in the layer, skip it */ if(lv_draw_dispatch_layer(disp, layer))
if(layer->draw_task_head && lv_draw_dispatch_layer(disp, layer))
task_dispatched = true; task_dispatched = true;
layer = layer->next; layer = layer->next;
} }
@ -311,6 +310,41 @@ uint32_t lv_draw_get_unit_count(void)
lv_draw_task_t * lv_draw_get_next_available_task(lv_layer_t * layer, lv_draw_task_t * t_prev, uint8_t draw_unit_id) lv_draw_task_t * lv_draw_get_next_available_task(lv_layer_t * layer, lv_draw_task_t * t_prev, uint8_t draw_unit_id)
{ {
LV_PROFILER_BEGIN; LV_PROFILER_BEGIN;
/* If there is only 1 draw unit the task can be consumed linearly as
* they are added in the correct order. However, it can happen that
* there is a `LV_DRAW_TASK_TYPE_LAYER` which can be blended only when
* all its tasks are ready. As other areas might be on top of that
* layer-to-blend don't skip it. Instead stop there, so that the
* draw tasks of that layer can be consumed and can be finished.
* After that this layer-to-blenf will have `LV_DRAW_TASK_STATE_QUEUED`
* so it can be blended normally.*/
if(_draw_info.unit_cnt <= 1) {
lv_draw_task_t * t = layer->draw_task_head;
while(t) {
/*Mark unsupported draw tasks as ready as no one else will consume them*/
if(t->state == LV_DRAW_TASK_STATE_QUEUED &&
t->preferred_draw_unit_id != LV_DRAW_UNIT_NONE &&
t->preferred_draw_unit_id != draw_unit_id) {
t->state = LV_DRAW_TASK_STATE_READY;
}
/*Not queued yet, leave this layer while the first task will be queued*/
else if(t->state != LV_DRAW_TASK_STATE_QUEUED) {
t = NULL;
break;
}
/*It's a supported and queued task, process it*/
else {
break;
}
t = t->next;
}
LV_PROFILER_END;
return t;
}
/*Handle the case of multiply draw units*/
/*If the first task is screen sized, there cannot be independent areas*/ /*If the first task is screen sized, there cannot be independent areas*/
if(layer->draw_task_head) { if(layer->draw_task_head) {
int32_t hor_res = lv_display_get_horizontal_resolution(lv_refr_get_disp_refreshing()); int32_t hor_res = lv_display_get_horizontal_resolution(lv_refr_get_disp_refreshing());

View File

@ -83,6 +83,16 @@ lv_draw_buf_handlers_t * lv_draw_buf_get_handlers(void)
return &default_handlers; return &default_handlers;
} }
lv_draw_buf_handlers_t * lv_draw_buf_get_font_handlers(void)
{
return &font_draw_buf_handlers;
}
lv_draw_buf_handlers_t * lv_draw_buf_get_image_handlers(void)
{
return &image_cache_draw_buf_handlers;
}
uint32_t lv_draw_buf_width_to_stride(uint32_t w, lv_color_format_t color_format) uint32_t lv_draw_buf_width_to_stride(uint32_t w, lv_color_format_t color_format)
{ {
return lv_draw_buf_width_to_stride_ex(&default_handlers, w, color_format); return lv_draw_buf_width_to_stride_ex(&default_handlers, w, color_format);
@ -536,7 +546,7 @@ void lv_draw_buf_set_palette(lv_draw_buf_t * draw_buf, uint8_t index, lv_color32
palette[index] = color; palette[index] = color;
} }
bool lv_draw_buf_has_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag) bool lv_draw_buf_has_flag(const lv_draw_buf_t * draw_buf, lv_image_flags_t flag)
{ {
return draw_buf->header.flags & flag; return draw_buf->header.flags & flag;
} }

View File

@ -67,7 +67,7 @@ LV_EXPORT_CONST_INT(LV_STRIDE_AUTO);
#define LV_DRAW_BUF_INIT_STATIC(name) \ #define LV_DRAW_BUF_INIT_STATIC(name) \
do { \ do { \
lv_image_header_t * header = &name.header; \ lv_image_header_t * header = &name.header; \
lv_draw_buf_init(&name, header->w, header->h, header->cf, header->stride, buf_##name, sizeof(buf_##name)); \ lv_draw_buf_init(&name, header->w, header->h, (lv_color_format_t)header->cf, header->stride, buf_##name, sizeof(buf_##name)); \
lv_draw_buf_set_flag(&name, LV_IMAGE_FLAGS_MODIFIABLE); \ lv_draw_buf_set_flag(&name, LV_IMAGE_FLAGS_MODIFIABLE); \
} while(0) } while(0)
@ -129,6 +129,9 @@ void lv_draw_buf_handlers_init(lv_draw_buf_handlers_t * handlers,
* @return pointer to the struct of handlers * @return pointer to the struct of handlers
*/ */
lv_draw_buf_handlers_t * lv_draw_buf_get_handlers(void); lv_draw_buf_handlers_t * lv_draw_buf_get_handlers(void);
lv_draw_buf_handlers_t * lv_draw_buf_get_font_handlers(void);
lv_draw_buf_handlers_t * lv_draw_buf_get_image_handlers(void);
/** /**
* Align the address of a buffer. The buffer needs to be large enough for the real data after alignment * Align the address of a buffer. The buffer needs to be large enough for the real data after alignment
@ -304,7 +307,7 @@ lv_result_t lv_draw_buf_adjust_stride(lv_draw_buf_t * src, uint32_t stride);
*/ */
lv_result_t lv_draw_buf_premultiply(lv_draw_buf_t * draw_buf); lv_result_t lv_draw_buf_premultiply(lv_draw_buf_t * draw_buf);
bool lv_draw_buf_has_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag); bool lv_draw_buf_has_flag(const lv_draw_buf_t * draw_buf, lv_image_flags_t flag);
void lv_draw_buf_set_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag); void lv_draw_buf_set_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag);

View File

@ -15,6 +15,7 @@
#include "lv_draw_pxp.h" #include "lv_draw_pxp.h"
#if LV_USE_PXP
#if LV_USE_DRAW_PXP #if LV_USE_DRAW_PXP
#include "../../lv_draw_buf_private.h" #include "../../lv_draw_buf_private.h"
#include "lv_pxp_cfg.h" #include "lv_pxp_cfg.h"
@ -51,8 +52,12 @@ static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t *
void lv_draw_buf_pxp_init_handlers(void) void lv_draw_buf_pxp_init_handlers(void)
{ {
lv_draw_buf_handlers_t * handlers = lv_draw_buf_get_handlers(); lv_draw_buf_handlers_t * handlers = lv_draw_buf_get_handlers();
lv_draw_buf_handlers_t * font_handlers = lv_draw_buf_get_font_handlers();
lv_draw_buf_handlers_t * image_handlers = lv_draw_buf_get_image_handlers();
handlers->invalidate_cache_cb = _invalidate_cache; handlers->invalidate_cache_cb = _invalidate_cache;
font_handlers->invalidate_cache_cb = _invalidate_cache;
image_handlers->invalidate_cache_cb = _invalidate_cache;
} }
/********************** /**********************
@ -66,7 +71,7 @@ static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t *
lv_color_format_t cf = header->cf; lv_color_format_t cf = header->cf;
if(area->y1 == 0) { if(area->y1 == 0) {
uint16_t size = stride * lv_area_get_height(area); uint32_t size = stride * lv_area_get_height(area);
/* Invalidate full buffer. */ /* Invalidate full buffer. */
DEMO_CleanInvalidateCacheByAddr((void *)draw_buf->data, size); DEMO_CleanInvalidateCacheByAddr((void *)draw_buf->data, size);
@ -109,3 +114,4 @@ static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t *
} }
#endif /*LV_USE_DRAW_PXP*/ #endif /*LV_USE_DRAW_PXP*/
#endif /*LV_USE_PXP*/

View File

@ -15,7 +15,8 @@
#include "lv_draw_pxp.h" #include "lv_draw_pxp.h"
#if LV_USE_DRAW_PXP #if LV_USE_PXP
#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP
#include "lv_pxp_cfg.h" #include "lv_pxp_cfg.h"
#include "lv_pxp_utils.h" #include "lv_pxp_utils.h"
@ -82,6 +83,9 @@ static void _pxp_execute_drawing(lv_draw_pxp_unit_t * u);
void lv_draw_pxp_init(void) void lv_draw_pxp_init(void)
{ {
lv_pxp_init();
#if LV_USE_DRAW_PXP
lv_draw_buf_pxp_init_handlers(); lv_draw_buf_pxp_init_handlers();
lv_draw_pxp_unit_t * draw_pxp_unit = lv_draw_create_unit(sizeof(lv_draw_pxp_unit_t)); lv_draw_pxp_unit_t * draw_pxp_unit = lv_draw_create_unit(sizeof(lv_draw_pxp_unit_t));
@ -89,11 +93,10 @@ void lv_draw_pxp_init(void)
draw_pxp_unit->base_unit.dispatch_cb = _pxp_dispatch; draw_pxp_unit->base_unit.dispatch_cb = _pxp_dispatch;
draw_pxp_unit->base_unit.delete_cb = _pxp_delete; draw_pxp_unit->base_unit.delete_cb = _pxp_delete;
lv_pxp_init();
#if LV_USE_PXP_DRAW_THREAD #if LV_USE_PXP_DRAW_THREAD
lv_thread_init(&draw_pxp_unit->thread, LV_THREAD_PRIO_HIGH, _pxp_render_thread_cb, 2 * 1024, draw_pxp_unit); lv_thread_init(&draw_pxp_unit->thread, LV_THREAD_PRIO_HIGH, _pxp_render_thread_cb, 2 * 1024, draw_pxp_unit);
#endif #endif
#endif /*LV_USE_DRAW_PXP*/
} }
void lv_draw_pxp_deinit(void) void lv_draw_pxp_deinit(void)
@ -107,19 +110,26 @@ void lv_draw_pxp_rotate(const void * src_buf, void * dest_buf, int32_t src_width
{ {
lv_pxp_reset(); lv_pxp_reset();
/* convert rotation angle */ /* Convert rotation angle
* To be in sync with CPU, the received angle is counterclockwise
* and the PXP constants are for clockwise rotation
*
* counterclockwise clockwise
* LV_DISPLAY_ROTATION_90 -> kPXP_Rotate270
* LV_DISPLAY_ROTATION_270 -> kPXP_Rotate90
*/
pxp_rotate_degree_t pxp_rotation; pxp_rotate_degree_t pxp_rotation;
switch(rotation) { switch(rotation) {
case LV_DISPLAY_ROTATION_0: case LV_DISPLAY_ROTATION_0:
pxp_rotation = kPXP_Rotate0; pxp_rotation = kPXP_Rotate0;
break; break;
case LV_DISPLAY_ROTATION_90: case LV_DISPLAY_ROTATION_270:
pxp_rotation = kPXP_Rotate90; pxp_rotation = kPXP_Rotate90;
break; break;
case LV_DISPLAY_ROTATION_180: case LV_DISPLAY_ROTATION_180:
pxp_rotation = kPXP_Rotate180; pxp_rotation = kPXP_Rotate180;
break; break;
case LV_DISPLAY_ROTATION_270: case LV_DISPLAY_ROTATION_90:
pxp_rotation = kPXP_Rotate270; pxp_rotation = kPXP_Rotate270;
break; break;
default: default:
@ -159,7 +169,7 @@ void lv_draw_pxp_rotate(const void * src_buf, void * dest_buf, int32_t src_width
/********************** /**********************
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/
#if LV_USE_DRAW_PXP
static inline bool _pxp_src_cf_supported(lv_color_format_t cf) static inline bool _pxp_src_cf_supported(lv_color_format_t cf)
{ {
bool is_cf_supported = false; bool is_cf_supported = false;
@ -321,8 +331,7 @@ static int32_t _pxp_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer)
if(t == NULL || t->preferred_draw_unit_id != DRAW_UNIT_ID_PXP) if(t == NULL || t->preferred_draw_unit_id != DRAW_UNIT_ID_PXP)
return LV_DRAW_UNIT_IDLE; return LV_DRAW_UNIT_IDLE;
void * buf = lv_draw_layer_alloc_buf(layer); if(lv_draw_layer_alloc_buf(layer) == NULL)
if(buf == NULL)
return LV_DRAW_UNIT_IDLE; return LV_DRAW_UNIT_IDLE;
t->state = LV_DRAW_TASK_STATE_IN_PROGRESS; t->state = LV_DRAW_TASK_STATE_IN_PROGRESS;
@ -484,5 +493,6 @@ static void _pxp_render_thread_cb(void * ptr)
LV_LOG_INFO("Exit PXP draw thread."); LV_LOG_INFO("Exit PXP draw thread.");
} }
#endif #endif
#endif /*LV_USE_DRAW_PXP*/ #endif /*LV_USE_DRAW_PXP*/
#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/
#endif /*LV_USE_PXP*/

View File

@ -22,8 +22,10 @@ extern "C" {
#include "../../../lv_conf_internal.h" #include "../../../lv_conf_internal.h"
#if LV_USE_DRAW_PXP #if LV_USE_PXP
#include "../../sw/lv_draw_sw.h" #if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP
#include "../../sw/lv_draw_sw_private.h"
#include "../../../misc/lv_area_private.h"
/********************* /*********************
* DEFINES * DEFINES
@ -39,8 +41,6 @@ typedef lv_draw_sw_unit_t lv_draw_pxp_unit_t;
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
**********************/ **********************/
void lv_draw_buf_pxp_init_handlers(void);
void lv_draw_pxp_init(void); void lv_draw_pxp_init(void);
void lv_draw_pxp_deinit(void); void lv_draw_pxp_deinit(void);
@ -49,6 +49,9 @@ void lv_draw_pxp_rotate(const void * src_buf, void * dest_buf, int32_t src_width
int32_t src_stride, int32_t dest_stride, lv_display_rotation_t rotation, int32_t src_stride, int32_t dest_stride, lv_display_rotation_t rotation,
lv_color_format_t cf); lv_color_format_t cf);
#if LV_USE_DRAW_PXP
void lv_draw_buf_pxp_init_handlers(void);
void lv_draw_pxp_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc, void lv_draw_pxp_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc,
const lv_area_t * coords); const lv_area_t * coords);
@ -62,6 +65,8 @@ void lv_draw_pxp_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * d
* MACROS * MACROS
**********************/ **********************/
#endif /*LV_USE_DRAW_PXP*/ #endif /*LV_USE_DRAW_PXP*/
#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/
#endif /*LV_USE_PXP*/
#ifdef __cplusplus #ifdef __cplusplus
} /*extern "C"*/ } /*extern "C"*/

View File

@ -15,6 +15,7 @@
#include "lv_draw_pxp.h" #include "lv_draw_pxp.h"
#if LV_USE_PXP
#if LV_USE_DRAW_PXP #if LV_USE_DRAW_PXP
#include "lv_pxp_cfg.h" #include "lv_pxp_cfg.h"
#include "lv_pxp_utils.h" #include "lv_pxp_utils.h"
@ -145,3 +146,4 @@ static void _pxp_fill(uint8_t * dest_buf, const lv_area_t * dest_area, int32_t d
} }
#endif /*LV_USE_DRAW_PXP*/ #endif /*LV_USE_DRAW_PXP*/
#endif /*LV_USE_PXP*/

View File

@ -15,6 +15,7 @@
#include "lv_draw_pxp.h" #include "lv_draw_pxp.h"
#if LV_USE_PXP
#if LV_USE_DRAW_PXP #if LV_USE_DRAW_PXP
#include "lv_pxp_cfg.h" #include "lv_pxp_cfg.h"
#include "lv_pxp_utils.h" #include "lv_pxp_utils.h"
@ -363,3 +364,4 @@ static void _pxp_blit(uint8_t * dest_buf, const lv_area_t * dest_area, int32_t d
} }
#endif /*LV_USE_DRAW_PXP*/ #endif /*LV_USE_DRAW_PXP*/
#endif /*LV_USE_PXP*/

View File

@ -15,6 +15,7 @@
#include "lv_draw_pxp.h" #include "lv_draw_pxp.h"
#if LV_USE_PXP
#if LV_USE_DRAW_PXP #if LV_USE_DRAW_PXP
#include "../../../stdlib/lv_string.h" #include "../../../stdlib/lv_string.h"
@ -154,3 +155,4 @@ void lv_draw_pxp_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * d
} }
#endif /*LV_USE_DRAW_PXP*/ #endif /*LV_USE_DRAW_PXP*/
#endif /*LV_USE_PXP*/

View File

@ -15,7 +15,8 @@
#include "lv_pxp_cfg.h" #include "lv_pxp_cfg.h"
#if LV_USE_DRAW_PXP #if LV_USE_PXP
#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP
#include "lv_pxp_osa.h" #include "lv_pxp_osa.h"
/********************* /*********************
@ -88,4 +89,5 @@ void lv_pxp_wait(void)
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/
#endif /*LV_USE_DRAW_PXP*/ #endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/
#endif /*LV_USE_PXP*/

View File

@ -22,7 +22,8 @@ extern "C" {
#include "../../../lv_conf_internal.h" #include "../../../lv_conf_internal.h"
#if LV_USE_DRAW_PXP #if LV_USE_PXP
#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP
#include "fsl_cache.h" #include "fsl_cache.h"
#include "fsl_pxp.h" #include "fsl_pxp.h"
@ -93,7 +94,8 @@ void lv_pxp_wait(void);
* MACROS * MACROS
**********************/ **********************/
#endif /*LV_USE_DRAW_PXP*/ #endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/
#endif /*LV_USE_PXP*/
#ifdef __cplusplus #ifdef __cplusplus
} /*extern "C"*/ } /*extern "C"*/

View File

@ -15,7 +15,8 @@
#include "lv_pxp_osa.h" #include "lv_pxp_osa.h"
#if LV_USE_DRAW_PXP #if LV_USE_PXP
#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP
#include "lv_pxp_utils.h" #include "lv_pxp_utils.h"
#include "../../../misc/lv_log.h" #include "../../../misc/lv_log.h"
#include "../../../osal/lv_os.h" #include "../../../osal/lv_os.h"
@ -183,4 +184,5 @@ static void _pxp_wait(void)
#endif #endif
} }
#endif /*LV_USE_DRAW_PXP*/ #endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/
#endif /*LV_USE_PXP*/

View File

@ -22,7 +22,8 @@ extern "C" {
#include "../../../lv_conf_internal.h" #include "../../../lv_conf_internal.h"
#if LV_USE_DRAW_PXP #if LV_USE_PXP
#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP
#include "lv_pxp_cfg.h" #include "lv_pxp_cfg.h"
/********************* /*********************
@ -51,7 +52,8 @@ pxp_cfg_t * pxp_get_default_cfg(void);
* MACROS * MACROS
**********************/ **********************/
#endif /*LV_USE_DRAW_PXP*/ #endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/
#endif /*LV_USE_PXP*/
#ifdef __cplusplus #ifdef __cplusplus
} /*extern "C"*/ } /*extern "C"*/

View File

@ -15,7 +15,8 @@
#include "lv_pxp_utils.h" #include "lv_pxp_utils.h"
#if LV_USE_DRAW_PXP #if LV_USE_PXP
#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP
/********************* /*********************
* DEFINES * DEFINES
@ -89,6 +90,7 @@ pxp_as_pixel_format_t pxp_get_as_px_format(lv_color_format_t cf)
return as_px_format; return as_px_format;
} }
#if LV_USE_DRAW_PXP
pxp_ps_pixel_format_t pxp_get_ps_px_format(lv_color_format_t cf) pxp_ps_pixel_format_t pxp_get_ps_px_format(lv_color_format_t cf)
{ {
pxp_ps_pixel_format_t ps_px_format = kPXP_PsPixelFormatRGB565; pxp_ps_pixel_format_t ps_px_format = kPXP_PsPixelFormatRGB565;
@ -143,3 +145,5 @@ bool pxp_buf_aligned(const void * buf, uint32_t stride)
**********************/ **********************/
#endif /*LV_USE_DRAW_PXP*/ #endif /*LV_USE_DRAW_PXP*/
#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/
#endif /*LV_USE_PXP*/

View File

@ -21,7 +21,8 @@ extern "C" {
*********************/ *********************/
#include "../../../lv_conf_internal.h" #include "../../../lv_conf_internal.h"
#if LV_USE_DRAW_PXP #if LV_USE_PXP
#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP
#include "fsl_pxp.h" #include "fsl_pxp.h"
#include "../../../misc/lv_color.h" #include "../../../misc/lv_color.h"
@ -59,6 +60,7 @@ pxp_output_pixel_format_t pxp_get_out_px_format(lv_color_format_t cf);
pxp_as_pixel_format_t pxp_get_as_px_format(lv_color_format_t cf); pxp_as_pixel_format_t pxp_get_as_px_format(lv_color_format_t cf);
#if LV_USE_DRAW_PXP
pxp_ps_pixel_format_t pxp_get_ps_px_format(lv_color_format_t cf); pxp_ps_pixel_format_t pxp_get_ps_px_format(lv_color_format_t cf);
bool pxp_buf_aligned(const void * buf, uint32_t stride); bool pxp_buf_aligned(const void * buf, uint32_t stride);
@ -72,6 +74,8 @@ bool pxp_buf_aligned(const void * buf, uint32_t stride);
**********************/ **********************/
#endif /*LV_USE_DRAW_PXP*/ #endif /*LV_USE_DRAW_PXP*/
#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/
#endif /*LV_USE_PXP*/
#ifdef __cplusplus #ifdef __cplusplus
} /*extern "C"*/ } /*extern "C"*/

View File

@ -35,6 +35,7 @@
**********************/ **********************/
static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area); static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area);
static uint32_t _width_to_stride(uint32_t w, lv_color_format_t cf);
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
@ -51,8 +52,17 @@ static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t *
void lv_draw_buf_vglite_init_handlers(void) void lv_draw_buf_vglite_init_handlers(void)
{ {
lv_draw_buf_handlers_t * handlers = lv_draw_buf_get_handlers(); lv_draw_buf_handlers_t * handlers = lv_draw_buf_get_handlers();
lv_draw_buf_handlers_t * font_handlers = lv_draw_buf_get_font_handlers();
lv_draw_buf_handlers_t * image_handlers = lv_draw_buf_get_image_handlers();
handlers->invalidate_cache_cb = _invalidate_cache; handlers->invalidate_cache_cb = _invalidate_cache;
font_handlers->invalidate_cache_cb = _invalidate_cache;
image_handlers->invalidate_cache_cb = _invalidate_cache;
handlers->width_to_stride_cb = _width_to_stride;
font_handlers->width_to_stride_cb = _width_to_stride;
image_handlers->width_to_stride_cb = _width_to_stride;
} }
/********************** /**********************
@ -66,7 +76,7 @@ static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t *
lv_color_format_t cf = header->cf; lv_color_format_t cf = header->cf;
if(area->y1 == 0) { if(area->y1 == 0) {
uint16_t size = stride * lv_area_get_height(area); uint32_t size = stride * lv_area_get_height(area);
/* Invalidate full buffer. */ /* Invalidate full buffer. */
DEMO_CleanInvalidateCacheByAddr((void *)draw_buf->data, size); DEMO_CleanInvalidateCacheByAddr((void *)draw_buf->data, size);
@ -108,4 +118,14 @@ static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t *
} }
} }
static uint32_t _width_to_stride(uint32_t w, lv_color_format_t cf)
{
uint8_t bits_per_pixel = lv_color_format_get_bpp(cf);
uint32_t width_bits = (w * bits_per_pixel + 7) & ~7;
uint32_t width_bytes = width_bits / 8;
uint8_t align_bytes = vglite_get_stride_alignment(cf);
return (width_bytes + align_bytes - 1) & ~(align_bytes - 1);
}
#endif /*LV_USE_DRAW_VGLITE*/ #endif /*LV_USE_DRAW_VGLITE*/

View File

@ -291,16 +291,14 @@ static int32_t _vglite_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer)
if(t == NULL) if(t == NULL)
return LV_DRAW_UNIT_IDLE; return LV_DRAW_UNIT_IDLE;
if(lv_draw_get_unit_count() > 1) { if(t->preferred_draw_unit_id != DRAW_UNIT_ID_VGLITE) {
/* Let the SW unit to draw this task. */ /* Let the preferred known unit to draw this task. */
if(t->preferred_draw_unit_id != DRAW_UNIT_ID_VGLITE) if(t->preferred_draw_unit_id != LV_DRAW_UNIT_NONE) {
return LV_DRAW_UNIT_IDLE; return LV_DRAW_UNIT_IDLE;
} }
else { else {
/* Fake unsupported tasks as ready. */ /* Fake unsupported tasks as ready. */
if(t->preferred_draw_unit_id != DRAW_UNIT_ID_VGLITE) {
t->state = LV_DRAW_TASK_STATE_READY; t->state = LV_DRAW_TASK_STATE_READY;
/* Request a new dispatching as it can get a new task. */ /* Request a new dispatching as it can get a new task. */
lv_draw_dispatch_request(); lv_draw_dispatch_request();
@ -308,8 +306,7 @@ static int32_t _vglite_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer)
} }
} }
void * buf = lv_draw_layer_alloc_buf(layer); if(lv_draw_layer_alloc_buf(layer) == NULL)
if(buf == NULL)
return LV_DRAW_UNIT_IDLE; return LV_DRAW_UNIT_IDLE;
t->state = LV_DRAW_TASK_STATE_IN_PROGRESS; t->state = LV_DRAW_TASK_STATE_IN_PROGRESS;
@ -340,9 +337,13 @@ static int32_t _vglite_wait_for_finish(lv_draw_unit_t * draw_unit)
lv_draw_vglite_unit_t * draw_vglite_unit = (lv_draw_vglite_unit_t *) draw_unit; lv_draw_vglite_unit_t * draw_vglite_unit = (lv_draw_vglite_unit_t *) draw_unit;
draw_vglite_unit->wait_for_finish = true; draw_vglite_unit->wait_for_finish = true;
/* Signal draw unit to finish its tasks and return READY state after completion. */
if(draw_vglite_unit->inited) if(draw_vglite_unit->inited)
lv_thread_sync_signal(&draw_vglite_unit->sync); lv_thread_sync_signal(&draw_vglite_unit->sync);
/* Wait for finish now. */
lv_draw_dispatch_wait_for_request();
return 1; return 1;
} }
#endif #endif

View File

@ -97,8 +97,8 @@ static void _vglite_draw_triangle(const lv_area_t * coords, const lv_area_t * cl
tri_area.x2 = (int32_t)LV_MAX3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x); tri_area.x2 = (int32_t)LV_MAX3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x);
tri_area.y2 = (int32_t)LV_MAX3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y); tri_area.y2 = (int32_t)LV_MAX3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y);
uint32_t width = tri_area.x2 - tri_area.x1; uint32_t width = lv_area_get_width(&tri_area);
uint32_t height = tri_area.y2 - tri_area.y1; uint32_t height = lv_area_get_height(&tri_area);
/* Init path */ /* Init path */
int32_t triangle_path[] = { /*VG line path*/ int32_t triangle_path[] = { /*VG line path*/

View File

@ -16,6 +16,8 @@ extern "C" {
#include "lv_draw_sw_mask.h" #include "lv_draw_sw_mask.h"
#if LV_DRAW_SW_COMPLEX
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
@ -146,6 +148,8 @@ void lv_draw_sw_mask_cleanup(void);
* MACROS * MACROS
**********************/ **********************/
#endif /*LV_DRAW_SW_COMPLEX*/
#ifdef __cplusplus #ifdef __cplusplus
} /*extern "C"*/ } /*extern "C"*/
#endif #endif

View File

@ -455,7 +455,7 @@ static void transform_argb8888(const uint8_t * src, int32_t src_w, int32_t src_h
dest_c32[x].alpha = (dest_c32[x].alpha * (0xFF - ys_fract)) >> 8; dest_c32[x].alpha = (dest_c32[x].alpha * (0xFF - ys_fract)) >> 8;
} }
else if(!lv_color32_eq(dest_c32[x], px_ver)) { else if(!lv_color32_eq(dest_c32[x], px_ver)) {
dest_c32[x].alpha = ((px_ver.alpha * ys_fract) + (dest_c32[x].alpha * (0xFF - ys_fract))) >> 8; if(dest_c32[x].alpha) dest_c32[x].alpha = ((px_ver.alpha * ys_fract) + (dest_c32[x].alpha * (0xFF - ys_fract))) >> 8;
px_ver.alpha = ys_fract; px_ver.alpha = ys_fract;
dest_c32[x] = lv_color_mix32(px_ver, dest_c32[x]); dest_c32[x] = lv_color_mix32(px_ver, dest_c32[x]);
} }
@ -464,7 +464,7 @@ static void transform_argb8888(const uint8_t * src, int32_t src_w, int32_t src_h
dest_c32[x].alpha = (dest_c32[x].alpha * (0xFF - xs_fract)) >> 8; dest_c32[x].alpha = (dest_c32[x].alpha * (0xFF - xs_fract)) >> 8;
} }
else if(!lv_color32_eq(dest_c32[x], px_hor)) { else if(!lv_color32_eq(dest_c32[x], px_hor)) {
dest_c32[x].alpha = ((px_hor.alpha * xs_fract) + (dest_c32[x].alpha * (0xFF - xs_fract))) >> 8; if(dest_c32[x].alpha) dest_c32[x].alpha = ((px_hor.alpha * xs_fract) + (dest_c32[x].alpha * (0xFF - xs_fract))) >> 8;
px_hor.alpha = xs_fract; px_hor.alpha = xs_fract;
dest_c32[x] = lv_color_mix32(px_hor, dest_c32[x]); dest_c32[x] = lv_color_mix32(px_hor, dest_c32[x]);
} }

View File

@ -114,7 +114,9 @@ static void draw_execute(lv_draw_vg_lite_unit_t * u)
lv_draw_buf_set_flag(layer->draw_buf, LV_IMAGE_FLAGS_PREMULTIPLIED); lv_draw_buf_set_flag(layer->draw_buf, LV_IMAGE_FLAGS_PREMULTIPLIED);
vg_lite_identity(&u->global_matrix); vg_lite_identity(&u->global_matrix);
vg_lite_translate(-layer->buf_area.x1, -layer->buf_area.y1, &u->global_matrix); if(layer->buf_area.x1 || layer->buf_area.y1) {
vg_lite_translate(-layer->buf_area.x1, -layer->buf_area.y1, &u->global_matrix);
}
#if LV_DRAW_TRANSFORM_USE_MATRIX #if LV_DRAW_TRANSFORM_USE_MATRIX
vg_lite_matrix_t layer_matrix; vg_lite_matrix_t layer_matrix;

View File

@ -149,9 +149,7 @@ void lv_draw_vg_lite_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * d
lv_vg_lite_path_end(path); lv_vg_lite_path_end(path);
vg_lite_matrix_t matrix; vg_lite_matrix_t matrix = u->global_matrix;
vg_lite_identity(&matrix);
lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix);
vg_lite_color_t color = lv_vg_lite_color(dsc->color, dsc->opa, true); vg_lite_color_t color = lv_vg_lite_color(dsc->color, dsc->opa, true);
@ -174,10 +172,8 @@ void lv_draw_vg_lite_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * d
if(dsc->img_src) { if(dsc->img_src) {
vg_lite_buffer_t src_buf; vg_lite_buffer_t src_buf;
lv_image_decoder_dsc_t decoder_dsc; lv_image_decoder_dsc_t decoder_dsc;
if(lv_vg_lite_buffer_open_image(&src_buf, &decoder_dsc, dsc->img_src, false)) { if(lv_vg_lite_buffer_open_image(&src_buf, &decoder_dsc, dsc->img_src, false, true)) {
vg_lite_matrix_t path_matrix; vg_lite_matrix_t path_matrix = u->global_matrix;
vg_lite_identity(&path_matrix);
lv_vg_lite_matrix_multiply(&path_matrix, &u->global_matrix);
/* move image to center */ /* move image to center */
vg_lite_translate(cx - radius_out, cy - radius_out, &matrix); vg_lite_translate(cx - radius_out, cy - radius_out, &matrix);

View File

@ -83,9 +83,7 @@ void lv_draw_vg_lite_border(lv_draw_unit_t * draw_unit, const lv_draw_border_dsc
lv_vg_lite_path_end(path); lv_vg_lite_path_end(path);
vg_lite_matrix_t matrix; vg_lite_matrix_t matrix = u->global_matrix;
vg_lite_identity(&matrix);
lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix);
vg_lite_color_t color = lv_vg_lite_color(dsc->color, dsc->opa, true); vg_lite_color_t color = lv_vg_lite_color(dsc->color, dsc->opa, true);

View File

@ -57,22 +57,15 @@ void lv_draw_vg_lite_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t *
LV_PROFILER_BEGIN; LV_PROFILER_BEGIN;
vg_lite_matrix_t matrix; vg_lite_matrix_t matrix = u->global_matrix;
vg_lite_identity(&matrix);
lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix);
int32_t w = lv_area_get_width(coords);
int32_t h = lv_area_get_height(coords);
float r = dsc->radius;
if(dsc->radius) {
float r_short = LV_MIN(w, h) / 2.0f;
r = LV_MIN(r, r_short);
}
lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_FP32); lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_FP32);
lv_vg_lite_path_set_quality(path, dsc->radius == 0 ? VG_LITE_LOW : VG_LITE_HIGH); lv_vg_lite_path_set_quality(path, dsc->radius == 0 ? VG_LITE_LOW : VG_LITE_HIGH);
lv_vg_lite_path_set_bonding_box_area(path, &clip_area); lv_vg_lite_path_set_bonding_box_area(path, &clip_area);
lv_vg_lite_path_append_rect(path, coords->x1, coords->y1, w, h, r); lv_vg_lite_path_append_rect(path,
coords->x1, coords->y1,
lv_area_get_width(coords), lv_area_get_height(coords),
dsc->radius);
lv_vg_lite_path_end(path); lv_vg_lite_path_end(path);
vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path); vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path);

View File

@ -74,7 +74,10 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t *
vg_lite_buffer_t src_buf; vg_lite_buffer_t src_buf;
lv_image_decoder_dsc_t decoder_dsc; lv_image_decoder_dsc_t decoder_dsc;
if(!lv_vg_lite_buffer_open_image(&src_buf, &decoder_dsc, dsc->src, no_cache)) {
/* if not support blend normal, premultiply alpha */
bool premultiply = !lv_vg_lite_support_blend_normal();
if(!lv_vg_lite_buffer_open_image(&src_buf, &decoder_dsc, dsc->src, no_cache, premultiply)) {
LV_PROFILER_END; LV_PROFILER_END;
return; return;
} }
@ -91,13 +94,22 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t *
lv_memset(&color, dsc->opa, sizeof(color)); lv_memset(&color, dsc->opa, sizeof(color));
} }
vg_lite_matrix_t matrix; /* convert the blend mode to vg-lite blend mode, considering the premultiplied alpha */
vg_lite_identity(&matrix); bool has_pre_mul = lv_draw_buf_has_flag(decoder_dsc.decoded, LV_IMAGE_FLAGS_PREMULTIPLIED);
lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix); vg_lite_blend_t blend = lv_vg_lite_blend_mode(dsc->blend_mode, has_pre_mul);
lv_vg_lite_image_matrix(&matrix, coords->x1, coords->y1, dsc);
/* original image matrix */
vg_lite_matrix_t image_matrix;
vg_lite_identity(&image_matrix);
lv_vg_lite_image_matrix(&image_matrix, coords->x1, coords->y1, dsc);
/* image drawing matrix */
vg_lite_matrix_t matrix = u->global_matrix;
lv_vg_lite_matrix_multiply(&matrix, &image_matrix);
LV_VG_LITE_ASSERT_SRC_BUFFER(&src_buf); LV_VG_LITE_ASSERT_SRC_BUFFER(&src_buf);
LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer); LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer);
LV_VG_LITE_ASSERT_MATRIX(&matrix);
bool no_transform = lv_matrix_is_identity_or_translation((const lv_matrix_t *)&matrix); bool no_transform = lv_matrix_is_identity_or_translation((const lv_matrix_t *)&matrix);
vg_lite_filter_t filter = no_transform ? VG_LITE_FILTER_POINT : VG_LITE_FILTER_BI_LINEAR; vg_lite_filter_t filter = no_transform ? VG_LITE_FILTER_POINT : VG_LITE_FILTER_BI_LINEAR;
@ -118,7 +130,7 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t *
&src_buf, &src_buf,
&rect, &rect,
&matrix, &matrix,
lv_vg_lite_blend_mode(dsc->blend_mode), blend,
color, color,
filter)); filter));
LV_PROFILER_END_TAG("vg_lite_blit_rect"); LV_PROFILER_END_TAG("vg_lite_blit_rect");
@ -126,23 +138,22 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t *
else { else {
lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_FP32); lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_FP32);
if(dsc->clip_radius) { /**
int32_t width = lv_area_get_width(coords); * When the image is transformed or rounded, create a path around
int32_t height = lv_area_get_height(coords); * the image and follow the image_matrix for coordinate transformation
float r_short = LV_MIN(width, height) / 2.0f; */
float radius = LV_MIN(dsc->clip_radius, r_short); if(!no_transform || dsc->clip_radius) {
/* apply the image transform to the path */
/** lv_vg_lite_path_set_transform(path, &image_matrix);
* When clip_radius is enabled, the clipping edges
* are aligned with the image edges
*/
lv_vg_lite_path_append_rect( lv_vg_lite_path_append_rect(
path, path,
coords->x1, coords->y1, 0, 0,
width, height, lv_area_get_width(coords), lv_area_get_height(coords),
radius); dsc->clip_radius);
lv_vg_lite_path_set_transform(path, NULL);
} }
else { else {
/* append normal rect to the path */
lv_vg_lite_path_append_rect( lv_vg_lite_path_append_rect(
path, path,
clip_area.x1, clip_area.y1, clip_area.x1, clip_area.y1,
@ -156,9 +167,8 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t *
vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path); vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path);
LV_VG_LITE_ASSERT_PATH(vg_lite_path); LV_VG_LITE_ASSERT_PATH(vg_lite_path);
vg_lite_matrix_t path_matrix; vg_lite_matrix_t path_matrix = u->global_matrix;
vg_lite_identity(&path_matrix); LV_VG_LITE_ASSERT_MATRIX(&path_matrix);
lv_vg_lite_matrix_multiply(&path_matrix, &u->global_matrix);
LV_PROFILER_BEGIN_TAG("vg_lite_draw_pattern"); LV_PROFILER_BEGIN_TAG("vg_lite_draw_pattern");
LV_VG_LITE_CHECK_ERROR(vg_lite_draw_pattern( LV_VG_LITE_CHECK_ERROR(vg_lite_draw_pattern(
@ -168,7 +178,7 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t *
&path_matrix, &path_matrix,
&src_buf, &src_buf,
&matrix, &matrix,
lv_vg_lite_blend_mode(dsc->blend_mode), blend,
VG_LITE_PATTERN_COLOR, VG_LITE_PATTERN_COLOR,
0, 0,
color, color,

View File

@ -150,9 +150,7 @@ static void draw_letter_bitmap(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_d
lv_area_t image_area = *dsc->letter_coords; lv_area_t image_area = *dsc->letter_coords;
vg_lite_matrix_t matrix; vg_lite_matrix_t matrix = u->global_matrix;
vg_lite_identity(&matrix);
lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix);
vg_lite_translate(image_area.x1, image_area.y1, &matrix); vg_lite_translate(image_area.x1, image_area.y1, &matrix);
vg_lite_buffer_t src_buf; vg_lite_buffer_t src_buf;
@ -198,9 +196,7 @@ static void draw_letter_bitmap(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_d
vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path); vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path);
LV_VG_LITE_ASSERT_PATH(vg_lite_path); LV_VG_LITE_ASSERT_PATH(vg_lite_path);
vg_lite_matrix_t path_matrix; vg_lite_matrix_t path_matrix = u->global_matrix;
vg_lite_identity(&path_matrix);
lv_vg_lite_matrix_multiply(&path_matrix, &u->global_matrix);
LV_VG_LITE_ASSERT_MATRIX(&path_matrix); LV_VG_LITE_ASSERT_MATRIX(&path_matrix);
LV_PROFILER_BEGIN_TAG("vg_lite_draw_pattern"); LV_PROFILER_BEGIN_TAG("vg_lite_draw_pattern");
@ -255,10 +251,7 @@ static void draw_letter_outline(lv_draw_vg_lite_unit_t * u, const lv_draw_glyph_
vg_lite_identity(&matrix); vg_lite_identity(&matrix);
/* matrix for drawing, different from matrix for calculating the bonding box */ /* matrix for drawing, different from matrix for calculating the bonding box */
vg_lite_matrix_t draw_matrix; vg_lite_matrix_t draw_matrix = u->global_matrix;
vg_lite_identity(&draw_matrix);
lv_vg_lite_matrix_multiply(&draw_matrix, &u->global_matrix);
/* convert to vg-lite coordinate */ /* convert to vg-lite coordinate */
vg_lite_translate(pos.x - dsc->g->ofs_x, pos.y + dsc->g->box_h + dsc->g->ofs_y, &draw_matrix); vg_lite_translate(pos.x - dsc->g->ofs_x, pos.y + dsc->g->box_h + dsc->g->ofs_y, &draw_matrix);

View File

@ -180,9 +180,7 @@ void lv_draw_vg_lite_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t *
lv_vg_lite_path_end(path); lv_vg_lite_path_end(path);
vg_lite_matrix_t matrix; vg_lite_matrix_t matrix = u->global_matrix;
vg_lite_identity(&matrix);
lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix);
vg_lite_color_t color = lv_vg_lite_color(dsc->color, dsc->opa, true); vg_lite_color_t color = lv_vg_lite_color(dsc->color, dsc->opa, true);

View File

@ -102,28 +102,23 @@ void lv_draw_vg_lite_mask_rect(lv_draw_unit_t * draw_unit, const lv_draw_mask_re
int32_t w = lv_area_get_width(&dsc->area); int32_t w = lv_area_get_width(&dsc->area);
int32_t h = lv_area_get_height(&dsc->area); int32_t h = lv_area_get_height(&dsc->area);
float r = dsc->radius;
if(dsc->radius) {
float r_short = LV_MIN(w, h) / 2.0f;
r = LV_MIN(r, r_short);
}
lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_FP32); lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_FP32);
lv_vg_lite_path_set_quality(path, VG_LITE_HIGH); lv_vg_lite_path_set_quality(path, VG_LITE_HIGH);
lv_vg_lite_path_set_bonding_box_area(path, &draw_area); lv_vg_lite_path_set_bonding_box_area(path, &draw_area);
/* Use rounded rectangles and normal rectangles of the same size to nest the cropped area */ /* Use rounded rectangles and normal rectangles of the same size to nest the cropped area */
lv_vg_lite_path_append_rect(path, dsc->area.x1, dsc->area.y1, w, h, r); lv_vg_lite_path_append_rect(path, dsc->area.x1, dsc->area.y1, w, h, dsc->radius);
lv_vg_lite_path_append_rect(path, dsc->area.x1, dsc->area.y1, w, h, 0); lv_vg_lite_path_append_rect(path, dsc->area.x1, dsc->area.y1, w, h, 0);
lv_vg_lite_path_end(path); lv_vg_lite_path_end(path);
vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path); vg_lite_path_t * vg_lite_path = lv_vg_lite_path_get_path(path);
vg_lite_matrix_t * matrix = &u->global_matrix; vg_lite_matrix_t matrix = u->global_matrix;
LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer); LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer);
LV_VG_LITE_ASSERT_PATH(vg_lite_path); LV_VG_LITE_ASSERT_PATH(vg_lite_path);
LV_VG_LITE_ASSERT_MATRIX(matrix); LV_VG_LITE_ASSERT_MATRIX(&matrix);
/* Use VG_LITE_BLEND_DST_IN (Sa * D) blending mode to make the corners transparent */ /* Use VG_LITE_BLEND_DST_IN (Sa * D) blending mode to make the corners transparent */
LV_PROFILER_BEGIN_TAG("vg_lite_draw"); LV_PROFILER_BEGIN_TAG("vg_lite_draw");
@ -131,7 +126,7 @@ void lv_draw_vg_lite_mask_rect(lv_draw_unit_t * draw_unit, const lv_draw_mask_re
&u->target_buffer, &u->target_buffer,
vg_lite_path, vg_lite_path,
VG_LITE_FILL_EVEN_ODD, VG_LITE_FILL_EVEN_ODD,
matrix, &matrix,
VG_LITE_BLEND_DST_IN, VG_LITE_BLEND_DST_IN,
0)); 0));
LV_PROFILER_END_TAG("vg_lite_draw"); LV_PROFILER_END_TAG("vg_lite_draw");

View File

@ -71,9 +71,7 @@ void lv_draw_vg_lite_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle
LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer); LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer);
LV_VG_LITE_ASSERT_PATH(vg_lite_path); LV_VG_LITE_ASSERT_PATH(vg_lite_path);
vg_lite_matrix_t matrix; vg_lite_matrix_t matrix = u->global_matrix;
vg_lite_identity(&matrix);
lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix);
LV_VG_LITE_ASSERT_MATRIX(&matrix); LV_VG_LITE_ASSERT_MATRIX(&matrix);
if(dsc->bg_grad.dir != LV_GRAD_DIR_NONE) { if(dsc->bg_grad.dir != LV_GRAD_DIR_NONE) {

View File

@ -217,7 +217,7 @@ static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vec
/* draw image */ /* draw image */
vg_lite_buffer_t image_buffer; vg_lite_buffer_t image_buffer;
lv_image_decoder_dsc_t decoder_dsc; lv_image_decoder_dsc_t decoder_dsc;
if(lv_vg_lite_buffer_open_image(&image_buffer, &decoder_dsc, dsc->fill_dsc.img_dsc.src, false)) { if(lv_vg_lite_buffer_open_image(&image_buffer, &decoder_dsc, dsc->fill_dsc.img_dsc.src, false, true)) {
/* Calculate pattern matrix. Should start from path bond box, and also apply fill matrix. */ /* Calculate pattern matrix. Should start from path bond box, and also apply fill matrix. */
lv_matrix_t m = dsc->matrix; lv_matrix_t m = dsc->matrix;
lv_matrix_translate(&m, min_x, min_y); lv_matrix_translate(&m, min_x, min_y);
@ -251,7 +251,15 @@ static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vec
break; break;
case LV_VECTOR_DRAW_STYLE_GRADIENT: { case LV_VECTOR_DRAW_STYLE_GRADIENT: {
vg_lite_matrix_t grad_matrix; vg_lite_matrix_t grad_matrix;
lv_vg_lite_matrix(&grad_matrix, &dsc->fill_dsc.matrix); vg_lite_identity(&grad_matrix);
#if !LV_USE_VG_LITE_THORVG
/* Workaround inconsistent matrix behavior between device and ThorVG */
lv_vg_lite_matrix_multiply(&grad_matrix, &matrix);
#endif
vg_lite_matrix_t fill_matrix;
lv_vg_lite_matrix(&fill_matrix, &dsc->fill_dsc.matrix);
lv_vg_lite_matrix_multiply(&grad_matrix, &fill_matrix);
lv_vg_lite_draw_grad( lv_vg_lite_draw_grad(
u, u,

View File

@ -36,8 +36,10 @@
struct lv_vg_lite_path_t { struct lv_vg_lite_path_t {
vg_lite_path_t base; vg_lite_path_t base;
vg_lite_matrix_t matrix;
size_t mem_size; size_t mem_size;
uint8_t format_len; uint8_t format_len;
bool has_transform;
}; };
typedef struct { typedef struct {
@ -138,6 +140,7 @@ void lv_vg_lite_path_reset(lv_vg_lite_path_t * path, vg_lite_format_t data_forma
path->base.quality = VG_LITE_MEDIUM; path->base.quality = VG_LITE_MEDIUM;
path->base.path_type = VG_LITE_DRAW_ZERO; path->base.path_type = VG_LITE_DRAW_ZERO;
path->format_len = lv_vg_lite_path_format_len(data_format); path->format_len = lv_vg_lite_path_format_len(data_format);
path->has_transform = false;
} }
vg_lite_path_t * lv_vg_lite_path_get_path(lv_vg_lite_path_t * path) vg_lite_path_t * lv_vg_lite_path_get_path(lv_vg_lite_path_t * path)
@ -234,6 +237,16 @@ bool lv_vg_lite_path_update_bonding_box(lv_vg_lite_path_t * path)
return true; return true;
} }
void lv_vg_lite_path_set_transform(lv_vg_lite_path_t * path, const vg_lite_matrix_t * matrix)
{
LV_ASSERT_NULL(path);
if(matrix) {
path->matrix = *matrix;
}
path->has_transform = matrix ? true : false;
}
void lv_vg_lite_path_set_quality(lv_vg_lite_path_t * path, vg_lite_quality_t quality) void lv_vg_lite_path_set_quality(lv_vg_lite_path_t * path, vg_lite_quality_t quality)
{ {
LV_ASSERT_NULL(path); LV_ASSERT_NULL(path);
@ -267,6 +280,15 @@ static void lv_vg_lite_path_append_op(lv_vg_lite_path_t * path, uint32_t op)
static void lv_vg_lite_path_append_point(lv_vg_lite_path_t * path, float x, float y) static void lv_vg_lite_path_append_point(lv_vg_lite_path_t * path, float x, float y)
{ {
if(path->has_transform) {
LV_VG_LITE_ASSERT_MATRIX(&path->matrix);
/* transform point */
float ori_x = x;
float ori_y = y;
x = ori_x * path->matrix.m[0][0] + ori_y * path->matrix.m[0][1] + path->matrix.m[0][2];
y = ori_x * path->matrix.m[1][0] + ori_y * path->matrix.m[1][1] + path->matrix.m[1][2];
}
if(path->base.format == VG_LITE_FP32) { if(path->base.format == VG_LITE_FP32) {
lv_vg_lite_path_append_data(path, &x, sizeof(x)); lv_vg_lite_path_append_data(path, &x, sizeof(x));
lv_vg_lite_path_append_data(path, &y, sizeof(y)); lv_vg_lite_path_append_data(path, &y, sizeof(y));

View File

@ -61,6 +61,8 @@ void lv_vg_lite_path_get_bonding_box(lv_vg_lite_path_t * path,
bool lv_vg_lite_path_update_bonding_box(lv_vg_lite_path_t * path); bool lv_vg_lite_path_update_bonding_box(lv_vg_lite_path_t * path);
void lv_vg_lite_path_set_transform(lv_vg_lite_path_t * path, const vg_lite_matrix_t * matrix);
void lv_vg_lite_path_set_quality(lv_vg_lite_path_t * path, vg_lite_quality_t quality); void lv_vg_lite_path_set_quality(lv_vg_lite_path_t * path, vg_lite_quality_t quality);
vg_lite_path_t * lv_vg_lite_path_get_path(lv_vg_lite_path_t * path); vg_lite_path_t * lv_vg_lite_path_get_path(lv_vg_lite_path_t * path);

View File

@ -714,7 +714,7 @@ void lv_vg_lite_image_matrix(vg_lite_matrix_t * matrix, int32_t x, int32_t y, co
} }
bool lv_vg_lite_buffer_open_image(vg_lite_buffer_t * buffer, lv_image_decoder_dsc_t * decoder_dsc, const void * src, bool lv_vg_lite_buffer_open_image(vg_lite_buffer_t * buffer, lv_image_decoder_dsc_t * decoder_dsc, const void * src,
bool no_cache) bool no_cache, bool premultiply)
{ {
LV_ASSERT_NULL(buffer); LV_ASSERT_NULL(buffer);
LV_ASSERT_NULL(decoder_dsc); LV_ASSERT_NULL(decoder_dsc);
@ -722,7 +722,7 @@ bool lv_vg_lite_buffer_open_image(vg_lite_buffer_t * buffer, lv_image_decoder_ds
lv_image_decoder_args_t args; lv_image_decoder_args_t args;
lv_memzero(&args, sizeof(lv_image_decoder_args_t)); lv_memzero(&args, sizeof(lv_image_decoder_args_t));
args.premultiply = !lv_vg_lite_support_blend_normal(); args.premultiply = premultiply;
args.stride_align = true; args.stride_align = true;
args.use_indexed = true; args.use_indexed = true;
args.no_cache = no_cache; args.no_cache = no_cache;
@ -778,15 +778,11 @@ void lv_vg_lite_rect(vg_lite_rectangle_t * rect, const lv_area_t * area)
rect->height = lv_area_get_height(area); rect->height = lv_area_get_height(area);
} }
#if LV_USE_MATRIX
void lv_vg_lite_matrix(vg_lite_matrix_t * dest, const lv_matrix_t * src) void lv_vg_lite_matrix(vg_lite_matrix_t * dest, const lv_matrix_t * src)
{ {
lv_memcpy(dest, src, sizeof(lv_matrix_t)); lv_memcpy(dest, src, sizeof(lv_matrix_t));
} }
#endif
uint32_t lv_vg_lite_get_palette_size(vg_lite_buffer_format_t format) uint32_t lv_vg_lite_get_palette_size(vg_lite_buffer_format_t format)
{ {
uint32_t size = 0; uint32_t size = 0;
@ -819,9 +815,9 @@ vg_lite_color_t lv_vg_lite_color(lv_color_t color, lv_opa_t opa, bool pre_mul)
return (uint32_t)opa << 24 | (uint32_t)color.blue << 16 | (uint32_t)color.green << 8 | color.red; return (uint32_t)opa << 24 | (uint32_t)color.blue << 16 | (uint32_t)color.green << 8 | color.red;
} }
vg_lite_blend_t lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode) vg_lite_blend_t lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode, bool has_pre_mul)
{ {
if(vg_lite_query_feature(gcFEATURE_BIT_VG_LVGL_SUPPORT)) { if(!has_pre_mul && vg_lite_query_feature(gcFEATURE_BIT_VG_LVGL_SUPPORT)) {
switch(blend_mode) { switch(blend_mode) {
case LV_BLEND_MODE_NORMAL: /**< Simply mix according to the opacity value*/ case LV_BLEND_MODE_NORMAL: /**< Simply mix according to the opacity value*/
return VG_LITE_BLEND_NORMAL_LVGL; return VG_LITE_BLEND_NORMAL_LVGL;
@ -842,7 +838,7 @@ vg_lite_blend_t lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode)
switch(blend_mode) { switch(blend_mode) {
case LV_BLEND_MODE_NORMAL: /**< Simply mix according to the opacity value*/ case LV_BLEND_MODE_NORMAL: /**< Simply mix according to the opacity value*/
if(vg_lite_query_feature(gcFEATURE_BIT_VG_HW_PREMULTIPLY)) { if(!has_pre_mul && vg_lite_query_feature(gcFEATURE_BIT_VG_HW_PREMULTIPLY)) {
return VG_LITE_BLEND_PREMULTIPLY_SRC_OVER; return VG_LITE_BLEND_PREMULTIPLY_SRC_OVER;
} }
return VG_LITE_BLEND_SRC_OVER; return VG_LITE_BLEND_SRC_OVER;
@ -883,11 +879,6 @@ bool lv_vg_lite_buffer_check(const vg_lite_buffer_t * buffer, bool is_src)
return false; return false;
} }
if(buffer->stride < 1) {
LV_LOG_ERROR("buffer stride(%d) < 1", (int)buffer->stride);
return false;
}
if(!(buffer->tiled == VG_LITE_LINEAR || buffer->tiled == VG_LITE_TILED)) { if(!(buffer->tiled == VG_LITE_LINEAR || buffer->tiled == VG_LITE_TILED)) {
LV_LOG_ERROR("buffer tiled(%d) is invalid", (int)buffer->tiled); LV_LOG_ERROR("buffer tiled(%d) is invalid", (int)buffer->tiled);
return false; return false;
@ -898,12 +889,6 @@ bool lv_vg_lite_buffer_check(const vg_lite_buffer_t * buffer, bool is_src)
return false; return false;
} }
if((uint32_t)(uintptr_t)buffer->memory != buffer->address) {
LV_LOG_ERROR("buffer memory(%p) != address(%p)",
buffer->memory, (void *)(uintptr_t)buffer->address);
return false;
}
if(is_src && buffer->width != (vg_lite_int32_t)lv_vg_lite_width_align(buffer->width)) { if(is_src && buffer->width != (vg_lite_int32_t)lv_vg_lite_width_align(buffer->width)) {
LV_LOG_ERROR("buffer width(%d) is not aligned", (int)buffer->width); LV_LOG_ERROR("buffer width(%d) is not aligned", (int)buffer->width);
return false; return false;

View File

@ -131,13 +131,13 @@ void lv_vg_lite_image_matrix(vg_lite_matrix_t * matrix, int32_t x, int32_t y, co
void lv_vg_lite_image_dec_init(vg_lite_matrix_t * matrix, int32_t x, int32_t y, const lv_draw_image_dsc_t * dsc); void lv_vg_lite_image_dec_init(vg_lite_matrix_t * matrix, int32_t x, int32_t y, const lv_draw_image_dsc_t * dsc);
bool lv_vg_lite_buffer_open_image(vg_lite_buffer_t * buffer, lv_image_decoder_dsc_t * decoder_dsc, const void * src, bool lv_vg_lite_buffer_open_image(vg_lite_buffer_t * buffer, lv_image_decoder_dsc_t * decoder_dsc, const void * src,
bool no_cache); bool no_cache, bool premultiply);
void lv_vg_lite_image_dsc_init(struct lv_draw_vg_lite_unit_t * unit); void lv_vg_lite_image_dsc_init(struct lv_draw_vg_lite_unit_t * unit);
void lv_vg_lite_image_dsc_deinit(struct lv_draw_vg_lite_unit_t * unit); void lv_vg_lite_image_dsc_deinit(struct lv_draw_vg_lite_unit_t * unit);
vg_lite_blend_t lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode); vg_lite_blend_t lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode, bool has_pre_mul);
uint32_t lv_vg_lite_get_palette_size(vg_lite_buffer_format_t format); uint32_t lv_vg_lite_get_palette_size(vg_lite_buffer_format_t format);
@ -145,12 +145,8 @@ vg_lite_color_t lv_vg_lite_color(lv_color_t color, lv_opa_t opa, bool pre_mul);
void lv_vg_lite_rect(vg_lite_rectangle_t * rect, const lv_area_t * area); void lv_vg_lite_rect(vg_lite_rectangle_t * rect, const lv_area_t * area);
#if LV_USE_MATRIX
void lv_vg_lite_matrix(vg_lite_matrix_t * dest, const lv_matrix_t * src); void lv_vg_lite_matrix(vg_lite_matrix_t * dest, const lv_matrix_t * src);
#endif
/* Param checker */ /* Param checker */
bool lv_vg_lite_buffer_check(const vg_lite_buffer_t * buffer, bool is_src); bool lv_vg_lite_buffer_check(const vg_lite_buffer_t * buffer, bool is_src);

View File

@ -61,7 +61,7 @@ lv_display_t * lv_opengles_texture_create(int32_t w, int32_t h)
return NULL; return NULL;
} }
uint32_t stride = lv_draw_buf_width_to_stride(w, lv_display_get_color_format(disp)); uint32_t stride = lv_draw_buf_width_to_stride(w, lv_display_get_color_format(disp));
uint32_t buf_size = stride * w; uint32_t buf_size = stride * h;
dsc->fb1 = malloc(buf_size); dsc->fb1 = malloc(buf_size);
if(dsc->fb1 == NULL) { if(dsc->fb1 == NULL) {
lv_free(dsc); lv_free(dsc);

View File

@ -18,6 +18,10 @@ extern "C" {
#if LV_USE_LIBINPUT #if LV_USE_LIBINPUT
#if LV_LIBINPUT_XKB
#include "lv_xkb_private.h"
#endif
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/

View File

@ -18,6 +18,7 @@ extern "C" {
#if defined(LV_LIBINPUT_XKB) && LV_LIBINPUT_XKB #if defined(LV_LIBINPUT_XKB) && LV_LIBINPUT_XKB
#include "../../misc/lv_types.h"
#include <stdbool.h> #include <stdbool.h>
#include <xkbcommon/xkbcommon.h> #include <xkbcommon/xkbcommon.h>

View File

@ -216,11 +216,11 @@ static void display_release_cb(lv_event_t * e)
/* clear display buffer */ /* clear display buffer */
if(disp->buf_1) { if(disp->buf_1) {
lv_free(disp->buf_1); lv_free(disp->buf_1->data);
disp->buf_1 = NULL; disp->buf_1 = NULL;
} }
if(disp->buf_2) { if(disp->buf_2) {
lv_free(disp->buf_2); lv_free(disp->buf_2->data);
disp->buf_2 = NULL; disp->buf_2 = NULL;
} }

View File

@ -122,7 +122,7 @@ lv_display_t * lv_sdl_window_create(int32_t hor_res, int32_t ver_res)
lv_display_set_buffers(disp, dsc->fb1, dsc->fb2, stride * disp->ver_res, lv_display_set_buffers(disp, dsc->fb1, dsc->fb2, stride * disp->ver_res,
LV_SDL_RENDER_MODE); LV_SDL_RENDER_MODE);
} }
#else /*/*LV_USE_DRAW_SDL == 1*/ #else /*LV_USE_DRAW_SDL == 1*/
/*It will render directly to default Texture, so the buffer is not used, so just set something*/ /*It will render directly to default Texture, so the buffer is not used, so just set something*/
static lv_draw_buf_t draw_buf; static lv_draw_buf_t draw_buf;
static uint8_t dummy_buf; /*It won't be used as it will render to the SDL textures directly*/ static uint8_t dummy_buf; /*It won't be used as it will render to the SDL textures directly*/
@ -166,7 +166,7 @@ lv_display_t * lv_sdl_get_disp_from_win_id(uint32_t win_id)
while(disp) { while(disp) {
lv_sdl_window_t * dsc = lv_display_get_driver_data(disp); lv_sdl_window_t * dsc = lv_display_get_driver_data(disp);
if(SDL_GetWindowID(dsc->window) == win_id) { if(dsc != NULL && SDL_GetWindowID(dsc->window) == win_id) {
return disp; return disp;
} }
disp = lv_display_get_next(disp); disp = lv_display_get_next(disp);

View File

@ -1203,11 +1203,6 @@ static void indev_proc_press(lv_indev_t * indev)
lv_obj_send_event(last_obj, LV_EVENT_PRESS_LOST, indev_act); lv_obj_send_event(last_obj, LV_EVENT_PRESS_LOST, indev_act);
if(indev_reset_check(indev)) return; if(indev_reset_check(indev)) return;
/*Do nothing until release and a new press*/
lv_indev_reset(indev, NULL);
lv_indev_wait_release(indev);
return;
} }
indev->pointer.act_obj = indev_obj_act; /*Save the pressed object*/ indev->pointer.act_obj = indev_obj_act; /*Save the pressed object*/

View File

@ -113,9 +113,21 @@ static gd_GIF * gif_open(gd_GIF * gif_base)
/* Aspect Ratio */ /* Aspect Ratio */
f_gif_read(gif_base, &aspect, 1); f_gif_read(gif_base, &aspect, 1);
/* Create gd_GIF Structure. */ /* Create gd_GIF Structure. */
if(0 == width || 0 == height){
LV_LOG_WARN("Zero size image");
goto fail;
}
#if LV_GIF_CACHE_DECODE_DATA #if LV_GIF_CACHE_DECODE_DATA
if(0 == (INT_MAX - sizeof(gd_GIF) - LZW_CACHE_SIZE) / width / height / 5){
LV_LOG_WARN("Image dimensions are too large");
goto fail;
}
gif = lv_malloc(sizeof(gd_GIF) + 5 * width * height + LZW_CACHE_SIZE); gif = lv_malloc(sizeof(gd_GIF) + 5 * width * height + LZW_CACHE_SIZE);
#else #else
if(0 == (INT_MAX - sizeof(gd_GIF)) / width / height / 5){
LV_LOG_WARN("Image dimensions are too large");
goto fail;
}
gif = lv_malloc(sizeof(gd_GIF) + 5 * width * height); gif = lv_malloc(sizeof(gd_GIF) + 5 * width * height);
#endif #endif
if(!gif) goto fail; if(!gif) goto fail;
@ -318,6 +330,8 @@ get_key(gd_GIF *gif, int key_size, uint8_t *sub_len, uint8_t *shift, uint8_t *by
} }
#if LV_GIF_CACHE_DECODE_DATA #if LV_GIF_CACHE_DECODE_DATA
/* Decompress image pixels.
* Return 0 on success or -1 on out-of-memory (w.r.t. LZW code table) or parse error. */
static int static int
read_image_data(gd_GIF *gif, int interlace) read_image_data(gd_GIF *gif, int interlace)
{ {
@ -375,6 +389,10 @@ read_image_data(gd_GIF *gif, int interlace)
while (frm_off < frm_size) { while (frm_off < frm_size) {
/* copy data to frame buffer */ /* copy data to frame buffer */
while (sp > p_stack) { while (sp > p_stack) {
if(frm_off >= frm_size){
LV_LOG_WARN("LZW table token overflows the frame buffer");
return -1;
}
*ptr++ = *(--sp); *ptr++ = *(--sp);
frm_off += 1; frm_off += 1;
/* read one line */ /* read one line */
@ -526,7 +544,7 @@ interlaced_line_index(int h, int y)
} }
/* Decompress image pixels. /* Decompress image pixels.
* Return 0 on success or -1 on out-of-memory (w.r.t. LZW code table). */ * Return 0 on success or -1 on out-of-memory (w.r.t. LZW code table) or parse error. */
static int static int
read_image_data(gd_GIF * gif, int interlace) read_image_data(gd_GIF * gif, int interlace)
{ {
@ -578,6 +596,10 @@ read_image_data(gd_GIF * gif, int interlace)
if(ret == 1) key_size++; if(ret == 1) key_size++;
entry = table->entries[key]; entry = table->entries[key];
str_len = entry.length; str_len = entry.length;
if(frm_off + str_len >= frm_size){
LV_LOG_WARN("LZW table token overflows the frame buffer");
return -1;
}
for(i = 0; i < str_len; i++) { for(i = 0; i < str_len; i++) {
p = frm_off + entry.length - 1; p = frm_off + entry.length - 1;
x = p % gif->fw; x = p % gif->fw;
@ -603,7 +625,7 @@ read_image_data(gd_GIF * gif, int interlace)
#endif #endif
/* Read image. /* Read image.
* Return 0 on success or -1 on out-of-memory (w.r.t. LZW code table). */ * Return 0 on success or -1 on out-of-memory (w.r.t. LZW code table) or parse error. */
static int static int
read_image(gd_GIF * gif) read_image(gd_GIF * gif)
{ {
@ -615,6 +637,10 @@ read_image(gd_GIF * gif)
gif->fy = read_num(gif); gif->fy = read_num(gif);
gif->fw = read_num(gif); gif->fw = read_num(gif);
gif->fh = read_num(gif); gif->fh = read_num(gif);
if(gif->fx + (uint32_t)gif->fw > gif->width || gif->fy + (uint32_t)gif->fh > gif->height){
LV_LOG_WARN("Frame coordinates out of image bounds");
return -1;
}
f_gif_read(gif, &fisrz, 1); f_gif_read(gif, &fisrz, 1);
interlace = fisrz & 0x40; interlace = fisrz & 0x40;
/* Ignore Sort Flag. */ /* Ignore Sort Flag. */

View File

@ -137,6 +137,36 @@ void lv_gif_resume(lv_obj_t * obj)
lv_timer_resume(gifobj->timer); lv_timer_resume(gifobj->timer);
} }
bool lv_gif_is_loaded(lv_obj_t * obj)
{
lv_gif_t * gifobj = (lv_gif_t *) obj;
return (gifobj->gif != NULL);
}
int32_t lv_gif_get_loop_count(lv_obj_t * obj)
{
lv_gif_t * gifobj = (lv_gif_t *) obj;
if(gifobj->gif == NULL) {
return -1;
}
return gifobj->gif->loop_count;
}
void lv_gif_set_loop_count(lv_obj_t * obj, int32_t count)
{
lv_gif_t * gifobj = (lv_gif_t *) obj;
if(gifobj->gif == NULL) {
LV_LOG_WARN("Gif resource not loaded correctly");
return;
}
gifobj->gif->loop_count = count;
}
/********************** /**********************
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/

View File

@ -72,6 +72,25 @@ void lv_gif_pause(lv_obj_t * obj);
*/ */
void lv_gif_resume(lv_obj_t * obj); void lv_gif_resume(lv_obj_t * obj);
/**
* Checks if the GIF was loaded correctly.
* @param obj pointer to a gif obj
*/
bool lv_gif_is_loaded(lv_obj_t * obj);
/**
* Get the loop count for the GIF.
* @param obj pointer to a gif obj
*/
int32_t lv_gif_get_loop_count(lv_obj_t * obj);
/**
* Set the loop count for the GIF.
* @param obj pointer to a gif obj
* @param count the loop count to set
*/
void lv_gif_set_loop_count(lv_obj_t * obj, int32_t count);
/********************** /**********************
* MACROS * MACROS
**********************/ **********************/

View File

@ -266,6 +266,24 @@
#endif #endif
#endif #endif
#endif #endif
#if LV_USE_OS == LV_OS_FREERTOS
/*
* Unblocking an RTOS task with a direct notification is 45% faster and uses less RAM
* than unblocking a task using an intermediary object such as a binary semaphore.
* RTOS task notifications can only be used when there is only one task that can be the recipient of the event.
*/
#ifndef LV_USE_FREERTOS_TASK_NOTIFY
#ifdef LV_KCONFIG_PRESENT
#ifdef CONFIG_LV_USE_FREERTOS_TASK_NOTIFY
#define LV_USE_FREERTOS_TASK_NOTIFY CONFIG_LV_USE_FREERTOS_TASK_NOTIFY
#else
#define LV_USE_FREERTOS_TASK_NOTIFY 0
#endif
#else
#define LV_USE_FREERTOS_TASK_NOTIFY 1
#endif
#endif
#endif
/*======================== /*========================
* RENDERING CONFIGURATION * RENDERING CONFIGURATION
@ -610,16 +628,38 @@
#endif #endif
/* Use NXP's PXP on iMX RTxxx platforms. */ /* Use NXP's PXP on iMX RTxxx platforms. */
#ifndef LV_USE_DRAW_PXP #ifndef LV_USE_PXP
#ifdef CONFIG_LV_USE_DRAW_PXP #ifdef CONFIG_LV_USE_PXP
#define LV_USE_DRAW_PXP CONFIG_LV_USE_DRAW_PXP #define LV_USE_PXP CONFIG_LV_USE_PXP
#else #else
#define LV_USE_DRAW_PXP 0 #define LV_USE_PXP 0
#endif #endif
#endif #endif
#if LV_USE_DRAW_PXP #if LV_USE_PXP
#if LV_USE_OS /* Use PXP for drawing.*/
#ifndef LV_USE_DRAW_PXP
#ifdef LV_KCONFIG_PRESENT
#ifdef CONFIG_LV_USE_DRAW_PXP
#define LV_USE_DRAW_PXP CONFIG_LV_USE_DRAW_PXP
#else
#define LV_USE_DRAW_PXP 0
#endif
#else
#define LV_USE_DRAW_PXP 1
#endif
#endif
/* Use PXP to rotate display.*/
#ifndef LV_USE_ROTATE_PXP
#ifdef CONFIG_LV_USE_ROTATE_PXP
#define LV_USE_ROTATE_PXP CONFIG_LV_USE_ROTATE_PXP
#else
#define LV_USE_ROTATE_PXP 0
#endif
#endif
#if LV_USE_DRAW_PXP && LV_USE_OS
/* Use additional draw thread for PXP processing.*/ /* Use additional draw thread for PXP processing.*/
#ifndef LV_USE_PXP_DRAW_THREAD #ifndef LV_USE_PXP_DRAW_THREAD
#ifdef LV_KCONFIG_PRESENT #ifdef LV_KCONFIG_PRESENT

View File

@ -18,6 +18,16 @@ extern "C" {
# ifdef __NuttX__ # ifdef __NuttX__
# include <nuttx/config.h> # include <nuttx/config.h>
/*
* Make sure version number in Kconfig file is correctly set.
* Mismatch can happen when user manually copy lvgl/Kconfig file to their project, like what NuttX does.
*/
# include "../lv_version.h"
# if CONFIG_LVGL_VERSION_MAJOR != LVGL_VERSION_MAJOR || CONFIG_LVGL_VERSION_MINOR != LVGL_VERSION_MINOR \
|| CONFIG_LVGL_VERSION_PATCH != LVGL_VERSION_PATCH
# warning "Version mismatch between Kconfig and lvgl/lv_version.h"
# endif
# elif defined(__RTTHREAD__) # elif defined(__RTTHREAD__)
# define LV_CONF_INCLUDE_SIMPLE # define LV_CONF_INCLUDE_SIMPLE
# include <lv_rt_thread_conf.h> # include <lv_rt_thread_conf.h>

View File

@ -43,8 +43,10 @@
#if LV_USE_DRAW_VGLITE #if LV_USE_DRAW_VGLITE
#include "draw/nxp/vglite/lv_draw_vglite.h" #include "draw/nxp/vglite/lv_draw_vglite.h"
#endif #endif
#if LV_USE_DRAW_PXP #if LV_USE_PXP
#include "draw/nxp/pxp/lv_draw_pxp.h" #if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP
#include "draw/nxp/pxp/lv_draw_pxp.h"
#endif
#endif #endif
#if LV_USE_DRAW_DAVE2D #if LV_USE_DRAW_DAVE2D
#include "draw/renesas/dave2d/lv_draw_dave2d.h" #include "draw/renesas/dave2d/lv_draw_dave2d.h"
@ -198,9 +200,11 @@ void lv_init(void)
lv_draw_vglite_init(); lv_draw_vglite_init();
#endif #endif
#if LV_USE_DRAW_PXP #if LV_USE_PXP
#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP
lv_draw_pxp_init(); lv_draw_pxp_init();
#endif #endif
#endif
#if LV_USE_DRAW_DAVE2D #if LV_USE_DRAW_DAVE2D
lv_draw_dave2d_init(); lv_draw_dave2d_init();
@ -385,9 +389,11 @@ void lv_deinit(void)
lv_obj_style_deinit(); lv_obj_style_deinit();
#if LV_USE_DRAW_PXP #if LV_USE_PXP
#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP
lv_draw_pxp_deinit(); lv_draw_pxp_deinit();
#endif #endif
#endif
#if LV_USE_DRAW_VGLITE #if LV_USE_DRAW_VGLITE
lv_draw_vglite_deinit(); lv_draw_vglite_deinit();

View File

@ -70,7 +70,6 @@ extern "C" {
#include "widgets/buttonmatrix/lv_buttonmatrix_private.h" #include "widgets/buttonmatrix/lv_buttonmatrix_private.h"
#include "widgets/slider/lv_slider_private.h" #include "widgets/slider/lv_slider_private.h"
#include "widgets/switch/lv_switch_private.h" #include "widgets/switch/lv_switch_private.h"
#include "widgets/calendar/lv_calendar_chinese_private.h"
#include "widgets/calendar/lv_calendar_private.h" #include "widgets/calendar/lv_calendar_private.h"
#include "widgets/imagebutton/lv_imagebutton_private.h" #include "widgets/imagebutton/lv_imagebutton_private.h"
#include "widgets/bar/lv_bar_private.h" #include "widgets/bar/lv_bar_private.h"

View File

@ -138,7 +138,7 @@ uint32_t lv_anim_get_playtime(const lv_anim_t * a)
if(repeat_cnt < 1) repeat_cnt = 1; if(repeat_cnt < 1) repeat_cnt = 1;
uint32_t playtime = a->repeat_delay + a->duration + a->playback_delay + a->playback_duration; uint32_t playtime = a->repeat_delay + a->duration + a->playback_delay + a->playback_duration;
playtime = playtime * a->repeat_cnt; playtime = playtime * repeat_cnt;
return playtime; return playtime;
} }

View File

@ -15,6 +15,7 @@ extern "C" {
*********************/ *********************/
#include "lv_bidi.h" #include "lv_bidi.h"
#if LV_USE_BIDI
/********************* /*********************
* DEFINES * DEFINES
@ -91,6 +92,8 @@ void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len
* MACROS * MACROS
**********************/ **********************/
#endif /*LV_USE_BIDI*/
#ifdef __cplusplus #ifdef __cplusplus
} /*extern "C"*/ } /*extern "C"*/
#endif #endif

View File

@ -87,6 +87,7 @@ bool lv_color_format_has_alpha(lv_color_format_t cf)
case LV_COLOR_FORMAT_I4: case LV_COLOR_FORMAT_I4:
case LV_COLOR_FORMAT_I8: case LV_COLOR_FORMAT_I8:
case LV_COLOR_FORMAT_RGB565A8: case LV_COLOR_FORMAT_RGB565A8:
case LV_COLOR_FORMAT_ARGB8565:
case LV_COLOR_FORMAT_ARGB8888: case LV_COLOR_FORMAT_ARGB8888:
case LV_COLOR_FORMAT_AL88: case LV_COLOR_FORMAT_AL88:
return true; return true;

View File

@ -91,6 +91,12 @@ typedef struct {
lv_fs_file_cache_t * cache; lv_fs_file_cache_t * cache;
} lv_fs_file_t; } lv_fs_file_t;
typedef struct {
void * dir_d;
lv_fs_drv_t * drv;
} lv_fs_dir_t;
/********************** /**********************
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
**********************/ **********************/

View File

@ -38,12 +38,6 @@ struct lv_fs_path_ex_t {
uint32_t size; uint32_t size;
}; };
struct lv_fs_dir_t {
void * dir_d;
lv_fs_drv_t * drv;
};
/********************** /**********************
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
**********************/ **********************/

View File

@ -139,8 +139,6 @@ typedef struct lv_fs_file_cache_t lv_fs_file_cache_t;
typedef struct lv_fs_path_ex_t lv_fs_path_ex_t; typedef struct lv_fs_path_ex_t lv_fs_path_ex_t;
typedef struct lv_fs_dir_t lv_fs_dir_t;
typedef struct lv_image_decoder_args_t lv_image_decoder_args_t; typedef struct lv_image_decoder_args_t lv_image_decoder_args_t;
typedef struct lv_image_cache_data_t lv_image_cache_data_t; typedef struct lv_image_cache_data_t lv_image_cache_data_t;
@ -187,8 +185,6 @@ typedef struct lv_buttonmatrix_t lv_buttonmatrix_t;
typedef struct lv_calendar_t lv_calendar_t; typedef struct lv_calendar_t lv_calendar_t;
typedef struct lv_calendar_chinese_t lv_calendar_chinese_t;
typedef struct lv_canvas_t lv_canvas_t; typedef struct lv_canvas_t lv_canvas_t;
typedef struct lv_chart_series_t lv_chart_series_t; typedef struct lv_chart_series_t lv_chart_series_t;

View File

@ -15,11 +15,7 @@
#include "lv_os.h" #include "lv_os.h"
#if LV_USE_OS == LV_OS_FREERTOS #if LV_USE_OS == LV_OS_FREERTOS
#if (ESP_PLATFORM) #include "atomic.h"
#include "freertos/atomic.h"
#else
#include "atomic.h"
#endif
#include "../tick/lv_tick.h" #include "../tick/lv_tick.h"
#include "../misc/lv_log.h" #include "../misc/lv_log.h"
@ -54,7 +50,9 @@ static void prvCondInit(lv_thread_sync_t * pxCond);
static void prvCheckCondInit(lv_thread_sync_t * pxCond); static void prvCheckCondInit(lv_thread_sync_t * pxCond);
#if !USE_FREERTOS_TASK_NOTIFY static void prvCheckCondInitIsr(lv_thread_sync_t * pxCond);
#if !LV_USE_FREERTOS_TASK_NOTIFY
static void prvTestAndDecrement(lv_thread_sync_t * pxCond, static void prvTestAndDecrement(lv_thread_sync_t * pxCond,
uint32_t ulLocalWaitingThreads); uint32_t ulLocalWaitingThreads);
#endif #endif
@ -74,9 +72,13 @@ static void prvTestAndDecrement(lv_thread_sync_t * pxCond,
#if (ESP_PLATFORM) #if (ESP_PLATFORM)
#define _enter_critical() taskENTER_CRITICAL(&critSectionMux); #define _enter_critical() taskENTER_CRITICAL(&critSectionMux);
#define _exit_critical() taskEXIT_CRITICAL(&critSectionMux); #define _exit_critical() taskEXIT_CRITICAL(&critSectionMux);
#define _enter_critical_isr() taskENTER_CRITICAL_FROM_ISR();
#define _exit_critical_isr(x) taskEXIT_CRITICAL_FROM_ISR(x);
#else #else
#define _enter_critical() taskENTER_CRITICAL(); #define _enter_critical() taskENTER_CRITICAL();
#define _exit_critical() taskEXIT_CRITICAL(); #define _exit_critical() taskEXIT_CRITICAL();
#define _enter_critical_isr() taskENTER_CRITICAL_FROM_ISR();
#define _exit_critical_isr(x) taskEXIT_CRITICAL_FROM_ISR(x);
#endif #endif
/********************** /**********************
@ -195,20 +197,20 @@ lv_result_t lv_thread_sync_wait(lv_thread_sync_t * pxCond)
/* If the cond is uninitialized, perform initialization. */ /* If the cond is uninitialized, perform initialization. */
prvCheckCondInit(pxCond); prvCheckCondInit(pxCond);
#if USE_FREERTOS_TASK_NOTIFY #if LV_USE_FREERTOS_TASK_NOTIFY
TaskHandle_t current_task_handle = xTaskGetCurrentTaskHandle(); TaskHandle_t xCurrentTaskHandle = xTaskGetCurrentTaskHandle();
_enter_critical(); _enter_critical();
BaseType_t signal_sent = pxCond->xSyncSignal; BaseType_t xSyncSygnal = pxCond->xSyncSignal;
pxCond->xSyncSignal = pdFALSE; pxCond->xSyncSignal = pdFALSE;
if(signal_sent == pdFALSE) { if(xSyncSygnal == pdFALSE) {
/* The signal hasn't been sent yet. Tell the sender to notify this task */ /* The signal hasn't been sent yet. Tell the sender to notify this task */
pxCond->xTaskToNotify = current_task_handle; pxCond->xTaskToNotify = xCurrentTaskHandle;
} }
/* If we have a signal from the other task, we should not ask to be notified */ /* If we have a signal from the other task, we should not ask to be notified */
_exit_critical(); _exit_critical();
if(signal_sent == pdFALSE) { if(xSyncSygnal == pdFALSE) {
/* Wait for other task to notify this task. */ /* Wait for other task to notify this task. */
ulTaskNotifyTake(pdTRUE, portMAX_DELAY); ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
} }
@ -275,20 +277,20 @@ lv_result_t lv_thread_sync_signal(lv_thread_sync_t * pxCond)
/* If the cond is uninitialized, perform initialization. */ /* If the cond is uninitialized, perform initialization. */
prvCheckCondInit(pxCond); prvCheckCondInit(pxCond);
#if USE_FREERTOS_TASK_NOTIFY #if LV_USE_FREERTOS_TASK_NOTIFY
_enter_critical(); _enter_critical();
TaskHandle_t task_to_notify = pxCond->xTaskToNotify; TaskHandle_t xTaskToNotify = pxCond->xTaskToNotify;
pxCond->xTaskToNotify = NULL; pxCond->xTaskToNotify = NULL;
if(task_to_notify == NULL) { if(xTaskToNotify == NULL) {
/* No task waiting to be notified. Send this signal for later */ /* No task waiting to be notified. Send this signal for later */
pxCond->xSyncSignal = pdTRUE; pxCond->xSyncSignal = pdTRUE;
} }
/* If a task is already waiting, there is no need to set the sync signal */ /* If a task is already waiting, there is no need to set the sync signal */
_exit_critical(); _exit_critical();
if(task_to_notify != NULL) { if(xTaskToNotify != NULL) {
/* There is a task waiting. Send a notification to it */ /* There is a task waiting. Send a notification to it */
xTaskNotifyGive(task_to_notify); xTaskNotifyGive(xTaskToNotify);
} }
/* If there was no task waiting to be notified, we sent a signal for it to see later. */ /* If there was no task waiting to be notified, we sent a signal for it to see later. */
#else #else
@ -329,13 +331,13 @@ lv_result_t lv_thread_sync_signal(lv_thread_sync_t * pxCond)
lv_result_t lv_thread_sync_delete(lv_thread_sync_t * pxCond) lv_result_t lv_thread_sync_delete(lv_thread_sync_t * pxCond)
{ {
#if !USE_FREERTOS_TASK_NOTIFY #if !LV_USE_FREERTOS_TASK_NOTIFY
/* Cleanup all resources used by the cond. */ /* Cleanup all resources used by the cond. */
vSemaphoreDelete(pxCond->xCondWaitSemaphore); vSemaphoreDelete(pxCond->xCondWaitSemaphore);
vSemaphoreDelete(pxCond->xSyncMutex); vSemaphoreDelete(pxCond->xSyncMutex);
pxCond->ulWaitingThreads = 0; pxCond->ulWaitingThreads = 0;
pxCond->xSyncSignal = pdFALSE;
#endif #endif
pxCond->xSyncSignal = pdFALSE;
pxCond->xIsInitialized = pdFALSE; pxCond->xIsInitialized = pdFALSE;
return LV_RESULT_OK; return LV_RESULT_OK;
@ -346,28 +348,28 @@ lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * pxCond)
BaseType_t xHigherPriorityTaskWoken = pdFALSE; BaseType_t xHigherPriorityTaskWoken = pdFALSE;
/* If the cond is uninitialized, perform initialization. */ /* If the cond is uninitialized, perform initialization. */
prvCheckCondInit(pxCond); prvCheckCondInitIsr(pxCond);
#if USE_FREERTOS_TASK_NOTIFY #if LV_USE_FREERTOS_TASK_NOTIFY
_enter_critical(); uint32_t mask = _enter_critical_isr();
TaskHandle_t task_to_notify = pxCond->xTaskToNotify; TaskHandle_t xTaskToNotify = pxCond->xTaskToNotify;
pxCond->xTaskToNotify = NULL; pxCond->xTaskToNotify = NULL;
if(task_to_notify == NULL) { if(xTaskToNotify == NULL) {
/* No task waiting to be notified. Send this signal for later */ /* No task waiting to be notified. Send this signal for later */
pxCond->xSyncSignal = pdTRUE; pxCond->xSyncSignal = pdTRUE;
} }
/* If a task is already waiting, there is no need to set the sync signal */ /* If a task is already waiting, there is no need to set the sync signal */
_exit_critical(); _exit_critical_isr(mask);
if(task_to_notify != NULL) { if(xTaskToNotify != NULL) {
/* There is a task waiting. Send a notification to it */ /* There is a task waiting. Send a notification to it */
vTaskNotifyGiveFromISR(task_to_notify, &xHigherPriorityTaskWoken); vTaskNotifyGiveFromISR(xTaskToNotify, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
} }
/* If there was no task waiting to be notified, we sent a signal for it to see later. */ /* If there was no task waiting to be notified, we sent a signal for it to see later. */
#else #else
/* Enter critical section to prevent preemption. */ /* Enter critical section to prevent preemption. */
_enter_critical(); uint32_t mask = _enter_critical_isr();
pxCond->xSyncSignal = pdTRUE; pxCond->xSyncSignal = pdTRUE;
BaseType_t xAnyHigherPriorityTaskWoken = pdFALSE; BaseType_t xAnyHigherPriorityTaskWoken = pdFALSE;
@ -378,7 +380,7 @@ lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * pxCond)
xHigherPriorityTaskWoken |= xAnyHigherPriorityTaskWoken; xHigherPriorityTaskWoken |= xAnyHigherPriorityTaskWoken;
} }
_exit_critical(); _exit_critical_isr(mask);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
#endif #endif
@ -470,7 +472,7 @@ static void prvCondInit(lv_thread_sync_t * pxCond)
pxCond->xIsInitialized = pdTRUE; pxCond->xIsInitialized = pdTRUE;
pxCond->xSyncSignal = pdFALSE; pxCond->xSyncSignal = pdFALSE;
#if USE_FREERTOS_TASK_NOTIFY #if LV_USE_FREERTOS_TASK_NOTIFY
pxCond->xTaskToNotify = NULL; pxCond->xTaskToNotify = NULL;
#else #else
pxCond->xCondWaitSemaphore = xSemaphoreCreateCounting(ulMAX_COUNT, 0U); pxCond->xCondWaitSemaphore = xSemaphoreCreateCounting(ulMAX_COUNT, 0U);
@ -516,7 +518,27 @@ static void prvCheckCondInit(lv_thread_sync_t * pxCond)
} }
} }
#if !USE_FREERTOS_TASK_NOTIFY static void prvCheckCondInitIsr(lv_thread_sync_t * pxCond)
{
/* Check if the condition variable needs to be initialized. */
if(pxCond->xIsInitialized == pdFALSE) {
/* Cond initialization must be in a critical section to prevent two
* threads from initializing it at the same time. */
uint32_t mask = _enter_critical_isr();
/* Check again that the condition is still uninitialized, i.e. it wasn't
* initialized while this function was waiting to enter the critical
* section. */
if(pxCond->xIsInitialized == pdFALSE) {
prvCondInit(pxCond);
}
/* Exit the critical section. */
_exit_critical_isr(mask);
}
}
#if !LV_USE_FREERTOS_TASK_NOTIFY
static void prvTestAndDecrement(lv_thread_sync_t * pxCond, static void prvTestAndDecrement(lv_thread_sync_t * pxCond,
uint32_t ulLocalWaitingThreads) uint32_t ulLocalWaitingThreads)
{ {

View File

@ -37,14 +37,6 @@ extern "C" {
* DEFINES * DEFINES
*********************/ *********************/
/*
* Unblocking an RTOS task with a direct notification is 45% faster and uses less RAM
* than unblocking a task using an intermediary object such as a binary semaphore.
*
* RTOS task notifications can only be used when there is only one task that can be the recipient of the event.
*/
#define USE_FREERTOS_TASK_NOTIFY 1
/********************** /**********************
* TYPEDEFS * TYPEDEFS
**********************/ **********************/
@ -64,7 +56,7 @@ typedef struct {
BaseType_t BaseType_t
xIsInitialized; /**< Set to pdTRUE if this condition variable is initialized, pdFALSE otherwise. */ xIsInitialized; /**< Set to pdTRUE if this condition variable is initialized, pdFALSE otherwise. */
BaseType_t xSyncSignal; /**< Set to pdTRUE if the thread is signaled, pdFALSE otherwise. */ BaseType_t xSyncSignal; /**< Set to pdTRUE if the thread is signaled, pdFALSE otherwise. */
#if USE_FREERTOS_TASK_NOTIFY #if LV_USE_FREERTOS_TASK_NOTIFY
TaskHandle_t xTaskToNotify; /**< The task waiting to be signalled. NULL if nothing is waiting. */ TaskHandle_t xTaskToNotify; /**< The task waiting to be signalled. NULL if nothing is waiting. */
#else #else
SemaphoreHandle_t xCondWaitSemaphore; /**< Threads block on this semaphore in lv_thread_sync_wait. */ SemaphoreHandle_t xCondWaitSemaphore; /**< Threads block on this semaphore in lv_thread_sync_wait. */

View File

@ -707,7 +707,8 @@ static void lv_ime_pinyin_kb_event(lv_event_t * e)
} }
else if((pinyin_ime->mode == LV_IME_PINYIN_MODE_K26) && ((txt[0] >= 'a' && txt[0] <= 'z') || (txt[0] >= 'A' && else if((pinyin_ime->mode == LV_IME_PINYIN_MODE_K26) && ((txt[0] >= 'a' && txt[0] <= 'z') || (txt[0] >= 'A' &&
txt[0] <= 'Z'))) { txt[0] <= 'Z'))) {
lv_strcat(pinyin_ime->input_char, txt); uint16_t len = lv_strlen(pinyin_ime->input_char);
lv_snprintf(pinyin_ime->input_char + len, sizeof(pinyin_ime->input_char) - len, "%s", txt);
pinyin_input_proc(obj); pinyin_input_proc(obj);
pinyin_ime->ta_count++; pinyin_ime->ta_count++;
} }
@ -877,8 +878,8 @@ static void init_pinyin_dict(lv_obj_t * obj, const lv_pinyin_dict_t * dict)
} }
else { else {
headletter = dict[i].py[0]; headletter = dict[i].py[0];
pinyin_ime->py_num[letter_calc] = offset_count;
letter_calc = headletter - 'a'; letter_calc = headletter - 'a';
pinyin_ime->py_num[letter_calc - 1] = offset_count;
offset_sum += offset_count; offset_sum += offset_count;
pinyin_ime->py_pos[letter_calc] = offset_sum; pinyin_ime->py_pos[letter_calc] = offset_sum;

View File

@ -277,11 +277,10 @@ static void perf_update_timer_cb(lv_timer_t * t)
static void perf_observer_cb(lv_observer_t * observer, lv_subject_t * subject) static void perf_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
{ {
lv_obj_t * label = lv_observer_get_target(observer);
const lv_sysmon_perf_info_t * perf = lv_subject_get_pointer(subject); const lv_sysmon_perf_info_t * perf = lv_subject_get_pointer(subject);
#if LV_USE_PERF_MONITOR_LOG_MODE #if LV_USE_PERF_MONITOR_LOG_MODE
LV_UNUSED(label); LV_UNUSED(observer);
LV_LOG("sysmon: " LV_LOG("sysmon: "
"%" LV_PRIu32 " FPS (refr_cnt: %" LV_PRIu32 " | redraw_cnt: %" LV_PRIu32"), " "%" LV_PRIu32 " FPS (refr_cnt: %" LV_PRIu32 " | redraw_cnt: %" LV_PRIu32"), "
"refr %" LV_PRIu32 "ms (render %" LV_PRIu32 "ms | flush %" LV_PRIu32 "ms), " "refr %" LV_PRIu32 "ms (render %" LV_PRIu32 "ms | flush %" LV_PRIu32 "ms), "
@ -290,6 +289,7 @@ static void perf_observer_cb(lv_observer_t * observer, lv_subject_t * subject)
perf->calculated.refr_avg_time, perf->calculated.render_avg_time, perf->calculated.flush_avg_time, perf->calculated.refr_avg_time, perf->calculated.render_avg_time, perf->calculated.flush_avg_time,
perf->calculated.cpu); perf->calculated.cpu);
#else #else
lv_obj_t * label = lv_observer_get_target(observer);
lv_label_set_text_fmt( lv_label_set_text_fmt(
label, label,
"%" LV_PRIu32" FPS, %" LV_PRIu32 "%% CPU\n" "%" LV_PRIu32" FPS, %" LV_PRIu32 "%% CPU\n"

View File

@ -134,6 +134,13 @@ uint32_t lv_animimg_get_repeat_count(lv_obj_t * obj)
return lv_anim_get_repeat_count(&animimg->anim); return lv_anim_get_repeat_count(&animimg->anim);
} }
lv_anim_t * lv_animimg_get_anim(lv_obj_t * obj)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_animimg_t * animimg = (lv_animimg_t *)obj;
return &animimg->anim;
}
/********************** /**********************
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/

View File

@ -14,6 +14,7 @@ extern "C" {
* INCLUDES * INCLUDES
*********************/ *********************/
#include "../image/lv_image.h" #include "../image/lv_image.h"
#include "../../misc/lv_types.h"
#if LV_USE_ANIMIMG != 0 #if LV_USE_ANIMIMG != 0
@ -112,6 +113,13 @@ uint32_t lv_animimg_get_duration(lv_obj_t * img);
*/ */
uint32_t lv_animimg_get_repeat_count(lv_obj_t * img); uint32_t lv_animimg_get_repeat_count(lv_obj_t * img);
/**
* Get the image animation underlying animation.
* @param img pointer to an animation image object
* @return the animation reference
*/
lv_anim_t * lv_animimg_get_anim(lv_obj_t * img);
#endif /*LV_USE_ANIMIMG*/ #endif /*LV_USE_ANIMIMG*/
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -199,6 +199,9 @@ void lv_arc_set_rotation(lv_obj_t * obj, int32_t rotation)
LV_ASSERT_OBJ(obj, MY_CLASS); LV_ASSERT_OBJ(obj, MY_CLASS);
lv_arc_t * arc = (lv_arc_t *)obj; lv_arc_t * arc = (lv_arc_t *)obj;
/* ensure the angle is in the range [0, 360) */
while(rotation < 0) rotation += 360;
while(rotation >= 360) rotation -= 360;
arc->rotation = rotation; arc->rotation = rotation;
lv_obj_invalidate(obj); lv_obj_invalidate(obj);
@ -506,8 +509,9 @@ static void lv_arc_event(const lv_obj_class_t * class_p, lv_event_t * e)
angle -= arc->rotation; angle -= arc->rotation;
angle -= arc->bg_angle_start; /*Make the angle relative to the start angle*/ angle -= arc->bg_angle_start; /*Make the angle relative to the start angle*/
/* If we click near the bg_angle_start the angle will be close to 360° instead of a small angle */ /* ensure the angle is in the range [0, 360) */
if(angle < 0) angle += 360; while(angle < 0) angle += 360;
while(angle >= 360) angle -= 360;
const uint32_t circumference = (uint32_t)((2U * r * 314U) / 100U); /* Equivalent to: 2r * 3.14, avoiding floats */ const uint32_t circumference = (uint32_t)((2U * r * 314U) / 100U); /* Equivalent to: 2r * 3.14, avoiding floats */
const lv_value_precise_t tolerance_deg = (360 * lv_dpx(50U)) / circumference; const lv_value_precise_t tolerance_deg = (360 * lv_dpx(50U)) / circumference;
@ -655,6 +659,25 @@ static void lv_arc_event(const lv_obj_class_t * class_p, lv_event_t * e)
return; return;
} }
/*Calculate the angle of the pressed point*/
lv_value_precise_t angle = lv_atan2(info->point->y - p.y, info->point->x - p.x);
angle -= arc->rotation;
angle -= arc->bg_angle_start; /*Make the angle relative to the start angle*/
/* ensure the angle is in the range [0, 360) */
while(angle < 0) angle += 360;
while(angle >= 360) angle -= 360;
const uint32_t circumference = (uint32_t)((2U * r * 314U) / 100U); /* Equivalent to: 2r * 3.14, avoiding floats */
const lv_value_precise_t tolerance_deg = (360 * lv_dpx(50U)) / circumference;
/* Check if the angle is outside the drawn background arc */
const bool is_angle_within_bg_bounds = lv_arc_angle_within_bg_bounds(obj, angle, tolerance_deg);
if(!is_angle_within_bg_bounds) {
info->res = false;
return;
}
/*Valid if no clicked outside*/ /*Valid if no clicked outside*/
lv_area_increase(&a, w + ext_click_area * 2, w + ext_click_area * 2); lv_area_increase(&a, w + ext_click_area * 2, w + ext_click_area * 2);
info->res = lv_area_is_point_on(&a, info->point, LV_RADIUS_CIRCLE); info->res = lv_area_is_point_on(&a, info->point, LV_RADIUS_CIRCLE);
@ -941,7 +964,10 @@ static bool lv_arc_angle_within_bg_bounds(lv_obj_t * obj, const lv_value_precise
lv_arc_t * arc = (lv_arc_t *)obj; lv_arc_t * arc = (lv_arc_t *)obj;
lv_value_precise_t bounds_angle = arc->bg_angle_end - arc->bg_angle_start; lv_value_precise_t bounds_angle = arc->bg_angle_end - arc->bg_angle_start;
if(bounds_angle < 0) bounds_angle += 360;
/* ensure the angle is in the range [0, 360) */
while(bounds_angle < 0) bounds_angle += 360;
while(bounds_angle >= 360) bounds_angle -= 360;
/* Angle is in the bounds */ /* Angle is in the bounds */
if(angle <= bounds_angle) { if(angle <= bounds_angle) {

View File

@ -44,8 +44,8 @@ struct lv_bar_t {
bool val_reversed; /**< Whether value been reversed */ bool val_reversed; /**< Whether value been reversed */
lv_bar_anim_t cur_value_anim; lv_bar_anim_t cur_value_anim;
lv_bar_anim_t start_value_anim; lv_bar_anim_t start_value_anim;
lv_bar_mode_t mode : 2; /**< Type of bar*/ lv_bar_mode_t mode : 3; /**< Type of bar*/
lv_bar_orientation_t orientation : 2; /**< Orientation of bar*/ lv_bar_orientation_t orientation : 3; /**< Orientation of bar*/
}; };

View File

@ -51,7 +51,7 @@ static bool button_is_popover(lv_buttonmatrix_ctrl_t ctrl_bits);
static bool button_is_checkable(lv_buttonmatrix_ctrl_t ctrl_bits); static bool button_is_checkable(lv_buttonmatrix_ctrl_t ctrl_bits);
static bool button_get_checked(lv_buttonmatrix_ctrl_t ctrl_bits); static bool button_get_checked(lv_buttonmatrix_ctrl_t ctrl_bits);
static uint32_t get_button_from_point(lv_obj_t * obj, lv_point_t * p); static uint32_t get_button_from_point(lv_obj_t * obj, lv_point_t * p);
static void allocate_button_areas_and_controls(const lv_obj_t * obj, const char ** map); static void allocate_button_areas_and_controls(const lv_obj_t * obj, const char * const * map);
static void invalidate_button_area(const lv_obj_t * obj, uint32_t btn_idx); static void invalidate_button_area(const lv_obj_t * obj, uint32_t btn_idx);
static void make_one_button_checked(lv_obj_t * obj, uint32_t btn_idx); static void make_one_button_checked(lv_obj_t * obj, uint32_t btn_idx);
static bool has_popovers_in_top_row(lv_obj_t * obj); static bool has_popovers_in_top_row(lv_obj_t * obj);
@ -60,7 +60,7 @@ static bool has_popovers_in_top_row(lv_obj_t * obj);
* STATIC VARIABLES * STATIC VARIABLES
**********************/ **********************/
#if LV_WIDGETS_HAS_DEFAULT_VALUE #if LV_WIDGETS_HAS_DEFAULT_VALUE
static const char * lv_buttonmatrix_def_map[] = {"Btn1", "Btn2", "Btn3", "\n", "Btn4", "Btn5", ""}; static const char * const lv_buttonmatrix_def_map[] = {"Btn1", "Btn2", "Btn3", "\n", "Btn4", "Btn5", ""};
#endif #endif
const lv_obj_class_t lv_buttonmatrix_class = { const lv_obj_class_t lv_buttonmatrix_class = {
@ -96,7 +96,7 @@ lv_obj_t * lv_buttonmatrix_create(lv_obj_t * parent)
* Setter functions * Setter functions
*====================*/ *====================*/
void lv_buttonmatrix_set_map(lv_obj_t * obj, const char * map[]) void lv_buttonmatrix_set_map(lv_obj_t * obj, const char * const map[])
{ {
LV_ASSERT_OBJ(obj, MY_CLASS); LV_ASSERT_OBJ(obj, MY_CLASS);
if(map == NULL) return; if(map == NULL) return;
@ -125,7 +125,7 @@ void lv_buttonmatrix_set_map(lv_obj_t * obj, const char * map[])
*(A button can be 1,2,3... unit wide)*/ *(A button can be 1,2,3... unit wide)*/
uint32_t txt_tot_i = 0; /*Act. index in the str map*/ uint32_t txt_tot_i = 0; /*Act. index in the str map*/
uint32_t btn_tot_i = 0; /*Act. index of button areas*/ uint32_t btn_tot_i = 0; /*Act. index of button areas*/
const char ** map_row = map; const char * const * map_row = map;
/*Count the units and the buttons in a line*/ /*Count the units and the buttons in a line*/
uint32_t row; uint32_t row;
@ -295,7 +295,7 @@ void lv_buttonmatrix_set_one_checked(lv_obj_t * obj, bool en)
* Getter functions * Getter functions
*====================*/ *====================*/
const char ** lv_buttonmatrix_get_map(const lv_obj_t * obj) const char * const * lv_buttonmatrix_get_map(const lv_obj_t * obj)
{ {
LV_ASSERT_OBJ(obj, MY_CLASS); LV_ASSERT_OBJ(obj, MY_CLASS);
@ -813,7 +813,7 @@ static void draw_main(lv_event_t * e)
* @param obj pointer to button matrix object * @param obj pointer to button matrix object
* @param map_p pointer to a string array * @param map_p pointer to a string array
*/ */
static void allocate_button_areas_and_controls(const lv_obj_t * obj, const char ** map) static void allocate_button_areas_and_controls(const lv_obj_t * obj, const char * const * map)
{ {
lv_buttonmatrix_t * btnm = (lv_buttonmatrix_t *)obj; lv_buttonmatrix_t * btnm = (lv_buttonmatrix_t *)obj;
btnm->row_cnt = 1; btnm->row_cnt = 1;
@ -1029,7 +1029,7 @@ static bool has_popovers_in_top_row(lv_obj_t * obj)
return false; return false;
} }
const char ** map_row = btnm->map_p; const char * const * map_row = btnm->map_p;
uint32_t btn_cnt = 0; uint32_t btn_cnt = 0;
while(map_row[btn_cnt] && lv_strcmp(map_row[btn_cnt], "\n") != 0 && map_row[btn_cnt][0] != '\0') { while(map_row[btn_cnt] && lv_strcmp(map_row[btn_cnt], "\n") != 0 && map_row[btn_cnt][0] != '\0') {

View File

@ -73,7 +73,7 @@ lv_obj_t * lv_buttonmatrix_create(lv_obj_t * parent);
* @param obj pointer to a button matrix object * @param obj pointer to a button matrix object
* @param map pointer a string array. The last string has to be: "". Use "\n" to make a line break. * @param map pointer a string array. The last string has to be: "". Use "\n" to make a line break.
*/ */
void lv_buttonmatrix_set_map(lv_obj_t * obj, const char * map[]); void lv_buttonmatrix_set_map(lv_obj_t * obj, const char * const map[]);
/** /**
* Set the button control map (hidden, disabled etc.) for a button matrix. * Set the button control map (hidden, disabled etc.) for a button matrix.
@ -155,7 +155,7 @@ void lv_buttonmatrix_set_one_checked(lv_obj_t * obj, bool en);
* @param obj pointer to a button matrix object * @param obj pointer to a button matrix object
* @return the current map * @return the current map
*/ */
const char ** lv_buttonmatrix_get_map(const lv_obj_t * obj); const char * const * lv_buttonmatrix_get_map(const lv_obj_t * obj);
/** /**
* Get the index of the lastly "activated" button by the user (pressed, released, focused etc) * Get the index of the lastly "activated" button by the user (pressed, released, focused etc)

View File

@ -30,7 +30,7 @@ extern "C" {
/** Data of button matrix */ /** Data of button matrix */
struct lv_buttonmatrix_t { struct lv_buttonmatrix_t {
lv_obj_t obj; lv_obj_t obj;
const char ** map_p; /**< Pointer to the current map */ const char * const * map_p; /**< Pointer to the current map */
lv_area_t * button_areas; /**< Array of areas of buttons */ lv_area_t * button_areas; /**< Array of areas of buttons */
lv_buttonmatrix_ctrl_t * ctrl_bits; /**< Array of control bytes */ lv_buttonmatrix_ctrl_t * ctrl_bits; /**< Array of control bytes */
uint32_t btn_cnt; /**< Number of button in 'map_p'(Handled by the library) */ uint32_t btn_cnt; /**< Number of button in 'map_p'(Handled by the library) */

View File

@ -6,7 +6,6 @@
/********************* /*********************
* INCLUDES * INCLUDES
*********************/ *********************/
#include "lv_calendar_chinese_private.h"
#include "lv_calendar_private.h" #include "lv_calendar_private.h"
#if LV_USE_CALENDAR && LV_USE_CALENDAR_CHINESE #if LV_USE_CALENDAR && LV_USE_CALENDAR_CHINESE
@ -124,7 +123,7 @@ const char * lv_calendar_get_day_name(lv_calendar_date_t * gregorian)
{ {
uint16_t i, len; uint16_t i, len;
lv_calendar_chinese_t chinese_calendar; lv_calendar_chinese_t chinese_calendar;
chinese_calendar = lv_calendar_gregorian_to_chinese(gregorian); lv_calendar_gregorian_to_chinese(gregorian, &chinese_calendar);
if(gregorian->year > 2099 || gregorian->year < 1901) if(gregorian->year > 2099 || gregorian->year < 1901)
return NULL; return NULL;
@ -170,11 +169,11 @@ const char * lv_calendar_get_day_name(lv_calendar_date_t * gregorian)
return (char *)chinese_calendar_day_name[chinese_calendar.today.day - 1]; return (char *)chinese_calendar_day_name[chinese_calendar.today.day - 1];
} }
lv_calendar_chinese_t lv_calendar_gregorian_to_chinese(lv_calendar_date_t * gregorian) void lv_calendar_gregorian_to_chinese(lv_calendar_date_t * gregorian_time, lv_calendar_chinese_t * chinese_time)
{ {
uint16_t year = gregorian->year; uint16_t year = gregorian_time->year;
uint8_t month = gregorian->month; uint8_t month = gregorian_time->month;
uint8_t day = gregorian->day; uint8_t day = gregorian_time->day;
/*Record the number of days between the Spring Festival /*Record the number of days between the Spring Festival
and the New Year's Day of that year.*/ and the New Year's Day of that year.*/
@ -191,14 +190,13 @@ lv_calendar_chinese_t lv_calendar_gregorian_to_chinese(lv_calendar_date_t * greg
uint8_t index; uint8_t index;
bool leep_month; bool leep_month;
lv_calendar_chinese_t chinese_calendar;
if(year < 1901 || year > 2099) { if(year < 1901 || year > 2099) {
chinese_calendar.leep_month = 0; chinese_time->leep_month = 0;
chinese_calendar.today.year = 2000; chinese_time->today.year = 2000;
chinese_calendar.today.month = 1; chinese_time->today.month = 1;
chinese_calendar.today.day = 1; chinese_time->today.day = 1;
return chinese_calendar; return;
} }
if(((calendar_chinese_table[year - 1901] & 0x0060) >> 5) == 1) if(((calendar_chinese_table[year - 1901] & 0x0060) >> 5) == 1)
@ -274,11 +272,10 @@ lv_calendar_chinese_t lv_calendar_gregorian_to_chinese(lv_calendar_date_t * greg
day = days_per_month - by_spring + 1; day = days_per_month - by_spring + 1;
} }
chinese_calendar.today.day = day; chinese_time->today.day = day;
chinese_calendar.today.month = month; chinese_time->today.month = month;
chinese_calendar.today.year = year; chinese_time->today.year = year;
chinese_calendar.leep_month = leep_month; chinese_time->leep_month = leep_month;
return chinese_calendar;
} }
/********************** /**********************

View File

@ -21,6 +21,15 @@ extern "C" {
* DEFINES * DEFINES
*********************/ *********************/
/**********************
* TYPEDEFS
**********************/
typedef struct {
lv_calendar_date_t today;
bool leep_month;
} lv_calendar_chinese_t;
/********************** /**********************
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
**********************/ **********************/
@ -41,10 +50,10 @@ const char * lv_calendar_get_day_name(lv_calendar_date_t * gregorian);
/** /**
* Get the chinese time of the gregorian time (reference: https://www.cnblogs.com/liyang31tg/p/4123171.html) * Get the chinese time of the gregorian time (reference: https://www.cnblogs.com/liyang31tg/p/4123171.html)
* @param gregorian need to convert to chinese time in gregorian time * @param gregorian_time need to convert to chinese time in gregorian time
* @return return the chinese time of the gregorian time * @param chinese_time the chinese time convert from gregorian time
*/ */
lv_calendar_chinese_t lv_calendar_gregorian_to_chinese(lv_calendar_date_t * gregorian); void lv_calendar_gregorian_to_chinese(lv_calendar_date_t * gregorian_time, lv_calendar_chinese_t * chinese_time);
/********************** /**********************
* MACROS * MACROS

View File

@ -862,7 +862,6 @@ static void draw_main(lv_event_t * e)
int32_t border_width = lv_obj_get_style_border_width(obj, LV_PART_MAIN); int32_t border_width = lv_obj_get_style_border_width(obj, LV_PART_MAIN);
int32_t left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN) + border_width; int32_t left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN) + border_width;
int32_t right = lv_obj_get_style_pad_right(obj, LV_PART_MAIN) + border_width; int32_t right = lv_obj_get_style_pad_right(obj, LV_PART_MAIN) + border_width;
int32_t top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN) + border_width;
lv_draw_label_dsc_t symbol_dsc; lv_draw_label_dsc_t symbol_dsc;
lv_draw_label_dsc_init(&symbol_dsc); lv_draw_label_dsc_init(&symbol_dsc);
@ -906,24 +905,22 @@ static void draw_main(lv_event_t * e)
} }
lv_area_t symbol_area; lv_area_t symbol_area;
symbol_area.y1 = obj->coords.y1;
symbol_area.y2 = symbol_area.y1 + symbol_h - 1;
symbol_area.x1 = obj->coords.x1;
symbol_area.x2 = symbol_area.x1 + symbol_w - 1;
if(symbol_to_left) { if(symbol_to_left) {
symbol_area.x1 = obj->coords.x1 + left; lv_area_align(&obj->coords, &symbol_area, LV_ALIGN_LEFT_MID, left, 0);
symbol_area.x2 = symbol_area.x1 + symbol_w - 1;
} }
else { else {
symbol_area.x1 = obj->coords.x2 - right - symbol_w; lv_area_align(&obj->coords, &symbol_area, LV_ALIGN_RIGHT_MID, -right, 0);
symbol_area.x2 = symbol_area.x1 + symbol_w - 1;
} }
if(symbol_type == LV_IMAGE_SRC_SYMBOL) { if(symbol_type == LV_IMAGE_SRC_SYMBOL) {
symbol_area.y1 = obj->coords.y1 + top;
symbol_area.y2 = symbol_area.y1 + symbol_h - 1;
symbol_dsc.text = dropdown->symbol; symbol_dsc.text = dropdown->symbol;
lv_draw_label(layer, &symbol_dsc, &symbol_area); lv_draw_label(layer, &symbol_dsc, &symbol_area);
} }
else { else {
symbol_area.y1 = obj->coords.y1 + (lv_obj_get_height(obj) - symbol_h) / 2;
symbol_area.y2 = symbol_area.y1 + symbol_h - 1;
lv_draw_image_dsc_t img_dsc; lv_draw_image_dsc_t img_dsc;
lv_draw_image_dsc_init(&img_dsc); lv_draw_image_dsc_init(&img_dsc);
lv_obj_init_draw_image_dsc(obj, LV_PART_INDICATOR, &img_dsc); lv_obj_init_draw_image_dsc(obj, LV_PART_INDICATOR, &img_dsc);
@ -943,22 +940,21 @@ static void draw_main(lv_event_t * e)
label_dsc.flag); label_dsc.flag);
lv_area_t txt_area; lv_area_t txt_area;
txt_area.y1 = obj->coords.y1 + top; txt_area.x1 = obj->coords.x1;
txt_area.y2 = txt_area.y1 + size.y; txt_area.x2 = txt_area.x1 + size.x - 1;
txt_area.y1 = obj->coords.y1;
txt_area.y2 = txt_area.y1 + size.y - 1;
/*Center align the text if no symbol*/ /*Center align the text if no symbol*/
if(dropdown->symbol == NULL) { if(dropdown->symbol == NULL) {
txt_area.x1 = obj->coords.x1 + (lv_obj_get_width(obj) - size.x) / 2; lv_area_align(&obj->coords, &txt_area, LV_ALIGN_CENTER, 0, 0);
txt_area.x2 = txt_area.x1 + size.x;
} }
else { else {
/*Text to the right*/ /*Text to the right*/
if(symbol_to_left) { if(symbol_to_left) {
txt_area.x1 = obj->coords.x2 - right - size.x; lv_area_align(&obj->coords, &txt_area, LV_ALIGN_RIGHT_MID, -right, 0);
txt_area.x2 = txt_area.x1 + size.x;
} }
else { else {
txt_area.x1 = obj->coords.x1 + left; lv_area_align(&obj->coords, &txt_area, LV_ALIGN_LEFT_MID, left, 0);
txt_area.x2 = txt_area.x1 + size.x;
} }
} }

View File

@ -435,6 +435,11 @@ void lv_image_set_inner_align(lv_obj_t * obj, lv_image_align_t align)
lv_image_t * img = (lv_image_t *)obj; lv_image_t * img = (lv_image_t *)obj;
if(align == img->align) return; if(align == img->align) return;
/*If we're removing STRETCH, reset the scale*/
if(img->align == LV_IMAGE_ALIGN_STRETCH) {
lv_image_set_scale(obj, LV_SCALE_NONE);
}
img->align = align; img->align = align;
update_align(obj); update_align(obj);
@ -849,9 +854,11 @@ static void update_align(lv_obj_t * obj)
if(img->align == LV_IMAGE_ALIGN_STRETCH) { if(img->align == LV_IMAGE_ALIGN_STRETCH) {
lv_image_set_rotation(obj, 0); lv_image_set_rotation(obj, 0);
lv_image_set_pivot(obj, 0, 0); lv_image_set_pivot(obj, 0, 0);
int32_t scale_x = lv_obj_get_width(obj) * LV_SCALE_NONE / img->w; if(img->w != 0 && img->h != 0) {
int32_t scale_y = lv_obj_get_height(obj) * LV_SCALE_NONE / img->h; int32_t scale_x = lv_obj_get_width(obj) * LV_SCALE_NONE / img->w;
scale_update(obj, scale_x, scale_y); int32_t scale_y = lv_obj_get_height(obj) * LV_SCALE_NONE / img->h;
scale_update(obj, scale_x, scale_y);
}
} }
else if(img->align == LV_IMAGE_ALIGN_TILE) { else if(img->align == LV_IMAGE_ALIGN_TILE) {
lv_image_set_rotation(obj, 0); lv_image_set_rotation(obj, 0);

View File

@ -176,19 +176,19 @@ static const lv_buttonmatrix_ctrl_t default_kb_ctrl_num_map[] = {
1, 1, 1, 1, 1 1, 1, 1, 1, 1
}; };
static const char * * kb_map[10] = { static const char * const * kb_map[10] = {
(const char * *)default_kb_map_lc, default_kb_map_lc,
(const char * *)default_kb_map_uc, default_kb_map_uc,
(const char * *)default_kb_map_spec, default_kb_map_spec,
(const char * *)default_kb_map_num, default_kb_map_num,
(const char * *)default_kb_map_lc, default_kb_map_lc,
(const char * *)default_kb_map_lc, default_kb_map_lc,
(const char * *)default_kb_map_lc, default_kb_map_lc,
(const char * *)default_kb_map_lc, default_kb_map_lc,
#if LV_USE_ARABIC_PERSIAN_CHARS == 1 #if LV_USE_ARABIC_PERSIAN_CHARS == 1
(const char * *)default_kb_map_ar, default_kb_map_ar,
#endif #endif
(const char * *)NULL NULL
}; };
static const lv_buttonmatrix_ctrl_t * kb_ctrl[10] = { static const lv_buttonmatrix_ctrl_t * kb_ctrl[10] = {
default_kb_ctrl_lc_map, default_kb_ctrl_lc_map,
@ -269,7 +269,7 @@ void lv_keyboard_set_popovers(lv_obj_t * obj, bool en)
lv_keyboard_update_ctrl_map(obj); lv_keyboard_update_ctrl_map(obj);
} }
void lv_keyboard_set_map(lv_obj_t * obj, lv_keyboard_mode_t mode, const char * map[], void lv_keyboard_set_map(lv_obj_t * obj, lv_keyboard_mode_t mode, const char * const map[],
const lv_buttonmatrix_ctrl_t ctrl_map[]) const lv_buttonmatrix_ctrl_t ctrl_map[])
{ {
LV_ASSERT_OBJ(obj, MY_CLASS); LV_ASSERT_OBJ(obj, MY_CLASS);
@ -410,7 +410,7 @@ void lv_keyboard_def_event_cb(lv_event_t * e)
} }
} }
const char ** lv_keyboard_get_map_array(const lv_obj_t * kb) const char * const * lv_keyboard_get_map_array(const lv_obj_t * kb)
{ {
return lv_buttonmatrix_get_map(kb); return lv_buttonmatrix_get_map(kb);
} }

View File

@ -107,7 +107,7 @@ void lv_keyboard_set_popovers(lv_obj_t * kb, bool en);
* @param ctrl_map See 'lv_buttonmatrix_set_ctrl_map()' for more info. * @param ctrl_map See 'lv_buttonmatrix_set_ctrl_map()' for more info.
*/ */
void lv_keyboard_set_map(lv_obj_t * kb, lv_keyboard_mode_t mode, const char * map[], void lv_keyboard_set_map(lv_obj_t * kb, lv_keyboard_mode_t mode, const char * const map[],
const lv_buttonmatrix_ctrl_t ctrl_map[]); const lv_buttonmatrix_ctrl_t ctrl_map[]);
/*===================== /*=====================
@ -140,7 +140,7 @@ bool lv_keyboard_get_popovers(const lv_obj_t * obj);
* @param kb pointer to a keyboard object * @param kb pointer to a keyboard object
* @return the current map * @return the current map
*/ */
const char ** lv_keyboard_get_map_array(const lv_obj_t * kb); const char * const * lv_keyboard_get_map_array(const lv_obj_t * kb);
/** /**
* Get the index of the lastly "activated" button by the user (pressed, released, focused etc) * Get the index of the lastly "activated" button by the user (pressed, released, focused etc)

View File

@ -158,13 +158,19 @@ void lv_roller_set_options(lv_obj_t * obj, const char * options, lv_roller_mode_
LV_LOG_INFO("Using %" LV_PRIu32 " pages to make the roller look infinite", roller->inf_page_cnt); LV_LOG_INFO("Using %" LV_PRIu32 " pages to make the roller look infinite", roller->inf_page_cnt);
size_t opt_len = lv_strlen(options) + 1; /*+1 to add '\n' after option lists*/ size_t opt_len = lv_strlen(options) + 1; /*+1 to add '\n' after option lists*/
char * opt_extra = lv_malloc(opt_len * roller->inf_page_cnt); size_t opt_extra_len = opt_len * roller->inf_page_cnt;
if(opt_extra_len == 0) {
/*Prevent write overflow*/
opt_extra_len = 1;
}
char * opt_extra = lv_malloc(opt_extra_len);
uint32_t i; uint32_t i;
for(i = 0; i < roller->inf_page_cnt; i++) { for(i = 0; i < roller->inf_page_cnt; i++) {
lv_strcpy(&opt_extra[opt_len * i], options); lv_strcpy(&opt_extra[opt_len * i], options);
opt_extra[opt_len * (i + 1) - 1] = '\n'; opt_extra[opt_len * (i + 1) - 1] = '\n';
} }
opt_extra[opt_len * roller->inf_page_cnt - 1] = '\0'; opt_extra[opt_extra_len - 1] = '\0';
lv_label_set_text(label, opt_extra); lv_label_set_text(label, opt_extra);
lv_free(opt_extra); lv_free(opt_extra);

View File

@ -442,7 +442,7 @@ int32_t lv_spangroup_get_expand_height(lv_obj_t * obj, int32_t width)
/* coords of draw span-txt */ /* coords of draw span-txt */
lv_point_t txt_pos; lv_point_t txt_pos;
lv_point_set(&txt_pos, 0, indent); /* first line need add indent */ lv_point_set(&txt_pos, indent, 0); /* first line need add indent */
lv_span_t * cur_span = lv_ll_get_head(&spans->child_ll); lv_span_t * cur_span = lv_ll_get_head(&spans->child_ll);
const char * cur_txt = cur_span->txt; const char * cur_txt = cur_span->txt;

View File

@ -1403,11 +1403,16 @@ static void draw_placeholder(lv_event_t * e)
if(ta->one_line) ph_dsc.flag |= LV_TEXT_FLAG_EXPAND; if(ta->one_line) ph_dsc.flag |= LV_TEXT_FLAG_EXPAND;
int32_t left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN); int32_t left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN);
int32_t right = lv_obj_get_style_pad_right(obj, LV_PART_MAIN);
int32_t top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN); int32_t top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN);
int32_t bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_MAIN);
int32_t border_width = lv_obj_get_style_border_width(obj, LV_PART_MAIN); int32_t border_width = lv_obj_get_style_border_width(obj, LV_PART_MAIN);
lv_area_t ph_coords; lv_area_t ph_coords;
lv_area_copy(&ph_coords, &obj->coords); lv_area_copy(&ph_coords, &obj->coords);
lv_area_move(&ph_coords, left + border_width, top + border_width); ph_coords.x1 += left + border_width;
ph_coords.x2 -= right + border_width;
ph_coords.y1 += top + border_width;
ph_coords.y2 -= bottom + border_width;
ph_dsc.text = ta->placeholder_txt; ph_dsc.text = ta->placeholder_txt;
lv_draw_label(layer, &ph_dsc, &ph_coords); lv_draw_label(layer, &ph_dsc, &ph_coords);
} }

View File

@ -1,6 +1,6 @@
/** /**
* @file lv_conf.h * @file lv_conf.h
* Configuration file for v9.2.0 * Configuration file for v9.2.2
*/ */
/* /*
@ -95,6 +95,14 @@
#if LV_USE_OS == LV_OS_CUSTOM #if LV_USE_OS == LV_OS_CUSTOM
#define LV_OS_CUSTOM_INCLUDE <stdint.h> #define LV_OS_CUSTOM_INCLUDE <stdint.h>
#endif #endif
#if LV_USE_OS == LV_OS_FREERTOS
/*
* Unblocking an RTOS task with a direct notification is 45% faster and uses less RAM
* than unblocking a task using an intermediary object such as a binary semaphore.
* RTOS task notifications can only be used when there is only one task that can be the recipient of the event.
*/
#define LV_USE_FREERTOS_TASK_NOTIFY 1
#endif
/*======================== /*========================
* RENDERING CONFIGURATION * RENDERING CONFIGURATION
@ -205,10 +213,16 @@
#endif #endif
/* Use NXP's PXP on iMX RTxxx platforms. */ /* Use NXP's PXP on iMX RTxxx platforms. */
#define LV_USE_DRAW_PXP 0 #define LV_USE_PXP 0
#if LV_USE_DRAW_PXP #if LV_USE_PXP
#if LV_USE_OS /* Use PXP for drawing.*/
#define LV_USE_DRAW_PXP 1
/* Use PXP to rotate display.*/
#define LV_USE_ROTATE_PXP 0
#if LV_USE_DRAW_PXP && LV_USE_OS
/* Use additional draw thread for PXP processing.*/ /* Use additional draw thread for PXP processing.*/
#define LV_USE_PXP_DRAW_THREAD 1 #define LV_USE_PXP_DRAW_THREAD 1
#endif #endif