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
- 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
- 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
:---|:---|:---|:---
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_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)

View File

@ -818,6 +818,7 @@ const be_ntv_func_def_t lv_timer_func[] = {
/* `lv_animimg` methods */
#ifdef BE_LV_WIDGET_ANIMIMG
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_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)" } },

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)
uint32_t lv_animimg_get_duration(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
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
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_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)
@ -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_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)
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)
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)
@ -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
void lv_calendar_set_chinese_mode(lv_obj_t * obj, bool en)
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
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_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_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_keyboard_mode_t lv_keyboard_get_mode(const lv_obj_t * kb)
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)
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_table_cell_ctrl_t": "i",
"lv_calendar_chinese_t": "c",
# "lv_calendar_chinese_t": "c",
# adding ad-hoc colorwheel from LVGL8 to LVGL9
"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
"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
"constchar * *": "c",
# callbacks
"lv_group_focus_cb_t": "lv_group_focus_cb",

View File

@ -1,6 +1,6 @@
{
"name": "lvgl",
"version": "9.2.0",
"version": "9.2.2",
"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.",
"repository": {

View File

@ -1,5 +1,5 @@
name=lvgl
version=9.2.0
version=9.2.2
author=kisvegabor
maintainer=kisvegabor,embeddedt,pete-pjb
sentence=Full-featured Graphics Library for Embedded Systems

View File

@ -1,6 +1,6 @@
/**
* @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
#define LV_OS_CUSTOM_INCLUDE <stdint.h>
#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
@ -205,10 +213,16 @@
#endif
/* 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_OS
#if LV_USE_PXP
/* 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.*/
#define LV_USE_PXP_DRAW_THREAD 1
#endif

View File

@ -8,7 +8,7 @@
#define LVGL_VERSION_MAJOR 9
#define LVGL_VERSION_MINOR 2
#define LVGL_VERSION_PATCH 0
#define LVGL_VERSION_PATCH 2
#define LVGL_VERSION_INFO ""
#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;
if(obj->state != new_state) {
if(new_state & LV_STATE_DISABLED) {
if(new_state & ~obj->state & LV_STATE_DISABLED) {
lv_indev_reset(NULL, obj);
}

View File

@ -1046,7 +1046,7 @@ static int32_t calc_content_width(lv_obj_t * obj)
default:
/* Consider other cases only if x=0 and use the width of the object.
* 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_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 int32_t property_name_compare(const void * ref, const void * element);
static int property_name_compare(const void * ref, const void * element);
/**********************
* 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);
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.num = 0;
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*/
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;
}
@ -278,7 +278,7 @@ static lv_result_t obj_property(lv_obj_t * obj, lv_prop_id_t id, lv_property_t *
break;
}
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;
}
}
@ -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*/
}
LV_LOG_WARN("Unknown property id: 0x%08x", id);
LV_LOG_WARN("Unknown property id: 0x%08" LV_PRIx32, id);
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,
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);
if(selector == LV_PART_MAIN && lv_style_prop_has_flag(prop, LV_STYLE_PROP_FLAG_TRANSFORM)) {
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.
* 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.*/
#if LV_USE_PERF_MONITOR
#if !LV_USE_PERF_MONITOR
lv_timer_pause(tmr);
#endif
}

View File

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

View File

@ -179,8 +179,7 @@ void lv_draw_dispatch(void)
while(disp) {
lv_layer_t * layer = disp->layer_head;
while(layer) {
/* If there are no tasks in the layer, skip it */
if(layer->draw_task_head && lv_draw_dispatch_layer(disp, layer))
if(lv_draw_dispatch_layer(disp, layer))
task_dispatched = true;
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_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(layer->draw_task_head) {
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;
}
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)
{
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;
}
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;
}

View File

@ -67,7 +67,7 @@ LV_EXPORT_CONST_INT(LV_STRIDE_AUTO);
#define LV_DRAW_BUF_INIT_STATIC(name) \
do { \
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); \
} 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
*/
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
@ -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);
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);

View File

@ -15,6 +15,7 @@
#include "lv_draw_pxp.h"
#if LV_USE_PXP
#if LV_USE_DRAW_PXP
#include "../../lv_draw_buf_private.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)
{
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;
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;
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. */
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_PXP*/

View File

@ -15,7 +15,8 @@
#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_utils.h"
@ -82,6 +83,9 @@ static void _pxp_execute_drawing(lv_draw_pxp_unit_t * u);
void lv_draw_pxp_init(void)
{
lv_pxp_init();
#if LV_USE_DRAW_PXP
lv_draw_buf_pxp_init_handlers();
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.delete_cb = _pxp_delete;
lv_pxp_init();
#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);
#endif
#endif /*LV_USE_DRAW_PXP*/
}
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();
/* 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;
switch(rotation) {
case LV_DISPLAY_ROTATION_0:
pxp_rotation = kPXP_Rotate0;
break;
case LV_DISPLAY_ROTATION_90:
case LV_DISPLAY_ROTATION_270:
pxp_rotation = kPXP_Rotate90;
break;
case LV_DISPLAY_ROTATION_180:
pxp_rotation = kPXP_Rotate180;
break;
case LV_DISPLAY_ROTATION_270:
case LV_DISPLAY_ROTATION_90:
pxp_rotation = kPXP_Rotate270;
break;
default:
@ -159,7 +169,7 @@ void lv_draw_pxp_rotate(const void * src_buf, void * dest_buf, int32_t src_width
/**********************
* STATIC FUNCTIONS
**********************/
#if LV_USE_DRAW_PXP
static inline bool _pxp_src_cf_supported(lv_color_format_t cf)
{
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)
return LV_DRAW_UNIT_IDLE;
void * buf = lv_draw_layer_alloc_buf(layer);
if(buf == NULL)
if(lv_draw_layer_alloc_buf(layer) == NULL)
return LV_DRAW_UNIT_IDLE;
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.");
}
#endif
#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"
#if LV_USE_DRAW_PXP
#include "../../sw/lv_draw_sw.h"
#if LV_USE_PXP
#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP
#include "../../sw/lv_draw_sw_private.h"
#include "../../../misc/lv_area_private.h"
/*********************
* DEFINES
@ -39,8 +41,6 @@ typedef lv_draw_sw_unit_t lv_draw_pxp_unit_t;
* GLOBAL PROTOTYPES
**********************/
void lv_draw_buf_pxp_init_handlers(void);
void lv_draw_pxp_init(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,
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,
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
**********************/
#endif /*LV_USE_DRAW_PXP*/
#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/
#endif /*LV_USE_PXP*/
#ifdef __cplusplus
} /*extern "C"*/

View File

@ -15,6 +15,7 @@
#include "lv_draw_pxp.h"
#if LV_USE_PXP
#if LV_USE_DRAW_PXP
#include "lv_pxp_cfg.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_PXP*/

View File

@ -15,6 +15,7 @@
#include "lv_draw_pxp.h"
#if LV_USE_PXP
#if LV_USE_DRAW_PXP
#include "lv_pxp_cfg.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_PXP*/

View File

@ -15,6 +15,7 @@
#include "lv_draw_pxp.h"
#if LV_USE_PXP
#if LV_USE_DRAW_PXP
#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_PXP*/

View File

@ -15,7 +15,8 @@
#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"
/*********************
@ -88,4 +89,5 @@ void lv_pxp_wait(void)
* 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"
#if LV_USE_DRAW_PXP
#if LV_USE_PXP
#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP
#include "fsl_cache.h"
#include "fsl_pxp.h"
@ -93,7 +94,8 @@ void lv_pxp_wait(void);
* MACROS
**********************/
#endif /*LV_USE_DRAW_PXP*/
#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/
#endif /*LV_USE_PXP*/
#ifdef __cplusplus
} /*extern "C"*/

View File

@ -15,7 +15,8 @@
#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 "../../../misc/lv_log.h"
#include "../../../osal/lv_os.h"
@ -183,4 +184,5 @@ static void _pxp_wait(void)
#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"
#if LV_USE_DRAW_PXP
#if LV_USE_PXP
#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP
#include "lv_pxp_cfg.h"
/*********************
@ -51,7 +52,8 @@ pxp_cfg_t * pxp_get_default_cfg(void);
* MACROS
**********************/
#endif /*LV_USE_DRAW_PXP*/
#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/
#endif /*LV_USE_PXP*/
#ifdef __cplusplus
} /*extern "C"*/

View File

@ -15,7 +15,8 @@
#include "lv_pxp_utils.h"
#if LV_USE_DRAW_PXP
#if LV_USE_PXP
#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP
/*********************
* DEFINES
@ -89,6 +90,7 @@ pxp_as_pixel_format_t pxp_get_as_px_format(lv_color_format_t cf)
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 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 || LV_USE_ROTATE_PXP*/
#endif /*LV_USE_PXP*/

View File

@ -21,7 +21,8 @@ extern "C" {
*********************/
#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 "../../../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);
#if LV_USE_DRAW_PXP
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);
@ -72,6 +74,8 @@ bool pxp_buf_aligned(const void * buf, uint32_t stride);
**********************/
#endif /*LV_USE_DRAW_PXP*/
#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/
#endif /*LV_USE_PXP*/
#ifdef __cplusplus
} /*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 uint32_t _width_to_stride(uint32_t w, lv_color_format_t cf);
/**********************
* 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)
{
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;
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;
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. */
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*/

View File

@ -291,16 +291,14 @@ static int32_t _vglite_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer)
if(t == NULL)
return LV_DRAW_UNIT_IDLE;
if(lv_draw_get_unit_count() > 1) {
/* Let the SW unit to draw this task. */
if(t->preferred_draw_unit_id != DRAW_UNIT_ID_VGLITE)
if(t->preferred_draw_unit_id != DRAW_UNIT_ID_VGLITE) {
/* Let the preferred known unit to draw this task. */
if(t->preferred_draw_unit_id != LV_DRAW_UNIT_NONE) {
return LV_DRAW_UNIT_IDLE;
}
else {
/* Fake unsupported tasks as ready. */
if(t->preferred_draw_unit_id != DRAW_UNIT_ID_VGLITE) {
}
else {
/* Fake unsupported tasks as ready. */
t->state = LV_DRAW_TASK_STATE_READY;
/* Request a new dispatching as it can get a new task. */
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(buf == NULL)
if(lv_draw_layer_alloc_buf(layer) == NULL)
return LV_DRAW_UNIT_IDLE;
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;
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)
lv_thread_sync_signal(&draw_vglite_unit->sync);
/* Wait for finish now. */
lv_draw_dispatch_wait_for_request();
return 1;
}
#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.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 height = tri_area.y2 - tri_area.y1;
uint32_t width = lv_area_get_width(&tri_area);
uint32_t height = lv_area_get_height(&tri_area);
/* Init path */
int32_t triangle_path[] = { /*VG line path*/

View File

@ -16,6 +16,8 @@ extern "C" {
#include "lv_draw_sw_mask.h"
#if LV_DRAW_SW_COMPLEX
/*********************
* DEFINES
*********************/
@ -146,6 +148,8 @@ void lv_draw_sw_mask_cleanup(void);
* MACROS
**********************/
#endif /*LV_DRAW_SW_COMPLEX*/
#ifdef __cplusplus
} /*extern "C"*/
#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;
}
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;
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;
}
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;
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);
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
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);
vg_lite_matrix_t matrix;
vg_lite_identity(&matrix);
lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix);
vg_lite_matrix_t matrix = u->global_matrix;
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) {
vg_lite_buffer_t src_buf;
lv_image_decoder_dsc_t decoder_dsc;
if(lv_vg_lite_buffer_open_image(&src_buf, &decoder_dsc, dsc->img_src, false)) {
vg_lite_matrix_t path_matrix;
vg_lite_identity(&path_matrix);
lv_vg_lite_matrix_multiply(&path_matrix, &u->global_matrix);
if(lv_vg_lite_buffer_open_image(&src_buf, &decoder_dsc, dsc->img_src, false, true)) {
vg_lite_matrix_t path_matrix = u->global_matrix;
/* move image to center */
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);
vg_lite_matrix_t matrix;
vg_lite_identity(&matrix);
lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix);
vg_lite_matrix_t matrix = u->global_matrix;
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;
vg_lite_matrix_t 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);
}
vg_lite_matrix_t matrix = u->global_matrix;
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_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);
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;
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;
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));
}
vg_lite_matrix_t matrix;
vg_lite_identity(&matrix);
lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix);
lv_vg_lite_image_matrix(&matrix, coords->x1, coords->y1, dsc);
/* convert the blend mode to vg-lite blend mode, considering the premultiplied alpha */
bool has_pre_mul = lv_draw_buf_has_flag(decoder_dsc.decoded, LV_IMAGE_FLAGS_PREMULTIPLIED);
vg_lite_blend_t blend = lv_vg_lite_blend_mode(dsc->blend_mode, has_pre_mul);
/* 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_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);
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,
&rect,
&matrix,
lv_vg_lite_blend_mode(dsc->blend_mode),
blend,
color,
filter));
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 {
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);
int32_t height = lv_area_get_height(coords);
float r_short = LV_MIN(width, height) / 2.0f;
float radius = LV_MIN(dsc->clip_radius, r_short);
/**
* When clip_radius is enabled, the clipping edges
* are aligned with the image edges
*/
/**
* When the image is transformed or rounded, create a path around
* the image and follow the image_matrix for coordinate transformation
*/
if(!no_transform || dsc->clip_radius) {
/* apply the image transform to the path */
lv_vg_lite_path_set_transform(path, &image_matrix);
lv_vg_lite_path_append_rect(
path,
coords->x1, coords->y1,
width, height,
radius);
0, 0,
lv_area_get_width(coords), lv_area_get_height(coords),
dsc->clip_radius);
lv_vg_lite_path_set_transform(path, NULL);
}
else {
/* append normal rect to the path */
lv_vg_lite_path_append_rect(
path,
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);
LV_VG_LITE_ASSERT_PATH(vg_lite_path);
vg_lite_matrix_t path_matrix;
vg_lite_identity(&path_matrix);
lv_vg_lite_matrix_multiply(&path_matrix, &u->global_matrix);
vg_lite_matrix_t path_matrix = u->global_matrix;
LV_VG_LITE_ASSERT_MATRIX(&path_matrix);
LV_PROFILER_BEGIN_TAG("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,
&src_buf,
&matrix,
lv_vg_lite_blend_mode(dsc->blend_mode),
blend,
VG_LITE_PATTERN_COLOR,
0,
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;
vg_lite_matrix_t matrix;
vg_lite_identity(&matrix);
lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix);
vg_lite_matrix_t matrix = u->global_matrix;
vg_lite_translate(image_area.x1, image_area.y1, &matrix);
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);
LV_VG_LITE_ASSERT_PATH(vg_lite_path);
vg_lite_matrix_t path_matrix;
vg_lite_identity(&path_matrix);
lv_vg_lite_matrix_multiply(&path_matrix, &u->global_matrix);
vg_lite_matrix_t path_matrix = u->global_matrix;
LV_VG_LITE_ASSERT_MATRIX(&path_matrix);
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);
/* matrix for drawing, different from matrix for calculating the bonding box */
vg_lite_matrix_t draw_matrix;
vg_lite_identity(&draw_matrix);
lv_vg_lite_matrix_multiply(&draw_matrix, &u->global_matrix);
vg_lite_matrix_t draw_matrix = u->global_matrix;
/* 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);

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);
vg_lite_matrix_t matrix;
vg_lite_identity(&matrix);
lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix);
vg_lite_matrix_t matrix = u->global_matrix;
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 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_set_quality(path, VG_LITE_HIGH);
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 */
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_end(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_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 */
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,
vg_lite_path,
VG_LITE_FILL_EVEN_ODD,
matrix,
&matrix,
VG_LITE_BLEND_DST_IN,
0));
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_PATH(vg_lite_path);
vg_lite_matrix_t matrix;
vg_lite_identity(&matrix);
lv_vg_lite_matrix_multiply(&matrix, &u->global_matrix);
vg_lite_matrix_t matrix = u->global_matrix;
LV_VG_LITE_ASSERT_MATRIX(&matrix);
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 */
vg_lite_buffer_t image_buffer;
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. */
lv_matrix_t m = dsc->matrix;
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;
case LV_VECTOR_DRAW_STYLE_GRADIENT: {
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(
u,

View File

@ -36,8 +36,10 @@
struct lv_vg_lite_path_t {
vg_lite_path_t base;
vg_lite_matrix_t matrix;
size_t mem_size;
uint8_t format_len;
bool has_transform;
};
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.path_type = VG_LITE_DRAW_ZERO;
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)
@ -234,6 +237,16 @@ bool lv_vg_lite_path_update_bonding_box(lv_vg_lite_path_t * path)
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)
{
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)
{
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) {
lv_vg_lite_path_append_data(path, &x, sizeof(x));
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);
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);
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 no_cache)
bool no_cache, bool premultiply)
{
LV_ASSERT_NULL(buffer);
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_memzero(&args, sizeof(lv_image_decoder_args_t));
args.premultiply = !lv_vg_lite_support_blend_normal();
args.premultiply = premultiply;
args.stride_align = true;
args.use_indexed = true;
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);
}
#if LV_USE_MATRIX
void lv_vg_lite_matrix(vg_lite_matrix_t * dest, const lv_matrix_t * src)
{
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 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;
}
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) {
case LV_BLEND_MODE_NORMAL: /**< Simply mix according to the opacity value*/
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) {
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_SRC_OVER;
@ -883,11 +879,6 @@ bool lv_vg_lite_buffer_check(const vg_lite_buffer_t * buffer, bool is_src)
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)) {
LV_LOG_ERROR("buffer tiled(%d) is invalid", (int)buffer->tiled);
return false;
@ -898,12 +889,6 @@ bool lv_vg_lite_buffer_check(const vg_lite_buffer_t * buffer, bool is_src)
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)) {
LV_LOG_ERROR("buffer width(%d) is not aligned", (int)buffer->width);
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);
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_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);
@ -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);
#if LV_USE_MATRIX
void lv_vg_lite_matrix(vg_lite_matrix_t * dest, const lv_matrix_t * src);
#endif
/* Param checker */
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;
}
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);
if(dsc->fb1 == NULL) {
lv_free(dsc);

View File

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

View File

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

View File

@ -216,11 +216,11 @@ static void display_release_cb(lv_event_t * e)
/* clear display buffer */
if(disp->buf_1) {
lv_free(disp->buf_1);
lv_free(disp->buf_1->data);
disp->buf_1 = NULL;
}
if(disp->buf_2) {
lv_free(disp->buf_2);
lv_free(disp->buf_2->data);
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_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*/
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*/
@ -166,7 +166,7 @@ lv_display_t * lv_sdl_get_disp_from_win_id(uint32_t win_id)
while(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;
}
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);
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*/

View File

@ -113,9 +113,21 @@ static gd_GIF * gif_open(gd_GIF * gif_base)
/* Aspect Ratio */
f_gif_read(gif_base, &aspect, 1);
/* Create gd_GIF Structure. */
if(0 == width || 0 == height){
LV_LOG_WARN("Zero size image");
goto fail;
}
#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);
#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);
#endif
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
/* Decompress image pixels.
* Return 0 on success or -1 on out-of-memory (w.r.t. LZW code table) or parse error. */
static int
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) {
/* copy data to frame buffer */
while (sp > p_stack) {
if(frm_off >= frm_size){
LV_LOG_WARN("LZW table token overflows the frame buffer");
return -1;
}
*ptr++ = *(--sp);
frm_off += 1;
/* read one line */
@ -526,7 +544,7 @@ interlaced_line_index(int h, int y)
}
/* 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
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++;
entry = table->entries[key];
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++) {
p = frm_off + entry.length - 1;
x = p % gif->fw;
@ -603,7 +625,7 @@ read_image_data(gd_GIF * gif, int interlace)
#endif
/* 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
read_image(gd_GIF * gif)
{
@ -615,6 +637,10 @@ read_image(gd_GIF * gif)
gif->fy = read_num(gif);
gif->fw = 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);
interlace = fisrz & 0x40;
/* Ignore Sort Flag. */

View File

@ -137,6 +137,36 @@ void lv_gif_resume(lv_obj_t * obj)
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
**********************/

View File

@ -72,6 +72,25 @@ void lv_gif_pause(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
**********************/

View File

@ -266,6 +266,24 @@
#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
@ -610,16 +628,38 @@
#endif
/* Use NXP's PXP on iMX RTxxx platforms. */
#ifndef LV_USE_DRAW_PXP
#ifdef CONFIG_LV_USE_DRAW_PXP
#define LV_USE_DRAW_PXP CONFIG_LV_USE_DRAW_PXP
#ifndef LV_USE_PXP
#ifdef CONFIG_LV_USE_PXP
#define LV_USE_PXP CONFIG_LV_USE_PXP
#else
#define LV_USE_DRAW_PXP 0
#define LV_USE_PXP 0
#endif
#endif
#if LV_USE_DRAW_PXP
#if LV_USE_OS
#if LV_USE_PXP
/* 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.*/
#ifndef LV_USE_PXP_DRAW_THREAD
#ifdef LV_KCONFIG_PRESENT

View File

@ -18,6 +18,16 @@ extern "C" {
# ifdef __NuttX__
# 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__)
# define LV_CONF_INCLUDE_SIMPLE
# include <lv_rt_thread_conf.h>

View File

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

View File

@ -70,7 +70,6 @@ extern "C" {
#include "widgets/buttonmatrix/lv_buttonmatrix_private.h"
#include "widgets/slider/lv_slider_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/imagebutton/lv_imagebutton_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;
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;
}

View File

@ -15,6 +15,7 @@ extern "C" {
*********************/
#include "lv_bidi.h"
#if LV_USE_BIDI
/*********************
* DEFINES
@ -91,6 +92,8 @@ void lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len
* MACROS
**********************/
#endif /*LV_USE_BIDI*/
#ifdef __cplusplus
} /*extern "C"*/
#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_I8:
case LV_COLOR_FORMAT_RGB565A8:
case LV_COLOR_FORMAT_ARGB8565:
case LV_COLOR_FORMAT_ARGB8888:
case LV_COLOR_FORMAT_AL88:
return true;

View File

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

View File

@ -38,12 +38,6 @@ struct lv_fs_path_ex_t {
uint32_t size;
};
struct lv_fs_dir_t {
void * dir_d;
lv_fs_drv_t * drv;
};
/**********************
* 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_dir_t lv_fs_dir_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;
@ -187,8 +185,6 @@ typedef struct lv_buttonmatrix_t lv_buttonmatrix_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_chart_series_t lv_chart_series_t;

View File

@ -15,11 +15,7 @@
#include "lv_os.h"
#if LV_USE_OS == LV_OS_FREERTOS
#if (ESP_PLATFORM)
#include "freertos/atomic.h"
#else
#include "atomic.h"
#endif
#include "atomic.h"
#include "../tick/lv_tick.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);
#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,
uint32_t ulLocalWaitingThreads);
#endif
@ -74,9 +72,13 @@ static void prvTestAndDecrement(lv_thread_sync_t * pxCond,
#if (ESP_PLATFORM)
#define _enter_critical() taskENTER_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
#define _enter_critical() taskENTER_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
/**********************
@ -195,20 +197,20 @@ lv_result_t lv_thread_sync_wait(lv_thread_sync_t * pxCond)
/* If the cond is uninitialized, perform initialization. */
prvCheckCondInit(pxCond);
#if USE_FREERTOS_TASK_NOTIFY
TaskHandle_t current_task_handle = xTaskGetCurrentTaskHandle();
#if LV_USE_FREERTOS_TASK_NOTIFY
TaskHandle_t xCurrentTaskHandle = xTaskGetCurrentTaskHandle();
_enter_critical();
BaseType_t signal_sent = pxCond->xSyncSignal;
BaseType_t xSyncSygnal = pxCond->xSyncSignal;
pxCond->xSyncSignal = pdFALSE;
if(signal_sent == pdFALSE) {
if(xSyncSygnal == pdFALSE) {
/* 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 */
_exit_critical();
if(signal_sent == pdFALSE) {
if(xSyncSygnal == pdFALSE) {
/* Wait for other task to notify this task. */
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. */
prvCheckCondInit(pxCond);
#if USE_FREERTOS_TASK_NOTIFY
#if LV_USE_FREERTOS_TASK_NOTIFY
_enter_critical();
TaskHandle_t task_to_notify = pxCond->xTaskToNotify;
TaskHandle_t xTaskToNotify = pxCond->xTaskToNotify;
pxCond->xTaskToNotify = NULL;
if(task_to_notify == NULL) {
if(xTaskToNotify == NULL) {
/* No task waiting to be notified. Send this signal for later */
pxCond->xSyncSignal = pdTRUE;
}
/* If a task is already waiting, there is no need to set the sync signal */
_exit_critical();
if(task_to_notify != NULL) {
if(xTaskToNotify != NULL) {
/* 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. */
#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)
{
#if !USE_FREERTOS_TASK_NOTIFY
#if !LV_USE_FREERTOS_TASK_NOTIFY
/* Cleanup all resources used by the cond. */
vSemaphoreDelete(pxCond->xCondWaitSemaphore);
vSemaphoreDelete(pxCond->xSyncMutex);
pxCond->ulWaitingThreads = 0;
pxCond->xSyncSignal = pdFALSE;
#endif
pxCond->xSyncSignal = pdFALSE;
pxCond->xIsInitialized = pdFALSE;
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;
/* If the cond is uninitialized, perform initialization. */
prvCheckCondInit(pxCond);
prvCheckCondInitIsr(pxCond);
#if USE_FREERTOS_TASK_NOTIFY
_enter_critical();
TaskHandle_t task_to_notify = pxCond->xTaskToNotify;
#if LV_USE_FREERTOS_TASK_NOTIFY
uint32_t mask = _enter_critical_isr();
TaskHandle_t xTaskToNotify = pxCond->xTaskToNotify;
pxCond->xTaskToNotify = NULL;
if(task_to_notify == NULL) {
if(xTaskToNotify == NULL) {
/* No task waiting to be notified. Send this signal for later */
pxCond->xSyncSignal = pdTRUE;
}
/* 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 */
vTaskNotifyGiveFromISR(task_to_notify, &xHigherPriorityTaskWoken);
vTaskNotifyGiveFromISR(xTaskToNotify, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
/* If there was no task waiting to be notified, we sent a signal for it to see later. */
#else
/* Enter critical section to prevent preemption. */
_enter_critical();
uint32_t mask = _enter_critical_isr();
pxCond->xSyncSignal = pdTRUE;
BaseType_t xAnyHigherPriorityTaskWoken = pdFALSE;
@ -378,7 +380,7 @@ lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * pxCond)
xHigherPriorityTaskWoken |= xAnyHigherPriorityTaskWoken;
}
_exit_critical();
_exit_critical_isr(mask);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
#endif
@ -470,7 +472,7 @@ static void prvCondInit(lv_thread_sync_t * pxCond)
pxCond->xIsInitialized = pdTRUE;
pxCond->xSyncSignal = pdFALSE;
#if USE_FREERTOS_TASK_NOTIFY
#if LV_USE_FREERTOS_TASK_NOTIFY
pxCond->xTaskToNotify = NULL;
#else
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,
uint32_t ulLocalWaitingThreads)
{

View File

@ -37,14 +37,6 @@ extern "C" {
* 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
**********************/
@ -64,7 +56,7 @@ typedef struct {
BaseType_t
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. */
#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. */
#else
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' &&
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_ime->ta_count++;
}
@ -877,8 +878,8 @@ static void init_pinyin_dict(lv_obj_t * obj, const lv_pinyin_dict_t * dict)
}
else {
headletter = dict[i].py[0];
pinyin_ime->py_num[letter_calc] = offset_count;
letter_calc = headletter - 'a';
pinyin_ime->py_num[letter_calc - 1] = offset_count;
offset_sum += offset_count;
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)
{
lv_obj_t * label = lv_observer_get_target(observer);
const lv_sysmon_perf_info_t * perf = lv_subject_get_pointer(subject);
#if LV_USE_PERF_MONITOR_LOG_MODE
LV_UNUSED(label);
LV_UNUSED(observer);
LV_LOG("sysmon: "
"%" LV_PRIu32 " FPS (refr_cnt: %" LV_PRIu32 " | redraw_cnt: %" LV_PRIu32"), "
"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.cpu);
#else
lv_obj_t * label = lv_observer_get_target(observer);
lv_label_set_text_fmt(
label,
"%" 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);
}
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
**********************/

View File

@ -14,6 +14,7 @@ extern "C" {
* INCLUDES
*********************/
#include "../image/lv_image.h"
#include "../../misc/lv_types.h"
#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);
/**
* 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*/
#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_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;
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->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 */
if(angle < 0) angle += 360;
/* 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;
@ -655,6 +659,25 @@ static void lv_arc_event(const lv_obj_class_t * class_p, lv_event_t * e)
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*/
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);
@ -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_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 */
if(angle <= bounds_angle) {

View File

@ -44,8 +44,8 @@ struct lv_bar_t {
bool val_reversed; /**< Whether value been reversed */
lv_bar_anim_t cur_value_anim;
lv_bar_anim_t start_value_anim;
lv_bar_mode_t mode : 2; /**< Type of bar*/
lv_bar_orientation_t orientation : 2; /**< Orientation of bar*/
lv_bar_mode_t mode : 3; /**< Type 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_get_checked(lv_buttonmatrix_ctrl_t ctrl_bits);
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 make_one_button_checked(lv_obj_t * obj, uint32_t btn_idx);
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
**********************/
#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
const lv_obj_class_t lv_buttonmatrix_class = {
@ -96,7 +96,7 @@ lv_obj_t * lv_buttonmatrix_create(lv_obj_t * parent)
* 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);
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)*/
uint32_t txt_tot_i = 0; /*Act. index in the str map*/
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*/
uint32_t row;
@ -295,7 +295,7 @@ void lv_buttonmatrix_set_one_checked(lv_obj_t * obj, bool en)
* 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);
@ -813,7 +813,7 @@ static void draw_main(lv_event_t * e)
* @param obj pointer to button matrix object
* @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;
btnm->row_cnt = 1;
@ -1029,7 +1029,7 @@ static bool has_popovers_in_top_row(lv_obj_t * obj)
return false;
}
const char ** map_row = btnm->map_p;
const char * const * map_row = btnm->map_p;
uint32_t btn_cnt = 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 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.
@ -155,7 +155,7 @@ void lv_buttonmatrix_set_one_checked(lv_obj_t * obj, bool en);
* @param obj pointer to a button matrix object
* @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)

View File

@ -30,7 +30,7 @@ extern "C" {
/** Data of button matrix */
struct lv_buttonmatrix_t {
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_buttonmatrix_ctrl_t * ctrl_bits; /**< Array of control bytes */
uint32_t btn_cnt; /**< Number of button in 'map_p'(Handled by the library) */

View File

@ -6,7 +6,6 @@
/*********************
* INCLUDES
*********************/
#include "lv_calendar_chinese_private.h"
#include "lv_calendar_private.h"
#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;
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)
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];
}
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;
uint8_t month = gregorian->month;
uint8_t day = gregorian->day;
uint16_t year = gregorian_time->year;
uint8_t month = gregorian_time->month;
uint8_t day = gregorian_time->day;
/*Record the number of days between the Spring Festival
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;
bool leep_month;
lv_calendar_chinese_t chinese_calendar;
if(year < 1901 || year > 2099) {
chinese_calendar.leep_month = 0;
chinese_calendar.today.year = 2000;
chinese_calendar.today.month = 1;
chinese_calendar.today.day = 1;
return chinese_calendar;
chinese_time->leep_month = 0;
chinese_time->today.year = 2000;
chinese_time->today.month = 1;
chinese_time->today.day = 1;
return;
}
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;
}
chinese_calendar.today.day = day;
chinese_calendar.today.month = month;
chinese_calendar.today.year = year;
chinese_calendar.leep_month = leep_month;
return chinese_calendar;
chinese_time->today.day = day;
chinese_time->today.month = month;
chinese_time->today.year = year;
chinese_time->leep_month = leep_month;
}
/**********************

View File

@ -21,6 +21,15 @@ extern "C" {
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
typedef struct {
lv_calendar_date_t today;
bool leep_month;
} lv_calendar_chinese_t;
/**********************
* 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)
* @param gregorian need to convert to chinese time in gregorian time
* @return return the chinese time of the gregorian time
* @param gregorian_time need to convert to chinese time in 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

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 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 top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN) + border_width;
lv_draw_label_dsc_t 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;
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) {
symbol_area.x1 = obj->coords.x1 + left;
symbol_area.x2 = symbol_area.x1 + symbol_w - 1;
lv_area_align(&obj->coords, &symbol_area, LV_ALIGN_LEFT_MID, left, 0);
}
else {
symbol_area.x1 = obj->coords.x2 - right - symbol_w;
symbol_area.x2 = symbol_area.x1 + symbol_w - 1;
lv_area_align(&obj->coords, &symbol_area, LV_ALIGN_RIGHT_MID, -right, 0);
}
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;
lv_draw_label(layer, &symbol_dsc, &symbol_area);
}
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_init(&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);
lv_area_t txt_area;
txt_area.y1 = obj->coords.y1 + top;
txt_area.y2 = txt_area.y1 + size.y;
txt_area.x1 = obj->coords.x1;
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*/
if(dropdown->symbol == NULL) {
txt_area.x1 = obj->coords.x1 + (lv_obj_get_width(obj) - size.x) / 2;
txt_area.x2 = txt_area.x1 + size.x;
lv_area_align(&obj->coords, &txt_area, LV_ALIGN_CENTER, 0, 0);
}
else {
/*Text to the right*/
if(symbol_to_left) {
txt_area.x1 = obj->coords.x2 - right - size.x;
txt_area.x2 = txt_area.x1 + size.x;
lv_area_align(&obj->coords, &txt_area, LV_ALIGN_RIGHT_MID, -right, 0);
}
else {
txt_area.x1 = obj->coords.x1 + left;
txt_area.x2 = txt_area.x1 + size.x;
lv_area_align(&obj->coords, &txt_area, LV_ALIGN_LEFT_MID, left, 0);
}
}

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;
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;
update_align(obj);
@ -849,9 +854,11 @@ static void update_align(lv_obj_t * obj)
if(img->align == LV_IMAGE_ALIGN_STRETCH) {
lv_image_set_rotation(obj, 0);
lv_image_set_pivot(obj, 0, 0);
int32_t scale_x = lv_obj_get_width(obj) * LV_SCALE_NONE / img->w;
int32_t scale_y = lv_obj_get_height(obj) * LV_SCALE_NONE / img->h;
scale_update(obj, scale_x, scale_y);
if(img->w != 0 && img->h != 0) {
int32_t scale_x = lv_obj_get_width(obj) * LV_SCALE_NONE / img->w;
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) {
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
};
static const char * * kb_map[10] = {
(const char * *)default_kb_map_lc,
(const char * *)default_kb_map_uc,
(const char * *)default_kb_map_spec,
(const char * *)default_kb_map_num,
(const char * *)default_kb_map_lc,
(const char * *)default_kb_map_lc,
(const char * *)default_kb_map_lc,
(const char * *)default_kb_map_lc,
static const char * const * kb_map[10] = {
default_kb_map_lc,
default_kb_map_uc,
default_kb_map_spec,
default_kb_map_num,
default_kb_map_lc,
default_kb_map_lc,
default_kb_map_lc,
default_kb_map_lc,
#if LV_USE_ARABIC_PERSIAN_CHARS == 1
(const char * *)default_kb_map_ar,
default_kb_map_ar,
#endif
(const char * *)NULL
NULL
};
static const lv_buttonmatrix_ctrl_t * kb_ctrl[10] = {
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);
}
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[])
{
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);
}

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.
*/
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[]);
/*=====================
@ -140,7 +140,7 @@ bool lv_keyboard_get_popovers(const lv_obj_t * obj);
* @param kb pointer to a keyboard object
* @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)

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);
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;
for(i = 0; i < roller->inf_page_cnt; i++) {
lv_strcpy(&opt_extra[opt_len * i], options);
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_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 */
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);
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;
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 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);
lv_area_t ph_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;
lv_draw_label(layer, &ph_dsc, &ph_coords);
}

View File

@ -1,6 +1,6 @@
/**
* @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
#define LV_OS_CUSTOM_INCLUDE <stdint.h>
#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
@ -205,10 +213,16 @@
#endif
/* 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_OS
#if LV_USE_PXP
/* 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.*/
#define LV_USE_PXP_DRAW_THREAD 1
#endif