mirror of
https://github.com/No-Chicken/Power-Pico.git
synced 2026-04-03 13:02:36 +08:00
移动文件夹
This commit is contained in:
266
software/Power_Pico/Middlewares/LVGL/src/core/lv_global.h
Normal file
266
software/Power_Pico/Middlewares/LVGL/src/core/lv_global.h
Normal file
@@ -0,0 +1,266 @@
|
||||
/**
|
||||
* @file lv_global.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_GLOBAL_H
|
||||
#define LV_GLOBAL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_conf_internal.h"
|
||||
|
||||
#include "../misc/lv_types.h"
|
||||
#include "../draw/lv_draw.h"
|
||||
#if LV_USE_DRAW_SW
|
||||
#include "../draw/sw/lv_draw_sw.h"
|
||||
#endif
|
||||
#include "../misc/lv_anim.h"
|
||||
#include "../misc/lv_area.h"
|
||||
#include "../misc/lv_color_op.h"
|
||||
#include "../misc/lv_ll.h"
|
||||
#include "../misc/lv_log.h"
|
||||
#include "../misc/lv_style.h"
|
||||
#include "../misc/lv_timer.h"
|
||||
#include "../osal/lv_os.h"
|
||||
#include "../others/sysmon/lv_sysmon.h"
|
||||
#include "../stdlib/builtin/lv_tlsf.h"
|
||||
|
||||
#if LV_USE_FONT_COMPRESSED
|
||||
#include "../font/lv_font_fmt_txt_private.h"
|
||||
#endif
|
||||
|
||||
#include "../tick/lv_tick.h"
|
||||
#include "../layouts/lv_layout.h"
|
||||
|
||||
#include "../misc/lv_types.h"
|
||||
|
||||
#include "../misc/lv_timer_private.h"
|
||||
#include "../misc/lv_anim_private.h"
|
||||
#include "../tick/lv_tick_private.h"
|
||||
#include "../draw/lv_draw_buf_private.h"
|
||||
#include "../draw/lv_draw_private.h"
|
||||
#include "../draw/sw/lv_draw_sw_private.h"
|
||||
#include "../draw/sw/lv_draw_sw_mask_private.h"
|
||||
#include "../stdlib/builtin/lv_tlsf_private.h"
|
||||
#include "../others/sysmon/lv_sysmon_private.h"
|
||||
#include "../layouts/lv_layout_private.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define ZERO_MEM_SENTINEL 0xa1b2c3d4
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
#if LV_USE_SPAN != 0
|
||||
struct _snippet_stack;
|
||||
#endif
|
||||
|
||||
#if LV_USE_FREETYPE
|
||||
struct lv_freetype_context_t;
|
||||
#endif
|
||||
|
||||
#if LV_USE_PROFILER && LV_USE_PROFILER_BUILTIN
|
||||
struct lv_profiler_builtin_ctx_t;
|
||||
#endif
|
||||
|
||||
#if LV_USE_NUTTX
|
||||
struct lv_nuttx_ctx_t;
|
||||
#endif
|
||||
|
||||
typedef struct lv_global_t {
|
||||
bool inited;
|
||||
bool deinit_in_progress; /**< Can be used e.g. in the LV_EVENT_DELETE to deinit the drivers too */
|
||||
|
||||
lv_ll_t disp_ll;
|
||||
lv_display_t * disp_refresh;
|
||||
lv_display_t * disp_default;
|
||||
|
||||
lv_ll_t style_trans_ll;
|
||||
bool style_refresh;
|
||||
uint32_t style_custom_table_size;
|
||||
uint32_t style_last_custom_prop_id;
|
||||
uint8_t * style_custom_prop_flag_lookup_table;
|
||||
|
||||
lv_ll_t group_ll;
|
||||
lv_group_t * group_default;
|
||||
|
||||
lv_ll_t indev_ll;
|
||||
lv_indev_t * indev_active;
|
||||
lv_obj_t * indev_obj_active;
|
||||
|
||||
uint32_t layout_count;
|
||||
lv_layout_dsc_t * layout_list;
|
||||
bool layout_update_mutex;
|
||||
|
||||
uint32_t memory_zero;
|
||||
uint32_t math_rand_seed;
|
||||
|
||||
lv_event_t * event_header;
|
||||
uint32_t event_last_register_id;
|
||||
|
||||
lv_timer_state_t timer_state;
|
||||
lv_anim_state_t anim_state;
|
||||
lv_tick_state_t tick_state;
|
||||
|
||||
lv_draw_buf_handlers_t draw_buf_handlers;
|
||||
lv_draw_buf_handlers_t font_draw_buf_handlers;
|
||||
lv_draw_buf_handlers_t image_cache_draw_buf_handlers; /**< Ensure that all assigned draw buffers
|
||||
* can be managed by image cache. */
|
||||
|
||||
lv_ll_t img_decoder_ll;
|
||||
|
||||
lv_cache_t * img_cache;
|
||||
lv_cache_t * img_header_cache;
|
||||
|
||||
lv_draw_global_info_t draw_info;
|
||||
#if defined(LV_DRAW_SW_SHADOW_CACHE_SIZE) && LV_DRAW_SW_SHADOW_CACHE_SIZE > 0
|
||||
lv_draw_sw_shadow_cache_t sw_shadow_cache;
|
||||
#endif
|
||||
#if LV_DRAW_SW_COMPLEX
|
||||
lv_draw_sw_mask_radius_circle_dsc_arr_t sw_circle_cache;
|
||||
#endif
|
||||
|
||||
#if LV_USE_LOG
|
||||
lv_log_print_g_cb_t custom_log_print_cb;
|
||||
#endif
|
||||
|
||||
#if LV_USE_LOG && LV_LOG_USE_TIMESTAMP
|
||||
uint32_t log_last_log_time;
|
||||
#endif
|
||||
|
||||
#if LV_USE_THEME_SIMPLE
|
||||
void * theme_simple;
|
||||
#endif
|
||||
|
||||
#if LV_USE_THEME_DEFAULT
|
||||
void * theme_default;
|
||||
#endif
|
||||
|
||||
#if LV_USE_THEME_MONO
|
||||
void * theme_mono;
|
||||
#endif
|
||||
|
||||
#if LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN
|
||||
lv_tlsf_state_t tlsf_state;
|
||||
#endif
|
||||
|
||||
lv_ll_t fsdrv_ll;
|
||||
#if LV_USE_FS_STDIO != '\0'
|
||||
lv_fs_drv_t stdio_fs_drv;
|
||||
#endif
|
||||
#if LV_USE_FS_POSIX
|
||||
lv_fs_drv_t posix_fs_drv;
|
||||
#endif
|
||||
|
||||
#if LV_USE_FS_FATFS
|
||||
lv_fs_drv_t fatfs_fs_drv;
|
||||
#endif
|
||||
|
||||
#if LV_USE_FS_WIN32 != '\0'
|
||||
lv_fs_drv_t win32_fs_drv;
|
||||
#endif
|
||||
|
||||
#if LV_USE_FS_LITTLEFS
|
||||
lv_fs_drv_t littlefs_fs_drv;
|
||||
#endif
|
||||
|
||||
#if LV_USE_FS_ARDUINO_ESP_LITTLEFS
|
||||
lv_fs_drv_t arduino_esp_littlefs_fs_drv;
|
||||
#endif
|
||||
|
||||
#if LV_USE_FS_ARDUINO_SD
|
||||
lv_fs_drv_t arduino_sd_fs_drv;
|
||||
#endif
|
||||
|
||||
#if LV_USE_FREETYPE
|
||||
struct lv_freetype_context_t * ft_context;
|
||||
#endif
|
||||
|
||||
#if LV_USE_FONT_COMPRESSED
|
||||
lv_font_fmt_rle_t font_fmt_rle;
|
||||
#endif
|
||||
|
||||
#if LV_USE_SPAN != 0
|
||||
struct _snippet_stack * span_snippet_stack;
|
||||
#endif
|
||||
|
||||
#if LV_USE_PROFILER && LV_USE_PROFILER_BUILTIN
|
||||
struct lv_profiler_builtin_ctx_t * profiler_context;
|
||||
#endif
|
||||
|
||||
#if LV_USE_FILE_EXPLORER != 0
|
||||
lv_style_t fe_list_button_style;
|
||||
#endif
|
||||
|
||||
#if LV_USE_MEM_MONITOR
|
||||
lv_sysmon_backend_data_t sysmon_mem;
|
||||
#endif
|
||||
|
||||
#if LV_USE_IME_PINYIN != 0
|
||||
size_t ime_cand_len;
|
||||
#endif
|
||||
|
||||
#if LV_USE_OBJ_ID_BUILTIN
|
||||
void * objid_array;
|
||||
uint32_t objid_count;
|
||||
#endif
|
||||
|
||||
#if LV_USE_NUTTX
|
||||
struct lv_nuttx_ctx_t * nuttx_ctx;
|
||||
#endif
|
||||
|
||||
#if LV_USE_OS != LV_OS_NONE
|
||||
lv_mutex_t lv_general_mutex;
|
||||
#endif
|
||||
|
||||
#if LV_USE_OS == LV_OS_FREERTOS
|
||||
uint32_t freertos_idle_time_sum;
|
||||
uint32_t freertos_non_idle_time_sum;
|
||||
uint32_t freertos_task_switch_timestamp;
|
||||
bool freertos_idle_task_running;
|
||||
#endif
|
||||
|
||||
|
||||
void * user_data;
|
||||
} lv_global_t;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#if LV_ENABLE_GLOBAL_CUSTOM
|
||||
#include LV_GLOBAL_CUSTOM_INCLUDE
|
||||
|
||||
#ifndef LV_GLOBAL_CUSTOM
|
||||
#define LV_GLOBAL_CUSTOM() lv_global_default()
|
||||
#endif
|
||||
#define LV_GLOBAL_DEFAULT() LV_GLOBAL_CUSTOM()
|
||||
#else
|
||||
LV_ATTRIBUTE_EXTERN_DATA extern lv_global_t lv_global;
|
||||
#define LV_GLOBAL_DEFAULT() (&lv_global)
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
#if LV_ENABLE_GLOBAL_CUSTOM
|
||||
/**
|
||||
* Get the default global object for current thread
|
||||
* @return pointer to the default global object
|
||||
*/
|
||||
lv_global_t * lv_global_default(void);
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_GLOBAL_H*/
|
||||
530
software/Power_Pico/Middlewares/LVGL/src/core/lv_group.c
Normal file
530
software/Power_Pico/Middlewares/LVGL/src/core/lv_group.c
Normal file
@@ -0,0 +1,530 @@
|
||||
/**
|
||||
* @file lv_group.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_group_private.h"
|
||||
#include "../core/lv_obj_private.h"
|
||||
#include "../core/lv_global.h"
|
||||
#include "../indev/lv_indev.h"
|
||||
#include "../misc/lv_types.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define default_group LV_GLOBAL_DEFAULT()->group_default
|
||||
#define group_ll_p &(LV_GLOBAL_DEFAULT()->group_ll)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static bool focus_next_core(lv_group_t * group, void * (*begin)(const lv_ll_t *),
|
||||
void * (*move)(const lv_ll_t *, const void *));
|
||||
static void lv_group_refocus(lv_group_t * g);
|
||||
static lv_indev_t * get_indev(const lv_group_t * g);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_group_init(void)
|
||||
{
|
||||
lv_ll_init(group_ll_p, sizeof(lv_group_t));
|
||||
}
|
||||
|
||||
void lv_group_deinit(void)
|
||||
{
|
||||
lv_ll_clear(group_ll_p);
|
||||
}
|
||||
|
||||
lv_group_t * lv_group_create(void)
|
||||
{
|
||||
lv_group_t * group = lv_ll_ins_head(group_ll_p);
|
||||
LV_ASSERT_MALLOC(group);
|
||||
if(group == NULL) return NULL;
|
||||
lv_ll_init(&group->obj_ll, sizeof(lv_obj_t *));
|
||||
|
||||
group->obj_focus = NULL;
|
||||
group->frozen = 0;
|
||||
group->focus_cb = NULL;
|
||||
group->edge_cb = NULL;
|
||||
group->editing = 0;
|
||||
group->refocus_policy = LV_GROUP_REFOCUS_POLICY_PREV;
|
||||
group->wrap = 1;
|
||||
group->user_data = NULL;
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
void lv_group_delete(lv_group_t * group)
|
||||
{
|
||||
/*Defocus the currently focused object*/
|
||||
LV_ASSERT_NULL(group);
|
||||
if(group->obj_focus != NULL) {
|
||||
lv_obj_send_event(*group->obj_focus, LV_EVENT_DEFOCUSED, get_indev(group));
|
||||
lv_obj_invalidate(*group->obj_focus);
|
||||
}
|
||||
|
||||
/*Remove the objects from the group*/
|
||||
lv_obj_t ** obj;
|
||||
LV_LL_READ(&group->obj_ll, obj) {
|
||||
if((*obj)->spec_attr)(*obj)->spec_attr->group_p = NULL;
|
||||
}
|
||||
|
||||
/*Remove the group from any indev devices */
|
||||
lv_indev_t * indev = lv_indev_get_next(NULL);
|
||||
while(indev) {
|
||||
if(lv_indev_get_group(indev) == group) {
|
||||
lv_indev_set_group(indev, NULL);
|
||||
}
|
||||
indev = lv_indev_get_next(indev);
|
||||
}
|
||||
|
||||
/*If the group is the default group, set the default group as NULL*/
|
||||
if(group == lv_group_get_default()) lv_group_set_default(NULL);
|
||||
|
||||
lv_ll_clear(&(group->obj_ll));
|
||||
lv_ll_remove(group_ll_p, group);
|
||||
lv_free(group);
|
||||
}
|
||||
|
||||
void lv_group_set_default(lv_group_t * group)
|
||||
{
|
||||
default_group = group;
|
||||
}
|
||||
|
||||
lv_group_t * lv_group_get_default(void)
|
||||
{
|
||||
return default_group;
|
||||
}
|
||||
|
||||
void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj)
|
||||
{
|
||||
if(group == NULL) return;
|
||||
|
||||
LV_LOG_TRACE("begin");
|
||||
|
||||
/*Be sure the object is removed from its current group*/
|
||||
lv_group_remove_obj(obj);
|
||||
|
||||
if(obj->spec_attr == NULL) lv_obj_allocate_spec_attr(obj);
|
||||
obj->spec_attr->group_p = group;
|
||||
|
||||
lv_obj_t ** next = lv_ll_ins_tail(&group->obj_ll);
|
||||
LV_ASSERT_MALLOC(next);
|
||||
if(next == NULL) return;
|
||||
*next = obj;
|
||||
|
||||
/*If the head and the tail is equal then there is only one object in the linked list.
|
||||
*In this case automatically activate it*/
|
||||
if(lv_ll_get_head(&group->obj_ll) == next) {
|
||||
lv_group_refocus(group);
|
||||
}
|
||||
|
||||
LV_LOG_TRACE("finished");
|
||||
}
|
||||
|
||||
void lv_group_swap_obj(lv_obj_t * obj1, lv_obj_t * obj2)
|
||||
{
|
||||
lv_group_t * g1 = lv_obj_get_group(obj1);
|
||||
lv_group_t * g2 = lv_obj_get_group(obj2);
|
||||
if(g1 != g2) return;
|
||||
if(g1 == NULL) return;
|
||||
|
||||
/*Do not add the object twice*/
|
||||
lv_obj_t ** obj_i;
|
||||
LV_LL_READ(&g1->obj_ll, obj_i) {
|
||||
if((*obj_i) == obj1)(*obj_i) = obj2;
|
||||
else if((*obj_i) == obj2)(*obj_i) = obj1;
|
||||
}
|
||||
|
||||
lv_obj_t * focused = lv_group_get_focused(g1);
|
||||
if(focused == obj1) lv_group_focus_obj(obj2);
|
||||
else if(focused == obj2) lv_group_focus_obj(obj1);
|
||||
|
||||
}
|
||||
|
||||
void lv_group_remove_obj(lv_obj_t * obj)
|
||||
{
|
||||
lv_group_t * g = lv_obj_get_group(obj);
|
||||
if(g == NULL) return;
|
||||
|
||||
LV_LOG_TRACE("begin");
|
||||
|
||||
/*Focus on the next object*/
|
||||
if(g->obj_focus && *g->obj_focus == obj) {
|
||||
if(g->frozen) g->frozen = 0;
|
||||
|
||||
/*If this is the only object in the group then focus to nothing.*/
|
||||
if(lv_ll_get_head(&g->obj_ll) == g->obj_focus && lv_ll_get_tail(&g->obj_ll) == g->obj_focus) {
|
||||
lv_obj_send_event(*g->obj_focus, LV_EVENT_DEFOCUSED, get_indev(g));
|
||||
}
|
||||
/*If there more objects in the group then focus to the next/prev object*/
|
||||
else {
|
||||
lv_group_refocus(g);
|
||||
}
|
||||
}
|
||||
|
||||
/*If the focuses object is still the same then it was the only object in the group but it will
|
||||
*be deleted. Set the `obj_focus` to NULL to get back to the initial state of the group with
|
||||
*zero objects*/
|
||||
if(g->obj_focus && *g->obj_focus == obj) {
|
||||
g->obj_focus = NULL;
|
||||
}
|
||||
|
||||
/*Search the object and remove it from its group*/
|
||||
lv_obj_t ** i;
|
||||
LV_LL_READ(&g->obj_ll, i) {
|
||||
if(*i == obj) {
|
||||
lv_ll_remove(&g->obj_ll, i);
|
||||
lv_free(i);
|
||||
if(obj->spec_attr) obj->spec_attr->group_p = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
LV_LOG_TRACE("finished");
|
||||
}
|
||||
|
||||
void lv_group_remove_all_objs(lv_group_t * group)
|
||||
{
|
||||
LV_ASSERT_NULL(group);
|
||||
|
||||
/*Defocus the currently focused object*/
|
||||
if(group->obj_focus != NULL) {
|
||||
lv_obj_send_event(*group->obj_focus, LV_EVENT_DEFOCUSED, get_indev(group));
|
||||
lv_obj_invalidate(*group->obj_focus);
|
||||
group->obj_focus = NULL;
|
||||
}
|
||||
|
||||
/*Remove the objects from the group*/
|
||||
lv_obj_t ** obj;
|
||||
LV_LL_READ(&group->obj_ll, obj) {
|
||||
if((*obj)->spec_attr)(*obj)->spec_attr->group_p = NULL;
|
||||
}
|
||||
|
||||
lv_ll_clear(&(group->obj_ll));
|
||||
}
|
||||
|
||||
void lv_group_focus_obj(lv_obj_t * obj)
|
||||
{
|
||||
if(obj == NULL) return;
|
||||
lv_group_t * g = lv_obj_get_group(obj);
|
||||
if(g == NULL) return;
|
||||
|
||||
if(g->frozen != 0) return;
|
||||
|
||||
/*On defocus edit mode must be leaved*/
|
||||
lv_group_set_editing(g, false);
|
||||
|
||||
lv_obj_t ** i;
|
||||
LV_LL_READ(&g->obj_ll, i) {
|
||||
if(*i == obj) {
|
||||
if(g->obj_focus != NULL && obj != *g->obj_focus) { /*Do not defocus if the same object needs to be focused again*/
|
||||
lv_result_t res = lv_obj_send_event(*g->obj_focus, LV_EVENT_DEFOCUSED, get_indev(g));
|
||||
if(res != LV_RESULT_OK) return;
|
||||
lv_obj_invalidate(*g->obj_focus);
|
||||
}
|
||||
|
||||
g->obj_focus = i;
|
||||
|
||||
if(g->obj_focus != NULL) {
|
||||
if(g->focus_cb) g->focus_cb(g);
|
||||
lv_result_t res = lv_obj_send_event(*g->obj_focus, LV_EVENT_FOCUSED, get_indev(g));
|
||||
if(res != LV_RESULT_OK) return;
|
||||
lv_obj_invalidate(*g->obj_focus);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void lv_group_focus_next(lv_group_t * group)
|
||||
{
|
||||
LV_ASSERT_NULL(group);
|
||||
|
||||
bool focus_changed = focus_next_core(group, lv_ll_get_head, lv_ll_get_next);
|
||||
if(group->edge_cb) {
|
||||
if(!focus_changed)
|
||||
group->edge_cb(group, true);
|
||||
}
|
||||
}
|
||||
|
||||
void lv_group_focus_prev(lv_group_t * group)
|
||||
{
|
||||
LV_ASSERT_NULL(group);
|
||||
|
||||
bool focus_changed = focus_next_core(group, lv_ll_get_tail, lv_ll_get_prev);
|
||||
if(group->edge_cb) {
|
||||
if(!focus_changed)
|
||||
group->edge_cb(group, false);
|
||||
}
|
||||
}
|
||||
|
||||
void lv_group_focus_freeze(lv_group_t * group, bool en)
|
||||
{
|
||||
LV_ASSERT_NULL(group);
|
||||
|
||||
if(en == false) group->frozen = 0;
|
||||
else group->frozen = 1;
|
||||
}
|
||||
|
||||
lv_result_t lv_group_send_data(lv_group_t * group, uint32_t c)
|
||||
{
|
||||
LV_ASSERT_NULL(group);
|
||||
|
||||
lv_obj_t * act = lv_group_get_focused(group);
|
||||
if(act == NULL) return LV_RESULT_OK;
|
||||
|
||||
if(lv_obj_has_state(act, LV_STATE_DISABLED)) return LV_RESULT_OK;
|
||||
|
||||
return lv_obj_send_event(act, LV_EVENT_KEY, &c);
|
||||
}
|
||||
|
||||
void lv_group_set_focus_cb(lv_group_t * group, lv_group_focus_cb_t focus_cb)
|
||||
{
|
||||
if(group == NULL) return;
|
||||
|
||||
group->focus_cb = focus_cb;
|
||||
}
|
||||
|
||||
void lv_group_set_edge_cb(lv_group_t * group, lv_group_edge_cb_t edge_cb)
|
||||
{
|
||||
LV_ASSERT_NULL(group);
|
||||
|
||||
group->edge_cb = edge_cb;
|
||||
}
|
||||
|
||||
void lv_group_set_editing(lv_group_t * group, bool edit)
|
||||
{
|
||||
LV_ASSERT_NULL(group);
|
||||
uint8_t en_val = edit ? 1 : 0;
|
||||
|
||||
if(en_val == group->editing) return; /*Do not set the same mode again*/
|
||||
|
||||
group->editing = en_val;
|
||||
lv_obj_t * focused = lv_group_get_focused(group);
|
||||
|
||||
if(focused) {
|
||||
lv_result_t res = lv_obj_send_event(*group->obj_focus, LV_EVENT_FOCUSED, get_indev(group));
|
||||
if(res != LV_RESULT_OK) return;
|
||||
|
||||
lv_obj_invalidate(focused);
|
||||
}
|
||||
}
|
||||
|
||||
void lv_group_set_refocus_policy(lv_group_t * group, lv_group_refocus_policy_t policy)
|
||||
{
|
||||
LV_ASSERT_NULL(group);
|
||||
group->refocus_policy = policy & 0x01;
|
||||
}
|
||||
|
||||
void lv_group_set_wrap(lv_group_t * group, bool en)
|
||||
{
|
||||
LV_ASSERT_NULL(group);
|
||||
group->wrap = en ? 1 : 0;
|
||||
}
|
||||
|
||||
lv_obj_t * lv_group_get_focused(const lv_group_t * group)
|
||||
{
|
||||
if(!group) return NULL;
|
||||
if(group->obj_focus == NULL) return NULL;
|
||||
|
||||
return *group->obj_focus;
|
||||
}
|
||||
|
||||
lv_group_focus_cb_t lv_group_get_focus_cb(const lv_group_t * group)
|
||||
{
|
||||
if(!group) return NULL;
|
||||
return group->focus_cb;
|
||||
}
|
||||
|
||||
lv_group_edge_cb_t lv_group_get_edge_cb(const lv_group_t * group)
|
||||
{
|
||||
if(!group) return NULL;
|
||||
return group->edge_cb;
|
||||
}
|
||||
|
||||
bool lv_group_get_editing(const lv_group_t * group)
|
||||
{
|
||||
if(!group) return false;
|
||||
return group->editing;
|
||||
}
|
||||
|
||||
bool lv_group_get_wrap(lv_group_t * group)
|
||||
{
|
||||
if(!group) return false;
|
||||
return group->wrap;
|
||||
}
|
||||
|
||||
uint32_t lv_group_get_obj_count(lv_group_t * group)
|
||||
{
|
||||
LV_ASSERT_NULL(group);
|
||||
return lv_ll_get_len(&group->obj_ll);
|
||||
}
|
||||
|
||||
lv_obj_t * lv_group_get_obj_by_index(lv_group_t * group, uint32_t index)
|
||||
{
|
||||
uint32_t len = 0;
|
||||
lv_obj_t ** obj;
|
||||
|
||||
LV_LL_READ(&group->obj_ll, obj) {
|
||||
if(len == index) {
|
||||
return *obj;
|
||||
}
|
||||
len++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t lv_group_get_count(void)
|
||||
{
|
||||
return lv_ll_get_len(group_ll_p);
|
||||
}
|
||||
|
||||
lv_group_t * lv_group_by_index(uint32_t index)
|
||||
{
|
||||
uint32_t len = 0;
|
||||
lv_group_t * group;
|
||||
|
||||
LV_LL_READ_BACK(group_ll_p, group) {
|
||||
if(len == index) {
|
||||
return group;
|
||||
}
|
||||
len++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void lv_group_refocus(lv_group_t * g)
|
||||
{
|
||||
/*Refocus must temporarily allow wrapping to work correctly*/
|
||||
uint8_t temp_wrap = g->wrap;
|
||||
g->wrap = 1;
|
||||
|
||||
if(g->refocus_policy == LV_GROUP_REFOCUS_POLICY_NEXT)
|
||||
lv_group_focus_next(g);
|
||||
else if(g->refocus_policy == LV_GROUP_REFOCUS_POLICY_PREV)
|
||||
lv_group_focus_prev(g);
|
||||
/*Restore wrap property*/
|
||||
g->wrap = temp_wrap;
|
||||
}
|
||||
|
||||
static bool focus_next_core(lv_group_t * group, void * (*begin)(const lv_ll_t *),
|
||||
void * (*move)(const lv_ll_t *, const void *))
|
||||
{
|
||||
bool focus_changed = false;
|
||||
if(group->frozen) return focus_changed;
|
||||
|
||||
lv_obj_t ** obj_next = group->obj_focus;
|
||||
lv_obj_t ** obj_sentinel = NULL;
|
||||
bool can_move = true;
|
||||
bool can_begin = true;
|
||||
|
||||
for(;;) {
|
||||
if(obj_next == NULL) {
|
||||
if(group->wrap || obj_sentinel == NULL) {
|
||||
if(!can_begin) return focus_changed;
|
||||
obj_next = begin(&group->obj_ll);
|
||||
can_move = false;
|
||||
can_begin = false;
|
||||
}
|
||||
else {
|
||||
/*Currently focused object is the last/first in the group, keep it that way*/
|
||||
return focus_changed;
|
||||
}
|
||||
}
|
||||
|
||||
if(obj_sentinel == NULL) {
|
||||
obj_sentinel = obj_next;
|
||||
if(obj_sentinel == NULL) return focus_changed; /*Group is empty*/
|
||||
}
|
||||
|
||||
if(can_move) {
|
||||
obj_next = move(&group->obj_ll, obj_next);
|
||||
|
||||
/*Give up if we walked the entire list and haven't found another visible object*/
|
||||
if(obj_next == obj_sentinel) return focus_changed;
|
||||
}
|
||||
|
||||
can_move = true;
|
||||
|
||||
if(obj_next == NULL) continue;
|
||||
if(lv_obj_get_state(*obj_next) & LV_STATE_DISABLED) continue;
|
||||
|
||||
/*Hidden objects don't receive focus.
|
||||
*If any parent is hidden, the object is also hidden)*/
|
||||
lv_obj_t * parent = *obj_next;
|
||||
while(parent) {
|
||||
if(lv_obj_has_flag(parent, LV_OBJ_FLAG_HIDDEN)) break;
|
||||
parent = lv_obj_get_parent(parent);
|
||||
}
|
||||
|
||||
if(parent && lv_obj_has_flag(parent, LV_OBJ_FLAG_HIDDEN)) continue;
|
||||
|
||||
/*If we got her a good candidate is found*/
|
||||
break;
|
||||
}
|
||||
|
||||
if(obj_next == group->obj_focus) return focus_changed; /*There's only one visible object and it's already focused*/
|
||||
|
||||
if(group->obj_focus) {
|
||||
lv_result_t res = lv_obj_send_event(*group->obj_focus, LV_EVENT_DEFOCUSED, get_indev(group));
|
||||
if(res != LV_RESULT_OK) return focus_changed;
|
||||
lv_obj_invalidate(*group->obj_focus);
|
||||
}
|
||||
|
||||
group->obj_focus = obj_next;
|
||||
|
||||
lv_result_t res = lv_obj_send_event(*group->obj_focus, LV_EVENT_FOCUSED, get_indev(group));
|
||||
if(res != LV_RESULT_OK) return focus_changed;
|
||||
|
||||
lv_obj_invalidate(*group->obj_focus);
|
||||
|
||||
if(group->focus_cb) group->focus_cb(group);
|
||||
focus_changed = true;
|
||||
return focus_changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find an indev preferably with POINTER type (because it's the most generic) that uses the given group.
|
||||
* In other words, find an indev, that is related to the given group.
|
||||
* In the worst case simply return the latest indev
|
||||
* @param g a group the find in the indevs
|
||||
* @return the suggested indev
|
||||
*/
|
||||
static lv_indev_t * get_indev(const lv_group_t * g)
|
||||
{
|
||||
lv_indev_t * indev_guess = NULL;
|
||||
lv_indev_t * indev = lv_indev_get_next(NULL);
|
||||
|
||||
while(indev) {
|
||||
lv_indev_type_t indev_type = lv_indev_get_type(indev);
|
||||
/*Prefer POINTER*/
|
||||
if(indev_type == LV_INDEV_TYPE_POINTER) return indev;
|
||||
if(lv_indev_get_group(indev) == g) {
|
||||
indev_guess = indev;
|
||||
}
|
||||
indev = lv_indev_get_next(indev);
|
||||
}
|
||||
|
||||
return indev_guess;
|
||||
}
|
||||
245
software/Power_Pico/Middlewares/LVGL/src/core/lv_group.h
Normal file
245
software/Power_Pico/Middlewares/LVGL/src/core/lv_group.h
Normal file
@@ -0,0 +1,245 @@
|
||||
/**
|
||||
* @file lv_group.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_GROUP_H
|
||||
#define LV_GROUP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_conf_internal.h"
|
||||
|
||||
#include "../misc/lv_types.h"
|
||||
#include "../misc/lv_ll.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
/** Predefined keys to control focused object via lv_group_send(group, c) */
|
||||
typedef enum {
|
||||
LV_KEY_UP = 17, /*0x11*/
|
||||
LV_KEY_DOWN = 18, /*0x12*/
|
||||
LV_KEY_RIGHT = 19, /*0x13*/
|
||||
LV_KEY_LEFT = 20, /*0x14*/
|
||||
LV_KEY_ESC = 27, /*0x1B*/
|
||||
LV_KEY_DEL = 127, /*0x7F*/
|
||||
LV_KEY_BACKSPACE = 8, /*0x08*/
|
||||
LV_KEY_ENTER = 10, /*0x0A, '\n'*/
|
||||
LV_KEY_NEXT = 9, /*0x09, '\t'*/
|
||||
LV_KEY_PREV = 11, /*0x0B, '*/
|
||||
LV_KEY_HOME = 2, /*0x02, STX*/
|
||||
LV_KEY_END = 3, /*0x03, ETX*/
|
||||
} lv_key_t;
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef void (*lv_group_focus_cb_t)(lv_group_t *);
|
||||
typedef void (*lv_group_edge_cb_t)(lv_group_t *, bool);
|
||||
|
||||
typedef enum {
|
||||
LV_GROUP_REFOCUS_POLICY_NEXT = 0,
|
||||
LV_GROUP_REFOCUS_POLICY_PREV = 1
|
||||
} lv_group_refocus_policy_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a new object group
|
||||
* @return pointer to the new object group
|
||||
*/
|
||||
lv_group_t * lv_group_create(void);
|
||||
|
||||
/**
|
||||
* Delete a group object
|
||||
* @param group pointer to a group
|
||||
*/
|
||||
void lv_group_delete(lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Set a default group. New object are added to this group if it's enabled in their class with `add_to_def_group = true`
|
||||
* @param group pointer to a group (can be `NULL`)
|
||||
*/
|
||||
void lv_group_set_default(lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Get the default group
|
||||
* @return pointer to the default group
|
||||
*/
|
||||
lv_group_t * lv_group_get_default(void);
|
||||
|
||||
/**
|
||||
* Add an object to a group
|
||||
* @param group pointer to a group
|
||||
* @param obj pointer to an object to add
|
||||
*/
|
||||
void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Swap 2 object in a group. The object must be in the same group
|
||||
* @param obj1 pointer to an object
|
||||
* @param obj2 pointer to another object
|
||||
*/
|
||||
void lv_group_swap_obj(lv_obj_t * obj1, lv_obj_t * obj2);
|
||||
|
||||
/**
|
||||
* Remove an object from its group
|
||||
* @param obj pointer to an object to remove
|
||||
*/
|
||||
void lv_group_remove_obj(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Remove all objects from a group
|
||||
* @param group pointer to a group
|
||||
*/
|
||||
void lv_group_remove_all_objs(lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Focus on an object (defocus the current)
|
||||
* @param obj pointer to an object to focus on
|
||||
*/
|
||||
void lv_group_focus_obj(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Focus the next object in a group (defocus the current)
|
||||
* @param group pointer to a group
|
||||
*/
|
||||
void lv_group_focus_next(lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Focus the previous object in a group (defocus the current)
|
||||
* @param group pointer to a group
|
||||
*/
|
||||
void lv_group_focus_prev(lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Do not let to change the focus from the current object
|
||||
* @param group pointer to a group
|
||||
* @param en true: freeze, false: release freezing (normal mode)
|
||||
*/
|
||||
void lv_group_focus_freeze(lv_group_t * group, bool en);
|
||||
|
||||
/**
|
||||
* Send a control character to the focuses object of a group
|
||||
* @param group pointer to a group
|
||||
* @param c a character (use LV_KEY_.. to navigate)
|
||||
* @return result of focused object in group.
|
||||
*/
|
||||
lv_result_t lv_group_send_data(lv_group_t * group, uint32_t c);
|
||||
|
||||
/**
|
||||
* Set a function for a group which will be called when a new object is focused
|
||||
* @param group pointer to a group
|
||||
* @param focus_cb the call back function or NULL if unused
|
||||
*/
|
||||
void lv_group_set_focus_cb(lv_group_t * group, lv_group_focus_cb_t focus_cb);
|
||||
|
||||
/**
|
||||
* Set a function for a group which will be called when a focus edge is reached
|
||||
* @param group pointer to a group
|
||||
* @param edge_cb the call back function or NULL if unused
|
||||
*/
|
||||
void lv_group_set_edge_cb(lv_group_t * group, lv_group_edge_cb_t edge_cb);
|
||||
|
||||
/**
|
||||
* Set whether the next or previous item in a group is focused if the currently focused obj is
|
||||
* deleted.
|
||||
* @param group pointer to a group
|
||||
* @param policy new refocus policy enum
|
||||
*/
|
||||
void lv_group_set_refocus_policy(lv_group_t * group, lv_group_refocus_policy_t policy);
|
||||
|
||||
/**
|
||||
* Manually set the current mode (edit or navigate).
|
||||
* @param group pointer to group
|
||||
* @param edit true: edit mode; false: navigate mode
|
||||
*/
|
||||
void lv_group_set_editing(lv_group_t * group, bool edit);
|
||||
|
||||
/**
|
||||
* Set whether focus next/prev will allow wrapping from first->last or last->first object.
|
||||
* @param group pointer to group
|
||||
* @param en true: wrapping enabled; false: wrapping disabled
|
||||
*/
|
||||
void lv_group_set_wrap(lv_group_t * group, bool en);
|
||||
|
||||
/**
|
||||
* Get the focused object or NULL if there isn't one
|
||||
* @param group pointer to a group
|
||||
* @return pointer to the focused object
|
||||
*/
|
||||
lv_obj_t * lv_group_get_focused(const lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Get the focus callback function of a group
|
||||
* @param group pointer to a group
|
||||
* @return the call back function or NULL if not set
|
||||
*/
|
||||
lv_group_focus_cb_t lv_group_get_focus_cb(const lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Get the edge callback function of a group
|
||||
* @param group pointer to a group
|
||||
* @return the call back function or NULL if not set
|
||||
*/
|
||||
lv_group_edge_cb_t lv_group_get_edge_cb(const lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Get the current mode (edit or navigate).
|
||||
* @param group pointer to group
|
||||
* @return true: edit mode; false: navigate mode
|
||||
*/
|
||||
bool lv_group_get_editing(const lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Get whether focus next/prev will allow wrapping from first->last or last->first object.
|
||||
* @param group pointer to group
|
||||
*/
|
||||
bool lv_group_get_wrap(lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Get the number of object in the group
|
||||
* @param group pointer to a group
|
||||
* @return number of objects in the group
|
||||
*/
|
||||
uint32_t lv_group_get_obj_count(lv_group_t * group);
|
||||
|
||||
/**
|
||||
* Get the nth object within a group
|
||||
* @param group pointer to a group
|
||||
* @param index index of object within the group
|
||||
* @return pointer to the object
|
||||
*/
|
||||
lv_obj_t * lv_group_get_obj_by_index(lv_group_t * group, uint32_t index);
|
||||
|
||||
/**
|
||||
* Get the number of groups
|
||||
* @return number of groups
|
||||
*/
|
||||
uint32_t lv_group_get_count(void);
|
||||
|
||||
/**
|
||||
* Get a group by its index
|
||||
* @param index index of the group
|
||||
* @return pointer to the group
|
||||
*/
|
||||
lv_group_t * lv_group_by_index(uint32_t index);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_GROUP_H*/
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* @file lv_group_private.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_GROUP_PRIVATE_H
|
||||
#define LV_GROUP_PRIVATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_group.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Groups can be used to logically hold objects so that they can be individually focused.
|
||||
* They are NOT for laying out objects on a screen (try layouts for that).
|
||||
*/
|
||||
struct lv_group_t {
|
||||
lv_ll_t obj_ll; /**< Linked list to store the objects in the group*/
|
||||
lv_obj_t ** obj_focus; /**< The object in focus*/
|
||||
|
||||
lv_group_focus_cb_t focus_cb; /**< A function to call when a new object is focused (optional)*/
|
||||
lv_group_edge_cb_t edge_cb; /**< A function to call when an edge is reached, no more focus
|
||||
targets are available in this direction (to allow edge feedback
|
||||
like a sound or a scroll bounce) */
|
||||
|
||||
void * user_data;
|
||||
|
||||
uint8_t frozen : 1; /**< 1: can't focus to new object*/
|
||||
uint8_t editing : 1; /**< 1: Edit mode, 0: Navigate mode*/
|
||||
uint8_t refocus_policy : 1; /**< 1: Focus prev if focused on deletion. 0: Focus next if focused on
|
||||
deletion.*/
|
||||
uint8_t wrap : 1; /**< 1: Focus next/prev can wrap at end of list. 0: Focus next/prev stops at end
|
||||
of list.*/
|
||||
};
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Init the group module
|
||||
* @remarks Internal function, do not call directly.
|
||||
*/
|
||||
void lv_group_init(void);
|
||||
|
||||
/**
|
||||
* Deinit the group module
|
||||
* @remarks Internal function, do not call directly.
|
||||
*/
|
||||
void lv_group_deinit(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_GROUP_PRIVATE_H*/
|
||||
1047
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj.c
Normal file
1047
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj.c
Normal file
File diff suppressed because it is too large
Load Diff
486
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj.h
Normal file
486
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj.h
Normal file
@@ -0,0 +1,486 @@
|
||||
/**
|
||||
* @file lv_obj.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_OBJ_H
|
||||
#define LV_OBJ_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_conf_internal.h"
|
||||
|
||||
#include "../misc/lv_types.h"
|
||||
#include "../misc/lv_style.h"
|
||||
#include "../misc/lv_area.h"
|
||||
#include "../misc/lv_color.h"
|
||||
#include "../misc/lv_assert.h"
|
||||
|
||||
#include "lv_obj_tree.h"
|
||||
#include "lv_obj_pos.h"
|
||||
#include "lv_obj_scroll.h"
|
||||
#include "lv_obj_style.h"
|
||||
#include "lv_obj_draw.h"
|
||||
#include "lv_obj_class.h"
|
||||
#include "lv_obj_event.h"
|
||||
#include "lv_obj_property.h"
|
||||
#include "lv_group.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Possible states of a widget.
|
||||
* OR-ed values are possible
|
||||
*/
|
||||
enum {
|
||||
LV_STATE_DEFAULT = 0x0000,
|
||||
LV_STATE_CHECKED = 0x0001,
|
||||
LV_STATE_FOCUSED = 0x0002,
|
||||
LV_STATE_FOCUS_KEY = 0x0004,
|
||||
LV_STATE_EDITED = 0x0008,
|
||||
LV_STATE_HOVERED = 0x0010,
|
||||
LV_STATE_PRESSED = 0x0020,
|
||||
LV_STATE_SCROLLED = 0x0040,
|
||||
LV_STATE_DISABLED = 0x0080,
|
||||
LV_STATE_USER_1 = 0x1000,
|
||||
LV_STATE_USER_2 = 0x2000,
|
||||
LV_STATE_USER_3 = 0x4000,
|
||||
LV_STATE_USER_4 = 0x8000,
|
||||
|
||||
LV_STATE_ANY = 0xFFFF, /**< Special value can be used in some functions to target all states*/
|
||||
};
|
||||
|
||||
/**
|
||||
* The possible parts of widgets.
|
||||
* The parts can be considered as the internal building block of the widgets.
|
||||
* E.g. slider = background + indicator + knob
|
||||
* Not all parts are used by every widget
|
||||
*/
|
||||
|
||||
enum {
|
||||
LV_PART_MAIN = 0x000000, /**< A background like rectangle*/
|
||||
LV_PART_SCROLLBAR = 0x010000, /**< The scrollbar(s)*/
|
||||
LV_PART_INDICATOR = 0x020000, /**< Indicator, e.g. for slider, bar, switch, or the tick box of the checkbox*/
|
||||
LV_PART_KNOB = 0x030000, /**< Like handle to grab to adjust the value*/
|
||||
LV_PART_SELECTED = 0x040000, /**< Indicate the currently selected option or section*/
|
||||
LV_PART_ITEMS = 0x050000, /**< Used if the widget has multiple similar elements (e.g. table cells)*/
|
||||
LV_PART_CURSOR = 0x060000, /**< Mark a specific place e.g. for text area's cursor or on a chart*/
|
||||
|
||||
LV_PART_CUSTOM_FIRST = 0x080000, /**< Extension point for custom widgets*/
|
||||
|
||||
LV_PART_ANY = 0x0F0000, /**< Special value can be used in some functions to target all parts*/
|
||||
};
|
||||
|
||||
/**
|
||||
* On/Off features controlling the object's behavior.
|
||||
* OR-ed values are possible
|
||||
*
|
||||
* Note: update obj flags corresponding properties below
|
||||
* whenever add/remove flags or change bit definition of flags.
|
||||
*/
|
||||
typedef enum {
|
||||
LV_OBJ_FLAG_HIDDEN = (1L << 0), /**< Make the object hidden. (Like it wasn't there at all)*/
|
||||
LV_OBJ_FLAG_CLICKABLE = (1L << 1), /**< Make the object clickable by the input devices*/
|
||||
LV_OBJ_FLAG_CLICK_FOCUSABLE = (1L << 2), /**< Add focused state to the object when clicked*/
|
||||
LV_OBJ_FLAG_CHECKABLE = (1L << 3), /**< Toggle checked state when the object is clicked*/
|
||||
LV_OBJ_FLAG_SCROLLABLE = (1L << 4), /**< Make the object scrollable*/
|
||||
LV_OBJ_FLAG_SCROLL_ELASTIC = (1L << 5), /**< Allow scrolling inside but with slower speed*/
|
||||
LV_OBJ_FLAG_SCROLL_MOMENTUM = (1L << 6), /**< Make the object scroll further when "thrown"*/
|
||||
LV_OBJ_FLAG_SCROLL_ONE = (1L << 7), /**< Allow scrolling only one snappable children*/
|
||||
LV_OBJ_FLAG_SCROLL_CHAIN_HOR = (1L << 8), /**< Allow propagating the horizontal scroll to a parent*/
|
||||
LV_OBJ_FLAG_SCROLL_CHAIN_VER = (1L << 9), /**< Allow propagating the vertical scroll to a parent*/
|
||||
LV_OBJ_FLAG_SCROLL_CHAIN = (LV_OBJ_FLAG_SCROLL_CHAIN_HOR | LV_OBJ_FLAG_SCROLL_CHAIN_VER),
|
||||
LV_OBJ_FLAG_SCROLL_ON_FOCUS = (1L << 10), /**< Automatically scroll object to make it visible when focused*/
|
||||
LV_OBJ_FLAG_SCROLL_WITH_ARROW = (1L << 11), /**< Allow scrolling the focused object with arrow keys*/
|
||||
LV_OBJ_FLAG_SNAPPABLE = (1L << 12), /**< If scroll snap is enabled on the parent it can snap to this object*/
|
||||
LV_OBJ_FLAG_PRESS_LOCK = (1L << 13), /**< Keep the object pressed even if the press slid from the object*/
|
||||
LV_OBJ_FLAG_EVENT_BUBBLE = (1L << 14), /**< Propagate the events to the parent too*/
|
||||
LV_OBJ_FLAG_GESTURE_BUBBLE = (1L << 15), /**< Propagate the gestures to the parent*/
|
||||
LV_OBJ_FLAG_ADV_HITTEST = (1L << 16), /**< Allow performing more accurate hit (click) test. E.g. consider rounded corners.*/
|
||||
LV_OBJ_FLAG_IGNORE_LAYOUT = (1L << 17), /**< Make the object not positioned by the layouts*/
|
||||
LV_OBJ_FLAG_FLOATING = (1L << 18), /**< Do not scroll the object when the parent scrolls and ignore layout*/
|
||||
LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS = (1L << 19), /**< Send `LV_EVENT_DRAW_TASK_ADDED` events*/
|
||||
LV_OBJ_FLAG_OVERFLOW_VISIBLE = (1L << 20),/**< Do not clip the children to the parent's ext draw size*/
|
||||
#if LV_USE_FLEX
|
||||
LV_OBJ_FLAG_FLEX_IN_NEW_TRACK = (1L << 21), /**< Start a new flex track on this item*/
|
||||
#endif
|
||||
|
||||
LV_OBJ_FLAG_LAYOUT_1 = (1L << 23), /**< Custom flag, free to use by layouts*/
|
||||
LV_OBJ_FLAG_LAYOUT_2 = (1L << 24), /**< Custom flag, free to use by layouts*/
|
||||
|
||||
LV_OBJ_FLAG_WIDGET_1 = (1L << 25), /**< Custom flag, free to use by widget*/
|
||||
LV_OBJ_FLAG_WIDGET_2 = (1L << 26), /**< Custom flag, free to use by widget*/
|
||||
LV_OBJ_FLAG_USER_1 = (1L << 27), /**< Custom flag, free to use by user*/
|
||||
LV_OBJ_FLAG_USER_2 = (1L << 28), /**< Custom flag, free to use by user*/
|
||||
LV_OBJ_FLAG_USER_3 = (1L << 29), /**< Custom flag, free to use by user*/
|
||||
LV_OBJ_FLAG_USER_4 = (1L << 30), /**< Custom flag, free to use by user*/
|
||||
} lv_obj_flag_t;
|
||||
|
||||
#if LV_USE_OBJ_PROPERTY
|
||||
enum {
|
||||
/*OBJ flag properties */
|
||||
LV_PROPERTY_ID(OBJ, FLAG_START, LV_PROPERTY_TYPE_INT, 0),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_HIDDEN, LV_PROPERTY_TYPE_INT, 0),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_CLICKABLE, LV_PROPERTY_TYPE_INT, 1),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_CLICK_FOCUSABLE, LV_PROPERTY_TYPE_INT, 2),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_CHECKABLE, LV_PROPERTY_TYPE_INT, 3),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_SCROLLABLE, LV_PROPERTY_TYPE_INT, 4),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_SCROLL_ELASTIC, LV_PROPERTY_TYPE_INT, 5),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_SCROLL_MOMENTUM, LV_PROPERTY_TYPE_INT, 6),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_SCROLL_ONE, LV_PROPERTY_TYPE_INT, 7),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_SCROLL_CHAIN_HOR, LV_PROPERTY_TYPE_INT, 8),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_SCROLL_CHAIN_VER, LV_PROPERTY_TYPE_INT, 9),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_SCROLL_ON_FOCUS, LV_PROPERTY_TYPE_INT, 10),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_SCROLL_WITH_ARROW, LV_PROPERTY_TYPE_INT, 11),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_SNAPPABLE, LV_PROPERTY_TYPE_INT, 12),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_PRESS_LOCK, LV_PROPERTY_TYPE_INT, 13),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_EVENT_BUBBLE, LV_PROPERTY_TYPE_INT, 14),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_GESTURE_BUBBLE, LV_PROPERTY_TYPE_INT, 15),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_ADV_HITTEST, LV_PROPERTY_TYPE_INT, 16),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_IGNORE_LAYOUT, LV_PROPERTY_TYPE_INT, 17),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_FLOATING, LV_PROPERTY_TYPE_INT, 18),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_SEND_DRAW_TASK_EVENTS, LV_PROPERTY_TYPE_INT, 19),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_OVERFLOW_VISIBLE, LV_PROPERTY_TYPE_INT, 20),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_FLEX_IN_NEW_TRACK, LV_PROPERTY_TYPE_INT, 21),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_LAYOUT_1, LV_PROPERTY_TYPE_INT, 23),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_LAYOUT_2, LV_PROPERTY_TYPE_INT, 24),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_WIDGET_1, LV_PROPERTY_TYPE_INT, 25),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_WIDGET_2, LV_PROPERTY_TYPE_INT, 26),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_USER_1, LV_PROPERTY_TYPE_INT, 27),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_USER_2, LV_PROPERTY_TYPE_INT, 28),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_USER_3, LV_PROPERTY_TYPE_INT, 29),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_USER_4, LV_PROPERTY_TYPE_INT, 30),
|
||||
LV_PROPERTY_ID(OBJ, FLAG_END, LV_PROPERTY_TYPE_INT, 30),
|
||||
|
||||
LV_PROPERTY_ID(OBJ, STATE_START, LV_PROPERTY_TYPE_INT, 31),
|
||||
LV_PROPERTY_ID(OBJ, STATE_CHECKED, LV_PROPERTY_TYPE_INT, 31),
|
||||
LV_PROPERTY_ID(OBJ, STATE_FOCUSED, LV_PROPERTY_TYPE_INT, 32),
|
||||
LV_PROPERTY_ID(OBJ, STATE_FOCUS_KEY, LV_PROPERTY_TYPE_INT, 33),
|
||||
LV_PROPERTY_ID(OBJ, STATE_EDITED, LV_PROPERTY_TYPE_INT, 34),
|
||||
LV_PROPERTY_ID(OBJ, STATE_HOVERED, LV_PROPERTY_TYPE_INT, 35),
|
||||
LV_PROPERTY_ID(OBJ, STATE_PRESSED, LV_PROPERTY_TYPE_INT, 36),
|
||||
LV_PROPERTY_ID(OBJ, STATE_SCROLLED, LV_PROPERTY_TYPE_INT, 37),
|
||||
LV_PROPERTY_ID(OBJ, STATE_DISABLED, LV_PROPERTY_TYPE_INT, 38),
|
||||
/*not used bit8-bit11*/
|
||||
LV_PROPERTY_ID(OBJ, STATE_USER_1, LV_PROPERTY_TYPE_INT, 43),
|
||||
LV_PROPERTY_ID(OBJ, STATE_USER_2, LV_PROPERTY_TYPE_INT, 44),
|
||||
LV_PROPERTY_ID(OBJ, STATE_USER_3, LV_PROPERTY_TYPE_INT, 45),
|
||||
LV_PROPERTY_ID(OBJ, STATE_USER_4, LV_PROPERTY_TYPE_INT, 46),
|
||||
LV_PROPERTY_ID(OBJ, STATE_ANY, LV_PROPERTY_TYPE_INT, 47),
|
||||
LV_PROPERTY_ID(OBJ, STATE_END, LV_PROPERTY_TYPE_INT, 47),
|
||||
|
||||
/*OBJ normal properties*/
|
||||
LV_PROPERTY_ID(OBJ, PARENT, LV_PROPERTY_TYPE_OBJ, 48),
|
||||
LV_PROPERTY_ID(OBJ, X, LV_PROPERTY_TYPE_INT, 49),
|
||||
LV_PROPERTY_ID(OBJ, Y, LV_PROPERTY_TYPE_INT, 50),
|
||||
LV_PROPERTY_ID(OBJ, W, LV_PROPERTY_TYPE_INT, 51),
|
||||
LV_PROPERTY_ID(OBJ, H, LV_PROPERTY_TYPE_INT, 52),
|
||||
LV_PROPERTY_ID(OBJ, CONTENT_WIDTH, LV_PROPERTY_TYPE_INT, 53),
|
||||
LV_PROPERTY_ID(OBJ, CONTENT_HEIGHT, LV_PROPERTY_TYPE_INT, 54),
|
||||
LV_PROPERTY_ID(OBJ, LAYOUT, LV_PROPERTY_TYPE_INT, 55),
|
||||
LV_PROPERTY_ID(OBJ, ALIGN, LV_PROPERTY_TYPE_INT, 56),
|
||||
LV_PROPERTY_ID(OBJ, SCROLLBAR_MODE, LV_PROPERTY_TYPE_INT, 57),
|
||||
LV_PROPERTY_ID(OBJ, SCROLL_DIR, LV_PROPERTY_TYPE_INT, 58),
|
||||
LV_PROPERTY_ID(OBJ, SCROLL_SNAP_X, LV_PROPERTY_TYPE_INT, 59),
|
||||
LV_PROPERTY_ID(OBJ, SCROLL_SNAP_Y, LV_PROPERTY_TYPE_INT, 60),
|
||||
LV_PROPERTY_ID(OBJ, SCROLL_X, LV_PROPERTY_TYPE_INT, 61),
|
||||
LV_PROPERTY_ID(OBJ, SCROLL_Y, LV_PROPERTY_TYPE_INT, 62),
|
||||
LV_PROPERTY_ID(OBJ, SCROLL_TOP, LV_PROPERTY_TYPE_INT, 63),
|
||||
LV_PROPERTY_ID(OBJ, SCROLL_BOTTOM, LV_PROPERTY_TYPE_INT, 64),
|
||||
LV_PROPERTY_ID(OBJ, SCROLL_LEFT, LV_PROPERTY_TYPE_INT, 65),
|
||||
LV_PROPERTY_ID(OBJ, SCROLL_RIGHT, LV_PROPERTY_TYPE_INT, 66),
|
||||
LV_PROPERTY_ID(OBJ, SCROLL_END, LV_PROPERTY_TYPE_INT, 67),
|
||||
LV_PROPERTY_ID(OBJ, EXT_DRAW_SIZE, LV_PROPERTY_TYPE_INT, 68),
|
||||
LV_PROPERTY_ID(OBJ, EVENT_COUNT, LV_PROPERTY_TYPE_INT, 69),
|
||||
LV_PROPERTY_ID(OBJ, SCREEN, LV_PROPERTY_TYPE_OBJ, 70),
|
||||
LV_PROPERTY_ID(OBJ, DISPLAY, LV_PROPERTY_TYPE_POINTER, 71),
|
||||
LV_PROPERTY_ID(OBJ, CHILD_COUNT, LV_PROPERTY_TYPE_INT, 72),
|
||||
LV_PROPERTY_ID(OBJ, INDEX, LV_PROPERTY_TYPE_INT, 73),
|
||||
|
||||
LV_PROPERTY_OBJ_END,
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Make the base object's class publicly available.
|
||||
*/
|
||||
LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_obj_class;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a base object (a rectangle)
|
||||
* @param parent pointer to a parent object. If NULL then a screen will be created.
|
||||
* @return pointer to the new object
|
||||
*/
|
||||
lv_obj_t * lv_obj_create(lv_obj_t * parent);
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Set one or more flags
|
||||
* @param obj pointer to an object
|
||||
* @param f OR-ed values from `lv_obj_flag_t` to set.
|
||||
*/
|
||||
void lv_obj_add_flag(lv_obj_t * obj, lv_obj_flag_t f);
|
||||
|
||||
/**
|
||||
* Remove one or more flags
|
||||
* @param obj pointer to an object
|
||||
* @param f OR-ed values from `lv_obj_flag_t` to clear.
|
||||
*/
|
||||
void lv_obj_remove_flag(lv_obj_t * obj, lv_obj_flag_t f);
|
||||
|
||||
/**
|
||||
* Set add or remove one or more flags.
|
||||
* @param obj pointer to an object
|
||||
* @param f OR-ed values from `lv_obj_flag_t` to update.
|
||||
* @param v true: add the flags; false: remove the flags
|
||||
*/
|
||||
void lv_obj_update_flag(lv_obj_t * obj, lv_obj_flag_t f, bool v);
|
||||
|
||||
/**
|
||||
* Add one or more states to the object. The other state bits will remain unchanged.
|
||||
* If specified in the styles, transition animation will be started from the previous state to the current.
|
||||
* @param obj pointer to an object
|
||||
* @param state the states to add. E.g `LV_STATE_PRESSED | LV_STATE_FOCUSED`
|
||||
*/
|
||||
void lv_obj_add_state(lv_obj_t * obj, lv_state_t state);
|
||||
|
||||
/**
|
||||
* Remove one or more states to the object. The other state bits will remain unchanged.
|
||||
* If specified in the styles, transition animation will be started from the previous state to the current.
|
||||
* @param obj pointer to an object
|
||||
* @param state the states to add. E.g `LV_STATE_PRESSED | LV_STATE_FOCUSED`
|
||||
*/
|
||||
void lv_obj_remove_state(lv_obj_t * obj, lv_state_t state);
|
||||
|
||||
/**
|
||||
* Add or remove one or more states to the object. The other state bits will remain unchanged.
|
||||
* @param obj pointer to an object
|
||||
* @param state the states to add. E.g `LV_STATE_PRESSED | LV_STATE_FOCUSED`
|
||||
* @param v true: add the states; false: remove the states
|
||||
*/
|
||||
void lv_obj_set_state(lv_obj_t * obj, lv_state_t state, bool v);
|
||||
|
||||
/**
|
||||
* Set the user_data field of the object
|
||||
* @param obj pointer to an object
|
||||
* @param user_data pointer to the new user_data.
|
||||
*/
|
||||
void lv_obj_set_user_data(lv_obj_t * obj, void * user_data);
|
||||
|
||||
/*=======================
|
||||
* Getter functions
|
||||
*======================*/
|
||||
|
||||
/**
|
||||
* Check if a given flag or all the given flags are set on an object.
|
||||
* @param obj pointer to an object
|
||||
* @param f the flag(s) to check (OR-ed values can be used)
|
||||
* @return true: all flags are set; false: not all flags are set
|
||||
*/
|
||||
bool lv_obj_has_flag(const lv_obj_t * obj, lv_obj_flag_t f);
|
||||
|
||||
/**
|
||||
* Check if a given flag or any of the flags are set on an object.
|
||||
* @param obj pointer to an object
|
||||
* @param f the flag(s) to check (OR-ed values can be used)
|
||||
* @return true: at least one flag is set; false: none of the flags are set
|
||||
*/
|
||||
bool lv_obj_has_flag_any(const lv_obj_t * obj, lv_obj_flag_t f);
|
||||
|
||||
/**
|
||||
* Get the state of an object
|
||||
* @param obj pointer to an object
|
||||
* @return the state (OR-ed values from `lv_state_t`)
|
||||
*/
|
||||
lv_state_t lv_obj_get_state(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Check if the object is in a given state or not.
|
||||
* @param obj pointer to an object
|
||||
* @param state a state or combination of states to check
|
||||
* @return true: `obj` is in `state`; false: `obj` is not in `state`
|
||||
*/
|
||||
bool lv_obj_has_state(const lv_obj_t * obj, lv_state_t state);
|
||||
|
||||
/**
|
||||
* Get the group of the object
|
||||
* @param obj pointer to an object
|
||||
* @return the pointer to group of the object
|
||||
*/
|
||||
lv_group_t * lv_obj_get_group(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the user_data field of the object
|
||||
* @param obj pointer to an object
|
||||
* @return the pointer to the user_data of the object
|
||||
*/
|
||||
void * lv_obj_get_user_data(lv_obj_t * obj);
|
||||
|
||||
/*=======================
|
||||
* Other functions
|
||||
*======================*/
|
||||
|
||||
/**
|
||||
* Allocate special data for an object if not allocated yet.
|
||||
* @param obj pointer to an object
|
||||
*/
|
||||
void lv_obj_allocate_spec_attr(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Check the type of obj.
|
||||
* @param obj pointer to an object
|
||||
* @param class_p a class to check (e.g. `lv_slider_class`)
|
||||
* @return true: `class_p` is the `obj` class.
|
||||
*/
|
||||
bool lv_obj_check_type(const lv_obj_t * obj, const lv_obj_class_t * class_p);
|
||||
|
||||
/**
|
||||
* Check if any object has a given class (type).
|
||||
* It checks the ancestor classes too.
|
||||
* @param obj pointer to an object
|
||||
* @param class_p a class to check (e.g. `lv_slider_class`)
|
||||
* @return true: `obj` has the given class
|
||||
*/
|
||||
bool lv_obj_has_class(const lv_obj_t * obj, const lv_obj_class_t * class_p);
|
||||
|
||||
/**
|
||||
* Get the class (type) of the object
|
||||
* @param obj pointer to an object
|
||||
* @return the class (type) of the object
|
||||
*/
|
||||
const lv_obj_class_t * lv_obj_get_class(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Check if any object is still "alive".
|
||||
* @param obj pointer to an object
|
||||
* @return true: valid
|
||||
*/
|
||||
bool lv_obj_is_valid(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Utility to set an object reference to NULL when it gets deleted.
|
||||
* The reference should be in a location that will not become invalid
|
||||
* during the object's lifetime, i.e. static or allocated.
|
||||
* @param obj_ptr a pointer to a pointer to an object
|
||||
*/
|
||||
void lv_obj_null_on_delete(lv_obj_t ** obj_ptr);
|
||||
|
||||
#if LV_USE_OBJ_ID
|
||||
/**
|
||||
* Set an id for an object.
|
||||
* @param obj pointer to an object
|
||||
* @param id the id of the object
|
||||
*/
|
||||
void lv_obj_set_id(lv_obj_t * obj, void * id);
|
||||
|
||||
/**
|
||||
* Get the id of an object.
|
||||
* @param obj pointer to an object
|
||||
* @return the id of the object
|
||||
*/
|
||||
void * lv_obj_get_id(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the child object by its id.
|
||||
* It will check children and grandchildren recursively.
|
||||
* Function `lv_obj_id_compare` is used to matched obj id with given id.
|
||||
*
|
||||
* @param obj pointer to an object
|
||||
* @param id the id of the child object
|
||||
* @return pointer to the child object or NULL if not found
|
||||
*/
|
||||
lv_obj_t * lv_obj_get_child_by_id(const lv_obj_t * obj, const void * id);
|
||||
|
||||
/**
|
||||
* Assign id to object if not previously assigned.
|
||||
* This function gets called automatically when LV_OBJ_ID_AUTO_ASSIGN is enabled.
|
||||
*
|
||||
* Set `LV_USE_OBJ_ID_BUILTIN` to use the builtin method to generate object ID.
|
||||
* Otherwise, these functions including `lv_obj_[set|assign|free|stringify]_id` and
|
||||
* `lv_obj_id_compare`should be implemented externally.
|
||||
*
|
||||
* @param class_p the class this obj belongs to. Note obj->class_p is the class currently being constructed.
|
||||
* @param obj pointer to an object
|
||||
*/
|
||||
void lv_obj_assign_id(const lv_obj_class_t * class_p, lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Free resources allocated by `lv_obj_assign_id` or `lv_obj_set_id`.
|
||||
* This function is also called automatically when object is deleted.
|
||||
* @param obj pointer to an object
|
||||
*/
|
||||
void lv_obj_free_id(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Compare two obj id, return 0 if they are equal.
|
||||
*
|
||||
* Set `LV_USE_OBJ_ID_BUILTIN` to use the builtin method for compare.
|
||||
* Otherwise, it must be implemented externally.
|
||||
*
|
||||
* @param id1: the first id
|
||||
* @param id2: the second id
|
||||
* @return 0 if they are equal, non-zero otherwise.
|
||||
*/
|
||||
int lv_obj_id_compare(const void * id1, const void * id2);
|
||||
|
||||
/**
|
||||
* Format an object's id into a string.
|
||||
* @param obj pointer to an object
|
||||
* @param buf buffer to write the string into
|
||||
* @param len length of the buffer
|
||||
*/
|
||||
const char * lv_obj_stringify_id(lv_obj_t * obj, char * buf, uint32_t len);
|
||||
|
||||
#if LV_USE_OBJ_ID_BUILTIN
|
||||
/**
|
||||
* Free resources used by builtin ID generator.
|
||||
*/
|
||||
void lv_objid_builtin_destroy(void);
|
||||
#endif
|
||||
|
||||
#endif /*LV_USE_OBJ_ID*/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#if LV_USE_ASSERT_OBJ
|
||||
# define LV_ASSERT_OBJ(obj_p, obj_class) \
|
||||
do { \
|
||||
LV_ASSERT_MSG(obj_p != NULL, "The object is NULL"); \
|
||||
LV_ASSERT_MSG(lv_obj_has_class(obj_p, obj_class) == true, "Incompatible object type."); \
|
||||
LV_ASSERT_MSG(lv_obj_is_valid(obj_p) == true, "The object is invalid, deleted or corrupted?"); \
|
||||
} while(0)
|
||||
# else
|
||||
# define LV_ASSERT_OBJ(obj_p, obj_class) do{}while(0)
|
||||
#endif
|
||||
|
||||
#if LV_USE_LOG && LV_LOG_TRACE_OBJ_CREATE
|
||||
# define LV_TRACE_OBJ_CREATE(...) LV_LOG_TRACE(__VA_ARGS__)
|
||||
#else
|
||||
# define LV_TRACE_OBJ_CREATE(...)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_OBJ_H*/
|
||||
204
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_class.c
Normal file
204
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_class.c
Normal file
@@ -0,0 +1,204 @@
|
||||
/**
|
||||
* @file lv_obj_class.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_obj_class_private.h"
|
||||
#include "lv_obj_private.h"
|
||||
#include "../themes/lv_theme.h"
|
||||
#include "../display/lv_display.h"
|
||||
#include "../display/lv_display_private.h"
|
||||
#include "../stdlib/lv_string.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define MY_CLASS (&lv_obj_class)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void lv_obj_construct(const lv_obj_class_t * class_p, lv_obj_t * obj);
|
||||
static uint32_t get_instance_size(const lv_obj_class_t * class_p);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_obj_t * lv_obj_class_create_obj(const lv_obj_class_t * class_p, lv_obj_t * parent)
|
||||
{
|
||||
LV_TRACE_OBJ_CREATE("Creating object with %p class on %p parent", (void *)class_p, (void *)parent);
|
||||
uint32_t s = get_instance_size(class_p);
|
||||
lv_obj_t * obj = lv_malloc_zeroed(s);
|
||||
if(obj == NULL) return NULL;
|
||||
obj->class_p = class_p;
|
||||
obj->parent = parent;
|
||||
|
||||
/*Create a screen*/
|
||||
if(parent == NULL) {
|
||||
LV_TRACE_OBJ_CREATE("creating a screen");
|
||||
lv_display_t * disp = lv_display_get_default();
|
||||
if(!disp) {
|
||||
LV_LOG_WARN("No display created yet. No place to assign the new screen");
|
||||
lv_free(obj);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(disp->screens == NULL) {
|
||||
disp->screen_cnt = 0;
|
||||
}
|
||||
|
||||
lv_obj_t ** screens = lv_realloc(disp->screens, sizeof(lv_obj_t *) * (disp->screen_cnt + 1));
|
||||
LV_ASSERT_MALLOC(screens);
|
||||
if(screens == NULL) {
|
||||
lv_free(obj);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
disp->screen_cnt++;
|
||||
disp->screens = screens;
|
||||
disp->screens[disp->screen_cnt - 1] = obj;
|
||||
|
||||
/*Set coordinates to full screen size*/
|
||||
obj->coords.x1 = 0;
|
||||
obj->coords.y1 = 0;
|
||||
obj->coords.x2 = lv_display_get_horizontal_resolution(NULL) - 1;
|
||||
obj->coords.y2 = lv_display_get_vertical_resolution(NULL) - 1;
|
||||
}
|
||||
/*Create a normal object*/
|
||||
else {
|
||||
LV_TRACE_OBJ_CREATE("creating normal object");
|
||||
LV_ASSERT_OBJ(parent, MY_CLASS);
|
||||
if(parent->spec_attr == NULL) {
|
||||
lv_obj_allocate_spec_attr(parent);
|
||||
}
|
||||
|
||||
parent->spec_attr->child_cnt++;
|
||||
parent->spec_attr->children = lv_realloc(parent->spec_attr->children,
|
||||
sizeof(lv_obj_t *) * parent->spec_attr->child_cnt);
|
||||
parent->spec_attr->children[parent->spec_attr->child_cnt - 1] = obj;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
void lv_obj_class_init_obj(lv_obj_t * obj)
|
||||
{
|
||||
if(obj == NULL) return;
|
||||
|
||||
lv_obj_mark_layout_as_dirty(obj);
|
||||
lv_obj_enable_style_refresh(false);
|
||||
|
||||
lv_theme_apply(obj);
|
||||
lv_obj_construct(obj->class_p, obj);
|
||||
|
||||
lv_obj_enable_style_refresh(true);
|
||||
lv_obj_refresh_style(obj, LV_PART_ANY, LV_STYLE_PROP_ANY);
|
||||
|
||||
lv_obj_refresh_self_size(obj);
|
||||
|
||||
lv_group_t * def_group = lv_group_get_default();
|
||||
if(def_group && lv_obj_is_group_def(obj)) {
|
||||
lv_group_add_obj(def_group, obj);
|
||||
}
|
||||
|
||||
lv_obj_t * parent = lv_obj_get_parent(obj);
|
||||
if(parent) {
|
||||
/*Call the ancestor's event handler to the parent to notify it about the new child.
|
||||
*Also triggers layout update*/
|
||||
lv_obj_send_event(parent, LV_EVENT_CHILD_CHANGED, obj);
|
||||
lv_obj_send_event(parent, LV_EVENT_CHILD_CREATED, obj);
|
||||
|
||||
/*Invalidate the area if not screen created*/
|
||||
lv_obj_invalidate(obj);
|
||||
}
|
||||
}
|
||||
|
||||
void lv_obj_destruct(lv_obj_t * obj)
|
||||
{
|
||||
if(obj->class_p->destructor_cb) obj->class_p->destructor_cb(obj->class_p, obj);
|
||||
|
||||
if(obj->class_p->base_class) {
|
||||
/*Don't let the descendant methods run during destructing the ancestor type*/
|
||||
obj->class_p = obj->class_p->base_class;
|
||||
|
||||
/*Call the base class's destructor too*/
|
||||
lv_obj_destruct(obj);
|
||||
}
|
||||
}
|
||||
|
||||
bool lv_obj_is_editable(lv_obj_t * obj)
|
||||
{
|
||||
const lv_obj_class_t * class_p = obj->class_p;
|
||||
|
||||
/*Find a base in which editable is set*/
|
||||
while(class_p && class_p->editable == LV_OBJ_CLASS_EDITABLE_INHERIT) class_p = class_p->base_class;
|
||||
|
||||
if(class_p == NULL) return false;
|
||||
|
||||
return class_p->editable == LV_OBJ_CLASS_EDITABLE_TRUE;
|
||||
}
|
||||
|
||||
bool lv_obj_is_group_def(lv_obj_t * obj)
|
||||
{
|
||||
const lv_obj_class_t * class_p = obj->class_p;
|
||||
|
||||
/*Find a base in which group_def is set*/
|
||||
while(class_p && class_p->group_def == LV_OBJ_CLASS_GROUP_DEF_INHERIT) class_p = class_p->base_class;
|
||||
|
||||
if(class_p == NULL) return false;
|
||||
|
||||
return class_p->group_def == LV_OBJ_CLASS_GROUP_DEF_TRUE;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void lv_obj_construct(const lv_obj_class_t * class_p, lv_obj_t * obj)
|
||||
{
|
||||
if(obj->class_p->base_class) {
|
||||
const lv_obj_class_t * original_class_p = obj->class_p;
|
||||
|
||||
/*Don't let the descendant methods run during constructing the ancestor type*/
|
||||
obj->class_p = obj->class_p->base_class;
|
||||
|
||||
/*Construct the base first*/
|
||||
lv_obj_construct(class_p, obj);
|
||||
|
||||
/*Restore the original class*/
|
||||
obj->class_p = original_class_p;
|
||||
}
|
||||
|
||||
if(obj->class_p->constructor_cb) obj->class_p->constructor_cb(class_p, obj);
|
||||
}
|
||||
|
||||
static uint32_t get_instance_size(const lv_obj_class_t * class_p)
|
||||
{
|
||||
/*Find a base in which instance size is set*/
|
||||
const lv_obj_class_t * base = class_p;
|
||||
while(base && base->instance_size == 0) base = base->base_class;
|
||||
|
||||
if(base == NULL) return 0; /*Never happens: set at least in `lv_obj` class*/
|
||||
|
||||
return base->instance_size;
|
||||
}
|
||||
72
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_class.h
Normal file
72
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_class.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* @file lv_obj_class.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_OBJ_CLASS_H
|
||||
#define LV_OBJ_CLASS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../misc/lv_types.h"
|
||||
#include "../misc/lv_area.h"
|
||||
#include "lv_obj_property.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef enum {
|
||||
LV_OBJ_CLASS_EDITABLE_INHERIT, /**< Check the base class. Must have 0 value to let zero initialized class inherit*/
|
||||
LV_OBJ_CLASS_EDITABLE_TRUE,
|
||||
LV_OBJ_CLASS_EDITABLE_FALSE,
|
||||
} lv_obj_class_editable_t;
|
||||
|
||||
typedef enum {
|
||||
LV_OBJ_CLASS_GROUP_DEF_INHERIT, /**< Check the base class. Must have 0 value to let zero initialized class inherit*/
|
||||
LV_OBJ_CLASS_GROUP_DEF_TRUE,
|
||||
LV_OBJ_CLASS_GROUP_DEF_FALSE,
|
||||
} lv_obj_class_group_def_t;
|
||||
|
||||
typedef enum {
|
||||
LV_OBJ_CLASS_THEME_INHERITABLE_FALSE, /**< Do not inherit theme from base class. */
|
||||
LV_OBJ_CLASS_THEME_INHERITABLE_TRUE,
|
||||
} lv_obj_class_theme_inheritable_t;
|
||||
|
||||
typedef void (*lv_obj_class_event_cb_t)(lv_obj_class_t * class_p, lv_event_t * e);
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create an object form a class descriptor
|
||||
* @param class_p pointer to a class
|
||||
* @param parent pointer to an object where the new object should be created
|
||||
* @return pointer to the created object
|
||||
*/
|
||||
lv_obj_t * lv_obj_class_create_obj(const lv_obj_class_t * class_p, lv_obj_t * parent);
|
||||
|
||||
void lv_obj_class_init_obj(lv_obj_t * obj);
|
||||
|
||||
bool lv_obj_is_editable(lv_obj_t * obj);
|
||||
|
||||
bool lv_obj_is_group_def(lv_obj_t * obj);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_OBJ_CLASS_H*/
|
||||
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* @file lv_obj_class_private.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_OBJ_CLASS_PRIVATE_H
|
||||
#define LV_OBJ_CLASS_PRIVATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_obj_class.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Describe the common methods of every object.
|
||||
* Similar to a C++ class.
|
||||
*/
|
||||
struct lv_obj_class_t {
|
||||
const lv_obj_class_t * base_class;
|
||||
/** class_p is the final class while obj->class_p is the class currently being [de]constructed. */
|
||||
void (*constructor_cb)(const lv_obj_class_t * class_p, lv_obj_t * obj);
|
||||
void (*destructor_cb)(const lv_obj_class_t * class_p, lv_obj_t * obj);
|
||||
|
||||
/** class_p is the class in which event is being processed. */
|
||||
void (*event_cb)(const lv_obj_class_t * class_p, lv_event_t * e); /**< Widget type specific event function*/
|
||||
|
||||
#if LV_USE_OBJ_PROPERTY
|
||||
uint32_t prop_index_start;
|
||||
uint32_t prop_index_end;
|
||||
const lv_property_ops_t * properties;
|
||||
uint32_t properties_count;
|
||||
|
||||
#if LV_USE_OBJ_PROPERTY_NAME
|
||||
/* An array of property ID and name */
|
||||
const lv_property_name_t * property_names;
|
||||
uint32_t names_count;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void * user_data;
|
||||
const char * name;
|
||||
int32_t width_def;
|
||||
int32_t height_def;
|
||||
uint32_t editable : 2; /**< Value from ::lv_obj_class_editable_t*/
|
||||
uint32_t group_def : 2; /**< Value from ::lv_obj_class_group_def_t*/
|
||||
uint32_t instance_size : 16;
|
||||
uint32_t theme_inheritable : 1; /**< Value from ::lv_obj_class_theme_inheritable_t*/
|
||||
};
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
void lv_obj_destruct(lv_obj_t * obj);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_OBJ_CLASS_PRIVATE_H*/
|
||||
326
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_draw.c
Normal file
326
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_draw.c
Normal file
@@ -0,0 +1,326 @@
|
||||
/**
|
||||
* @file lv_obj_draw.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_obj_draw_private.h"
|
||||
#include "lv_obj_private.h"
|
||||
#include "lv_obj_style.h"
|
||||
#include "../display/lv_display.h"
|
||||
#include "../indev/lv_indev.h"
|
||||
#include "../stdlib/lv_string.h"
|
||||
#include "../draw/lv_draw_arc.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define MY_CLASS (&lv_obj_class)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_rect_dsc_t * draw_dsc)
|
||||
{
|
||||
draw_dsc->base.obj = obj;
|
||||
draw_dsc->base.part = part;
|
||||
|
||||
lv_opa_t opa = lv_obj_get_style_opa_recursive(obj, part);
|
||||
if(part != LV_PART_MAIN) {
|
||||
if(opa <= LV_OPA_MIN) {
|
||||
draw_dsc->bg_opa = LV_OPA_TRANSP;
|
||||
draw_dsc->bg_image_opa = LV_OPA_TRANSP;
|
||||
draw_dsc->border_opa = LV_OPA_TRANSP;
|
||||
draw_dsc->outline_opa = LV_OPA_TRANSP;
|
||||
draw_dsc->shadow_opa = LV_OPA_TRANSP;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
draw_dsc->radius = lv_obj_get_style_radius(obj, part);
|
||||
|
||||
if(draw_dsc->bg_opa != LV_OPA_TRANSP) {
|
||||
draw_dsc->bg_opa = lv_obj_get_style_bg_opa(obj, part);
|
||||
if(draw_dsc->bg_opa > LV_OPA_MIN) {
|
||||
draw_dsc->bg_color = lv_obj_get_style_bg_color_filtered(obj, part);
|
||||
const lv_grad_dsc_t * grad = lv_obj_get_style_bg_grad(obj, part);
|
||||
if(grad && grad->dir != LV_GRAD_DIR_NONE) {
|
||||
lv_memcpy(&draw_dsc->bg_grad, grad, sizeof(*grad));
|
||||
}
|
||||
else {
|
||||
draw_dsc->bg_grad.dir = lv_obj_get_style_bg_grad_dir(obj, part);
|
||||
if(draw_dsc->bg_grad.dir != LV_GRAD_DIR_NONE) {
|
||||
draw_dsc->bg_grad.stops[0].color = lv_obj_get_style_bg_color_filtered(obj, part);
|
||||
draw_dsc->bg_grad.stops[1].color = lv_obj_get_style_bg_grad_color_filtered(obj, part);
|
||||
draw_dsc->bg_grad.stops[0].frac = lv_obj_get_style_bg_main_stop(obj, part);
|
||||
draw_dsc->bg_grad.stops[1].frac = lv_obj_get_style_bg_grad_stop(obj, part);
|
||||
draw_dsc->bg_grad.stops[0].opa = lv_obj_get_style_bg_main_opa(obj, part);
|
||||
draw_dsc->bg_grad.stops[1].opa = lv_obj_get_style_bg_grad_opa(obj, part);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(draw_dsc->border_opa != LV_OPA_TRANSP) {
|
||||
draw_dsc->border_width = lv_obj_get_style_border_width(obj, part);
|
||||
if(draw_dsc->border_width) {
|
||||
draw_dsc->border_opa = lv_obj_get_style_border_opa(obj, part);
|
||||
if(draw_dsc->border_opa > LV_OPA_MIN) {
|
||||
draw_dsc->border_side = lv_obj_get_style_border_side(obj, part);
|
||||
draw_dsc->border_color = lv_obj_get_style_border_color_filtered(obj, part);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(draw_dsc->outline_opa != LV_OPA_TRANSP) {
|
||||
draw_dsc->outline_width = lv_obj_get_style_outline_width(obj, part);
|
||||
if(draw_dsc->outline_width) {
|
||||
draw_dsc->outline_opa = lv_obj_get_style_outline_opa(obj, part);
|
||||
if(draw_dsc->outline_opa > LV_OPA_MIN) {
|
||||
draw_dsc->outline_pad = lv_obj_get_style_outline_pad(obj, part);
|
||||
draw_dsc->outline_color = lv_obj_get_style_outline_color_filtered(obj, part);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(draw_dsc->bg_image_opa != LV_OPA_TRANSP) {
|
||||
draw_dsc->bg_image_src = lv_obj_get_style_bg_image_src(obj, part);
|
||||
if(draw_dsc->bg_image_src) {
|
||||
draw_dsc->bg_image_opa = lv_obj_get_style_bg_image_opa(obj, part);
|
||||
if(draw_dsc->bg_image_opa > LV_OPA_MIN) {
|
||||
if(lv_image_src_get_type(draw_dsc->bg_image_src) == LV_IMAGE_SRC_SYMBOL) {
|
||||
draw_dsc->bg_image_symbol_font = lv_obj_get_style_text_font(obj, part);
|
||||
draw_dsc->bg_image_recolor = lv_obj_get_style_text_color_filtered(obj, part);
|
||||
}
|
||||
else {
|
||||
draw_dsc->bg_image_recolor = lv_obj_get_style_bg_image_recolor_filtered(obj, part);
|
||||
draw_dsc->bg_image_recolor_opa = lv_obj_get_style_bg_image_recolor_opa(obj, part);
|
||||
draw_dsc->bg_image_tiled = lv_obj_get_style_bg_image_tiled(obj, part);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(draw_dsc->shadow_opa) {
|
||||
draw_dsc->shadow_width = lv_obj_get_style_shadow_width(obj, part);
|
||||
if(draw_dsc->shadow_width) {
|
||||
if(draw_dsc->shadow_opa > LV_OPA_MIN) {
|
||||
draw_dsc->shadow_opa = lv_obj_get_style_shadow_opa(obj, part);
|
||||
if(draw_dsc->shadow_opa > LV_OPA_MIN) {
|
||||
draw_dsc->shadow_offset_x = lv_obj_get_style_shadow_offset_x(obj, part);
|
||||
draw_dsc->shadow_offset_y = lv_obj_get_style_shadow_offset_y(obj, part);
|
||||
draw_dsc->shadow_spread = lv_obj_get_style_shadow_spread(obj, part);
|
||||
draw_dsc->shadow_color = lv_obj_get_style_shadow_color_filtered(obj, part);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(opa < LV_OPA_MAX) {
|
||||
draw_dsc->bg_opa = LV_OPA_MIX2(draw_dsc->bg_opa, opa);
|
||||
draw_dsc->bg_image_opa = LV_OPA_MIX2(draw_dsc->bg_image_opa, opa);
|
||||
draw_dsc->border_opa = LV_OPA_MIX2(draw_dsc->border_opa, opa);
|
||||
draw_dsc->shadow_opa = LV_OPA_MIX2(draw_dsc->shadow_opa, opa);
|
||||
draw_dsc->outline_opa = LV_OPA_MIX2(draw_dsc->outline_opa, opa);
|
||||
}
|
||||
}
|
||||
|
||||
void lv_obj_init_draw_label_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_label_dsc_t * draw_dsc)
|
||||
{
|
||||
draw_dsc->base.obj = obj;
|
||||
draw_dsc->base.part = part;
|
||||
|
||||
draw_dsc->opa = lv_obj_get_style_text_opa(obj, part);
|
||||
if(draw_dsc->opa <= LV_OPA_MIN) return;
|
||||
|
||||
lv_opa_t opa = lv_obj_get_style_opa_recursive(obj, part);
|
||||
if(opa < LV_OPA_MAX) {
|
||||
draw_dsc->opa = LV_OPA_MIX2(draw_dsc->opa, opa);
|
||||
}
|
||||
if(draw_dsc->opa <= LV_OPA_MIN) return;
|
||||
|
||||
draw_dsc->color = lv_obj_get_style_text_color_filtered(obj, part);
|
||||
draw_dsc->letter_space = lv_obj_get_style_text_letter_space(obj, part);
|
||||
draw_dsc->line_space = lv_obj_get_style_text_line_space(obj, part);
|
||||
draw_dsc->decor = lv_obj_get_style_text_decor(obj, part);
|
||||
if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part);
|
||||
|
||||
draw_dsc->font = lv_obj_get_style_text_font(obj, part);
|
||||
|
||||
#if LV_USE_BIDI
|
||||
draw_dsc->bidi_dir = lv_obj_get_style_base_dir(obj, LV_PART_MAIN);
|
||||
#endif
|
||||
|
||||
draw_dsc->align = lv_obj_get_style_text_align(obj, part);
|
||||
}
|
||||
|
||||
void lv_obj_init_draw_image_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_image_dsc_t * draw_dsc)
|
||||
{
|
||||
draw_dsc->base.obj = obj;
|
||||
draw_dsc->base.part = part;
|
||||
|
||||
draw_dsc->opa = lv_obj_get_style_image_opa(obj, part);
|
||||
if(draw_dsc->opa <= LV_OPA_MIN) return;
|
||||
|
||||
lv_opa_t opa = lv_obj_get_style_opa_recursive(obj, part);
|
||||
if(opa < LV_OPA_MAX) {
|
||||
draw_dsc->opa = LV_OPA_MIX2(draw_dsc->opa, opa);
|
||||
}
|
||||
if(draw_dsc->opa <= LV_OPA_MIN) return;
|
||||
|
||||
draw_dsc->rotation = 0;
|
||||
draw_dsc->scale_x = LV_SCALE_NONE;
|
||||
draw_dsc->scale_y = LV_SCALE_NONE;
|
||||
draw_dsc->pivot.x = lv_area_get_width(&obj->coords) / 2;
|
||||
draw_dsc->pivot.y = lv_area_get_height(&obj->coords) / 2;
|
||||
|
||||
draw_dsc->recolor_opa = lv_obj_get_style_image_recolor_opa(obj, part);
|
||||
draw_dsc->recolor = lv_obj_get_style_image_recolor_filtered(obj, part);
|
||||
|
||||
if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part);
|
||||
}
|
||||
|
||||
void lv_obj_init_draw_line_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_line_dsc_t * draw_dsc)
|
||||
{
|
||||
draw_dsc->base.obj = obj;
|
||||
draw_dsc->base.part = part;
|
||||
|
||||
draw_dsc->opa = lv_obj_get_style_line_opa(obj, part);
|
||||
if(draw_dsc->opa <= LV_OPA_MIN) return;
|
||||
|
||||
lv_opa_t opa = lv_obj_get_style_opa_recursive(obj, part);
|
||||
if(opa < LV_OPA_MAX) {
|
||||
draw_dsc->opa = LV_OPA_MIX2(draw_dsc->opa, opa);
|
||||
}
|
||||
if(draw_dsc->opa <= LV_OPA_MIN) return;
|
||||
|
||||
draw_dsc->width = lv_obj_get_style_line_width(obj, part);
|
||||
if(draw_dsc->width == 0) return;
|
||||
|
||||
draw_dsc->color = lv_obj_get_style_line_color_filtered(obj, part);
|
||||
|
||||
draw_dsc->dash_width = lv_obj_get_style_line_dash_width(obj, part);
|
||||
if(draw_dsc->dash_width) {
|
||||
draw_dsc->dash_gap = lv_obj_get_style_line_dash_gap(obj, part);
|
||||
}
|
||||
|
||||
draw_dsc->round_start = lv_obj_get_style_line_rounded(obj, part);
|
||||
draw_dsc->round_end = draw_dsc->round_start;
|
||||
|
||||
if(part != LV_PART_MAIN) draw_dsc->blend_mode = lv_obj_get_style_blend_mode(obj, part);
|
||||
}
|
||||
|
||||
void lv_obj_init_draw_arc_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_arc_dsc_t * draw_dsc)
|
||||
{
|
||||
draw_dsc->base.obj = obj;
|
||||
draw_dsc->base.part = part;
|
||||
|
||||
draw_dsc->width = lv_obj_get_style_arc_width(obj, part);
|
||||
if(draw_dsc->width == 0) return;
|
||||
|
||||
draw_dsc->opa = lv_obj_get_style_arc_opa(obj, part);
|
||||
if(draw_dsc->opa <= LV_OPA_MIN) return;
|
||||
|
||||
lv_opa_t opa = lv_obj_get_style_opa_recursive(obj, part);
|
||||
if(opa < LV_OPA_MAX) {
|
||||
draw_dsc->opa = LV_OPA_MIX2(draw_dsc->opa, opa);
|
||||
}
|
||||
if(draw_dsc->opa <= LV_OPA_MIN) return;
|
||||
|
||||
draw_dsc->color = lv_obj_get_style_arc_color_filtered(obj, part);
|
||||
draw_dsc->img_src = lv_obj_get_style_arc_image_src(obj, part);
|
||||
|
||||
draw_dsc->rounded = lv_obj_get_style_arc_rounded(obj, part);
|
||||
}
|
||||
|
||||
int32_t lv_obj_calculate_ext_draw_size(lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
int32_t s = 0;
|
||||
|
||||
int32_t sh_width = lv_obj_get_style_shadow_width(obj, part);
|
||||
if(sh_width) {
|
||||
lv_opa_t sh_opa = lv_obj_get_style_shadow_opa(obj, part);
|
||||
if(sh_opa > LV_OPA_MIN) {
|
||||
sh_width = sh_width / 2 + 1; /*The blur adds only half width*/
|
||||
sh_width += lv_obj_get_style_shadow_spread(obj, part);
|
||||
int32_t sh_ofs_x = lv_obj_get_style_shadow_offset_x(obj, part);
|
||||
int32_t sh_ofs_y = lv_obj_get_style_shadow_offset_y(obj, part);
|
||||
sh_width += LV_MAX(LV_ABS(sh_ofs_x), LV_ABS(sh_ofs_y));
|
||||
s = LV_MAX(s, sh_width);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t outline_width = lv_obj_get_style_outline_width(obj, part);
|
||||
if(outline_width) {
|
||||
lv_opa_t outline_opa = lv_obj_get_style_outline_opa(obj, part);
|
||||
if(outline_opa > LV_OPA_MIN) {
|
||||
int32_t outline_pad = lv_obj_get_style_outline_pad(obj, part);
|
||||
s = LV_MAX(s, outline_pad + outline_width);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t w = lv_obj_get_style_transform_width(obj, part);
|
||||
int32_t h = lv_obj_get_style_transform_height(obj, part);
|
||||
int32_t wh = LV_MAX(w, h);
|
||||
if(wh > 0) s += wh;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void lv_obj_refresh_ext_draw_size(lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
int32_t s_old = lv_obj_get_ext_draw_size(obj);
|
||||
int32_t s_new = 0;
|
||||
lv_obj_send_event(obj, LV_EVENT_REFR_EXT_DRAW_SIZE, &s_new);
|
||||
|
||||
/*Store the result if the special attrs already allocated*/
|
||||
if(obj->spec_attr) {
|
||||
obj->spec_attr->ext_draw_size = s_new;
|
||||
}
|
||||
/*Allocate spec. attrs. only if the result is not zero.
|
||||
*Zero is the default value if the spec. attr. are not defined.*/
|
||||
else if(s_new != 0) {
|
||||
lv_obj_allocate_spec_attr(obj);
|
||||
obj->spec_attr->ext_draw_size = s_new;
|
||||
}
|
||||
|
||||
if(s_new != s_old) lv_obj_invalidate(obj);
|
||||
}
|
||||
|
||||
int32_t lv_obj_get_ext_draw_size(const lv_obj_t * obj)
|
||||
{
|
||||
if(obj->spec_attr) return obj->spec_attr->ext_draw_size;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
lv_layer_type_t lv_obj_get_layer_type(const lv_obj_t * obj)
|
||||
{
|
||||
|
||||
if(obj->spec_attr) return (lv_layer_type_t)obj->spec_attr->layer_type;
|
||||
else return LV_LAYER_TYPE_NONE;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
113
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_draw.h
Normal file
113
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_draw.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* @file lv_obj_draw.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_OBJ_DRAW_H
|
||||
#define LV_OBJ_DRAW_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../misc/lv_types.h"
|
||||
#include "../draw/lv_draw_rect.h"
|
||||
#include "../draw/lv_draw_label.h"
|
||||
#include "../draw/lv_draw_image.h"
|
||||
#include "../draw/lv_draw_line.h"
|
||||
#include "../draw/lv_draw_arc.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef enum {
|
||||
LV_LAYER_TYPE_NONE,
|
||||
LV_LAYER_TYPE_SIMPLE,
|
||||
LV_LAYER_TYPE_TRANSFORM,
|
||||
} lv_layer_type_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize a rectangle draw descriptor from an object's styles in its current state
|
||||
* @param obj pointer to an object
|
||||
* @param part part of the object, e.g. `LV_PART_MAIN`, `LV_PART_SCROLLBAR`, `LV_PART_KNOB`, etc
|
||||
* @param draw_dsc the descriptor to initialize.
|
||||
* If an `..._opa` field is set to `LV_OPA_TRANSP` the related properties won't be initialized.
|
||||
* Should be initialized with `lv_draw_rect_dsc_init(draw_dsc)`.
|
||||
* @note Only the relevant fields will be set.
|
||||
* E.g. if `border width == 0` the other border properties won't be evaluated.
|
||||
*/
|
||||
void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_rect_dsc_t * draw_dsc);
|
||||
|
||||
/**
|
||||
* Initialize a label draw descriptor from an object's styles in its current state
|
||||
* @param obj pointer to an object
|
||||
* @param part part of the object, e.g. `LV_PART_MAIN`, `LV_PART_SCROLLBAR`, `LV_PART_KNOB`, etc
|
||||
* @param draw_dsc the descriptor to initialize.
|
||||
* If the `opa` field is set to or the property is equal to `LV_OPA_TRANSP` the rest won't be initialized.
|
||||
* Should be initialized with `lv_draw_label_dsc_init(draw_dsc)`.
|
||||
*/
|
||||
void lv_obj_init_draw_label_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_label_dsc_t * draw_dsc);
|
||||
|
||||
/**
|
||||
* Initialize an image draw descriptor from an object's styles in its current state
|
||||
* @param obj pointer to an object
|
||||
* @param part part of the object, e.g. `LV_PART_MAIN`, `LV_PART_SCROLLBAR`, `LV_PART_KNOB`, etc
|
||||
* @param draw_dsc the descriptor to initialize.
|
||||
* Should be initialized with `lv_draw_image_dsc_init(draw_dsc)`.
|
||||
*/
|
||||
void lv_obj_init_draw_image_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_image_dsc_t * draw_dsc);
|
||||
|
||||
/**
|
||||
* Initialize a line draw descriptor from an object's styles in its current state
|
||||
* @param obj pointer to an object
|
||||
* @param part part of the object, e.g. `LV_PART_MAIN`, `LV_PART_SCROLLBAR`, `LV_PART_KNOB`, etc
|
||||
* @param draw_dsc the descriptor to initialize.
|
||||
* Should be initialized with `lv_draw_line_dsc_init(draw_dsc)`.
|
||||
*/
|
||||
void lv_obj_init_draw_line_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_line_dsc_t * draw_dsc);
|
||||
|
||||
/**
|
||||
* Initialize an arc draw descriptor from an object's styles in its current state
|
||||
* @param obj pointer to an object
|
||||
* @param part part of the object, e.g. `LV_PART_MAIN`, `LV_PART_SCROLLBAR`, `LV_PART_KNOB`, etc
|
||||
* @param draw_dsc the descriptor to initialize.
|
||||
* Should be initialized with `lv_draw_arc_dsc_init(draw_dsc)`.
|
||||
*/
|
||||
void lv_obj_init_draw_arc_dsc(lv_obj_t * obj, lv_part_t part, lv_draw_arc_dsc_t * draw_dsc);
|
||||
|
||||
/**
|
||||
* Get the required extra size (around the object's part) to draw shadow, outline, value etc.
|
||||
* @param obj pointer to an object
|
||||
* @param part part of the object
|
||||
* @return the extra size required around the object
|
||||
*/
|
||||
int32_t lv_obj_calculate_ext_draw_size(lv_obj_t * obj, lv_part_t part);
|
||||
|
||||
/**
|
||||
* Send a 'LV_EVENT_REFR_EXT_DRAW_SIZE' Call the ancestor's event handler to the object to refresh the value of the extended draw size.
|
||||
* The result will be saved in `obj`.
|
||||
* @param obj pointer to an object
|
||||
*/
|
||||
void lv_obj_refresh_ext_draw_size(lv_obj_t * obj);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_OBJ_DRAW_H*/
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* @file lv_obj_draw_private.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_OBJ_DRAW_PRIVATE_H
|
||||
#define LV_OBJ_DRAW_PRIVATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_obj_draw.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Get the extended draw area of an object.
|
||||
* @param obj pointer to an object
|
||||
* @return the size extended draw area around the real coordinates
|
||||
*/
|
||||
int32_t lv_obj_get_ext_draw_size(const lv_obj_t * obj);
|
||||
|
||||
lv_layer_type_t lv_obj_get_layer_type(const lv_obj_t * obj);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_OBJ_DRAW_PRIVATE_H*/
|
||||
419
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_event.c
Normal file
419
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_event.c
Normal file
@@ -0,0 +1,419 @@
|
||||
/**
|
||||
* @file lv_obj_event.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../misc/lv_event_private.h"
|
||||
#include "lv_obj_event_private.h"
|
||||
#include "lv_obj_class_private.h"
|
||||
#include "lv_obj_private.h"
|
||||
#include "../indev/lv_indev.h"
|
||||
#include "../indev/lv_indev_private.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define MY_CLASS (&lv_obj_class)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static lv_result_t event_send_core(lv_event_t * e);
|
||||
static bool event_is_bubbled(lv_event_t * e);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
#if LV_USE_LOG && LV_LOG_TRACE_EVENT
|
||||
#define LV_TRACE_EVENT(...) LV_LOG_TRACE(__VA_ARGS__)
|
||||
#else
|
||||
#define LV_TRACE_EVENT(...)
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_result_t lv_obj_send_event(lv_obj_t * obj, lv_event_code_t event_code, void * param)
|
||||
{
|
||||
if(obj == NULL) return LV_RESULT_OK;
|
||||
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_event_t e;
|
||||
e.current_target = obj;
|
||||
e.original_target = obj;
|
||||
e.code = event_code;
|
||||
e.user_data = NULL;
|
||||
e.param = param;
|
||||
e.deleted = 0;
|
||||
e.stop_bubbling = 0;
|
||||
e.stop_processing = 0;
|
||||
|
||||
lv_event_push(&e);
|
||||
|
||||
/*Send the event*/
|
||||
lv_result_t res = event_send_core(&e);
|
||||
|
||||
/*Remove this element from the list*/
|
||||
lv_event_pop(&e);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
lv_result_t lv_obj_event_base(const lv_obj_class_t * class_p, lv_event_t * e)
|
||||
{
|
||||
const lv_obj_class_t * base;
|
||||
if(class_p == NULL) base = ((lv_obj_t *)e->current_target)->class_p;
|
||||
else base = class_p->base_class;
|
||||
|
||||
/*Find a base in which call the ancestor's event handler_cb if set*/
|
||||
while(base && base->event_cb == NULL) base = base->base_class;
|
||||
|
||||
if(base == NULL) return LV_RESULT_OK;
|
||||
if(base->event_cb == NULL) return LV_RESULT_OK;
|
||||
|
||||
/*Call the actual event callback*/
|
||||
e->user_data = NULL;
|
||||
base->event_cb(base, e);
|
||||
|
||||
lv_result_t res = LV_RESULT_OK;
|
||||
/*Stop if the object is deleted*/
|
||||
if(e->deleted) res = LV_RESULT_INVALID;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
lv_event_dsc_t * lv_obj_add_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb, lv_event_code_t filter, void * user_data)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
lv_obj_allocate_spec_attr(obj);
|
||||
|
||||
return lv_event_add(&obj->spec_attr->event_list, event_cb, filter, user_data);
|
||||
}
|
||||
|
||||
uint32_t lv_obj_get_event_count(lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_NULL(obj);
|
||||
if(obj->spec_attr == NULL) return 0;
|
||||
return lv_event_get_count(&obj->spec_attr->event_list);
|
||||
}
|
||||
|
||||
lv_event_dsc_t * lv_obj_get_event_dsc(lv_obj_t * obj, uint32_t index)
|
||||
{
|
||||
LV_ASSERT_NULL(obj);
|
||||
if(obj->spec_attr == NULL) return NULL;
|
||||
return lv_event_get_dsc(&obj->spec_attr->event_list, index);
|
||||
}
|
||||
|
||||
bool lv_obj_remove_event(lv_obj_t * obj, uint32_t index)
|
||||
{
|
||||
LV_ASSERT_NULL(obj);
|
||||
if(obj->spec_attr == NULL) return false;
|
||||
return lv_event_remove(&obj->spec_attr->event_list, index);
|
||||
}
|
||||
|
||||
bool lv_obj_remove_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb)
|
||||
{
|
||||
LV_ASSERT_NULL(obj);
|
||||
|
||||
uint32_t event_cnt = lv_obj_get_event_count(obj);
|
||||
uint32_t i;
|
||||
for(i = 0; i < event_cnt; i++) {
|
||||
lv_event_dsc_t * dsc = lv_obj_get_event_dsc(obj, i);
|
||||
if(dsc->cb == event_cb) {
|
||||
lv_obj_remove_event(obj, i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool lv_obj_remove_event_dsc(lv_obj_t * obj, lv_event_dsc_t * dsc)
|
||||
{
|
||||
LV_ASSERT_NULL(obj);
|
||||
LV_ASSERT_NULL(dsc);
|
||||
if(obj->spec_attr == NULL) return false;
|
||||
return lv_event_remove_dsc(&obj->spec_attr->event_list, dsc);
|
||||
}
|
||||
|
||||
uint32_t lv_obj_remove_event_cb_with_user_data(lv_obj_t * obj, lv_event_cb_t event_cb, void * user_data)
|
||||
{
|
||||
LV_ASSERT_NULL(obj);
|
||||
|
||||
uint32_t event_cnt = lv_obj_get_event_count(obj);
|
||||
uint32_t removed_count = 0;
|
||||
int32_t i;
|
||||
|
||||
for(i = event_cnt - 1; i >= 0; i--) {
|
||||
lv_event_dsc_t * dsc = lv_obj_get_event_dsc(obj, i);
|
||||
if(dsc && dsc->cb == event_cb && dsc->user_data == user_data) {
|
||||
lv_obj_remove_event(obj, i);
|
||||
removed_count ++;
|
||||
}
|
||||
}
|
||||
|
||||
return removed_count;
|
||||
}
|
||||
|
||||
lv_obj_t * lv_event_get_current_target_obj(lv_event_t * e)
|
||||
{
|
||||
return lv_event_get_current_target(e);
|
||||
}
|
||||
|
||||
lv_obj_t * lv_event_get_target_obj(lv_event_t * e)
|
||||
{
|
||||
return lv_event_get_target(e);
|
||||
}
|
||||
|
||||
lv_indev_t * lv_event_get_indev(lv_event_t * e)
|
||||
{
|
||||
|
||||
if(e->code == LV_EVENT_PRESSED ||
|
||||
e->code == LV_EVENT_PRESSING ||
|
||||
e->code == LV_EVENT_PRESS_LOST ||
|
||||
e->code == LV_EVENT_SHORT_CLICKED ||
|
||||
e->code == LV_EVENT_LONG_PRESSED ||
|
||||
e->code == LV_EVENT_LONG_PRESSED_REPEAT ||
|
||||
e->code == LV_EVENT_CLICKED ||
|
||||
e->code == LV_EVENT_RELEASED ||
|
||||
e->code == LV_EVENT_SCROLL_BEGIN ||
|
||||
e->code == LV_EVENT_SCROLL_END ||
|
||||
e->code == LV_EVENT_SCROLL ||
|
||||
e->code == LV_EVENT_GESTURE ||
|
||||
e->code == LV_EVENT_KEY ||
|
||||
e->code == LV_EVENT_FOCUSED ||
|
||||
e->code == LV_EVENT_DEFOCUSED ||
|
||||
e->code == LV_EVENT_LEAVE ||
|
||||
e->code == LV_EVENT_HOVER_OVER ||
|
||||
e->code == LV_EVENT_HOVER_LEAVE) {
|
||||
return lv_event_get_param(e);
|
||||
}
|
||||
else {
|
||||
LV_LOG_WARN("Not interpreted with this event code");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
lv_layer_t * lv_event_get_layer(lv_event_t * e)
|
||||
{
|
||||
if(e->code == LV_EVENT_DRAW_MAIN ||
|
||||
e->code == LV_EVENT_DRAW_MAIN_BEGIN ||
|
||||
e->code == LV_EVENT_DRAW_MAIN_END ||
|
||||
e->code == LV_EVENT_DRAW_POST ||
|
||||
e->code == LV_EVENT_DRAW_POST_BEGIN ||
|
||||
e->code == LV_EVENT_DRAW_POST_END) {
|
||||
return lv_event_get_param(e);
|
||||
}
|
||||
else {
|
||||
LV_LOG_WARN("Not interpreted with this event code");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const lv_area_t * lv_event_get_old_size(lv_event_t * e)
|
||||
{
|
||||
if(e->code == LV_EVENT_SIZE_CHANGED) {
|
||||
return lv_event_get_param(e);
|
||||
}
|
||||
else {
|
||||
LV_LOG_WARN("Not interpreted with this event code");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t lv_event_get_key(lv_event_t * e)
|
||||
{
|
||||
if(e->code == LV_EVENT_KEY) {
|
||||
uint32_t * k = lv_event_get_param(e);
|
||||
if(k) return *k;
|
||||
else return 0;
|
||||
}
|
||||
else {
|
||||
LV_LOG_WARN("Not interpreted with this event code");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t lv_event_get_rotary_diff(lv_event_t * e)
|
||||
{
|
||||
if(e->code == LV_EVENT_ROTARY) {
|
||||
int32_t * r = lv_event_get_param(e);
|
||||
if(r) return *r;
|
||||
else return 0;
|
||||
}
|
||||
else {
|
||||
LV_LOG_WARN("Not interpreted with this event code");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
lv_anim_t * lv_event_get_scroll_anim(lv_event_t * e)
|
||||
{
|
||||
if(e->code == LV_EVENT_SCROLL_BEGIN) {
|
||||
return lv_event_get_param(e);
|
||||
}
|
||||
else {
|
||||
LV_LOG_WARN("Not interpreted with this event code");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void lv_event_set_ext_draw_size(lv_event_t * e, int32_t size)
|
||||
{
|
||||
if(e->code == LV_EVENT_REFR_EXT_DRAW_SIZE) {
|
||||
int32_t * cur_size = lv_event_get_param(e);
|
||||
*cur_size = LV_MAX(*cur_size, size);
|
||||
}
|
||||
else {
|
||||
LV_LOG_WARN("Not interpreted with this event code");
|
||||
}
|
||||
}
|
||||
|
||||
lv_point_t * lv_event_get_self_size_info(lv_event_t * e)
|
||||
{
|
||||
if(e->code == LV_EVENT_GET_SELF_SIZE) {
|
||||
return lv_event_get_param(e);
|
||||
}
|
||||
else {
|
||||
LV_LOG_WARN("Not interpreted with this event code");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
lv_hit_test_info_t * lv_event_get_hit_test_info(lv_event_t * e)
|
||||
{
|
||||
if(e->code == LV_EVENT_HIT_TEST) {
|
||||
return lv_event_get_param(e);
|
||||
}
|
||||
else {
|
||||
LV_LOG_WARN("Not interpreted with this event code");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const lv_area_t * lv_event_get_cover_area(lv_event_t * e)
|
||||
{
|
||||
if(e->code == LV_EVENT_COVER_CHECK) {
|
||||
lv_cover_check_info_t * p = lv_event_get_param(e);
|
||||
return p->area;
|
||||
}
|
||||
else {
|
||||
LV_LOG_WARN("Not interpreted with this event code");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void lv_event_set_cover_res(lv_event_t * e, lv_cover_res_t res)
|
||||
{
|
||||
if(e->code == LV_EVENT_COVER_CHECK) {
|
||||
lv_cover_check_info_t * p = lv_event_get_param(e);
|
||||
if(res > p->res) p->res = res; /*Save only "stronger" results*/
|
||||
}
|
||||
else {
|
||||
LV_LOG_WARN("Not interpreted with this event code");
|
||||
}
|
||||
}
|
||||
|
||||
lv_draw_task_t * lv_event_get_draw_task(lv_event_t * e)
|
||||
{
|
||||
if(e->code == LV_EVENT_DRAW_TASK_ADDED) {
|
||||
return lv_event_get_param(e);
|
||||
}
|
||||
else {
|
||||
LV_LOG_WARN("Not interpreted with this event code");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static lv_result_t event_send_core(lv_event_t * e)
|
||||
{
|
||||
LV_TRACE_EVENT("Sending event %d to %p with %p param", e->code, (void *)e->original_target, e->param);
|
||||
|
||||
/*Call the input device's feedback callback if set*/
|
||||
lv_indev_t * indev_act = lv_indev_active();
|
||||
if(indev_act) {
|
||||
if(e->stop_processing) return LV_RESULT_OK;
|
||||
if(e->deleted) return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
lv_obj_t * target = e->current_target;
|
||||
lv_result_t res = LV_RESULT_OK;
|
||||
lv_event_list_t * list = target->spec_attr ? &target->spec_attr->event_list : NULL;
|
||||
|
||||
res = lv_event_send(list, e, true);
|
||||
if(res != LV_RESULT_OK || e->stop_processing) return res;
|
||||
|
||||
res = lv_obj_event_base(NULL, e);
|
||||
if(res != LV_RESULT_OK || e->stop_processing) return res;
|
||||
|
||||
res = lv_event_send(list, e, false);
|
||||
if(res != LV_RESULT_OK || e->stop_processing) return res;
|
||||
|
||||
lv_obj_t * parent = lv_obj_get_parent(e->current_target);
|
||||
if(parent && event_is_bubbled(e)) {
|
||||
e->current_target = parent;
|
||||
res = event_send_core(e);
|
||||
if(res != LV_RESULT_OK || e->stop_processing || e->stop_bubbling) return res;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool event_is_bubbled(lv_event_t * e)
|
||||
{
|
||||
if(e->stop_bubbling) return false;
|
||||
|
||||
/*Event codes that always bubble*/
|
||||
switch(e->code) {
|
||||
case LV_EVENT_CHILD_CREATED:
|
||||
case LV_EVENT_CHILD_DELETED:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/*Check other codes only if bubbling is enabled*/
|
||||
if(lv_obj_has_flag(e->current_target, LV_OBJ_FLAG_EVENT_BUBBLE) == false) return false;
|
||||
|
||||
switch(e->code) {
|
||||
case LV_EVENT_HIT_TEST:
|
||||
case LV_EVENT_COVER_CHECK:
|
||||
case LV_EVENT_REFR_EXT_DRAW_SIZE:
|
||||
case LV_EVENT_DRAW_MAIN_BEGIN:
|
||||
case LV_EVENT_DRAW_MAIN:
|
||||
case LV_EVENT_DRAW_MAIN_END:
|
||||
case LV_EVENT_DRAW_POST_BEGIN:
|
||||
case LV_EVENT_DRAW_POST:
|
||||
case LV_EVENT_DRAW_POST_END:
|
||||
case LV_EVENT_DRAW_TASK_ADDED:
|
||||
case LV_EVENT_REFRESH:
|
||||
case LV_EVENT_DELETE:
|
||||
case LV_EVENT_CHILD_CREATED:
|
||||
case LV_EVENT_CHILD_DELETED:
|
||||
case LV_EVENT_CHILD_CHANGED:
|
||||
case LV_EVENT_SIZE_CHANGED:
|
||||
case LV_EVENT_STYLE_CHANGED:
|
||||
case LV_EVENT_GET_SELF_SIZE:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
198
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_event.h
Normal file
198
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_event.h
Normal file
@@ -0,0 +1,198 @@
|
||||
/**
|
||||
* @file lv_obj_event.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_OBJ_EVENT_H
|
||||
#define LV_OBJ_EVENT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../misc/lv_types.h"
|
||||
#include "../misc/lv_event.h"
|
||||
#include "../indev/lv_indev.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/** Cover check results.*/
|
||||
typedef enum {
|
||||
LV_COVER_RES_COVER = 0,
|
||||
LV_COVER_RES_NOT_COVER = 1,
|
||||
LV_COVER_RES_MASKED = 2,
|
||||
} lv_cover_res_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Send an event to the object
|
||||
* @param obj pointer to an object
|
||||
* @param event_code the type of the event from `lv_event_t`
|
||||
* @param param arbitrary data depending on the widget type and the event. (Usually `NULL`)
|
||||
* @return LV_RESULT_OK: `obj` was not deleted in the event; LV_RESULT_INVALID: `obj` was deleted in the event_code
|
||||
*/
|
||||
lv_result_t lv_obj_send_event(lv_obj_t * obj, lv_event_code_t event_code, void * param);
|
||||
|
||||
/**
|
||||
* Used by the widgets internally to call the ancestor widget types's event handler
|
||||
* @param class_p pointer to the class of the widget (NOT the ancestor class)
|
||||
* @param e pointer to the event descriptor
|
||||
* @return LV_RESULT_OK: the target object was not deleted in the event; LV_RESULT_INVALID: it was deleted in the event_code
|
||||
*/
|
||||
lv_result_t lv_obj_event_base(const lv_obj_class_t * class_p, lv_event_t * e);
|
||||
|
||||
/**
|
||||
* Get the current target of the event. It's the object which event handler being called.
|
||||
* If the event is not bubbled it's the same as "original" target.
|
||||
* @param e pointer to the event descriptor
|
||||
* @return the target of the event_code
|
||||
*/
|
||||
lv_obj_t * lv_event_get_current_target_obj(lv_event_t * e);
|
||||
|
||||
/**
|
||||
* Get the object originally targeted by the event. It's the same even if the event is bubbled.
|
||||
* @param e pointer to the event descriptor
|
||||
* @return pointer to the original target of the event_code
|
||||
*/
|
||||
lv_obj_t * lv_event_get_target_obj(lv_event_t * e);
|
||||
|
||||
/**
|
||||
* Add an event handler function for an object.
|
||||
* Used by the user to react on event which happens with the object.
|
||||
* An object can have multiple event handler. They will be called in the same order as they were added.
|
||||
* @param obj pointer to an object
|
||||
* @param filter an event code (e.g. `LV_EVENT_CLICKED`) on which the event should be called. `LV_EVENT_ALL` can be used to receive all the events.
|
||||
* @param event_cb the new event function
|
||||
* @param user_data custom data will be available in `event_cb`
|
||||
* @return handler to the event. It can be used in `lv_obj_remove_event_dsc`.
|
||||
*/
|
||||
lv_event_dsc_t * lv_obj_add_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb, lv_event_code_t filter, void * user_data);
|
||||
|
||||
uint32_t lv_obj_get_event_count(lv_obj_t * obj);
|
||||
|
||||
lv_event_dsc_t * lv_obj_get_event_dsc(lv_obj_t * obj, uint32_t index);
|
||||
|
||||
bool lv_obj_remove_event(lv_obj_t * obj, uint32_t index);
|
||||
|
||||
bool lv_obj_remove_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb);
|
||||
|
||||
bool lv_obj_remove_event_dsc(lv_obj_t * obj, lv_event_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Remove an event_cb with user_data
|
||||
* @param obj pointer to a obj
|
||||
* @param event_cb the event_cb of the event to remove
|
||||
* @param user_data user_data
|
||||
* @return the count of the event removed
|
||||
*/
|
||||
uint32_t lv_obj_remove_event_cb_with_user_data(lv_obj_t * obj, lv_event_cb_t event_cb, void * user_data);
|
||||
|
||||
/**
|
||||
* Get the input device passed as parameter to indev related events.
|
||||
* @param e pointer to an event
|
||||
* @return the indev that triggered the event or NULL if called on a not indev related event
|
||||
*/
|
||||
lv_indev_t * lv_event_get_indev(lv_event_t * e);
|
||||
|
||||
/**
|
||||
* Get the draw context which should be the first parameter of the draw functions.
|
||||
* Namely: `LV_EVENT_DRAW_MAIN/POST`, `LV_EVENT_DRAW_MAIN/POST_BEGIN`, `LV_EVENT_DRAW_MAIN/POST_END`
|
||||
* @param e pointer to an event
|
||||
* @return pointer to a draw context or NULL if called on an unrelated event
|
||||
*/
|
||||
lv_layer_t * lv_event_get_layer(lv_event_t * e);
|
||||
|
||||
/**
|
||||
* Get the old area of the object before its size was changed. Can be used in `LV_EVENT_SIZE_CHANGED`
|
||||
* @param e pointer to an event
|
||||
* @return the old absolute area of the object or NULL if called on an unrelated event
|
||||
*/
|
||||
const lv_area_t * lv_event_get_old_size(lv_event_t * e);
|
||||
|
||||
/**
|
||||
* Get the key passed as parameter to an event. Can be used in `LV_EVENT_KEY`
|
||||
* @param e pointer to an event
|
||||
* @return the triggering key or NULL if called on an unrelated event
|
||||
*/
|
||||
uint32_t lv_event_get_key(lv_event_t * e);
|
||||
|
||||
/**
|
||||
* Get the signed rotary encoder diff. passed as parameter to an event. Can be used in `LV_EVENT_ROTARY`
|
||||
* @param e pointer to an event
|
||||
* @return the triggering key or NULL if called on an unrelated event
|
||||
*/
|
||||
int32_t lv_event_get_rotary_diff(lv_event_t * e);
|
||||
|
||||
/**
|
||||
* Get the animation descriptor of a scrolling. Can be used in `LV_EVENT_SCROLL_BEGIN`
|
||||
* @param e pointer to an event
|
||||
* @return the animation that will scroll the object. (can be modified as required)
|
||||
*/
|
||||
lv_anim_t * lv_event_get_scroll_anim(lv_event_t * e);
|
||||
|
||||
/**
|
||||
* Set the new extra draw size. Can be used in `LV_EVENT_REFR_EXT_DRAW_SIZE`
|
||||
* @param e pointer to an event
|
||||
* @param size The new extra draw size
|
||||
*/
|
||||
void lv_event_set_ext_draw_size(lv_event_t * e, int32_t size);
|
||||
|
||||
/**
|
||||
* Get a pointer to an `lv_point_t` variable in which the self size should be saved (width in `point->x` and height `point->y`).
|
||||
* Can be used in `LV_EVENT_GET_SELF_SIZE`
|
||||
* @param e pointer to an event
|
||||
* @return pointer to `lv_point_t` or NULL if called on an unrelated event
|
||||
*/
|
||||
lv_point_t * lv_event_get_self_size_info(lv_event_t * e);
|
||||
|
||||
/**
|
||||
* Get a pointer to an `lv_hit_test_info_t` variable in which the hit test result should be saved. Can be used in `LV_EVENT_HIT_TEST`
|
||||
* @param e pointer to an event
|
||||
* @return pointer to `lv_hit_test_info_t` or NULL if called on an unrelated event
|
||||
*/
|
||||
lv_hit_test_info_t * lv_event_get_hit_test_info(lv_event_t * e);
|
||||
|
||||
/**
|
||||
* Get a pointer to an area which should be examined whether the object fully covers it or not.
|
||||
* Can be used in `LV_EVENT_HIT_TEST`
|
||||
* @param e pointer to an event
|
||||
* @return an area with absolute coordinates to check
|
||||
*/
|
||||
const lv_area_t * lv_event_get_cover_area(lv_event_t * e);
|
||||
|
||||
/**
|
||||
* Set the result of cover checking. Can be used in `LV_EVENT_COVER_CHECK`
|
||||
* @param e pointer to an event
|
||||
* @param res an element of ::lv_cover_check_info_t
|
||||
*/
|
||||
void lv_event_set_cover_res(lv_event_t * e, lv_cover_res_t res);
|
||||
|
||||
/**
|
||||
* Get the draw task which was just added.
|
||||
* Can be used in `LV_EVENT_DRAW_TASK_ADDED event`
|
||||
* @param e pointer to an event
|
||||
* @return the added draw task
|
||||
*/
|
||||
lv_draw_task_t * lv_event_get_draw_task(lv_event_t * e);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_OBJ_EVENT_H*/
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* @file lv_obj_event_private.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_OBJ_EVENT_PRIVATE_H
|
||||
#define LV_OBJ_EVENT_PRIVATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_obj_event.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Used as the event parameter of ::LV_EVENT_HIT_TEST to check if an `point` can click the object or not.
|
||||
* `res` should be set like this:
|
||||
* - If already set to `false` another event wants that point non clickable. If you want to respect it leave it as `false` or set `true` to overwrite it.
|
||||
* - If already set `true` and `point` shouldn't be clickable set to `false`
|
||||
* - If already set to `true` you agree that `point` can click the object leave it as `true`
|
||||
*/
|
||||
struct lv_hit_test_info_t {
|
||||
const lv_point_t * point; /**< A point relative to screen to check if it can click the object or not*/
|
||||
bool res; /**< true: `point` can click the object; false: it cannot*/
|
||||
};
|
||||
|
||||
/**
|
||||
* Used as the event parameter of ::LV_EVENT_COVER_CHECK to check if an area is covered by the object or not.
|
||||
* In the event use `const lv_area_t * area = lv_event_get_cover_area(e)` to get the area to check
|
||||
* and `lv_event_set_cover_res(e, res)` to set the result.
|
||||
*/
|
||||
struct lv_cover_check_info_t {
|
||||
lv_cover_res_t res;
|
||||
const lv_area_t * area;
|
||||
};
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_OBJ_EVENT_PRIVATE_H*/
|
||||
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
* @file lv_obj_id.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_obj_class_private.h"
|
||||
#include "lv_obj_private.h"
|
||||
#include "lv_global.h"
|
||||
#include "../osal/lv_os.h"
|
||||
#include "../stdlib/lv_sprintf.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
typedef struct _class_info_t {
|
||||
const lv_obj_class_t * class_p;
|
||||
uint32_t obj_count;
|
||||
} class_info_t;
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#if LV_USE_OBJ_ID && LV_USE_OBJ_ID_BUILTIN
|
||||
|
||||
void lv_obj_assign_id(const lv_obj_class_t * class_p, lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT(obj && class_p);
|
||||
|
||||
uint32_t i;
|
||||
uint32_t id = 0;
|
||||
lv_global_t * global = LV_GLOBAL_DEFAULT();
|
||||
class_info_t * info = NULL;
|
||||
|
||||
if(obj == NULL || class_p == NULL) return;
|
||||
if(global == NULL) return;
|
||||
|
||||
obj->id = NULL;
|
||||
|
||||
for(i = 0; i < global->objid_count; i ++) {
|
||||
info = ((class_info_t *)global->objid_array) + i;
|
||||
if(class_p == info->class_p) break;
|
||||
}
|
||||
|
||||
/*Resize array*/
|
||||
if(i == global->objid_count) {
|
||||
void * array = lv_realloc(global->objid_array, sizeof(class_info_t) * (global->objid_count + 1));
|
||||
LV_ASSERT_MALLOC(array);
|
||||
if(array == NULL) return;
|
||||
global->objid_array = array;
|
||||
global->objid_count ++;
|
||||
info = ((class_info_t *)global->objid_array) + i;
|
||||
info->obj_count = 0;
|
||||
info->class_p = class_p;
|
||||
}
|
||||
|
||||
id = ++info->obj_count;
|
||||
|
||||
obj->id = (void *)(lv_uintptr_t)id;
|
||||
}
|
||||
|
||||
void lv_obj_set_id(lv_obj_t * obj, void * id)
|
||||
{
|
||||
LV_ASSERT_NULL(obj);
|
||||
if(obj->id) lv_obj_free_id(obj);
|
||||
obj->id = id;
|
||||
}
|
||||
|
||||
void lv_obj_free_id(lv_obj_t * obj)
|
||||
{
|
||||
LV_UNUSED(obj);
|
||||
obj->id = NULL;
|
||||
}
|
||||
|
||||
const char * lv_obj_stringify_id(lv_obj_t * obj, char * buf, uint32_t len)
|
||||
{
|
||||
const char * name;
|
||||
if(obj == NULL || obj->class_p == NULL) return NULL;
|
||||
if(buf == NULL) return NULL;
|
||||
|
||||
name = obj->class_p->name;
|
||||
if(name == NULL) name = "nameless";
|
||||
|
||||
lv_snprintf(buf, len, "%s%" LV_PRIu32 "", name, (uint32_t)(lv_uintptr_t)obj->id);
|
||||
return buf;
|
||||
}
|
||||
|
||||
void lv_objid_builtin_destroy(void)
|
||||
{
|
||||
lv_global_t * global = LV_GLOBAL_DEFAULT();
|
||||
if(global == NULL) return;
|
||||
|
||||
lv_free(global->objid_array);
|
||||
global->objid_count = 0;
|
||||
}
|
||||
|
||||
int lv_obj_id_compare(const void * id1, const void * id2)
|
||||
{
|
||||
return id1 == id2 ? 0 : 1;
|
||||
}
|
||||
|
||||
#endif /*LV_USE_OBJ_ID_BUILTIN*/
|
||||
1183
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_pos.c
Normal file
1183
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_pos.c
Normal file
File diff suppressed because it is too large
Load Diff
451
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_pos.h
Normal file
451
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_pos.h
Normal file
@@ -0,0 +1,451 @@
|
||||
/**
|
||||
* @file lv_obj_pos.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_OBJ_POS_H
|
||||
#define LV_OBJ_POS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../misc/lv_area.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef enum {
|
||||
/** No flags */
|
||||
LV_OBJ_POINT_TRANSFORM_FLAG_NONE = 0x00,
|
||||
|
||||
/** Consider the transformation properties of the parents too */
|
||||
LV_OBJ_POINT_TRANSFORM_FLAG_RECURSIVE = 0x01,
|
||||
|
||||
/** Execute the inverse of the transformation (-angle and 1/zoom) */
|
||||
LV_OBJ_POINT_TRANSFORM_FLAG_INVERSE = 0x02,
|
||||
|
||||
/** Both inverse and recursive*/
|
||||
LV_OBJ_POINT_TRANSFORM_FLAG_INVERSE_RECURSIVE = 0x03,
|
||||
} lv_obj_point_transform_flag_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Set the position of an object relative to the set alignment.
|
||||
* @param obj pointer to an object
|
||||
* @param x new x coordinate
|
||||
* @param y new y coordinate
|
||||
* @note With default alignment it's the distance from the top left corner
|
||||
* @note E.g. LV_ALIGN_CENTER alignment it's the offset from the center of the parent
|
||||
* @note The position is interpreted on the content area of the parent
|
||||
* @note The values can be set in pixel or in percentage of parent size with `lv_pct(v)`
|
||||
*/
|
||||
void lv_obj_set_pos(lv_obj_t * obj, int32_t x, int32_t y);
|
||||
|
||||
/**
|
||||
* Set the x coordinate of an object
|
||||
* @param obj pointer to an object
|
||||
* @param x new x coordinate
|
||||
* @note With default alignment it's the distance from the top left corner
|
||||
* @note E.g. LV_ALIGN_CENTER alignment it's the offset from the center of the parent
|
||||
* @note The position is interpreted on the content area of the parent
|
||||
* @note The values can be set in pixel or in percentage of parent size with `lv_pct(v)`
|
||||
*/
|
||||
void lv_obj_set_x(lv_obj_t * obj, int32_t x);
|
||||
|
||||
/**
|
||||
* Set the y coordinate of an object
|
||||
* @param obj pointer to an object
|
||||
* @param y new y coordinate
|
||||
* @note With default alignment it's the distance from the top left corner
|
||||
* @note E.g. LV_ALIGN_CENTER alignment it's the offset from the center of the parent
|
||||
* @note The position is interpreted on the content area of the parent
|
||||
* @note The values can be set in pixel or in percentage of parent size with `lv_pct(v)`
|
||||
*/
|
||||
void lv_obj_set_y(lv_obj_t * obj, int32_t y);
|
||||
|
||||
/**
|
||||
* Set the size of an object.
|
||||
* @param obj pointer to an object
|
||||
* @param w the new width
|
||||
* @param h the new height
|
||||
* @note possible values are:
|
||||
* pixel simple set the size accordingly
|
||||
* LV_SIZE_CONTENT set the size to involve all children in the given direction
|
||||
* lv_pct(x) to set size in percentage of the parent's content area size (the size without paddings).
|
||||
* x should be in [0..1000]% range
|
||||
*/
|
||||
void lv_obj_set_size(lv_obj_t * obj, int32_t w, int32_t h);
|
||||
|
||||
/**
|
||||
* Recalculate the size of the object
|
||||
* @param obj pointer to an object
|
||||
* @return true: the size has been changed
|
||||
*/
|
||||
bool lv_obj_refr_size(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Set the width of an object
|
||||
* @param obj pointer to an object
|
||||
* @param w the new width
|
||||
* @note possible values are:
|
||||
* pixel simple set the size accordingly
|
||||
* LV_SIZE_CONTENT set the size to involve all children in the given direction
|
||||
* lv_pct(x) to set size in percentage of the parent's content area size (the size without paddings).
|
||||
* x should be in [0..1000]% range
|
||||
*/
|
||||
void lv_obj_set_width(lv_obj_t * obj, int32_t w);
|
||||
|
||||
/**
|
||||
* Set the height of an object
|
||||
* @param obj pointer to an object
|
||||
* @param h the new height
|
||||
* @note possible values are:
|
||||
* pixel simple set the size accordingly
|
||||
* LV_SIZE_CONTENT set the size to involve all children in the given direction
|
||||
* lv_pct(x) to set size in percentage of the parent's content area size (the size without paddings).
|
||||
* x should be in [0..1000]% range
|
||||
*/
|
||||
void lv_obj_set_height(lv_obj_t * obj, int32_t h);
|
||||
|
||||
/**
|
||||
* Set the width reduced by the left and right padding and the border width.
|
||||
* @param obj pointer to an object
|
||||
* @param w the width without paddings in pixels
|
||||
*/
|
||||
void lv_obj_set_content_width(lv_obj_t * obj, int32_t w);
|
||||
|
||||
/**
|
||||
* Set the height reduced by the top and bottom padding and the border width.
|
||||
* @param obj pointer to an object
|
||||
* @param h the height without paddings in pixels
|
||||
*/
|
||||
void lv_obj_set_content_height(lv_obj_t * obj, int32_t h);
|
||||
|
||||
/**
|
||||
* Set a layout for an object
|
||||
* @param obj pointer to an object
|
||||
* @param layout pointer to a layout descriptor to set
|
||||
*/
|
||||
void lv_obj_set_layout(lv_obj_t * obj, uint32_t layout);
|
||||
|
||||
/**
|
||||
* Test whether the and object is positioned by a layout or not
|
||||
* @param obj pointer to an object to test
|
||||
* @return true: positioned by a layout; false: not positioned by a layout
|
||||
*/
|
||||
bool lv_obj_is_layout_positioned(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Mark the object for layout update.
|
||||
* @param obj pointer to an object whose children needs to be updated
|
||||
*/
|
||||
void lv_obj_mark_layout_as_dirty(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Update the layout of an object.
|
||||
* @param obj pointer to an object whose children needs to be updated
|
||||
*/
|
||||
void lv_obj_update_layout(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Change the alignment of an object.
|
||||
* @param obj pointer to an object to align
|
||||
* @param align type of alignment (see 'lv_align_t' enum) `LV_ALIGN_OUT_...` can't be used.
|
||||
*/
|
||||
void lv_obj_set_align(lv_obj_t * obj, lv_align_t align);
|
||||
|
||||
/**
|
||||
* Change the alignment of an object and set new coordinates.
|
||||
* Equivalent to:
|
||||
* lv_obj_set_align(obj, align);
|
||||
* lv_obj_set_pos(obj, x_ofs, y_ofs);
|
||||
* @param obj pointer to an object to align
|
||||
* @param align type of alignment (see 'lv_align_t' enum) `LV_ALIGN_OUT_...` can't be used.
|
||||
* @param x_ofs x coordinate offset after alignment
|
||||
* @param y_ofs y coordinate offset after alignment
|
||||
*/
|
||||
void lv_obj_align(lv_obj_t * obj, lv_align_t align, int32_t x_ofs, int32_t y_ofs);
|
||||
|
||||
/**
|
||||
* Align an object to another object.
|
||||
* @param obj pointer to an object to align
|
||||
* @param base pointer to another object (if NULL `obj`s parent is used). 'obj' will be aligned to it.
|
||||
* @param align type of alignment (see 'lv_align_t' enum)
|
||||
* @param x_ofs x coordinate offset after alignment
|
||||
* @param y_ofs y coordinate offset after alignment
|
||||
* @note if the position or size of `base` changes `obj` needs to be aligned manually again
|
||||
*/
|
||||
void lv_obj_align_to(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, int32_t x_ofs,
|
||||
int32_t y_ofs);
|
||||
|
||||
/**
|
||||
* Align an object to the center on its parent.
|
||||
* @param obj pointer to an object to align
|
||||
* @note if the parent size changes `obj` needs to be aligned manually again
|
||||
*/
|
||||
void lv_obj_center(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Copy the coordinates of an object to an area
|
||||
* @param obj pointer to an object
|
||||
* @param coords pointer to an area to store the coordinates
|
||||
*/
|
||||
void lv_obj_get_coords(const lv_obj_t * obj, lv_area_t * coords);
|
||||
|
||||
/**
|
||||
* Get the x coordinate of object.
|
||||
* @param obj pointer to an object
|
||||
* @return distance of `obj` from the left side of its parent plus the parent's left padding
|
||||
* @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation
|
||||
* call `lv_obj_update_layout(obj)`.
|
||||
* @note Zero return value means the object is on the left padding of the parent, and not on the left edge.
|
||||
* @note Scrolling of the parent doesn't change the returned value.
|
||||
* @note The returned value is always the distance from the parent even if `obj` is positioned by a layout.
|
||||
*/
|
||||
int32_t lv_obj_get_x(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the x2 coordinate of object.
|
||||
* @param obj pointer to an object
|
||||
* @return distance of `obj` from the right side of its parent plus the parent's right padding
|
||||
* @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation
|
||||
* call `lv_obj_update_layout(obj)`.
|
||||
* @note Zero return value means the object is on the right padding of the parent, and not on the right edge.
|
||||
* @note Scrolling of the parent doesn't change the returned value.
|
||||
* @note The returned value is always the distance from the parent even if `obj` is positioned by a layout.
|
||||
*/
|
||||
int32_t lv_obj_get_x2(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the y coordinate of object.
|
||||
* @param obj pointer to an object
|
||||
* @return distance of `obj` from the top side of its parent plus the parent's top padding
|
||||
* @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation
|
||||
* call `lv_obj_update_layout(obj)`.
|
||||
* @note Zero return value means the object is on the top padding of the parent, and not on the top edge.
|
||||
* @note Scrolling of the parent doesn't change the returned value.
|
||||
* @note The returned value is always the distance from the parent even if `obj` is positioned by a layout.
|
||||
*/
|
||||
int32_t lv_obj_get_y(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the y2 coordinate of object.
|
||||
* @param obj pointer to an object
|
||||
* @return distance of `obj` from the bottom side of its parent plus the parent's bottom padding
|
||||
* @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation
|
||||
* call `lv_obj_update_layout(obj)`.
|
||||
* @note Zero return value means the object is on the bottom padding of the parent, and not on the bottom edge.
|
||||
* @note Scrolling of the parent doesn't change the returned value.
|
||||
* @note The returned value is always the distance from the parent even if `obj` is positioned by a layout.
|
||||
*/
|
||||
int32_t lv_obj_get_y2(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the actually set x coordinate of object, i.e. the offset from the set alignment
|
||||
* @param obj pointer to an object
|
||||
* @return the set x coordinate
|
||||
*/
|
||||
int32_t lv_obj_get_x_aligned(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the actually set y coordinate of object, i.e. the offset from the set alignment
|
||||
* @param obj pointer to an object
|
||||
* @return the set y coordinate
|
||||
*/
|
||||
int32_t lv_obj_get_y_aligned(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the width of an object
|
||||
* @param obj pointer to an object
|
||||
* @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation
|
||||
* call `lv_obj_update_layout(obj)`.
|
||||
* @return the width in pixels
|
||||
*/
|
||||
int32_t lv_obj_get_width(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the height of an object
|
||||
* @param obj pointer to an object
|
||||
* @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation
|
||||
* call `lv_obj_update_layout(obj)`.
|
||||
* @return the height in pixels
|
||||
*/
|
||||
int32_t lv_obj_get_height(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the width reduced by the left and right padding and the border width.
|
||||
* @param obj pointer to an object
|
||||
* @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation
|
||||
* call `lv_obj_update_layout(obj)`.
|
||||
* @return the width which still fits into its parent without causing overflow (making the parent scrollable)
|
||||
*/
|
||||
int32_t lv_obj_get_content_width(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the height reduced by the top and bottom padding and the border width.
|
||||
* @param obj pointer to an object
|
||||
* @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation
|
||||
* call `lv_obj_update_layout(obj)`.
|
||||
* @return the height which still fits into the parent without causing overflow (making the parent scrollable)
|
||||
*/
|
||||
int32_t lv_obj_get_content_height(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the area reduced by the paddings and the border width.
|
||||
* @param obj pointer to an object
|
||||
* @note The position of the object is recalculated only on the next redraw. To force coordinate recalculation
|
||||
* call `lv_obj_update_layout(obj)`.
|
||||
* @param area the area which still fits into the parent without causing overflow (making the parent scrollable)
|
||||
*/
|
||||
void lv_obj_get_content_coords(const lv_obj_t * obj, lv_area_t * area);
|
||||
|
||||
/**
|
||||
* Get the width occupied by the "parts" of the widget. E.g. the width of all columns of a table.
|
||||
* @param obj pointer to an objects
|
||||
* @return the width of the virtually drawn content
|
||||
* @note This size independent from the real size of the widget.
|
||||
* It just tells how large the internal ("virtual") content is.
|
||||
*/
|
||||
int32_t lv_obj_get_self_width(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the height occupied by the "parts" of the widget. E.g. the height of all rows of a table.
|
||||
* @param obj pointer to an objects
|
||||
* @return the width of the virtually drawn content
|
||||
* @note This size independent from the real size of the widget.
|
||||
* It just tells how large the internal ("virtual") content is.
|
||||
*/
|
||||
int32_t lv_obj_get_self_height(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Handle if the size of the internal ("virtual") content of an object has changed.
|
||||
* @param obj pointer to an object
|
||||
* @return false: nothing happened; true: refresh happened
|
||||
*/
|
||||
bool lv_obj_refresh_self_size(lv_obj_t * obj);
|
||||
|
||||
void lv_obj_refr_pos(lv_obj_t * obj);
|
||||
|
||||
void lv_obj_move_to(lv_obj_t * obj, int32_t x, int32_t y);
|
||||
|
||||
void lv_obj_move_children_by(lv_obj_t * obj, int32_t x_diff, int32_t y_diff, bool ignore_floating);
|
||||
|
||||
/**
|
||||
* Transform a point using the angle and zoom style properties of an object
|
||||
* @param obj pointer to an object whose style properties should be used
|
||||
* @param p a point to transform, the result will be written back here too
|
||||
* @param flags OR-ed valued of :cpp:enum:`lv_obj_point_transform_flag_t`
|
||||
*/
|
||||
void lv_obj_transform_point(const lv_obj_t * obj, lv_point_t * p, lv_obj_point_transform_flag_t flags);
|
||||
|
||||
/**
|
||||
* Transform an array of points using the angle and zoom style properties of an object
|
||||
* @param obj pointer to an object whose style properties should be used
|
||||
* @param points the array of points to transform, the result will be written back here too
|
||||
* @param count number of points in the array
|
||||
* @param flags OR-ed valued of :cpp:enum:`lv_obj_point_transform_flag_t`
|
||||
*/
|
||||
void lv_obj_transform_point_array(const lv_obj_t * obj, lv_point_t points[], size_t count,
|
||||
lv_obj_point_transform_flag_t flags);
|
||||
|
||||
/**
|
||||
* Transform an area using the angle and zoom style properties of an object
|
||||
* @param obj pointer to an object whose style properties should be used
|
||||
* @param area an area to transform, the result will be written back here too
|
||||
* @param flags OR-ed valued of :cpp:enum:`lv_obj_point_transform_flag_t`
|
||||
*/
|
||||
void lv_obj_get_transformed_area(const lv_obj_t * obj, lv_area_t * area, lv_obj_point_transform_flag_t flags);
|
||||
|
||||
/**
|
||||
* Mark an area of an object as invalid.
|
||||
* The area will be truncated to the object's area and marked for redraw.
|
||||
* @param obj pointer to an object
|
||||
* @param area the area to redraw
|
||||
*/
|
||||
void lv_obj_invalidate_area(const lv_obj_t * obj, const lv_area_t * area);
|
||||
|
||||
/**
|
||||
* Mark the object as invalid to redrawn its area
|
||||
* @param obj pointer to an object
|
||||
*/
|
||||
void lv_obj_invalidate(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Tell whether an area of an object is visible (even partially) now or not
|
||||
* @param obj pointer to an object
|
||||
* @param area the are to check. The visible part of the area will be written back here.
|
||||
* @return true visible; false not visible (hidden, out of parent, on other screen, etc)
|
||||
*/
|
||||
bool lv_obj_area_is_visible(const lv_obj_t * obj, lv_area_t * area);
|
||||
|
||||
/**
|
||||
* Tell whether an object is visible (even partially) now or not
|
||||
* @param obj pointer to an object
|
||||
* @return true: visible; false not visible (hidden, out of parent, on other screen, etc)
|
||||
*/
|
||||
bool lv_obj_is_visible(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Set the size of an extended clickable area
|
||||
* @param obj pointer to an object
|
||||
* @param size extended clickable area in all 4 directions [px]
|
||||
*/
|
||||
void lv_obj_set_ext_click_area(lv_obj_t * obj, int32_t size);
|
||||
|
||||
/**
|
||||
* Get the an area where to object can be clicked.
|
||||
* It's the object's normal area plus the extended click area.
|
||||
* @param obj pointer to an object
|
||||
* @param area store the result area here
|
||||
*/
|
||||
void lv_obj_get_click_area(const lv_obj_t * obj, lv_area_t * area);
|
||||
|
||||
/**
|
||||
* Hit-test an object given a particular point in screen space.
|
||||
* @param obj object to hit-test
|
||||
* @param point screen-space point (absolute coordinate)
|
||||
* @return true: if the object is considered under the point
|
||||
*/
|
||||
bool lv_obj_hit_test(lv_obj_t * obj, const lv_point_t * point);
|
||||
|
||||
/**
|
||||
* Clamp a width between min and max width. If the min/max width is in percentage value use the ref_width
|
||||
* @param width width to clamp
|
||||
* @param min_width the minimal width
|
||||
* @param max_width the maximal width
|
||||
* @param ref_width the reference width used when min/max width is in percentage
|
||||
* @return the clamped width
|
||||
*/
|
||||
int32_t lv_clamp_width(int32_t width, int32_t min_width, int32_t max_width, int32_t ref_width);
|
||||
|
||||
/**
|
||||
* Clamp a height between min and max height. If the min/max height is in percentage value use the ref_height
|
||||
* @param height height to clamp
|
||||
* @param min_height the minimal height
|
||||
* @param max_height the maximal height
|
||||
* @param ref_height the reference height used when min/max height is in percentage
|
||||
* @return the clamped height
|
||||
*/
|
||||
int32_t lv_clamp_height(int32_t height, int32_t min_height, int32_t max_height, int32_t ref_height);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_OBJ_POS_H*/
|
||||
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* @file lv_obj_private.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_OBJ_PRIVATE_H
|
||||
#define LV_OBJ_PRIVATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_obj.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Special, rarely used attributes.
|
||||
* They are allocated automatically if any elements is set.
|
||||
*/
|
||||
struct lv_obj_spec_attr_t {
|
||||
lv_obj_t ** children; /**< Store the pointer of the children in an array.*/
|
||||
lv_group_t * group_p;
|
||||
lv_event_list_t event_list;
|
||||
|
||||
lv_point_t scroll; /**< The current X/Y scroll offset*/
|
||||
|
||||
int32_t ext_click_pad; /**< Extra click padding in all direction*/
|
||||
int32_t ext_draw_size; /**< EXTend the size in every direction for drawing.*/
|
||||
|
||||
uint16_t child_cnt; /**< Number of children*/
|
||||
uint16_t scrollbar_mode : 2; /**< How to display scrollbars, see `lv_scrollbar_mode_t`*/
|
||||
uint16_t scroll_snap_x : 2; /**< Where to align the snappable children horizontally, see `lv_scroll_snap_t`*/
|
||||
uint16_t scroll_snap_y : 2; /**< Where to align the snappable children vertically*/
|
||||
uint16_t scroll_dir : 4; /**< The allowed scroll direction(s), see `lv_dir_t`*/
|
||||
uint16_t layer_type : 2; /**< Cache the layer type here. Element of lv_intermediate_layer_type_t */
|
||||
};
|
||||
|
||||
struct lv_obj_t {
|
||||
const lv_obj_class_t * class_p;
|
||||
lv_obj_t * parent;
|
||||
lv_obj_spec_attr_t * spec_attr;
|
||||
lv_obj_style_t * styles;
|
||||
#if LV_OBJ_STYLE_CACHE
|
||||
uint32_t style_main_prop_is_set;
|
||||
uint32_t style_other_prop_is_set;
|
||||
#endif
|
||||
void * user_data;
|
||||
#if LV_USE_OBJ_ID
|
||||
void * id;
|
||||
#endif
|
||||
lv_area_t coords;
|
||||
lv_obj_flag_t flags;
|
||||
lv_state_t state;
|
||||
uint16_t layout_inv : 1;
|
||||
uint16_t readjust_scroll_after_layout : 1;
|
||||
uint16_t scr_layout_inv : 1;
|
||||
uint16_t skip_trans : 1;
|
||||
uint16_t style_cnt : 6;
|
||||
uint16_t h_layout : 1;
|
||||
uint16_t w_layout : 1;
|
||||
uint16_t is_deleting : 1;
|
||||
};
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_OBJ_PRIVATE_H*/
|
||||
302
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_property.c
Normal file
302
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_property.c
Normal file
@@ -0,0 +1,302 @@
|
||||
/**
|
||||
* @file lv_obj_id.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_obj_private.h"
|
||||
#include "../core/lv_obj.h"
|
||||
#include "../stdlib/lv_string.h"
|
||||
#include "../misc/lv_utils.h"
|
||||
#include "lv_obj_property.h"
|
||||
#include "lv_obj_class_private.h"
|
||||
|
||||
#if LV_USE_OBJ_PROPERTY
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef void (*lv_property_set_int_t)(lv_obj_t *, int32_t);
|
||||
typedef void (*lv_property_set_bool_t)(lv_obj_t *, bool);
|
||||
typedef void (*lv_property_set_precise_t)(lv_obj_t *, lv_value_precise_t);
|
||||
typedef void (*lv_property_set_color_t)(lv_obj_t *, lv_color_t);
|
||||
typedef void (*lv_property_set_point_t)(lv_obj_t *, lv_point_t *);
|
||||
typedef void (*lv_property_set_pointer_t)(lv_obj_t *, const void *);
|
||||
typedef lv_result_t (*lv_property_setter_t)(lv_obj_t *, lv_prop_id_t, const lv_property_t *);
|
||||
|
||||
typedef int32_t (*lv_property_get_int_t)(const lv_obj_t *);
|
||||
typedef bool (*lv_property_get_bool_t)(const lv_obj_t *);
|
||||
typedef lv_value_precise_t (*lv_property_get_precise_t)(const lv_obj_t *);
|
||||
typedef lv_color_t (*lv_property_get_color_t)(const lv_obj_t *);
|
||||
typedef lv_point_t (*lv_property_get_point_t)(lv_obj_t *);
|
||||
typedef void * (*lv_property_get_pointer_t)(const lv_obj_t *);
|
||||
typedef lv_result_t (*lv_property_getter_t)(const lv_obj_t *, lv_prop_id_t, lv_property_t *);
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static lv_result_t obj_property(lv_obj_t * obj, lv_prop_id_t id, lv_property_t * value, bool set);
|
||||
static int property_name_compare(const void * ref, const void * element);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_result_t lv_obj_set_property(lv_obj_t * obj, const lv_property_t * value)
|
||||
{
|
||||
LV_ASSERT(obj && value);
|
||||
|
||||
uint32_t index = LV_PROPERTY_ID_INDEX(value->id);
|
||||
if(value->id == LV_PROPERTY_ID_INVALID || index > LV_PROPERTY_ID_ANY) {
|
||||
LV_LOG_WARN("Invalid property id set to %p", obj);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
if(index < LV_PROPERTY_ID_START) {
|
||||
lv_obj_set_local_style_prop(obj, index, value->style, value->selector);
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
return obj_property(obj, value->id, (lv_property_t *)value, true);
|
||||
}
|
||||
|
||||
lv_result_t lv_obj_set_properties(lv_obj_t * obj, const lv_property_t * value, uint32_t count)
|
||||
{
|
||||
for(uint32_t i = 0; i < count; i++) {
|
||||
lv_result_t result = lv_obj_set_property(obj, &value[i]);
|
||||
if(result != LV_RESULT_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_property_t lv_obj_get_property(lv_obj_t * obj, lv_prop_id_t id)
|
||||
{
|
||||
lv_result_t result;
|
||||
lv_property_t value = { 0 };
|
||||
|
||||
uint32_t index = LV_PROPERTY_ID_INDEX(id);
|
||||
if(id == LV_PROPERTY_ID_INVALID || index > LV_PROPERTY_ID_ANY) {
|
||||
LV_LOG_WARN("Invalid property id to get from %p", obj);
|
||||
value.id = LV_PROPERTY_ID_INVALID;
|
||||
value.num = 0;
|
||||
return value;
|
||||
}
|
||||
|
||||
if(index < LV_PROPERTY_ID_START) {
|
||||
lv_obj_get_local_style_prop(obj, index, &value.style, 0);
|
||||
value.id = id;
|
||||
value.selector = 0;
|
||||
return value;
|
||||
}
|
||||
|
||||
result = obj_property(obj, id, &value, false);
|
||||
if(result != LV_RESULT_OK)
|
||||
value.id = LV_PROPERTY_ID_INVALID;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
lv_property_t lv_obj_get_style_property(lv_obj_t * obj, lv_prop_id_t id, uint32_t selector)
|
||||
{
|
||||
lv_property_t value;
|
||||
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 0x%" LV_PRIx32, id);
|
||||
value.id = LV_PROPERTY_ID_INVALID;
|
||||
value.num = 0;
|
||||
return value;
|
||||
}
|
||||
|
||||
lv_obj_get_local_style_prop(obj, id, &value.style, selector);
|
||||
value.id = id;
|
||||
value.selector = selector;
|
||||
return value;
|
||||
}
|
||||
|
||||
lv_prop_id_t lv_style_property_get_id(const char * name)
|
||||
{
|
||||
#if LV_USE_OBJ_PROPERTY_NAME
|
||||
lv_property_name_t * found;
|
||||
/*Check style property*/
|
||||
found = lv_utils_bsearch(name, lv_style_property_names, sizeof(lv_style_property_names) / sizeof(lv_property_name_t),
|
||||
sizeof(lv_property_name_t), property_name_compare);
|
||||
if(found) return found->id;
|
||||
#else
|
||||
LV_UNUSED(name);
|
||||
#endif
|
||||
return LV_PROPERTY_ID_INVALID;
|
||||
}
|
||||
|
||||
lv_prop_id_t lv_obj_class_property_get_id(const lv_obj_class_t * clz, const char * name)
|
||||
{
|
||||
#if LV_USE_OBJ_PROPERTY_NAME
|
||||
const lv_property_name_t * names;
|
||||
lv_property_name_t * found;
|
||||
|
||||
names = clz->property_names;
|
||||
if(names == NULL) {
|
||||
/* try base class*/
|
||||
return LV_PROPERTY_ID_INVALID;
|
||||
}
|
||||
|
||||
found = lv_utils_bsearch(name, names, clz->names_count, sizeof(lv_property_name_t), property_name_compare);
|
||||
if(found) return found->id;
|
||||
#else
|
||||
LV_UNUSED(obj);
|
||||
LV_UNUSED(name);
|
||||
LV_UNUSED(property_name_compare);
|
||||
#endif
|
||||
return LV_PROPERTY_ID_INVALID;
|
||||
}
|
||||
|
||||
lv_prop_id_t lv_obj_property_get_id(const lv_obj_t * obj, const char * name)
|
||||
{
|
||||
#if LV_USE_OBJ_PROPERTY_NAME
|
||||
const lv_obj_class_t * clz;
|
||||
lv_prop_id_t id;
|
||||
|
||||
for(clz = obj->class_p; clz; clz = clz->base_class) {
|
||||
id = lv_obj_class_property_get_id(clz, name);
|
||||
if(id != LV_PROPERTY_ID_INVALID) return id;
|
||||
}
|
||||
|
||||
/*Check style property*/
|
||||
id = lv_style_property_get_id(name);
|
||||
if(id != LV_PROPERTY_ID_INVALID) return id;
|
||||
#else
|
||||
LV_UNUSED(obj);
|
||||
LV_UNUSED(name);
|
||||
LV_UNUSED(property_name_compare);
|
||||
#endif
|
||||
return LV_PROPERTY_ID_INVALID;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static lv_result_t obj_property(lv_obj_t * obj, lv_prop_id_t id, lv_property_t * value, bool set)
|
||||
{
|
||||
const lv_property_ops_t * properties;
|
||||
const lv_property_ops_t * prop;
|
||||
|
||||
const lv_obj_class_t * clz;
|
||||
uint32_t index = LV_PROPERTY_ID_INDEX(id);
|
||||
|
||||
for(clz = obj->class_p ; clz; clz = clz->base_class) {
|
||||
properties = clz->properties;
|
||||
if(properties == NULL) {
|
||||
/* try base class*/
|
||||
continue;
|
||||
}
|
||||
|
||||
if(id != LV_PROPERTY_ID_ANY && (index < clz->prop_index_start || index > clz->prop_index_end)) {
|
||||
/* try base class*/
|
||||
continue;
|
||||
}
|
||||
|
||||
/*Check if there's setter available for this class*/
|
||||
for(uint32_t i = 0; i < clz->properties_count; i++) {
|
||||
prop = &properties[i];
|
||||
|
||||
/*pass id and value directly to widget's property method*/
|
||||
if(prop->id == LV_PROPERTY_ID_ANY) {
|
||||
value->id = prop->id;
|
||||
if(set) return ((lv_property_setter_t)prop->setter)(obj, id, value);
|
||||
else return ((lv_property_getter_t)prop->getter)(obj, id, value);
|
||||
}
|
||||
|
||||
/*Not this id, check next*/
|
||||
if(prop->id != id)
|
||||
continue;
|
||||
|
||||
/*id matched but we got null pointer to functions*/
|
||||
if(set ? prop->setter == NULL : prop->getter == NULL) {
|
||||
LV_LOG_WARN("NULL %s provided, id: 0x%" LV_PRIx32, set ? "setter" : "getter", id);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
/*Update value id if it's a read*/
|
||||
if(!set) value->id = prop->id;
|
||||
|
||||
switch(LV_PROPERTY_ID_TYPE(prop->id)) {
|
||||
case LV_PROPERTY_TYPE_INT: {
|
||||
if(set)((lv_property_set_int_t)(prop->setter))(obj, value->num);
|
||||
else value->num = ((lv_property_get_int_t)(prop->getter))(obj);
|
||||
break;
|
||||
}
|
||||
case LV_PROPERTY_TYPE_BOOL: {
|
||||
if(set)((lv_property_set_bool_t)(prop->setter))(obj, value->enable);
|
||||
else value->enable = ((lv_property_get_bool_t)(prop->getter))(obj);
|
||||
break;
|
||||
}
|
||||
|
||||
case LV_PROPERTY_TYPE_PRECISE: {
|
||||
if(set)((lv_property_set_precise_t)(prop->setter))(obj, value->precise);
|
||||
else value->precise = ((lv_property_get_precise_t)(prop->getter))(obj);
|
||||
break;
|
||||
}
|
||||
case LV_PROPERTY_TYPE_COLOR: {
|
||||
if(set)((lv_property_set_color_t)prop->setter)(obj, value->color);
|
||||
else value->color = ((lv_property_get_color_t)(prop->getter))(obj);
|
||||
break;
|
||||
}
|
||||
case LV_PROPERTY_TYPE_POINT: {
|
||||
lv_point_t * point = &value->point;
|
||||
if(set)((lv_property_set_point_t)(prop->setter))(obj, point);
|
||||
else *point = ((lv_property_get_point_t)(prop->getter))(obj);
|
||||
break;
|
||||
}
|
||||
case LV_PROPERTY_TYPE_POINTER:
|
||||
case LV_PROPERTY_TYPE_IMGSRC:
|
||||
case LV_PROPERTY_TYPE_TEXT:
|
||||
case LV_PROPERTY_TYPE_OBJ:
|
||||
case LV_PROPERTY_TYPE_DISPLAY:
|
||||
case LV_PROPERTY_TYPE_FONT: {
|
||||
if(set)((lv_property_set_pointer_t)(prop->setter))(obj, value->ptr);
|
||||
else value->ptr = ((lv_property_get_pointer_t)(prop->getter))(obj);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LV_LOG_WARN("Unknown property id: 0x%08" LV_PRIx32, prop->id);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
/*If no setter found, try base class then*/
|
||||
}
|
||||
|
||||
LV_LOG_WARN("Unknown property id: 0x%08" LV_PRIx32, id);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
static int property_name_compare(const void * ref, const void * element)
|
||||
{
|
||||
const lv_property_name_t * prop = element;
|
||||
return lv_strcmp(ref, prop->name);
|
||||
}
|
||||
|
||||
#endif /*LV_USE_OBJ_PROPERTY*/
|
||||
209
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_property.h
Normal file
209
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_property.h
Normal file
@@ -0,0 +1,209 @@
|
||||
/**
|
||||
* @file lv_obj_property.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_OBJ_PROPERTY_H
|
||||
#define LV_OBJ_PROPERTY_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../misc/lv_types.h"
|
||||
#include "../misc/lv_style.h"
|
||||
|
||||
#if LV_USE_OBJ_PROPERTY
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/*All possible property value types*/
|
||||
#define LV_PROPERTY_TYPE_INVALID 0 /*Use default 0 as invalid to detect program outliers*/
|
||||
#define LV_PROPERTY_TYPE_INT 1 /*int32_t type*/
|
||||
#define LV_PROPERTY_TYPE_PRECISE 2 /*lv_value_precise_t, int32_t or float depending on LV_USE_FLOAT*/
|
||||
#define LV_PROPERTY_TYPE_COLOR 3 /*ARGB8888 type*/
|
||||
#define LV_PROPERTY_TYPE_POINT 4 /*lv_point_t */
|
||||
#define LV_PROPERTY_TYPE_POINTER 5 /*void * pointer*/
|
||||
#define LV_PROPERTY_TYPE_IMGSRC 6 /*Special pointer for image*/
|
||||
#define LV_PROPERTY_TYPE_TEXT 7 /*Special pointer of char* */
|
||||
#define LV_PROPERTY_TYPE_OBJ 8 /*Special pointer of lv_obj_t* */
|
||||
#define LV_PROPERTY_TYPE_DISPLAY 9 /*Special pointer of lv_display_t* */
|
||||
#define LV_PROPERTY_TYPE_FONT 10 /*Special pointer of lv_font_t* */
|
||||
#define LV_PROPERTY_TYPE_BOOL 11 /*int32_t type*/
|
||||
|
||||
#define LV_PROPERTY_TYPE_SHIFT 28
|
||||
#define LV_PROPERTY_ID(clz, name, type, index) LV_PROPERTY_## clz ##_##name = (LV_PROPERTY_## clz ##_START + (index)) | ((type) << LV_PROPERTY_TYPE_SHIFT)
|
||||
|
||||
#define LV_PROPERTY_ID_TYPE(id) ((id) >> LV_PROPERTY_TYPE_SHIFT)
|
||||
#define LV_PROPERTY_ID_INDEX(id) ((id) & 0xfffffff)
|
||||
|
||||
/*Set properties from an array of lv_property_t*/
|
||||
#define LV_OBJ_SET_PROPERTY_ARRAY(obj, array) lv_obj_set_properties(obj, array, sizeof(array)/sizeof(array[0]))
|
||||
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Group of predefined widget ID start value.
|
||||
*/
|
||||
enum {
|
||||
LV_PROPERTY_ID_INVALID = 0,
|
||||
|
||||
/*ID 0x01 to 0xff are style ID, check lv_style_prop_t*/
|
||||
LV_PROPERTY_STYLE_START = 0x00,
|
||||
|
||||
LV_PROPERTY_ID_START = 0x0100, /*ID smaller than 0xff is style ID*/
|
||||
/*Define the property ID for every widget here. */
|
||||
LV_PROPERTY_OBJ_START = 0x0100, /* lv_obj.c */
|
||||
LV_PROPERTY_IMAGE_START = 0x0200, /* lv_image.c */
|
||||
LV_PROPERTY_LABEL_START = 0x0300, /* lv_label.c */
|
||||
LV_PROPERTY_KEYBOARD_START = 0x0400, /* lv_keyboard.c */
|
||||
LV_PROPERTY_TEXTAREA_START = 0x0500, /* lv_textarea.c */
|
||||
LV_PROPERTY_ROLLER_START = 0x0600, /* lv_roller.c */
|
||||
LV_PROPERTY_DROPDOWN_START = 0x0700, /* lv_dropdown.c */
|
||||
|
||||
/*Special ID, use it to extend ID and make sure it's unique and compile time determinant*/
|
||||
LV_PROPERTY_ID_BUILTIN_LAST = 0xffff, /*ID of 0x10000 ~ 0xfffffff is reserved for user*/
|
||||
|
||||
LV_PROPERTY_ID_ANY = 0x7ffffffe, /*Special ID used by lvgl to intercept all setter/getter call.*/
|
||||
};
|
||||
|
||||
struct lv_property_name_t {
|
||||
const char * name;
|
||||
lv_prop_id_t id;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
lv_prop_id_t id;
|
||||
union {
|
||||
int32_t num; /**< Number integer number (opacity, enums, booleans or "normal" numbers)*/
|
||||
bool enable; /**< booleans*/
|
||||
const void * ptr; /**< Constant pointers (font, cone text, etc)*/
|
||||
lv_color_t color; /**< Colors*/
|
||||
lv_value_precise_t precise; /**< float or int for precise value*/
|
||||
lv_point_t point; /**< Point*/
|
||||
struct {
|
||||
/**
|
||||
* Note that place struct member `style` at first place is intended.
|
||||
* `style` shares same memory with `num`, `ptr`, `color`.
|
||||
* So we set the style value directly without using `prop.style.num`.
|
||||
*
|
||||
* E.g.
|
||||
*
|
||||
* static const lv_property_t obj_pos_x = {
|
||||
* .id = LV_PROPERTY_STYLE_X,
|
||||
* .num = 123,
|
||||
* .selector = LV_STATE_PRESSED,
|
||||
* }
|
||||
*
|
||||
* instead of:
|
||||
* static const lv_property_t obj_pos_x = {
|
||||
* .id = LV_PROPERTY_STYLE_X,
|
||||
* .style.num = 123, // note this line.
|
||||
* .selector = LV_STATE_PRESSED,
|
||||
* }
|
||||
*/
|
||||
lv_style_value_t style; /**< Make sure it's the first element in struct. */
|
||||
uint32_t selector; /**< Style selector, lv_part_t | lv_state_t */
|
||||
};
|
||||
};
|
||||
} lv_property_t;
|
||||
|
||||
typedef struct {
|
||||
lv_prop_id_t id;
|
||||
|
||||
void * setter; /**< Callback used to set property. */
|
||||
void * getter; /**< Callback used to get property. */
|
||||
} lv_property_ops_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Set widget property.
|
||||
* @param obj pointer to an object
|
||||
* @param value The property value to set
|
||||
* @return return LV_RESULT_OK if success
|
||||
*/
|
||||
lv_result_t lv_obj_set_property(lv_obj_t * obj, const lv_property_t * value);
|
||||
|
||||
/**
|
||||
* Set multiple widget properties. Helper `LV_OBJ_SET_PROPERTY_ARRAY` can be used for constant property array.
|
||||
* @param obj pointer to an object
|
||||
* @param value The property value array to set
|
||||
* @param count The count of the property value array
|
||||
* @return return LV_RESULT_OK if success
|
||||
*/
|
||||
lv_result_t lv_obj_set_properties(lv_obj_t * obj, const lv_property_t * value, uint32_t count);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Read property value from object.
|
||||
* If id is a style property, the style selector is default to 0.
|
||||
* @param obj pointer to an object
|
||||
* @param id ID of which property to read
|
||||
* @return return the property value read. The returned property ID is set to `LV_PROPERTY_ID_INVALID` if failed.
|
||||
*/
|
||||
lv_property_t lv_obj_get_property(lv_obj_t * obj, lv_prop_id_t id);
|
||||
|
||||
/**
|
||||
* Read a style property value from object
|
||||
* @param obj pointer to an object
|
||||
* @param id ID of style property
|
||||
* @param selector selector for the style property.
|
||||
* @return return the property value read. The returned property ID is set to `LV_PROPERTY_ID_INVALID` if failed.
|
||||
*/
|
||||
lv_property_t lv_obj_get_style_property(lv_obj_t * obj, lv_prop_id_t id, uint32_t selector);
|
||||
|
||||
/**
|
||||
* Get the property ID by name recursively to base classes. Requires to enable `LV_USE_OBJ_PROPERTY_NAME`.
|
||||
* @param obj pointer to an object that has specified property or base class has.
|
||||
* @param name property name
|
||||
* @return property ID found or `LV_PROPERTY_ID_INVALID` if not found.
|
||||
*/
|
||||
lv_prop_id_t lv_obj_property_get_id(const lv_obj_t * obj, const char * name);
|
||||
|
||||
/**
|
||||
* Get the property ID by name without check base class recursively. Requires to enable `LV_USE_OBJ_PROPERTY_NAME`.
|
||||
* @param clz pointer to an object class that has specified property or base class has.
|
||||
* @param name property name
|
||||
* @return property ID found or `LV_PROPERTY_ID_INVALID` if not found.
|
||||
*/
|
||||
lv_prop_id_t lv_obj_class_property_get_id(const lv_obj_class_t * clz, const char * name);
|
||||
|
||||
/**
|
||||
* Get the style property ID by name. Requires to enable `LV_USE_OBJ_PROPERTY_NAME`.
|
||||
* @param name property name
|
||||
* @return property ID found or `LV_PROPERTY_ID_INVALID` if not found.
|
||||
*/
|
||||
lv_prop_id_t lv_style_property_get_id(const char * name);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#include "../widgets/property/lv_obj_property_names.h"
|
||||
#include "../widgets/property/lv_style_properties.h"
|
||||
|
||||
#endif /*LV_USE_OBJ_PROPERTY*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_OBJ_PROPERTY_H*/
|
||||
799
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_scroll.c
Normal file
799
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_scroll.c
Normal file
@@ -0,0 +1,799 @@
|
||||
/**
|
||||
* @file lv_obj_scroll.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_obj_scroll_private.h"
|
||||
#include "../misc/lv_anim_private.h"
|
||||
#include "lv_obj_private.h"
|
||||
#include "../indev/lv_indev.h"
|
||||
#include "../indev/lv_indev_scroll.h"
|
||||
#include "../display/lv_display.h"
|
||||
#include "../misc/lv_area.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define MY_CLASS (&lv_obj_class)
|
||||
#define SCROLL_ANIM_TIME_MIN 200 /*ms*/
|
||||
#define SCROLL_ANIM_TIME_MAX 400 /*ms*/
|
||||
#define SCROLLBAR_MIN_SIZE (LV_DPX(10))
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void scroll_x_anim(void * obj, int32_t v);
|
||||
static void scroll_y_anim(void * obj, int32_t v);
|
||||
static void scroll_end_cb(lv_anim_t * a);
|
||||
static void scroll_area_into_view(const lv_area_t * area, lv_obj_t * child, lv_point_t * scroll_value,
|
||||
lv_anim_enable_t anim_en);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
void lv_obj_set_scrollbar_mode(lv_obj_t * obj, lv_scrollbar_mode_t mode)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_obj_allocate_spec_attr(obj);
|
||||
|
||||
if(obj->spec_attr->scrollbar_mode == mode) return;
|
||||
obj->spec_attr->scrollbar_mode = mode;
|
||||
lv_obj_invalidate(obj);
|
||||
}
|
||||
|
||||
void lv_obj_set_scroll_dir(lv_obj_t * obj, lv_dir_t dir)
|
||||
{
|
||||
lv_obj_allocate_spec_attr(obj);
|
||||
|
||||
if(dir != obj->spec_attr->scroll_dir) {
|
||||
obj->spec_attr->scroll_dir = dir;
|
||||
}
|
||||
}
|
||||
|
||||
void lv_obj_set_scroll_snap_x(lv_obj_t * obj, lv_scroll_snap_t align)
|
||||
{
|
||||
lv_obj_allocate_spec_attr(obj);
|
||||
obj->spec_attr->scroll_snap_x = align;
|
||||
}
|
||||
|
||||
void lv_obj_set_scroll_snap_y(lv_obj_t * obj, lv_scroll_snap_t align)
|
||||
{
|
||||
lv_obj_allocate_spec_attr(obj);
|
||||
obj->spec_attr->scroll_snap_y = align;
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
lv_scrollbar_mode_t lv_obj_get_scrollbar_mode(const lv_obj_t * obj)
|
||||
{
|
||||
if(obj->spec_attr) return (lv_scrollbar_mode_t) obj->spec_attr->scrollbar_mode;
|
||||
else return LV_SCROLLBAR_MODE_AUTO;
|
||||
}
|
||||
|
||||
lv_dir_t lv_obj_get_scroll_dir(const lv_obj_t * obj)
|
||||
{
|
||||
if(obj->spec_attr) return (lv_dir_t) obj->spec_attr->scroll_dir;
|
||||
else return LV_DIR_ALL;
|
||||
}
|
||||
|
||||
lv_scroll_snap_t lv_obj_get_scroll_snap_x(const lv_obj_t * obj)
|
||||
{
|
||||
if(obj->spec_attr) return (lv_scroll_snap_t) obj->spec_attr->scroll_snap_x;
|
||||
else return LV_SCROLL_SNAP_NONE;
|
||||
}
|
||||
|
||||
lv_scroll_snap_t lv_obj_get_scroll_snap_y(const lv_obj_t * obj)
|
||||
{
|
||||
if(obj->spec_attr) return (lv_scroll_snap_t) obj->spec_attr->scroll_snap_y;
|
||||
else return LV_SCROLL_SNAP_NONE;
|
||||
}
|
||||
|
||||
int32_t lv_obj_get_scroll_x(const lv_obj_t * obj)
|
||||
{
|
||||
if(obj->spec_attr == NULL) return 0;
|
||||
return -obj->spec_attr->scroll.x;
|
||||
}
|
||||
|
||||
int32_t lv_obj_get_scroll_y(const lv_obj_t * obj)
|
||||
{
|
||||
if(obj->spec_attr == NULL) return 0;
|
||||
return -obj->spec_attr->scroll.y;
|
||||
}
|
||||
|
||||
int32_t lv_obj_get_scroll_top(lv_obj_t * obj)
|
||||
{
|
||||
if(obj->spec_attr == NULL) return 0;
|
||||
return -obj->spec_attr->scroll.y;
|
||||
}
|
||||
|
||||
int32_t lv_obj_get_scroll_bottom(lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
int32_t child_res = LV_COORD_MIN;
|
||||
uint32_t i;
|
||||
uint32_t child_cnt = lv_obj_get_child_count(obj);
|
||||
for(i = 0; i < child_cnt; i++) {
|
||||
lv_obj_t * child = obj->spec_attr->children[i];
|
||||
if(lv_obj_has_flag_any(child, LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_FLOATING)) continue;
|
||||
|
||||
int32_t tmp_y = child->coords.y2 + lv_obj_get_style_margin_bottom(child, LV_PART_MAIN);
|
||||
child_res = LV_MAX(child_res, tmp_y);
|
||||
}
|
||||
|
||||
int32_t space_top = lv_obj_get_style_space_top(obj, LV_PART_MAIN);
|
||||
int32_t space_bottom = lv_obj_get_style_space_bottom(obj, LV_PART_MAIN);
|
||||
|
||||
if(child_res != LV_COORD_MIN) {
|
||||
child_res -= (obj->coords.y2 - space_bottom);
|
||||
}
|
||||
|
||||
int32_t self_h = lv_obj_get_self_height(obj);
|
||||
self_h = self_h - (lv_obj_get_height(obj) - space_top - space_bottom);
|
||||
self_h -= lv_obj_get_scroll_y(obj);
|
||||
return LV_MAX(child_res, self_h);
|
||||
}
|
||||
|
||||
int32_t lv_obj_get_scroll_left(lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
/*Normally can't scroll the object out on the left.
|
||||
*So simply use the current scroll position as "left size"*/
|
||||
if(lv_obj_get_style_base_dir(obj, LV_PART_MAIN) != LV_BASE_DIR_RTL) {
|
||||
if(obj->spec_attr == NULL) return 0;
|
||||
return -obj->spec_attr->scroll.x;
|
||||
}
|
||||
|
||||
/*With RTL base direction scrolling the left is normal so find the left most coordinate*/
|
||||
int32_t space_right = lv_obj_get_style_space_right(obj, LV_PART_MAIN);
|
||||
int32_t space_left = lv_obj_get_style_space_left(obj, LV_PART_MAIN);
|
||||
|
||||
int32_t child_res = 0;
|
||||
|
||||
uint32_t i;
|
||||
int32_t x1 = LV_COORD_MAX;
|
||||
uint32_t child_cnt = lv_obj_get_child_count(obj);
|
||||
for(i = 0; i < child_cnt; i++) {
|
||||
lv_obj_t * child = obj->spec_attr->children[i];
|
||||
if(lv_obj_has_flag_any(child, LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_FLOATING)) continue;
|
||||
|
||||
int32_t tmp_x = child->coords.x1 - lv_obj_get_style_margin_left(child, LV_PART_MAIN);
|
||||
x1 = LV_MIN(x1, tmp_x);
|
||||
}
|
||||
|
||||
if(x1 != LV_COORD_MAX) {
|
||||
child_res = x1;
|
||||
child_res = (obj->coords.x1 + space_left) - child_res;
|
||||
}
|
||||
else {
|
||||
child_res = LV_COORD_MIN;
|
||||
}
|
||||
|
||||
int32_t self_w = lv_obj_get_self_width(obj);
|
||||
self_w = self_w - (lv_obj_get_width(obj) - space_right - space_left);
|
||||
self_w += lv_obj_get_scroll_x(obj);
|
||||
|
||||
return LV_MAX(child_res, self_w);
|
||||
}
|
||||
|
||||
int32_t lv_obj_get_scroll_right(lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
/*With RTL base dir can't scroll to the object out on the right.
|
||||
*So simply use the current scroll position as "right size"*/
|
||||
if(lv_obj_get_style_base_dir(obj, LV_PART_MAIN) == LV_BASE_DIR_RTL) {
|
||||
if(obj->spec_attr == NULL) return 0;
|
||||
return obj->spec_attr->scroll.x;
|
||||
}
|
||||
|
||||
/*With other base direction (LTR) scrolling to the right is normal so find the right most coordinate*/
|
||||
int32_t child_res = LV_COORD_MIN;
|
||||
uint32_t i;
|
||||
uint32_t child_cnt = lv_obj_get_child_count(obj);
|
||||
for(i = 0; i < child_cnt; i++) {
|
||||
lv_obj_t * child = obj->spec_attr->children[i];
|
||||
if(lv_obj_has_flag_any(child, LV_OBJ_FLAG_HIDDEN | LV_OBJ_FLAG_FLOATING)) continue;
|
||||
|
||||
int32_t tmp_x = child->coords.x2 + lv_obj_get_style_margin_right(child, LV_PART_MAIN);
|
||||
child_res = LV_MAX(child_res, tmp_x);
|
||||
}
|
||||
|
||||
int32_t space_right = lv_obj_get_style_space_right(obj, LV_PART_MAIN);
|
||||
int32_t space_left = lv_obj_get_style_space_left(obj, LV_PART_MAIN);
|
||||
|
||||
if(child_res != LV_COORD_MIN) {
|
||||
child_res -= (obj->coords.x2 - space_right);
|
||||
}
|
||||
|
||||
int32_t self_w;
|
||||
self_w = lv_obj_get_self_width(obj);
|
||||
self_w = self_w - (lv_obj_get_width(obj) - space_right - space_left);
|
||||
self_w -= lv_obj_get_scroll_x(obj);
|
||||
return LV_MAX(child_res, self_w);
|
||||
}
|
||||
|
||||
void lv_obj_get_scroll_end(lv_obj_t * obj, lv_point_t * end)
|
||||
{
|
||||
lv_anim_t * a;
|
||||
a = lv_anim_get(obj, scroll_x_anim);
|
||||
end->x = a ? -a->end_value : lv_obj_get_scroll_x(obj);
|
||||
|
||||
a = lv_anim_get(obj, scroll_y_anim);
|
||||
end->y = a ? -a->end_value : lv_obj_get_scroll_y(obj);
|
||||
}
|
||||
|
||||
/*=====================
|
||||
* Other functions
|
||||
*====================*/
|
||||
|
||||
void lv_obj_scroll_by_bounded(lv_obj_t * obj, int32_t dx, int32_t dy, lv_anim_enable_t anim_en)
|
||||
{
|
||||
if(dx == 0 && dy == 0) return;
|
||||
|
||||
/*We need to know the final sizes for bound check*/
|
||||
lv_obj_update_layout(obj);
|
||||
|
||||
/*Don't let scroll more than naturally possible by the size of the content*/
|
||||
int32_t x_current = -lv_obj_get_scroll_x(obj);
|
||||
int32_t x_bounded = x_current + dx;
|
||||
|
||||
if(lv_obj_get_style_base_dir(obj, LV_PART_MAIN) != LV_BASE_DIR_RTL) {
|
||||
if(x_bounded > 0) x_bounded = 0;
|
||||
if(x_bounded < 0) {
|
||||
int32_t scroll_max = lv_obj_get_scroll_left(obj) + lv_obj_get_scroll_right(obj);
|
||||
if(scroll_max < 0) scroll_max = 0;
|
||||
|
||||
if(x_bounded < -scroll_max) x_bounded = -scroll_max;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(x_bounded < 0) x_bounded = 0;
|
||||
if(x_bounded > 0) {
|
||||
int32_t scroll_max = lv_obj_get_scroll_left(obj) + lv_obj_get_scroll_right(obj);
|
||||
if(scroll_max < 0) scroll_max = 0;
|
||||
|
||||
if(x_bounded > scroll_max) x_bounded = scroll_max;
|
||||
}
|
||||
}
|
||||
|
||||
/*Don't let scroll more than naturally possible by the size of the content*/
|
||||
int32_t y_current = -lv_obj_get_scroll_y(obj);
|
||||
int32_t y_bounded = y_current + dy;
|
||||
|
||||
if(y_bounded > 0) y_bounded = 0;
|
||||
if(y_bounded < 0) {
|
||||
int32_t scroll_max = lv_obj_get_scroll_top(obj) + lv_obj_get_scroll_bottom(obj);
|
||||
if(scroll_max < 0) scroll_max = 0;
|
||||
if(y_bounded < -scroll_max) y_bounded = -scroll_max;
|
||||
}
|
||||
|
||||
dx = x_bounded - x_current;
|
||||
dy = y_bounded - y_current;
|
||||
if(dx || dy) {
|
||||
lv_obj_scroll_by(obj, dx, dy, anim_en);
|
||||
}
|
||||
}
|
||||
|
||||
void lv_obj_scroll_by(lv_obj_t * obj, int32_t dx, int32_t dy, lv_anim_enable_t anim_en)
|
||||
{
|
||||
if(dx == 0 && dy == 0) return;
|
||||
if(anim_en == LV_ANIM_ON) {
|
||||
lv_display_t * d = lv_obj_get_display(obj);
|
||||
lv_anim_t a;
|
||||
lv_anim_init(&a);
|
||||
lv_anim_set_var(&a, obj);
|
||||
lv_anim_set_deleted_cb(&a, scroll_end_cb);
|
||||
|
||||
if(dx) {
|
||||
uint32_t t = lv_anim_speed_clamped((lv_display_get_horizontal_resolution(d)) >> 1, SCROLL_ANIM_TIME_MIN,
|
||||
SCROLL_ANIM_TIME_MAX);
|
||||
lv_anim_set_duration(&a, t);
|
||||
int32_t sx = lv_obj_get_scroll_x(obj);
|
||||
lv_anim_set_values(&a, -sx, -sx + dx);
|
||||
lv_anim_set_exec_cb(&a, scroll_x_anim);
|
||||
lv_anim_set_path_cb(&a, lv_anim_path_ease_out);
|
||||
|
||||
lv_result_t res;
|
||||
res = lv_obj_send_event(obj, LV_EVENT_SCROLL_BEGIN, &a);
|
||||
if(res != LV_RESULT_OK) return;
|
||||
lv_anim_start(&a);
|
||||
}
|
||||
|
||||
if(dy) {
|
||||
uint32_t t = lv_anim_speed_clamped((lv_display_get_vertical_resolution(d)) >> 1, SCROLL_ANIM_TIME_MIN,
|
||||
SCROLL_ANIM_TIME_MAX);
|
||||
lv_anim_set_duration(&a, t);
|
||||
int32_t sy = lv_obj_get_scroll_y(obj);
|
||||
lv_anim_set_values(&a, -sy, -sy + dy);
|
||||
lv_anim_set_exec_cb(&a, scroll_y_anim);
|
||||
lv_anim_set_path_cb(&a, lv_anim_path_ease_out);
|
||||
|
||||
lv_result_t res;
|
||||
res = lv_obj_send_event(obj, LV_EVENT_SCROLL_BEGIN, &a);
|
||||
if(res != LV_RESULT_OK) return;
|
||||
lv_anim_start(&a);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*Remove pending animations*/
|
||||
lv_anim_delete(obj, scroll_y_anim);
|
||||
lv_anim_delete(obj, scroll_x_anim);
|
||||
|
||||
lv_result_t res;
|
||||
res = lv_obj_send_event(obj, LV_EVENT_SCROLL_BEGIN, NULL);
|
||||
if(res != LV_RESULT_OK) return;
|
||||
|
||||
res = lv_obj_scroll_by_raw(obj, dx, dy);
|
||||
if(res != LV_RESULT_OK) return;
|
||||
|
||||
res = lv_obj_send_event(obj, LV_EVENT_SCROLL_END, NULL);
|
||||
if(res != LV_RESULT_OK) return;
|
||||
}
|
||||
}
|
||||
|
||||
void lv_obj_scroll_to(lv_obj_t * obj, int32_t x, int32_t y, lv_anim_enable_t anim_en)
|
||||
{
|
||||
lv_obj_scroll_to_x(obj, x, anim_en);
|
||||
lv_obj_scroll_to_y(obj, y, anim_en);
|
||||
}
|
||||
|
||||
void lv_obj_scroll_to_x(lv_obj_t * obj, int32_t x, lv_anim_enable_t anim_en)
|
||||
{
|
||||
lv_anim_delete(obj, scroll_x_anim);
|
||||
|
||||
int32_t scroll_x = lv_obj_get_scroll_x(obj);
|
||||
int32_t diff = -x + scroll_x;
|
||||
|
||||
lv_obj_scroll_by_bounded(obj, diff, 0, anim_en);
|
||||
}
|
||||
|
||||
void lv_obj_scroll_to_y(lv_obj_t * obj, int32_t y, lv_anim_enable_t anim_en)
|
||||
{
|
||||
lv_anim_delete(obj, scroll_y_anim);
|
||||
|
||||
int32_t scroll_y = lv_obj_get_scroll_y(obj);
|
||||
int32_t diff = -y + scroll_y;
|
||||
|
||||
lv_obj_scroll_by_bounded(obj, 0, diff, anim_en);
|
||||
}
|
||||
|
||||
void lv_obj_scroll_to_view(lv_obj_t * obj, lv_anim_enable_t anim_en)
|
||||
{
|
||||
/*Be sure the screens layout is correct*/
|
||||
lv_obj_update_layout(obj);
|
||||
|
||||
lv_point_t p = {0, 0};
|
||||
scroll_area_into_view(&obj->coords, obj, &p, anim_en);
|
||||
}
|
||||
|
||||
void lv_obj_scroll_to_view_recursive(lv_obj_t * obj, lv_anim_enable_t anim_en)
|
||||
{
|
||||
/*Be sure the screens layout is correct*/
|
||||
lv_obj_update_layout(obj);
|
||||
|
||||
lv_point_t p = {0, 0};
|
||||
lv_obj_t * child = obj;
|
||||
lv_obj_t * parent = lv_obj_get_parent(child);
|
||||
while(parent) {
|
||||
scroll_area_into_view(&obj->coords, child, &p, anim_en);
|
||||
child = parent;
|
||||
parent = lv_obj_get_parent(parent);
|
||||
}
|
||||
}
|
||||
|
||||
lv_result_t lv_obj_scroll_by_raw(lv_obj_t * obj, int32_t x, int32_t y)
|
||||
{
|
||||
if(x == 0 && y == 0) return LV_RESULT_OK;
|
||||
|
||||
lv_obj_allocate_spec_attr(obj);
|
||||
|
||||
obj->spec_attr->scroll.x += x;
|
||||
obj->spec_attr->scroll.y += y;
|
||||
|
||||
lv_obj_move_children_by(obj, x, y, true);
|
||||
lv_result_t res = lv_obj_send_event(obj, LV_EVENT_SCROLL, NULL);
|
||||
if(res != LV_RESULT_OK) return res;
|
||||
lv_obj_invalidate(obj);
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
bool lv_obj_is_scrolling(const lv_obj_t * obj)
|
||||
{
|
||||
lv_indev_t * indev = lv_indev_get_next(NULL);
|
||||
while(indev) {
|
||||
if(lv_indev_get_scroll_obj(indev) == obj) return true;
|
||||
indev = lv_indev_get_next(indev);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void lv_obj_update_snap(lv_obj_t * obj, lv_anim_enable_t anim_en)
|
||||
{
|
||||
lv_obj_update_layout(obj);
|
||||
lv_point_t p;
|
||||
lv_indev_scroll_get_snap_dist(obj, &p);
|
||||
if(p.x == LV_COORD_MAX || p.x == LV_COORD_MIN) p.x = 0;
|
||||
if(p.y == LV_COORD_MAX || p.y == LV_COORD_MIN) p.y = 0;
|
||||
lv_obj_scroll_by(obj, p.x, p.y, anim_en);
|
||||
}
|
||||
|
||||
void lv_obj_get_scrollbar_area(lv_obj_t * obj, lv_area_t * hor_area, lv_area_t * ver_area)
|
||||
{
|
||||
lv_area_set(hor_area, 0, 0, -1, -1);
|
||||
lv_area_set(ver_area, 0, 0, -1, -1);
|
||||
|
||||
if(lv_obj_has_flag(obj, LV_OBJ_FLAG_SCROLLABLE) == false) return;
|
||||
|
||||
lv_scrollbar_mode_t sm = lv_obj_get_scrollbar_mode(obj);
|
||||
if(sm == LV_SCROLLBAR_MODE_OFF) return;
|
||||
|
||||
/*If there is no indev scrolling this object but `mode==active` return*/
|
||||
lv_indev_t * indev = lv_indev_get_next(NULL);
|
||||
if(sm == LV_SCROLLBAR_MODE_ACTIVE) {
|
||||
while(indev) {
|
||||
if(lv_indev_get_scroll_obj(indev) == obj) break;
|
||||
indev = lv_indev_get_next(indev);
|
||||
}
|
||||
if(indev == NULL) return;
|
||||
}
|
||||
|
||||
int32_t st = lv_obj_get_scroll_top(obj);
|
||||
int32_t sb = lv_obj_get_scroll_bottom(obj);
|
||||
int32_t sl = lv_obj_get_scroll_left(obj);
|
||||
int32_t sr = lv_obj_get_scroll_right(obj);
|
||||
|
||||
lv_dir_t dir = lv_obj_get_scroll_dir(obj);
|
||||
|
||||
bool ver_draw = false;
|
||||
if((dir & LV_DIR_VER) &&
|
||||
((sm == LV_SCROLLBAR_MODE_ON) ||
|
||||
(sm == LV_SCROLLBAR_MODE_AUTO && (st > 0 || sb > 0)) ||
|
||||
(sm == LV_SCROLLBAR_MODE_ACTIVE && lv_indev_get_scroll_dir(indev) == LV_DIR_VER))) {
|
||||
ver_draw = true;
|
||||
}
|
||||
|
||||
bool hor_draw = false;
|
||||
if((dir & LV_DIR_HOR) &&
|
||||
((sm == LV_SCROLLBAR_MODE_ON) ||
|
||||
(sm == LV_SCROLLBAR_MODE_AUTO && (sl > 0 || sr > 0)) ||
|
||||
(sm == LV_SCROLLBAR_MODE_ACTIVE && lv_indev_get_scroll_dir(indev) == LV_DIR_HOR))) {
|
||||
hor_draw = true;
|
||||
}
|
||||
|
||||
if(!hor_draw && !ver_draw) return;
|
||||
|
||||
bool rtl = lv_obj_get_style_base_dir(obj, LV_PART_SCROLLBAR) == LV_BASE_DIR_RTL;
|
||||
|
||||
int32_t top_space = lv_obj_get_style_pad_top(obj, LV_PART_SCROLLBAR);
|
||||
int32_t bottom_space = lv_obj_get_style_pad_bottom(obj, LV_PART_SCROLLBAR);
|
||||
int32_t left_space = lv_obj_get_style_pad_left(obj, LV_PART_SCROLLBAR);
|
||||
int32_t right_space = lv_obj_get_style_pad_right(obj, LV_PART_SCROLLBAR);
|
||||
int32_t thickness = lv_obj_get_style_width(obj, LV_PART_SCROLLBAR);
|
||||
|
||||
int32_t obj_h = lv_obj_get_height(obj);
|
||||
int32_t obj_w = lv_obj_get_width(obj);
|
||||
|
||||
/*Space required for the vertical and horizontal scrollbars*/
|
||||
int32_t ver_reg_space = ver_draw ? thickness : 0;
|
||||
int32_t hor_req_space = hor_draw ? thickness : 0;
|
||||
int32_t rem;
|
||||
|
||||
if(lv_obj_get_style_bg_opa(obj, LV_PART_SCROLLBAR) < LV_OPA_MIN &&
|
||||
lv_obj_get_style_border_opa(obj, LV_PART_SCROLLBAR) < LV_OPA_MIN) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*Draw vertical scrollbar if the mode is ON or can be scrolled in this direction*/
|
||||
int32_t content_h = obj_h + st + sb;
|
||||
if(ver_draw && content_h) {
|
||||
ver_area->y1 = obj->coords.y1;
|
||||
ver_area->y2 = obj->coords.y2;
|
||||
if(rtl) {
|
||||
ver_area->x1 = obj->coords.x1 + left_space;
|
||||
ver_area->x2 = ver_area->x1 + thickness - 1;
|
||||
}
|
||||
else {
|
||||
ver_area->x2 = obj->coords.x2 - right_space;
|
||||
ver_area->x1 = ver_area->x2 - thickness + 1;
|
||||
}
|
||||
|
||||
int32_t sb_h = ((obj_h - top_space - bottom_space - hor_req_space) * obj_h) / content_h;
|
||||
sb_h = LV_MAX(sb_h, SCROLLBAR_MIN_SIZE);
|
||||
rem = (obj_h - top_space - bottom_space - hor_req_space) -
|
||||
sb_h; /*Remaining size from the scrollbar track that is not the scrollbar itself*/
|
||||
int32_t scroll_h = content_h - obj_h; /*The size of the content which can be really scrolled*/
|
||||
if(scroll_h <= 0) {
|
||||
ver_area->y1 = obj->coords.y1 + top_space;
|
||||
ver_area->y2 = obj->coords.y2 - bottom_space - hor_req_space - 1;
|
||||
}
|
||||
else {
|
||||
int32_t sb_y = (rem * sb) / scroll_h;
|
||||
sb_y = rem - sb_y;
|
||||
|
||||
ver_area->y1 = obj->coords.y1 + sb_y + top_space;
|
||||
ver_area->y2 = ver_area->y1 + sb_h - 1;
|
||||
if(ver_area->y1 < obj->coords.y1 + top_space) {
|
||||
ver_area->y1 = obj->coords.y1 + top_space;
|
||||
if(ver_area->y1 + SCROLLBAR_MIN_SIZE > ver_area->y2) {
|
||||
ver_area->y2 = ver_area->y1 + SCROLLBAR_MIN_SIZE;
|
||||
}
|
||||
}
|
||||
if(ver_area->y2 > obj->coords.y2 - hor_req_space - bottom_space) {
|
||||
ver_area->y2 = obj->coords.y2 - hor_req_space - bottom_space;
|
||||
if(ver_area->y2 - SCROLLBAR_MIN_SIZE < ver_area->y1) {
|
||||
ver_area->y1 = ver_area->y2 - SCROLLBAR_MIN_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*Draw horizontal scrollbar if the mode is ON or can be scrolled in this direction*/
|
||||
int32_t content_w = obj_w + sl + sr;
|
||||
if(hor_draw && content_w) {
|
||||
hor_area->y2 = obj->coords.y2 - bottom_space;
|
||||
hor_area->y1 = hor_area->y2 - thickness + 1;
|
||||
hor_area->x1 = obj->coords.x1;
|
||||
hor_area->x2 = obj->coords.x2;
|
||||
|
||||
int32_t sb_w = ((obj_w - left_space - right_space - ver_reg_space) * obj_w) / content_w;
|
||||
sb_w = LV_MAX(sb_w, SCROLLBAR_MIN_SIZE);
|
||||
rem = (obj_w - left_space - right_space - ver_reg_space) -
|
||||
sb_w; /*Remaining size from the scrollbar track that is not the scrollbar itself*/
|
||||
int32_t scroll_w = content_w - obj_w; /*The size of the content which can be really scrolled*/
|
||||
if(scroll_w <= 0) {
|
||||
if(rtl) {
|
||||
hor_area->x1 = obj->coords.x1 + left_space + ver_reg_space - 1;
|
||||
hor_area->x2 = obj->coords.x2 - right_space;
|
||||
}
|
||||
else {
|
||||
hor_area->x1 = obj->coords.x1 + left_space;
|
||||
hor_area->x2 = obj->coords.x2 - right_space - ver_reg_space - 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int32_t sb_x = (rem * sr) / scroll_w;
|
||||
sb_x = rem - sb_x;
|
||||
|
||||
if(rtl) {
|
||||
hor_area->x1 = obj->coords.x1 + sb_x + left_space + ver_reg_space;
|
||||
hor_area->x2 = hor_area->x1 + sb_w - 1;
|
||||
if(hor_area->x1 < obj->coords.x1 + left_space + ver_reg_space) {
|
||||
hor_area->x1 = obj->coords.x1 + left_space + ver_reg_space;
|
||||
if(hor_area->x1 + SCROLLBAR_MIN_SIZE > hor_area->x2) {
|
||||
hor_area->x2 = hor_area->x1 + SCROLLBAR_MIN_SIZE;
|
||||
}
|
||||
}
|
||||
if(hor_area->x2 > obj->coords.x2 - right_space) {
|
||||
hor_area->x2 = obj->coords.x2 - right_space;
|
||||
if(hor_area->x2 - SCROLLBAR_MIN_SIZE < hor_area->x1) {
|
||||
hor_area->x1 = hor_area->x2 - SCROLLBAR_MIN_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
hor_area->x1 = obj->coords.x1 + sb_x + left_space;
|
||||
hor_area->x2 = hor_area->x1 + sb_w - 1;
|
||||
if(hor_area->x1 < obj->coords.x1 + left_space) {
|
||||
hor_area->x1 = obj->coords.x1 + left_space;
|
||||
if(hor_area->x1 + SCROLLBAR_MIN_SIZE > hor_area->x2) {
|
||||
hor_area->x2 = hor_area->x1 + SCROLLBAR_MIN_SIZE;
|
||||
}
|
||||
}
|
||||
if(hor_area->x2 > obj->coords.x2 - ver_reg_space - right_space) {
|
||||
hor_area->x2 = obj->coords.x2 - ver_reg_space - right_space;
|
||||
if(hor_area->x2 - SCROLLBAR_MIN_SIZE < hor_area->x1) {
|
||||
hor_area->x1 = hor_area->x2 - SCROLLBAR_MIN_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void lv_obj_scrollbar_invalidate(lv_obj_t * obj)
|
||||
{
|
||||
lv_area_t hor_area;
|
||||
lv_area_t ver_area;
|
||||
lv_obj_get_scrollbar_area(obj, &hor_area, &ver_area);
|
||||
|
||||
if(lv_area_get_size(&hor_area) <= 0 && lv_area_get_size(&ver_area) <= 0) return;
|
||||
|
||||
if(lv_area_get_size(&hor_area) > 0) lv_obj_invalidate_area(obj, &hor_area);
|
||||
if(lv_area_get_size(&ver_area) > 0) lv_obj_invalidate_area(obj, &ver_area);
|
||||
}
|
||||
|
||||
void lv_obj_readjust_scroll(lv_obj_t * obj, lv_anim_enable_t anim_en)
|
||||
{
|
||||
/*Be sure the bottom side is not remains scrolled in*/
|
||||
/*With snapping the content can't be scrolled in*/
|
||||
if(lv_obj_get_scroll_snap_y(obj) == LV_SCROLL_SNAP_NONE) {
|
||||
int32_t st = lv_obj_get_scroll_top(obj);
|
||||
int32_t sb = lv_obj_get_scroll_bottom(obj);
|
||||
if(sb < 0 && st > 0) {
|
||||
sb = LV_MIN(st, -sb);
|
||||
lv_obj_scroll_by(obj, 0, sb, anim_en);
|
||||
}
|
||||
}
|
||||
|
||||
if(lv_obj_get_scroll_snap_x(obj) == LV_SCROLL_SNAP_NONE) {
|
||||
int32_t sl = lv_obj_get_scroll_left(obj);
|
||||
int32_t sr = lv_obj_get_scroll_right(obj);
|
||||
if(lv_obj_get_style_base_dir(obj, LV_PART_MAIN) != LV_BASE_DIR_RTL) {
|
||||
/*Be sure the left side is not remains scrolled in*/
|
||||
if(sr < 0 && sl > 0) {
|
||||
sr = LV_MIN(sl, -sr);
|
||||
lv_obj_scroll_by(obj, sr, 0, anim_en);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*Be sure the right side is not remains scrolled in*/
|
||||
if(sl < 0 && sr > 0) {
|
||||
sr = LV_MIN(sr, -sl);
|
||||
lv_obj_scroll_by(obj, sl, 0, anim_en);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void scroll_x_anim(void * obj, int32_t v)
|
||||
{
|
||||
lv_obj_scroll_by_raw(obj, v + lv_obj_get_scroll_x(obj), 0);
|
||||
}
|
||||
|
||||
static void scroll_y_anim(void * obj, int32_t v)
|
||||
{
|
||||
lv_obj_scroll_by_raw(obj, 0, v + lv_obj_get_scroll_y(obj));
|
||||
}
|
||||
|
||||
static void scroll_end_cb(lv_anim_t * a)
|
||||
{
|
||||
/*Do not sent END event if there wasn't a BEGIN*/
|
||||
if(a->start_cb_called) lv_obj_send_event(a->var, LV_EVENT_SCROLL_END, NULL);
|
||||
}
|
||||
|
||||
static void scroll_area_into_view(const lv_area_t * area, lv_obj_t * child, lv_point_t * scroll_value,
|
||||
lv_anim_enable_t anim_en)
|
||||
{
|
||||
lv_obj_t * parent = lv_obj_get_parent(child);
|
||||
if(!lv_obj_has_flag(parent, LV_OBJ_FLAG_SCROLLABLE)) return;
|
||||
|
||||
lv_dir_t scroll_dir = lv_obj_get_scroll_dir(parent);
|
||||
int32_t snap_goal = 0;
|
||||
int32_t act = 0;
|
||||
const lv_area_t * area_tmp;
|
||||
|
||||
int32_t y_scroll = 0;
|
||||
lv_scroll_snap_t snap_y = lv_obj_get_scroll_snap_y(parent);
|
||||
if(snap_y != LV_SCROLL_SNAP_NONE) area_tmp = &child->coords;
|
||||
else area_tmp = area;
|
||||
|
||||
int32_t stop = lv_obj_get_style_space_top(parent, LV_PART_MAIN);
|
||||
int32_t sbottom = lv_obj_get_style_space_bottom(parent, LV_PART_MAIN);
|
||||
int32_t top_diff = parent->coords.y1 + stop - area_tmp->y1 - scroll_value->y;
|
||||
int32_t bottom_diff = -(parent->coords.y2 - sbottom - area_tmp->y2 - scroll_value->y);
|
||||
int32_t parent_h = lv_obj_get_height(parent) - stop - sbottom;
|
||||
if((top_diff >= 0 && bottom_diff >= 0)) y_scroll = 0;
|
||||
else if(top_diff > 0) {
|
||||
y_scroll = top_diff;
|
||||
/*Do not let scrolling in*/
|
||||
int32_t st = lv_obj_get_scroll_top(parent);
|
||||
if(st - y_scroll < 0) y_scroll = 0;
|
||||
}
|
||||
else if(bottom_diff > 0) {
|
||||
y_scroll = -bottom_diff;
|
||||
/*Do not let scrolling in*/
|
||||
int32_t sb = lv_obj_get_scroll_bottom(parent);
|
||||
if(sb + y_scroll < 0) y_scroll = 0;
|
||||
}
|
||||
|
||||
switch(snap_y) {
|
||||
case LV_SCROLL_SNAP_START:
|
||||
snap_goal = parent->coords.y1 + stop;
|
||||
act = area_tmp->y1 + y_scroll;
|
||||
y_scroll += snap_goal - act;
|
||||
break;
|
||||
case LV_SCROLL_SNAP_END:
|
||||
snap_goal = parent->coords.y2 - sbottom;
|
||||
act = area_tmp->y2 + y_scroll;
|
||||
y_scroll += snap_goal - act;
|
||||
break;
|
||||
case LV_SCROLL_SNAP_CENTER:
|
||||
snap_goal = parent->coords.y1 + stop + parent_h / 2;
|
||||
act = lv_area_get_height(area_tmp) / 2 + area_tmp->y1 + y_scroll;
|
||||
y_scroll += snap_goal - act;
|
||||
break;
|
||||
case LV_SCROLL_SNAP_NONE:
|
||||
break;
|
||||
}
|
||||
|
||||
int32_t x_scroll = 0;
|
||||
lv_scroll_snap_t snap_x = lv_obj_get_scroll_snap_x(parent);
|
||||
if(snap_x != LV_SCROLL_SNAP_NONE) area_tmp = &child->coords;
|
||||
else area_tmp = area;
|
||||
|
||||
int32_t sleft = lv_obj_get_style_space_left(parent, LV_PART_MAIN);
|
||||
int32_t sright = lv_obj_get_style_space_right(parent, LV_PART_MAIN);
|
||||
int32_t left_diff = parent->coords.x1 + sleft - area_tmp->x1 - scroll_value->x;
|
||||
int32_t right_diff = -(parent->coords.x2 - sright - area_tmp->x2 - scroll_value->x);
|
||||
if((left_diff >= 0 && right_diff >= 0)) x_scroll = 0;
|
||||
else if(left_diff > 0) {
|
||||
x_scroll = left_diff;
|
||||
/*Do not let scrolling in*/
|
||||
int32_t sl = lv_obj_get_scroll_left(parent);
|
||||
if(sl - x_scroll < 0) x_scroll = 0;
|
||||
}
|
||||
else if(right_diff > 0) {
|
||||
x_scroll = -right_diff;
|
||||
/*Do not let scrolling in*/
|
||||
int32_t sr = lv_obj_get_scroll_right(parent);
|
||||
if(sr + x_scroll < 0) x_scroll = 0;
|
||||
}
|
||||
|
||||
int32_t parent_w = lv_obj_get_width(parent) - sleft - sright;
|
||||
switch(snap_x) {
|
||||
case LV_SCROLL_SNAP_START:
|
||||
snap_goal = parent->coords.x1 + sleft;
|
||||
act = area_tmp->x1 + x_scroll;
|
||||
x_scroll += snap_goal - act;
|
||||
break;
|
||||
case LV_SCROLL_SNAP_END:
|
||||
snap_goal = parent->coords.x2 - sright;
|
||||
act = area_tmp->x2 + x_scroll;
|
||||
x_scroll += snap_goal - act;
|
||||
break;
|
||||
case LV_SCROLL_SNAP_CENTER:
|
||||
snap_goal = parent->coords.x1 + sleft + parent_w / 2;
|
||||
act = lv_area_get_width(area_tmp) / 2 + area_tmp->x1 + x_scroll;
|
||||
x_scroll += snap_goal - act;
|
||||
break;
|
||||
case LV_SCROLL_SNAP_NONE:
|
||||
break;
|
||||
}
|
||||
|
||||
/*Remove any pending scroll animations.*/
|
||||
lv_anim_delete(parent, scroll_y_anim);
|
||||
lv_anim_delete(parent, scroll_x_anim);
|
||||
|
||||
if((scroll_dir & LV_DIR_LEFT) == 0 && x_scroll < 0) x_scroll = 0;
|
||||
if((scroll_dir & LV_DIR_RIGHT) == 0 && x_scroll > 0) x_scroll = 0;
|
||||
if((scroll_dir & LV_DIR_TOP) == 0 && y_scroll < 0) y_scroll = 0;
|
||||
if((scroll_dir & LV_DIR_BOTTOM) == 0 && y_scroll > 0) y_scroll = 0;
|
||||
|
||||
scroll_value->x += anim_en == LV_ANIM_OFF ? 0 : x_scroll;
|
||||
scroll_value->y += anim_en == LV_ANIM_OFF ? 0 : y_scroll;
|
||||
lv_obj_scroll_by(parent, x_scroll, y_scroll, anim_en);
|
||||
}
|
||||
290
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_scroll.h
Normal file
290
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_scroll.h
Normal file
@@ -0,0 +1,290 @@
|
||||
/**
|
||||
* @file lv_obj_scroll.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_OBJ_SCROLL_H
|
||||
#define LV_OBJ_SCROLL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../misc/lv_area.h"
|
||||
#include "../misc/lv_anim.h"
|
||||
#include "../misc/lv_types.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/*Can't include lv_obj.h because it includes this header file*/
|
||||
|
||||
/** Scrollbar modes: shows when should the scrollbars be visible*/
|
||||
typedef enum {
|
||||
LV_SCROLLBAR_MODE_OFF, /**< Never show scrollbars*/
|
||||
LV_SCROLLBAR_MODE_ON, /**< Always show scrollbars*/
|
||||
LV_SCROLLBAR_MODE_ACTIVE, /**< Show scroll bars when object is being scrolled*/
|
||||
LV_SCROLLBAR_MODE_AUTO, /**< Show scroll bars when the content is large enough to be scrolled*/
|
||||
} lv_scrollbar_mode_t;
|
||||
|
||||
/** Scroll span align options. Tells where to align the snappable children when scroll stops.*/
|
||||
typedef enum {
|
||||
LV_SCROLL_SNAP_NONE, /**< Do not align, leave where it is*/
|
||||
LV_SCROLL_SNAP_START, /**< Align to the left/top*/
|
||||
LV_SCROLL_SNAP_END, /**< Align to the right/bottom*/
|
||||
LV_SCROLL_SNAP_CENTER /**< Align to the center*/
|
||||
} lv_scroll_snap_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Set how the scrollbars should behave.
|
||||
* @param obj pointer to an object
|
||||
* @param mode LV_SCROLL_MODE_ON/OFF/AUTO/ACTIVE
|
||||
*/
|
||||
void lv_obj_set_scrollbar_mode(lv_obj_t * obj, lv_scrollbar_mode_t mode);
|
||||
|
||||
/**
|
||||
* Set the object in which directions can be scrolled
|
||||
* @param obj pointer to an object
|
||||
* @param dir the allow scroll directions. An element or OR-ed values of `lv_dir_t`
|
||||
*/
|
||||
void lv_obj_set_scroll_dir(lv_obj_t * obj, lv_dir_t dir);
|
||||
|
||||
/**
|
||||
* Set where to snap the children when scrolling ends horizontally
|
||||
* @param obj pointer to an object
|
||||
* @param align the snap align to set from `lv_scroll_snap_t`
|
||||
*/
|
||||
void lv_obj_set_scroll_snap_x(lv_obj_t * obj, lv_scroll_snap_t align);
|
||||
|
||||
/**
|
||||
* Set where to snap the children when scrolling ends vertically
|
||||
* @param obj pointer to an object
|
||||
* @param align the snap align to set from `lv_scroll_snap_t`
|
||||
*/
|
||||
void lv_obj_set_scroll_snap_y(lv_obj_t * obj, lv_scroll_snap_t align);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Get the current scroll mode (when to hide the scrollbars)
|
||||
* @param obj pointer to an object
|
||||
* @return the current scroll mode from `lv_scrollbar_mode_t`
|
||||
*/
|
||||
lv_scrollbar_mode_t lv_obj_get_scrollbar_mode(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the object in which directions can be scrolled
|
||||
* @param obj pointer to an object
|
||||
*/
|
||||
lv_dir_t lv_obj_get_scroll_dir(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get where to snap the children when scrolling ends horizontally
|
||||
* @param obj pointer to an object
|
||||
* @return the current snap align from `lv_scroll_snap_t`
|
||||
*/
|
||||
lv_scroll_snap_t lv_obj_get_scroll_snap_x(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get where to snap the children when scrolling ends vertically
|
||||
* @param obj pointer to an object
|
||||
* @return the current snap align from `lv_scroll_snap_t`
|
||||
*/
|
||||
lv_scroll_snap_t lv_obj_get_scroll_snap_y(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get current X scroll position.
|
||||
* @param obj pointer to an object
|
||||
* @return the current scroll position from the left edge.
|
||||
* If the object is not scrolled return 0
|
||||
* If scrolled return > 0
|
||||
* If scrolled in (elastic scroll) return < 0
|
||||
*/
|
||||
int32_t lv_obj_get_scroll_x(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get current Y scroll position.
|
||||
* @param obj pointer to an object
|
||||
* @return the current scroll position from the top edge.
|
||||
* If the object is not scrolled return 0
|
||||
* If scrolled return > 0
|
||||
* If scrolled inside return < 0
|
||||
*/
|
||||
int32_t lv_obj_get_scroll_y(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Return the height of the area above the object.
|
||||
* That is the number of pixels the object can be scrolled down.
|
||||
* Normally positive but can be negative when scrolled inside.
|
||||
* @param obj pointer to an object
|
||||
* @return the scrollable area above the object in pixels
|
||||
*/
|
||||
int32_t lv_obj_get_scroll_top(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Return the height of the area below the object.
|
||||
* That is the number of pixels the object can be scrolled down.
|
||||
* Normally positive but can be negative when scrolled inside.
|
||||
* @param obj pointer to an object
|
||||
* @return the scrollable area below the object in pixels
|
||||
*/
|
||||
int32_t lv_obj_get_scroll_bottom(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Return the width of the area on the left the object.
|
||||
* That is the number of pixels the object can be scrolled down.
|
||||
* Normally positive but can be negative when scrolled inside.
|
||||
* @param obj pointer to an object
|
||||
* @return the scrollable area on the left the object in pixels
|
||||
*/
|
||||
int32_t lv_obj_get_scroll_left(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Return the width of the area on the right the object.
|
||||
* That is the number of pixels the object can be scrolled down.
|
||||
* Normally positive but can be negative when scrolled inside.
|
||||
* @param obj pointer to an object
|
||||
* @return the scrollable area on the right the object in pixels
|
||||
*/
|
||||
int32_t lv_obj_get_scroll_right(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the X and Y coordinates where the scrolling will end for this object if a scrolling animation is in progress.
|
||||
* If no scrolling animation, give the current `x` or `y` scroll position.
|
||||
* @param obj pointer to an object
|
||||
* @param end pointer to store the result
|
||||
*/
|
||||
void lv_obj_get_scroll_end(lv_obj_t * obj, lv_point_t * end);
|
||||
|
||||
/*=====================
|
||||
* Other functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Scroll by a given amount of pixels
|
||||
* @param obj pointer to an object to scroll
|
||||
* @param x pixels to scroll horizontally
|
||||
* @param y pixels to scroll vertically
|
||||
* @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately
|
||||
* @note > 0 value means scroll right/bottom (show the more content on the right/bottom)
|
||||
* @note e.g. dy = -20 means scroll down 20 px
|
||||
*/
|
||||
void lv_obj_scroll_by(lv_obj_t * obj, int32_t x, int32_t y, lv_anim_enable_t anim_en);
|
||||
|
||||
/**
|
||||
* Scroll by a given amount of pixels.
|
||||
* `dx` and `dy` will be limited internally to allow scrolling only on the content area.
|
||||
* @param obj pointer to an object to scroll
|
||||
* @param dx pixels to scroll horizontally
|
||||
* @param dy pixels to scroll vertically
|
||||
* @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately
|
||||
* @note e.g. dy = -20 means scroll down 20 px
|
||||
*/
|
||||
void lv_obj_scroll_by_bounded(lv_obj_t * obj, int32_t dx, int32_t dy, lv_anim_enable_t anim_en);
|
||||
|
||||
/**
|
||||
* Scroll to a given coordinate on an object.
|
||||
* `x` and `y` will be limited internally to allow scrolling only on the content area.
|
||||
* @param obj pointer to an object to scroll
|
||||
* @param x pixels to scroll horizontally
|
||||
* @param y pixels to scroll vertically
|
||||
* @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately
|
||||
*/
|
||||
void lv_obj_scroll_to(lv_obj_t * obj, int32_t x, int32_t y, lv_anim_enable_t anim_en);
|
||||
|
||||
/**
|
||||
* Scroll to a given X coordinate on an object.
|
||||
* `x` will be limited internally to allow scrolling only on the content area.
|
||||
* @param obj pointer to an object to scroll
|
||||
* @param x pixels to scroll horizontally
|
||||
* @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately
|
||||
*/
|
||||
void lv_obj_scroll_to_x(lv_obj_t * obj, int32_t x, lv_anim_enable_t anim_en);
|
||||
|
||||
/**
|
||||
* Scroll to a given Y coordinate on an object
|
||||
* `y` will be limited internally to allow scrolling only on the content area.
|
||||
* @param obj pointer to an object to scroll
|
||||
* @param y pixels to scroll vertically
|
||||
* @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately
|
||||
*/
|
||||
void lv_obj_scroll_to_y(lv_obj_t * obj, int32_t y, lv_anim_enable_t anim_en);
|
||||
|
||||
/**
|
||||
* Scroll to an object until it becomes visible on its parent
|
||||
* @param obj pointer to an object to scroll into view
|
||||
* @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately
|
||||
*/
|
||||
void lv_obj_scroll_to_view(lv_obj_t * obj, lv_anim_enable_t anim_en);
|
||||
|
||||
/**
|
||||
* Scroll to an object until it becomes visible on its parent.
|
||||
* Do the same on the parent's parent, and so on.
|
||||
* Therefore the object will be scrolled into view even it has nested scrollable parents
|
||||
* @param obj pointer to an object to scroll into view
|
||||
* @param anim_en LV_ANIM_ON: scroll with animation; LV_ANIM_OFF: scroll immediately
|
||||
*/
|
||||
void lv_obj_scroll_to_view_recursive(lv_obj_t * obj, lv_anim_enable_t anim_en);
|
||||
|
||||
/**
|
||||
* Tell whether an object is being scrolled or not at this moment
|
||||
* @param obj pointer to an object
|
||||
* @return true: `obj` is being scrolled
|
||||
*/
|
||||
bool lv_obj_is_scrolling(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Check the children of `obj` and scroll `obj` to fulfill the scroll_snap settings
|
||||
* @param obj an object whose children needs to checked and snapped
|
||||
* @param anim_en LV_ANIM_ON/OFF
|
||||
*/
|
||||
void lv_obj_update_snap(lv_obj_t * obj, lv_anim_enable_t anim_en);
|
||||
|
||||
/**
|
||||
* Get the area of the scrollbars
|
||||
* @param obj pointer to an object
|
||||
* @param hor pointer to store the area of the horizontal scrollbar
|
||||
* @param ver pointer to store the area of the vertical scrollbar
|
||||
*/
|
||||
void lv_obj_get_scrollbar_area(lv_obj_t * obj, lv_area_t * hor, lv_area_t * ver);
|
||||
|
||||
/**
|
||||
* Invalidate the area of the scrollbars
|
||||
* @param obj pointer to an object
|
||||
*/
|
||||
void lv_obj_scrollbar_invalidate(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Checks if the content is scrolled "in" and adjusts it to a normal position.
|
||||
* @param obj pointer to an object
|
||||
* @param anim_en LV_ANIM_ON/OFF
|
||||
*/
|
||||
void lv_obj_readjust_scroll(lv_obj_t * obj, lv_anim_enable_t anim_en);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_OBJ_SCROLL_H*/
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* @file lv_obj_scroll_private.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_OBJ_SCROLL_PRIVATE_H
|
||||
#define LV_OBJ_SCROLL_PRIVATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_obj_scroll.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Low level function to scroll by given x and y coordinates.
|
||||
* `LV_EVENT_SCROLL` is sent.
|
||||
* @param obj pointer to an object to scroll
|
||||
* @param x pixels to scroll horizontally
|
||||
* @param y pixels to scroll vertically
|
||||
* @return `LV_RESULT_INVALID`: to object was deleted in `LV_EVENT_SCROLL`;
|
||||
* `LV_RESULT_OK`: if the object is still valid
|
||||
*/
|
||||
lv_result_t lv_obj_scroll_by_raw(lv_obj_t * obj, int32_t x, int32_t y);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_OBJ_SCROLL_PRIVATE_H*/
|
||||
1126
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_style.c
Normal file
1126
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_style.c
Normal file
File diff suppressed because it is too large
Load Diff
318
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_style.h
Normal file
318
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_style.h
Normal file
@@ -0,0 +1,318 @@
|
||||
/**
|
||||
* @file lv_obj_style.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_OBJ_STYLE_H
|
||||
#define LV_OBJ_STYLE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../misc/lv_bidi.h"
|
||||
#include "../misc/lv_style.h"
|
||||
#include "../misc/lv_types.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef enum {
|
||||
LV_STYLE_STATE_CMP_SAME, /**< The style properties in the 2 states are identical */
|
||||
LV_STYLE_STATE_CMP_DIFF_REDRAW, /**< The differences can be shown with a simple redraw */
|
||||
LV_STYLE_STATE_CMP_DIFF_DRAW_PAD, /**< The differences can be shown with a simple redraw */
|
||||
LV_STYLE_STATE_CMP_DIFF_LAYOUT, /**< The differences can be shown with a simple redraw */
|
||||
} lv_style_state_cmp_t;
|
||||
|
||||
typedef uint32_t lv_style_selector_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Add a style to an object.
|
||||
* @param obj pointer to an object
|
||||
* @param style pointer to a style to add
|
||||
* @param selector OR-ed value of parts and state to which the style should be added
|
||||
*
|
||||
* Examples:
|
||||
* @code
|
||||
* lv_obj_add_style(btn, &style_btn, 0); //Default button style
|
||||
*
|
||||
* lv_obj_add_style(btn, &btn_red, LV_STATE_PRESSED); //Overwrite only some colors to red when pressed
|
||||
* @endcode
|
||||
*/
|
||||
void lv_obj_add_style(lv_obj_t * obj, const lv_style_t * style, lv_style_selector_t selector);
|
||||
|
||||
/**
|
||||
* Replaces a style of an object, preserving the order of the style stack (local styles and transitions are ignored).
|
||||
* @param obj pointer to an object
|
||||
* @param old_style pointer to a style to replace.
|
||||
* @param new_style pointer to a style to replace the old style with.
|
||||
* @param selector OR-ed values of states and a part to replace only styles with matching selectors. LV_STATE_ANY and LV_PART_ANY can be used
|
||||
*
|
||||
* Examples:
|
||||
* @code
|
||||
* lv_obj_replace_style(obj, &yellow_style, &blue_style, LV_PART_ANY | LV_STATE_ANY); //Replace a specific style
|
||||
*
|
||||
* lv_obj_replace_style(obj, &yellow_style, &blue_style, LV_PART_MAIN | LV_STATE_PRESSED); //Replace a specific style assigned to the main part when it is pressed
|
||||
* @endcode
|
||||
*/
|
||||
bool lv_obj_replace_style(lv_obj_t * obj, const lv_style_t * old_style, const lv_style_t * new_style,
|
||||
lv_style_selector_t selector);
|
||||
|
||||
/**
|
||||
* Remove a style from an object.
|
||||
* @param obj pointer to an object
|
||||
* @param style pointer to a style to remove. Can be NULL to check only the selector
|
||||
* @param selector OR-ed values of states and a part to remove only styles with matching selectors. LV_STATE_ANY and LV_PART_ANY can be used
|
||||
*
|
||||
* Examples:
|
||||
* @code
|
||||
* lv_obj_remove_style(obj, &style, LV_PART_ANY | LV_STATE_ANY); //Remove a specific style
|
||||
*
|
||||
* lv_obj_remove_style(obj, NULL, LV_PART_MAIN | LV_STATE_ANY); //Remove all styles from the main part
|
||||
*
|
||||
* lv_obj_remove_style(obj, NULL, LV_PART_ANY | LV_STATE_ANY); //Remove all styles
|
||||
* @endcode
|
||||
*/
|
||||
void lv_obj_remove_style(lv_obj_t * obj, const lv_style_t * style, lv_style_selector_t selector);
|
||||
|
||||
/**
|
||||
* Remove all styles from an object
|
||||
* @param obj pointer to an object
|
||||
*/
|
||||
void lv_obj_remove_style_all(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Notify all object if a style is modified
|
||||
* @param style pointer to a style. Only the objects with this style will be notified
|
||||
* (NULL to notify all objects)
|
||||
*/
|
||||
void lv_obj_report_style_change(lv_style_t * style);
|
||||
|
||||
/**
|
||||
* Notify an object and its children about its style is modified.
|
||||
* @param obj pointer to an object
|
||||
* @param part the part whose style was changed. E.g. `LV_PART_ANY`, `LV_PART_MAIN`
|
||||
* @param prop `LV_STYLE_PROP_ANY` or an `LV_STYLE_...` property.
|
||||
* It is used to optimize what needs to be refreshed.
|
||||
* `LV_STYLE_PROP_INV` to perform only a style cache update
|
||||
*/
|
||||
void lv_obj_refresh_style(lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop);
|
||||
|
||||
/**
|
||||
* Enable or disable automatic style refreshing when a new style is added/removed to/from an object
|
||||
* or any other style change happens.
|
||||
* @param en true: enable refreshing; false: disable refreshing
|
||||
*/
|
||||
void lv_obj_enable_style_refresh(bool en);
|
||||
|
||||
/**
|
||||
* Get the value of a style property. The current state of the object will be considered.
|
||||
* Inherited properties will be inherited.
|
||||
* If a property is not set a default value will be returned.
|
||||
* @param obj pointer to an object
|
||||
* @param part a part from which the property should be get
|
||||
* @param prop the property to get
|
||||
* @return the value of the property.
|
||||
* Should be read from the correct field of the `lv_style_value_t` according to the type of the property.
|
||||
*/
|
||||
lv_style_value_t lv_obj_get_style_prop(const lv_obj_t * obj, lv_part_t part, lv_style_prop_t prop);
|
||||
|
||||
/**
|
||||
* Check if an object has a specified style property for a given style selector.
|
||||
* @param obj pointer to an object
|
||||
* @param selector the style selector to be checked, defining the scope of the style to be examined.
|
||||
* @param prop the property to be checked.
|
||||
* @return true if the object has the specified selector and property, false otherwise.
|
||||
*/
|
||||
bool lv_obj_has_style_prop(const lv_obj_t * obj, lv_style_selector_t selector, lv_style_prop_t prop);
|
||||
|
||||
/**
|
||||
* Set local style property on an object's part and state.
|
||||
* @param obj pointer to an object
|
||||
* @param prop the property
|
||||
* @param value value of the property. The correct element should be set according to the type of the property
|
||||
* @param selector OR-ed value of parts and state for which the style should be set
|
||||
*/
|
||||
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_res_t lv_obj_get_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_value_t * value,
|
||||
lv_style_selector_t selector);
|
||||
|
||||
/**
|
||||
* Remove a local style property from a part of an object with a given state.
|
||||
* @param obj pointer to an object
|
||||
* @param prop a style property to remove.
|
||||
* @param selector OR-ed value of parts and state for which the style should be removed
|
||||
* @return true the property was found and removed; false: the property was not found
|
||||
*/
|
||||
bool lv_obj_remove_local_style_prop(lv_obj_t * obj, lv_style_prop_t prop, lv_style_selector_t selector);
|
||||
|
||||
/**
|
||||
* Used internally for color filtering
|
||||
*/
|
||||
lv_style_value_t lv_obj_style_apply_color_filter(const lv_obj_t * obj, lv_part_t part, lv_style_value_t v);
|
||||
|
||||
/**
|
||||
* Fade in an an object and all its children.
|
||||
* @param obj the object to fade in
|
||||
* @param time time of fade
|
||||
* @param delay delay to start the animation
|
||||
*/
|
||||
void lv_obj_fade_in(lv_obj_t * obj, uint32_t time, uint32_t delay);
|
||||
|
||||
/**
|
||||
* Fade out an an object and all its children.
|
||||
* @param obj the object to fade out
|
||||
* @param time time of fade
|
||||
* @param delay delay to start the animation
|
||||
*/
|
||||
void lv_obj_fade_out(lv_obj_t * obj, uint32_t time, uint32_t delay);
|
||||
|
||||
static inline lv_state_t lv_obj_style_get_selector_state(lv_style_selector_t selector)
|
||||
{
|
||||
return selector & 0xFFFF;
|
||||
}
|
||||
|
||||
static inline lv_part_t lv_obj_style_get_selector_part(lv_style_selector_t selector)
|
||||
{
|
||||
return selector & 0xFF0000;
|
||||
}
|
||||
|
||||
#include "lv_obj_style_gen.h"
|
||||
|
||||
static inline void lv_obj_set_style_pad_all(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_obj_set_style_pad_left(obj, value, selector);
|
||||
lv_obj_set_style_pad_right(obj, value, selector);
|
||||
lv_obj_set_style_pad_top(obj, value, selector);
|
||||
lv_obj_set_style_pad_bottom(obj, value, selector);
|
||||
}
|
||||
|
||||
static inline void lv_obj_set_style_pad_hor(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_obj_set_style_pad_left(obj, value, selector);
|
||||
lv_obj_set_style_pad_right(obj, value, selector);
|
||||
}
|
||||
|
||||
static inline void lv_obj_set_style_pad_ver(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_obj_set_style_pad_top(obj, value, selector);
|
||||
lv_obj_set_style_pad_bottom(obj, value, selector);
|
||||
}
|
||||
|
||||
static inline void lv_obj_set_style_margin_all(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_obj_set_style_margin_left(obj, value, selector);
|
||||
lv_obj_set_style_margin_right(obj, value, selector);
|
||||
lv_obj_set_style_margin_top(obj, value, selector);
|
||||
lv_obj_set_style_margin_bottom(obj, value, selector);
|
||||
}
|
||||
|
||||
static inline void lv_obj_set_style_margin_hor(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_obj_set_style_margin_left(obj, value, selector);
|
||||
lv_obj_set_style_margin_right(obj, value, selector);
|
||||
}
|
||||
|
||||
static inline void lv_obj_set_style_margin_ver(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_obj_set_style_margin_top(obj, value, selector);
|
||||
lv_obj_set_style_margin_bottom(obj, value, selector);
|
||||
}
|
||||
|
||||
static inline void lv_obj_set_style_pad_gap(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_obj_set_style_pad_row(obj, value, selector);
|
||||
lv_obj_set_style_pad_column(obj, value, selector);
|
||||
}
|
||||
|
||||
static inline void lv_obj_set_style_size(lv_obj_t * obj, int32_t width, int32_t height,
|
||||
lv_style_selector_t selector)
|
||||
{
|
||||
lv_obj_set_style_width(obj, width, selector);
|
||||
lv_obj_set_style_height(obj, height, selector);
|
||||
}
|
||||
|
||||
static inline void lv_obj_set_style_transform_scale(lv_obj_t * obj, int32_t value,
|
||||
lv_style_selector_t selector)
|
||||
{
|
||||
lv_obj_set_style_transform_scale_x(obj, value, selector);
|
||||
lv_obj_set_style_transform_scale_y(obj, value, selector);
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_space_left(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
int32_t padding = lv_obj_get_style_pad_left(obj, part);
|
||||
int32_t border_width = lv_obj_get_style_border_width(obj, part);
|
||||
lv_border_side_t border_side = lv_obj_get_style_border_side(obj, part);
|
||||
return (border_side & LV_BORDER_SIDE_LEFT) ? padding + border_width : padding;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_space_right(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
int32_t padding = lv_obj_get_style_pad_right(obj, part);
|
||||
int32_t border_width = lv_obj_get_style_border_width(obj, part);
|
||||
lv_border_side_t border_side = lv_obj_get_style_border_side(obj, part);
|
||||
return (border_side & LV_BORDER_SIDE_RIGHT) ? padding + border_width : padding;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_space_top(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
int32_t padding = lv_obj_get_style_pad_top(obj, part);
|
||||
int32_t border_width = lv_obj_get_style_border_width(obj, part);
|
||||
lv_border_side_t border_side = lv_obj_get_style_border_side(obj, part);
|
||||
return (border_side & LV_BORDER_SIDE_TOP) ? padding + border_width : padding;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_space_bottom(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
int32_t padding = lv_obj_get_style_pad_bottom(obj, part);
|
||||
int32_t border_width = lv_obj_get_style_border_width(obj, part);
|
||||
lv_border_side_t border_side = lv_obj_get_style_border_side(obj, part);
|
||||
return (border_side & LV_BORDER_SIDE_BOTTOM) ? padding + border_width : padding;
|
||||
}
|
||||
|
||||
lv_text_align_t lv_obj_calculate_style_text_align(const lv_obj_t * obj, lv_part_t part, const char * txt);
|
||||
|
||||
static inline int32_t lv_obj_get_style_transform_scale_x_safe(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
int32_t scale = lv_obj_get_style_transform_scale_x(obj, part);
|
||||
return scale > 0 ? scale : 1;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_transform_scale_y_safe(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
int32_t scale = lv_obj_get_style_transform_scale_y(obj, part);
|
||||
return scale > 0 ? scale : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `opa` style property from all parents and multiply and `>> 8` them.
|
||||
* @param obj the object whose opacity should be get
|
||||
* @param part the part whose opacity should be get. Non-MAIN parts will consider the `opa` of the MAIN part too
|
||||
* @return the final opacity considering the parents' opacity too
|
||||
*/
|
||||
lv_opa_t lv_obj_get_style_opa_recursive(const lv_obj_t * obj, lv_part_t part);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_OBJ_STYLE_H*/
|
||||
897
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_style_gen.c
Normal file
897
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_style_gen.c
Normal file
@@ -0,0 +1,897 @@
|
||||
|
||||
/*
|
||||
**********************************************************************
|
||||
* DO NOT EDIT
|
||||
* This file is automatically generated by "style_api_gen.py"
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#include "lv_obj.h"
|
||||
|
||||
|
||||
void lv_obj_set_style_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_WIDTH, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_min_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_MIN_WIDTH, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_max_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_MAX_WIDTH, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_height(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_HEIGHT, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_min_height(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_MIN_HEIGHT, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_max_height(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_MAX_HEIGHT, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_length(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_LENGTH, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_x(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_X, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_y(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_Y, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_align(lv_obj_t * obj, lv_align_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_ALIGN, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_transform_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TRANSFORM_WIDTH, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_transform_height(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TRANSFORM_HEIGHT, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_translate_x(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TRANSLATE_X, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_translate_y(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TRANSLATE_Y, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_transform_scale_x(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TRANSFORM_SCALE_X, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_transform_scale_y(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TRANSFORM_SCALE_Y, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_transform_rotation(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TRANSFORM_ROTATION, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_transform_pivot_x(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TRANSFORM_PIVOT_X, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_transform_pivot_y(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TRANSFORM_PIVOT_Y, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_transform_skew_x(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TRANSFORM_SKEW_X, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_transform_skew_y(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TRANSFORM_SKEW_Y, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_pad_top(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_PAD_TOP, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_pad_bottom(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_PAD_BOTTOM, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_pad_left(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_PAD_LEFT, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_pad_right(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_PAD_RIGHT, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_pad_row(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_PAD_ROW, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_pad_column(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_PAD_COLUMN, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_margin_top(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_MARGIN_TOP, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_margin_bottom(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_MARGIN_BOTTOM, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_margin_left(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_MARGIN_LEFT, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_margin_right(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_MARGIN_RIGHT, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_bg_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.color = value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_COLOR, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_bg_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_OPA, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_bg_grad_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.color = value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_GRAD_COLOR, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_bg_grad_dir(lv_obj_t * obj, lv_grad_dir_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_GRAD_DIR, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_bg_main_stop(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_MAIN_STOP, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_bg_grad_stop(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_GRAD_STOP, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_bg_main_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_MAIN_OPA, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_bg_grad_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_GRAD_OPA, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_bg_grad(lv_obj_t * obj, const lv_grad_dsc_t * value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.ptr = value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_GRAD, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_bg_image_src(lv_obj_t * obj, const void * value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.ptr = value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_IMAGE_SRC, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_bg_image_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_IMAGE_OPA, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_bg_image_recolor(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.color = value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_IMAGE_RECOLOR, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_bg_image_recolor_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_IMAGE_RECOLOR_OPA, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_bg_image_tiled(lv_obj_t * obj, bool value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BG_IMAGE_TILED, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_border_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.color = value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BORDER_COLOR, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_border_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BORDER_OPA, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_border_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BORDER_WIDTH, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_border_side(lv_obj_t * obj, lv_border_side_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BORDER_SIDE, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_border_post(lv_obj_t * obj, bool value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BORDER_POST, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_outline_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_OUTLINE_WIDTH, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_outline_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.color = value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_OUTLINE_COLOR, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_outline_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_OUTLINE_OPA, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_outline_pad(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_OUTLINE_PAD, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_shadow_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_SHADOW_WIDTH, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_shadow_offset_x(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_SHADOW_OFFSET_X, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_shadow_offset_y(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_SHADOW_OFFSET_Y, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_shadow_spread(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_SHADOW_SPREAD, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_shadow_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.color = value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_SHADOW_COLOR, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_shadow_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_SHADOW_OPA, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_image_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_IMAGE_OPA, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_image_recolor(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.color = value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_IMAGE_RECOLOR, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_image_recolor_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_IMAGE_RECOLOR_OPA, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_line_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_LINE_WIDTH, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_line_dash_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_LINE_DASH_WIDTH, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_line_dash_gap(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_LINE_DASH_GAP, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_line_rounded(lv_obj_t * obj, bool value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_LINE_ROUNDED, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_line_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.color = value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_LINE_COLOR, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_line_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_LINE_OPA, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_arc_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_ARC_WIDTH, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_arc_rounded(lv_obj_t * obj, bool value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_ARC_ROUNDED, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_arc_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.color = value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_ARC_COLOR, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_arc_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_ARC_OPA, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_arc_image_src(lv_obj_t * obj, const void * value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.ptr = value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_ARC_IMAGE_SRC, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_text_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.color = value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TEXT_COLOR, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_text_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TEXT_OPA, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_text_font(lv_obj_t * obj, const lv_font_t * value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.ptr = value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TEXT_FONT, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_text_letter_space(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TEXT_LETTER_SPACE, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_text_line_space(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TEXT_LINE_SPACE, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_text_decor(lv_obj_t * obj, lv_text_decor_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TEXT_DECOR, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_text_align(lv_obj_t * obj, lv_text_align_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TEXT_ALIGN, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_radius(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_RADIUS, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_clip_corner(lv_obj_t * obj, bool value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_CLIP_CORNER, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_OPA, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_opa_layered(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_OPA_LAYERED, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_color_filter_dsc(lv_obj_t * obj, const lv_color_filter_dsc_t * value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.ptr = value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_COLOR_FILTER_DSC, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_color_filter_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_COLOR_FILTER_OPA, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_anim(lv_obj_t * obj, const lv_anim_t * value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.ptr = value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_ANIM, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_anim_duration(lv_obj_t * obj, uint32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_ANIM_DURATION, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_transition(lv_obj_t * obj, const lv_style_transition_dsc_t * value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.ptr = value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_TRANSITION, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_blend_mode(lv_obj_t * obj, lv_blend_mode_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BLEND_MODE, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_layout(lv_obj_t * obj, uint16_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_LAYOUT, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_base_dir(lv_obj_t * obj, lv_base_dir_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BASE_DIR, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_bitmap_mask_src(lv_obj_t * obj, const void * value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.ptr = value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_BITMAP_MASK_SRC, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_rotary_sensitivity(lv_obj_t * obj, uint32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_ROTARY_SENSITIVITY, v, selector);
|
||||
}
|
||||
#if LV_USE_FLEX
|
||||
|
||||
void lv_obj_set_style_flex_flow(lv_obj_t * obj, lv_flex_flow_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_FLEX_FLOW, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_flex_main_place(lv_obj_t * obj, lv_flex_align_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_FLEX_MAIN_PLACE, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_flex_cross_place(lv_obj_t * obj, lv_flex_align_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_FLEX_CROSS_PLACE, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_flex_track_place(lv_obj_t * obj, lv_flex_align_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_FLEX_TRACK_PLACE, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_flex_grow(lv_obj_t * obj, uint8_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_FLEX_GROW, v, selector);
|
||||
}
|
||||
#endif /*LV_USE_FLEX*/
|
||||
|
||||
#if LV_USE_GRID
|
||||
|
||||
void lv_obj_set_style_grid_column_dsc_array(lv_obj_t * obj, const int32_t * value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.ptr = value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_GRID_COLUMN_DSC_ARRAY, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_grid_column_align(lv_obj_t * obj, lv_grid_align_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_GRID_COLUMN_ALIGN, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_grid_row_dsc_array(lv_obj_t * obj, const int32_t * value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.ptr = value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_GRID_ROW_DSC_ARRAY, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_grid_row_align(lv_obj_t * obj, lv_grid_align_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_GRID_ROW_ALIGN, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_grid_cell_column_pos(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_GRID_CELL_COLUMN_POS, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_grid_cell_x_align(lv_obj_t * obj, lv_grid_align_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_GRID_CELL_X_ALIGN, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_grid_cell_column_span(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_GRID_CELL_COLUMN_SPAN, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_grid_cell_row_pos(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_GRID_CELL_ROW_POS, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_grid_cell_y_align(lv_obj_t * obj, lv_grid_align_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_GRID_CELL_Y_ALIGN, v, selector);
|
||||
}
|
||||
|
||||
void lv_obj_set_style_grid_cell_row_span(lv_obj_t * obj, int32_t value, lv_style_selector_t selector)
|
||||
{
|
||||
lv_style_value_t v = {
|
||||
.num = (int32_t)value
|
||||
};
|
||||
lv_obj_set_local_style_prop(obj, LV_STYLE_GRID_CELL_ROW_SPAN, v, selector);
|
||||
}
|
||||
#endif /*LV_USE_GRID*/
|
||||
|
||||
875
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_style_gen.h
Normal file
875
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_style_gen.h
Normal file
@@ -0,0 +1,875 @@
|
||||
|
||||
/*
|
||||
**********************************************************************
|
||||
* DO NOT EDIT
|
||||
* This file is automatically generated by "style_api_gen.py"
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LV_OBJ_STYLE_GEN_H
|
||||
#define LV_OBJ_STYLE_GEN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../misc/lv_area.h"
|
||||
#include "../misc/lv_style.h"
|
||||
#include "../core/lv_obj_style.h"
|
||||
#include "../misc/lv_types.h"
|
||||
|
||||
static inline int32_t lv_obj_get_style_width(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_WIDTH);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_min_width(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MIN_WIDTH);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_max_width(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MAX_WIDTH);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_height(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_HEIGHT);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_min_height(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MIN_HEIGHT);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_max_height(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MAX_HEIGHT);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_length(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LENGTH);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_x(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_X);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_y(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_Y);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline lv_align_t lv_obj_get_style_align(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ALIGN);
|
||||
return (lv_align_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_transform_width(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_WIDTH);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_transform_height(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_HEIGHT);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_translate_x(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSLATE_X);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_translate_y(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSLATE_Y);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_transform_scale_x(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_SCALE_X);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_transform_scale_y(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_SCALE_Y);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_transform_rotation(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_ROTATION);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_transform_pivot_x(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_PIVOT_X);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_transform_pivot_y(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_PIVOT_Y);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_transform_skew_x(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_SKEW_X);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_transform_skew_y(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSFORM_SKEW_Y);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_pad_top(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_PAD_TOP);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_pad_bottom(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_PAD_BOTTOM);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_pad_left(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_PAD_LEFT);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_pad_right(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_PAD_RIGHT);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_pad_row(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_PAD_ROW);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_pad_column(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_PAD_COLUMN);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_margin_top(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MARGIN_TOP);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_margin_bottom(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MARGIN_BOTTOM);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_margin_left(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MARGIN_LEFT);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_margin_right(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_MARGIN_RIGHT);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_bg_color(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_COLOR);
|
||||
return v.color;
|
||||
}
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_bg_color_filtered(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_BG_COLOR));
|
||||
return v.color;
|
||||
}
|
||||
|
||||
static inline lv_opa_t lv_obj_get_style_bg_opa(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_OPA);
|
||||
return (lv_opa_t)v.num;
|
||||
}
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_bg_grad_color(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_GRAD_COLOR);
|
||||
return v.color;
|
||||
}
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_bg_grad_color_filtered(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part,
|
||||
LV_STYLE_BG_GRAD_COLOR));
|
||||
return v.color;
|
||||
}
|
||||
|
||||
static inline lv_grad_dir_t lv_obj_get_style_bg_grad_dir(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_GRAD_DIR);
|
||||
return (lv_grad_dir_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_bg_main_stop(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_MAIN_STOP);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_bg_grad_stop(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_GRAD_STOP);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline lv_opa_t lv_obj_get_style_bg_main_opa(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_MAIN_OPA);
|
||||
return (lv_opa_t)v.num;
|
||||
}
|
||||
|
||||
static inline lv_opa_t lv_obj_get_style_bg_grad_opa(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_GRAD_OPA);
|
||||
return (lv_opa_t)v.num;
|
||||
}
|
||||
|
||||
static inline const lv_grad_dsc_t * lv_obj_get_style_bg_grad(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_GRAD);
|
||||
return (const lv_grad_dsc_t *)v.ptr;
|
||||
}
|
||||
|
||||
static inline const void * lv_obj_get_style_bg_image_src(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_IMAGE_SRC);
|
||||
return (const void *)v.ptr;
|
||||
}
|
||||
|
||||
static inline lv_opa_t lv_obj_get_style_bg_image_opa(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_IMAGE_OPA);
|
||||
return (lv_opa_t)v.num;
|
||||
}
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_bg_image_recolor(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_IMAGE_RECOLOR);
|
||||
return v.color;
|
||||
}
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_bg_image_recolor_filtered(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part,
|
||||
LV_STYLE_BG_IMAGE_RECOLOR));
|
||||
return v.color;
|
||||
}
|
||||
|
||||
static inline lv_opa_t lv_obj_get_style_bg_image_recolor_opa(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_IMAGE_RECOLOR_OPA);
|
||||
return (lv_opa_t)v.num;
|
||||
}
|
||||
|
||||
static inline bool lv_obj_get_style_bg_image_tiled(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BG_IMAGE_TILED);
|
||||
return (bool)v.num;
|
||||
}
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_border_color(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BORDER_COLOR);
|
||||
return v.color;
|
||||
}
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_border_color_filtered(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part,
|
||||
LV_STYLE_BORDER_COLOR));
|
||||
return v.color;
|
||||
}
|
||||
|
||||
static inline lv_opa_t lv_obj_get_style_border_opa(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BORDER_OPA);
|
||||
return (lv_opa_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_border_width(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BORDER_WIDTH);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline lv_border_side_t lv_obj_get_style_border_side(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BORDER_SIDE);
|
||||
return (lv_border_side_t)v.num;
|
||||
}
|
||||
|
||||
static inline bool lv_obj_get_style_border_post(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BORDER_POST);
|
||||
return (bool)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_outline_width(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_OUTLINE_WIDTH);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_outline_color(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_OUTLINE_COLOR);
|
||||
return v.color;
|
||||
}
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_outline_color_filtered(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part,
|
||||
LV_STYLE_OUTLINE_COLOR));
|
||||
return v.color;
|
||||
}
|
||||
|
||||
static inline lv_opa_t lv_obj_get_style_outline_opa(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_OUTLINE_OPA);
|
||||
return (lv_opa_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_outline_pad(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_OUTLINE_PAD);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_shadow_width(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_WIDTH);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_shadow_offset_x(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_OFFSET_X);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_shadow_offset_y(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_OFFSET_Y);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_shadow_spread(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_SPREAD);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_shadow_color(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_COLOR);
|
||||
return v.color;
|
||||
}
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_shadow_color_filtered(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part,
|
||||
LV_STYLE_SHADOW_COLOR));
|
||||
return v.color;
|
||||
}
|
||||
|
||||
static inline lv_opa_t lv_obj_get_style_shadow_opa(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_SHADOW_OPA);
|
||||
return (lv_opa_t)v.num;
|
||||
}
|
||||
|
||||
static inline lv_opa_t lv_obj_get_style_image_opa(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_IMAGE_OPA);
|
||||
return (lv_opa_t)v.num;
|
||||
}
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_image_recolor(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_IMAGE_RECOLOR);
|
||||
return v.color;
|
||||
}
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_image_recolor_filtered(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part,
|
||||
LV_STYLE_IMAGE_RECOLOR));
|
||||
return v.color;
|
||||
}
|
||||
|
||||
static inline lv_opa_t lv_obj_get_style_image_recolor_opa(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_IMAGE_RECOLOR_OPA);
|
||||
return (lv_opa_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_line_width(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_WIDTH);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_line_dash_width(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_DASH_WIDTH);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_line_dash_gap(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_DASH_GAP);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline bool lv_obj_get_style_line_rounded(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_ROUNDED);
|
||||
return (bool)v.num;
|
||||
}
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_line_color(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_COLOR);
|
||||
return v.color;
|
||||
}
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_line_color_filtered(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_COLOR));
|
||||
return v.color;
|
||||
}
|
||||
|
||||
static inline lv_opa_t lv_obj_get_style_line_opa(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LINE_OPA);
|
||||
return (lv_opa_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_arc_width(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ARC_WIDTH);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline bool lv_obj_get_style_arc_rounded(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ARC_ROUNDED);
|
||||
return (bool)v.num;
|
||||
}
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_arc_color(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ARC_COLOR);
|
||||
return v.color;
|
||||
}
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_arc_color_filtered(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_ARC_COLOR));
|
||||
return v.color;
|
||||
}
|
||||
|
||||
static inline lv_opa_t lv_obj_get_style_arc_opa(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ARC_OPA);
|
||||
return (lv_opa_t)v.num;
|
||||
}
|
||||
|
||||
static inline const void * lv_obj_get_style_arc_image_src(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ARC_IMAGE_SRC);
|
||||
return (const void *)v.ptr;
|
||||
}
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_text_color(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_COLOR);
|
||||
return v.color;
|
||||
}
|
||||
|
||||
static inline lv_color_t lv_obj_get_style_text_color_filtered(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_COLOR));
|
||||
return v.color;
|
||||
}
|
||||
|
||||
static inline lv_opa_t lv_obj_get_style_text_opa(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_OPA);
|
||||
return (lv_opa_t)v.num;
|
||||
}
|
||||
|
||||
static inline const lv_font_t * lv_obj_get_style_text_font(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_FONT);
|
||||
return (const lv_font_t *)v.ptr;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_text_letter_space(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_LETTER_SPACE);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_text_line_space(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_LINE_SPACE);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline lv_text_decor_t lv_obj_get_style_text_decor(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_DECOR);
|
||||
return (lv_text_decor_t)v.num;
|
||||
}
|
||||
|
||||
static inline lv_text_align_t lv_obj_get_style_text_align(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TEXT_ALIGN);
|
||||
return (lv_text_align_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_radius(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_RADIUS);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline bool lv_obj_get_style_clip_corner(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_CLIP_CORNER);
|
||||
return (bool)v.num;
|
||||
}
|
||||
|
||||
static inline lv_opa_t lv_obj_get_style_opa(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_OPA);
|
||||
return (lv_opa_t)v.num;
|
||||
}
|
||||
|
||||
static inline lv_opa_t lv_obj_get_style_opa_layered(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_OPA_LAYERED);
|
||||
return (lv_opa_t)v.num;
|
||||
}
|
||||
|
||||
static inline const lv_color_filter_dsc_t * lv_obj_get_style_color_filter_dsc(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_COLOR_FILTER_DSC);
|
||||
return (const lv_color_filter_dsc_t *)v.ptr;
|
||||
}
|
||||
|
||||
static inline lv_opa_t lv_obj_get_style_color_filter_opa(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_COLOR_FILTER_OPA);
|
||||
return (lv_opa_t)v.num;
|
||||
}
|
||||
|
||||
static inline const lv_anim_t * lv_obj_get_style_anim(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ANIM);
|
||||
return (const lv_anim_t *)v.ptr;
|
||||
}
|
||||
|
||||
static inline uint32_t lv_obj_get_style_anim_duration(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ANIM_DURATION);
|
||||
return (uint32_t)v.num;
|
||||
}
|
||||
|
||||
static inline const lv_style_transition_dsc_t * lv_obj_get_style_transition(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_TRANSITION);
|
||||
return (const lv_style_transition_dsc_t *)v.ptr;
|
||||
}
|
||||
|
||||
static inline lv_blend_mode_t lv_obj_get_style_blend_mode(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BLEND_MODE);
|
||||
return (lv_blend_mode_t)v.num;
|
||||
}
|
||||
|
||||
static inline uint16_t lv_obj_get_style_layout(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_LAYOUT);
|
||||
return (uint16_t)v.num;
|
||||
}
|
||||
|
||||
static inline lv_base_dir_t lv_obj_get_style_base_dir(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BASE_DIR);
|
||||
return (lv_base_dir_t)v.num;
|
||||
}
|
||||
|
||||
static inline const void * lv_obj_get_style_bitmap_mask_src(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_BITMAP_MASK_SRC);
|
||||
return (const void *)v.ptr;
|
||||
}
|
||||
|
||||
static inline uint32_t lv_obj_get_style_rotary_sensitivity(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_ROTARY_SENSITIVITY);
|
||||
return (uint32_t)v.num;
|
||||
}
|
||||
|
||||
#if LV_USE_FLEX
|
||||
static inline lv_flex_flow_t lv_obj_get_style_flex_flow(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_FLEX_FLOW);
|
||||
return (lv_flex_flow_t)v.num;
|
||||
}
|
||||
|
||||
static inline lv_flex_align_t lv_obj_get_style_flex_main_place(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_FLEX_MAIN_PLACE);
|
||||
return (lv_flex_align_t)v.num;
|
||||
}
|
||||
|
||||
static inline lv_flex_align_t lv_obj_get_style_flex_cross_place(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_FLEX_CROSS_PLACE);
|
||||
return (lv_flex_align_t)v.num;
|
||||
}
|
||||
|
||||
static inline lv_flex_align_t lv_obj_get_style_flex_track_place(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_FLEX_TRACK_PLACE);
|
||||
return (lv_flex_align_t)v.num;
|
||||
}
|
||||
|
||||
static inline uint8_t lv_obj_get_style_flex_grow(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_FLEX_GROW);
|
||||
return (uint8_t)v.num;
|
||||
}
|
||||
|
||||
#endif /*LV_USE_FLEX*/
|
||||
|
||||
#if LV_USE_GRID
|
||||
static inline const int32_t * lv_obj_get_style_grid_column_dsc_array(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_COLUMN_DSC_ARRAY);
|
||||
return (const int32_t *)v.ptr;
|
||||
}
|
||||
|
||||
static inline lv_grid_align_t lv_obj_get_style_grid_column_align(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_COLUMN_ALIGN);
|
||||
return (lv_grid_align_t)v.num;
|
||||
}
|
||||
|
||||
static inline const int32_t * lv_obj_get_style_grid_row_dsc_array(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_ROW_DSC_ARRAY);
|
||||
return (const int32_t *)v.ptr;
|
||||
}
|
||||
|
||||
static inline lv_grid_align_t lv_obj_get_style_grid_row_align(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_ROW_ALIGN);
|
||||
return (lv_grid_align_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_grid_cell_column_pos(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_CELL_COLUMN_POS);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline lv_grid_align_t lv_obj_get_style_grid_cell_x_align(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_CELL_X_ALIGN);
|
||||
return (lv_grid_align_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_grid_cell_column_span(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_CELL_COLUMN_SPAN);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_grid_cell_row_pos(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_CELL_ROW_POS);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
static inline lv_grid_align_t lv_obj_get_style_grid_cell_y_align(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_CELL_Y_ALIGN);
|
||||
return (lv_grid_align_t)v.num;
|
||||
}
|
||||
|
||||
static inline int32_t lv_obj_get_style_grid_cell_row_span(const lv_obj_t * obj, lv_part_t part)
|
||||
{
|
||||
lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_GRID_CELL_ROW_SPAN);
|
||||
return (int32_t)v.num;
|
||||
}
|
||||
|
||||
#endif /*LV_USE_GRID*/
|
||||
|
||||
void lv_obj_set_style_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_min_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_max_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_height(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_min_height(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_max_height(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_length(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_x(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_y(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_align(lv_obj_t * obj, lv_align_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_transform_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_transform_height(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_translate_x(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_translate_y(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_transform_scale_x(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_transform_scale_y(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_transform_rotation(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_transform_pivot_x(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_transform_pivot_y(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_transform_skew_x(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_transform_skew_y(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_pad_top(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_pad_bottom(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_pad_left(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_pad_right(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_pad_row(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_pad_column(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_margin_top(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_margin_bottom(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_margin_left(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_margin_right(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_bg_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_bg_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_bg_grad_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_bg_grad_dir(lv_obj_t * obj, lv_grad_dir_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_bg_main_stop(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_bg_grad_stop(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_bg_main_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_bg_grad_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_bg_grad(lv_obj_t * obj, const lv_grad_dsc_t * value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_bg_image_src(lv_obj_t * obj, const void * value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_bg_image_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_bg_image_recolor(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_bg_image_recolor_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_bg_image_tiled(lv_obj_t * obj, bool value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_border_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_border_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_border_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_border_side(lv_obj_t * obj, lv_border_side_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_border_post(lv_obj_t * obj, bool value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_outline_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_outline_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_outline_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_outline_pad(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_shadow_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_shadow_offset_x(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_shadow_offset_y(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_shadow_spread(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_shadow_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_shadow_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_image_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_image_recolor(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_image_recolor_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_line_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_line_dash_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_line_dash_gap(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_line_rounded(lv_obj_t * obj, bool value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_line_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_line_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_arc_width(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_arc_rounded(lv_obj_t * obj, bool value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_arc_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_arc_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_arc_image_src(lv_obj_t * obj, const void * value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_text_color(lv_obj_t * obj, lv_color_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_text_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_text_font(lv_obj_t * obj, const lv_font_t * value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_text_letter_space(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_text_line_space(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_text_decor(lv_obj_t * obj, lv_text_decor_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_text_align(lv_obj_t * obj, lv_text_align_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_radius(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_clip_corner(lv_obj_t * obj, bool value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_opa_layered(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_color_filter_dsc(lv_obj_t * obj, const lv_color_filter_dsc_t * value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_color_filter_opa(lv_obj_t * obj, lv_opa_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_anim(lv_obj_t * obj, const lv_anim_t * value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_anim_duration(lv_obj_t * obj, uint32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_transition(lv_obj_t * obj, const lv_style_transition_dsc_t * value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_blend_mode(lv_obj_t * obj, lv_blend_mode_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_layout(lv_obj_t * obj, uint16_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_base_dir(lv_obj_t * obj, lv_base_dir_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_bitmap_mask_src(lv_obj_t * obj, const void * value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_rotary_sensitivity(lv_obj_t * obj, uint32_t value, lv_style_selector_t selector);
|
||||
#if LV_USE_FLEX
|
||||
void lv_obj_set_style_flex_flow(lv_obj_t * obj, lv_flex_flow_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_flex_main_place(lv_obj_t * obj, lv_flex_align_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_flex_cross_place(lv_obj_t * obj, lv_flex_align_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_flex_track_place(lv_obj_t * obj, lv_flex_align_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_flex_grow(lv_obj_t * obj, uint8_t value, lv_style_selector_t selector);
|
||||
#endif /*LV_USE_FLEX*/
|
||||
|
||||
#if LV_USE_GRID
|
||||
void lv_obj_set_style_grid_column_dsc_array(lv_obj_t * obj, const int32_t * value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_grid_column_align(lv_obj_t * obj, lv_grid_align_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_grid_row_dsc_array(lv_obj_t * obj, const int32_t * value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_grid_row_align(lv_obj_t * obj, lv_grid_align_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_grid_cell_column_pos(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_grid_cell_x_align(lv_obj_t * obj, lv_grid_align_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_grid_cell_column_span(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_grid_cell_row_pos(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_grid_cell_y_align(lv_obj_t * obj, lv_grid_align_t value, lv_style_selector_t selector);
|
||||
void lv_obj_set_style_grid_cell_row_span(lv_obj_t * obj, int32_t value, lv_style_selector_t selector);
|
||||
#endif /*LV_USE_GRID*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* LV_OBJ_STYLE_GEN_H */
|
||||
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* @file lv_obj_style_private.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_OBJ_STYLE_PRIVATE_H
|
||||
#define LV_OBJ_STYLE_PRIVATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_obj_style.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
struct lv_obj_style_t {
|
||||
const lv_style_t * style;
|
||||
uint32_t selector : 24;
|
||||
uint32_t is_local : 1;
|
||||
uint32_t is_trans : 1;
|
||||
};
|
||||
|
||||
struct lv_obj_style_transition_dsc_t {
|
||||
uint16_t time;
|
||||
uint16_t delay;
|
||||
lv_style_selector_t selector;
|
||||
lv_style_prop_t prop;
|
||||
lv_anim_path_cb_t path_cb;
|
||||
void * user_data;
|
||||
};
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the object related style manager module.
|
||||
* Called by LVGL in `lv_init()`
|
||||
*/
|
||||
void lv_obj_style_init(void);
|
||||
|
||||
/**
|
||||
* Deinitialize the object related style manager module.
|
||||
* Called by LVGL in `lv_deinit()`
|
||||
*/
|
||||
void lv_obj_style_deinit(void);
|
||||
|
||||
/**
|
||||
* Used internally to create a style transition
|
||||
* @param obj
|
||||
* @param part
|
||||
* @param prev_state
|
||||
* @param new_state
|
||||
* @param tr
|
||||
*/
|
||||
void lv_obj_style_create_transition(lv_obj_t * obj, lv_part_t part, lv_state_t prev_state,
|
||||
lv_state_t new_state, const lv_obj_style_transition_dsc_t * tr);
|
||||
|
||||
/**
|
||||
* Used internally to compare the appearance of an object in 2 states
|
||||
* @param obj
|
||||
* @param state1
|
||||
* @param state2
|
||||
* @return
|
||||
*/
|
||||
lv_style_state_cmp_t lv_obj_style_state_compare(lv_obj_t * obj, lv_state_t state1, lv_state_t state2);
|
||||
|
||||
/**
|
||||
* Update the layer type of a widget bayed on its current styles.
|
||||
* The result will be stored in `obj->spec_attr->layer_type`
|
||||
* @param obj the object whose layer should be updated
|
||||
*/
|
||||
void lv_obj_update_layer_type(lv_obj_t * obj);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_OBJ_STYLE_PRIVATE_H*/
|
||||
662
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_tree.c
Normal file
662
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_tree.c
Normal file
@@ -0,0 +1,662 @@
|
||||
/**
|
||||
* @file lv_obj_tree.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_obj_private.h"
|
||||
#include "lv_obj_class_private.h"
|
||||
#include "../indev/lv_indev.h"
|
||||
#include "../indev/lv_indev_private.h"
|
||||
#include "../display/lv_display.h"
|
||||
#include "../display/lv_display_private.h"
|
||||
#include "../misc/lv_anim_private.h"
|
||||
#include "../misc/lv_async.h"
|
||||
#include "../core/lv_global.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define MY_CLASS (&lv_obj_class)
|
||||
#define disp_ll_p &(LV_GLOBAL_DEFAULT()->disp_ll)
|
||||
|
||||
#define OBJ_DUMP_STRING_LEN 128
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void lv_obj_delete_async_cb(void * obj);
|
||||
static void obj_delete_core(lv_obj_t * obj);
|
||||
static lv_obj_tree_walk_res_t walk_core(lv_obj_t * obj, lv_obj_tree_walk_cb_t cb, void * user_data);
|
||||
static void dump_tree_core(lv_obj_t * obj, int32_t depth);
|
||||
static lv_obj_t * lv_obj_get_first_not_deleting_child(lv_obj_t * obj);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_obj_delete(lv_obj_t * obj)
|
||||
{
|
||||
if(obj->is_deleting)
|
||||
return;
|
||||
|
||||
LV_LOG_TRACE("begin (delete %p)", (void *)obj);
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
lv_obj_invalidate(obj);
|
||||
|
||||
lv_obj_t * par = lv_obj_get_parent(obj);
|
||||
|
||||
lv_display_t * disp = NULL;
|
||||
bool act_screen_del = false;
|
||||
if(par == NULL) {
|
||||
disp = lv_obj_get_display(obj);
|
||||
if(!disp) return; /*Shouldn't happen*/
|
||||
if(disp->act_scr == obj) act_screen_del = true;
|
||||
}
|
||||
|
||||
obj_delete_core(obj);
|
||||
|
||||
/*Call the ancestor's event handler to the parent to notify it about the child delete*/
|
||||
if(par && !par->is_deleting) {
|
||||
lv_obj_scrollbar_invalidate(par);
|
||||
lv_obj_send_event(par, LV_EVENT_CHILD_CHANGED, NULL);
|
||||
lv_obj_send_event(par, LV_EVENT_CHILD_DELETED, NULL);
|
||||
}
|
||||
|
||||
/*Handle if the active screen was deleted*/
|
||||
if(act_screen_del) {
|
||||
LV_LOG_WARN("the active screen was deleted");
|
||||
disp->act_scr = NULL;
|
||||
}
|
||||
|
||||
LV_ASSERT_MEM_INTEGRITY();
|
||||
LV_LOG_TRACE("finished (delete %p)", (void *)obj);
|
||||
}
|
||||
|
||||
void lv_obj_clean(lv_obj_t * obj)
|
||||
{
|
||||
LV_LOG_TRACE("begin (clean %p)", (void *)obj);
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_obj_invalidate(obj);
|
||||
|
||||
uint32_t cnt = lv_obj_get_child_count(obj);
|
||||
lv_obj_t * child = lv_obj_get_first_not_deleting_child(obj);
|
||||
while(child) {
|
||||
obj_delete_core(child);
|
||||
child = lv_obj_get_first_not_deleting_child(obj);
|
||||
}
|
||||
/*Just to remove scroll animations if any*/
|
||||
lv_obj_scroll_to(obj, 0, 0, LV_ANIM_OFF);
|
||||
if(obj->spec_attr) {
|
||||
obj->spec_attr->scroll.x = 0;
|
||||
obj->spec_attr->scroll.y = 0;
|
||||
}
|
||||
|
||||
if(lv_obj_get_child_count(obj) < cnt) {
|
||||
lv_obj_send_event(obj, LV_EVENT_CHILD_CHANGED, NULL);
|
||||
lv_obj_send_event(obj, LV_EVENT_CHILD_DELETED, NULL);
|
||||
}
|
||||
|
||||
LV_ASSERT_MEM_INTEGRITY();
|
||||
|
||||
LV_LOG_TRACE("finished (clean %p)", (void *)obj);
|
||||
}
|
||||
|
||||
void lv_obj_delete_delayed(lv_obj_t * obj, uint32_t delay_ms)
|
||||
{
|
||||
lv_anim_t a;
|
||||
lv_anim_init(&a);
|
||||
lv_anim_set_var(&a, obj);
|
||||
lv_anim_set_exec_cb(&a, NULL);
|
||||
lv_anim_set_duration(&a, 1);
|
||||
lv_anim_set_delay(&a, delay_ms);
|
||||
lv_anim_set_completed_cb(&a, lv_obj_delete_anim_completed_cb);
|
||||
lv_anim_start(&a);
|
||||
}
|
||||
|
||||
void lv_obj_delete_anim_completed_cb(lv_anim_t * a)
|
||||
{
|
||||
lv_obj_delete(a->var);
|
||||
}
|
||||
|
||||
void lv_obj_delete_async(lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
lv_async_call(lv_obj_delete_async_cb, obj);
|
||||
}
|
||||
|
||||
void lv_obj_set_parent(lv_obj_t * obj, lv_obj_t * parent)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
LV_ASSERT_OBJ(parent, MY_CLASS);
|
||||
|
||||
if(obj->parent == NULL) {
|
||||
LV_LOG_WARN("Can't set the parent of a screen");
|
||||
return;
|
||||
}
|
||||
|
||||
if(parent == NULL) {
|
||||
LV_LOG_WARN("Can't set parent == NULL to an object");
|
||||
return;
|
||||
}
|
||||
|
||||
if(parent == obj->parent) {
|
||||
return;
|
||||
}
|
||||
|
||||
lv_obj_invalidate(obj);
|
||||
|
||||
lv_obj_allocate_spec_attr(parent);
|
||||
|
||||
lv_obj_t * old_parent = obj->parent;
|
||||
/*Remove the object from the old parent's child list*/
|
||||
int32_t i;
|
||||
for(i = lv_obj_get_index(obj); i <= (int32_t)lv_obj_get_child_count(old_parent) - 2; i++) {
|
||||
old_parent->spec_attr->children[i] = old_parent->spec_attr->children[i + 1];
|
||||
}
|
||||
old_parent->spec_attr->child_cnt--;
|
||||
if(old_parent->spec_attr->child_cnt) {
|
||||
old_parent->spec_attr->children = lv_realloc(old_parent->spec_attr->children,
|
||||
old_parent->spec_attr->child_cnt * (sizeof(lv_obj_t *)));
|
||||
}
|
||||
else {
|
||||
lv_free(old_parent->spec_attr->children);
|
||||
old_parent->spec_attr->children = NULL;
|
||||
}
|
||||
|
||||
/*Add the child to the new parent as the last (newest child)*/
|
||||
parent->spec_attr->child_cnt++;
|
||||
parent->spec_attr->children = lv_realloc(parent->spec_attr->children,
|
||||
parent->spec_attr->child_cnt * (sizeof(lv_obj_t *)));
|
||||
parent->spec_attr->children[lv_obj_get_child_count(parent) - 1] = obj;
|
||||
|
||||
obj->parent = parent;
|
||||
|
||||
/*Notify the original parent because one of its children is lost*/
|
||||
lv_obj_scrollbar_invalidate(old_parent);
|
||||
lv_obj_send_event(old_parent, LV_EVENT_CHILD_CHANGED, obj);
|
||||
lv_obj_send_event(old_parent, LV_EVENT_CHILD_DELETED, NULL);
|
||||
|
||||
/*Notify the new parent about the child*/
|
||||
lv_obj_send_event(parent, LV_EVENT_CHILD_CHANGED, obj);
|
||||
lv_obj_send_event(parent, LV_EVENT_CHILD_CREATED, NULL);
|
||||
|
||||
lv_obj_mark_layout_as_dirty(obj);
|
||||
|
||||
lv_obj_invalidate(obj);
|
||||
}
|
||||
|
||||
void lv_obj_move_to_index(lv_obj_t * obj, int32_t index)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
/* Check parent validity */
|
||||
lv_obj_t * parent = lv_obj_get_parent(obj);
|
||||
if(!parent) {
|
||||
LV_LOG_WARN("parent is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t parent_child_count = lv_obj_get_child_count(parent);
|
||||
/* old_index only can be 0 or greater, this point cannot be reached if the parent is not null */
|
||||
const int32_t old_index = lv_obj_get_index(obj);
|
||||
LV_ASSERT(0 <= old_index);
|
||||
|
||||
if(index < 0) {
|
||||
index += parent_child_count;
|
||||
}
|
||||
|
||||
/* Index was negative and the absolute value is greater than parent child count */
|
||||
if((index < 0)
|
||||
/* Index is same or bigger than parent child count */
|
||||
|| (index >= (int32_t) parent_child_count)
|
||||
/* If both previous and new index are the same */
|
||||
|| (index == old_index)) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t i = old_index;
|
||||
if(index < old_index) {
|
||||
while(i > index) {
|
||||
parent->spec_attr->children[i] = parent->spec_attr->children[i - 1];
|
||||
i--;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while(i < index) {
|
||||
parent->spec_attr->children[i] = parent->spec_attr->children[i + 1];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
parent->spec_attr->children[index] = obj;
|
||||
lv_obj_send_event(parent, LV_EVENT_CHILD_CHANGED, NULL);
|
||||
lv_obj_invalidate(parent);
|
||||
}
|
||||
|
||||
void lv_obj_swap(lv_obj_t * obj1, lv_obj_t * obj2)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj1, MY_CLASS);
|
||||
LV_ASSERT_OBJ(obj2, MY_CLASS);
|
||||
|
||||
lv_obj_t * parent = lv_obj_get_parent(obj1);
|
||||
lv_obj_t * parent2 = lv_obj_get_parent(obj2);
|
||||
|
||||
uint_fast32_t index1 = lv_obj_get_index(obj1);
|
||||
uint_fast32_t index2 = lv_obj_get_index(obj2);
|
||||
|
||||
lv_obj_send_event(parent2, LV_EVENT_CHILD_DELETED, obj2);
|
||||
lv_obj_send_event(parent, LV_EVENT_CHILD_DELETED, obj1);
|
||||
|
||||
parent->spec_attr->children[index1] = obj2;
|
||||
obj2->parent = parent;
|
||||
|
||||
parent2->spec_attr->children[index2] = obj1;
|
||||
obj1->parent = parent2;
|
||||
|
||||
lv_obj_send_event(parent, LV_EVENT_CHILD_CHANGED, obj2);
|
||||
lv_obj_send_event(parent, LV_EVENT_CHILD_CREATED, obj2);
|
||||
lv_obj_send_event(parent2, LV_EVENT_CHILD_CHANGED, obj1);
|
||||
lv_obj_send_event(parent2, LV_EVENT_CHILD_CREATED, obj1);
|
||||
|
||||
lv_obj_invalidate(parent);
|
||||
|
||||
if(parent != parent2) {
|
||||
lv_obj_invalidate(parent2);
|
||||
}
|
||||
lv_group_swap_obj(obj1, obj2);
|
||||
}
|
||||
|
||||
lv_obj_t * lv_obj_get_screen(const lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
const lv_obj_t * par = obj;
|
||||
const lv_obj_t * act_par;
|
||||
|
||||
do {
|
||||
act_par = par;
|
||||
par = lv_obj_get_parent(act_par);
|
||||
} while(par != NULL);
|
||||
|
||||
return (lv_obj_t *)act_par;
|
||||
}
|
||||
|
||||
lv_display_t * lv_obj_get_display(const lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
const lv_obj_t * scr;
|
||||
|
||||
if(obj->parent == NULL) scr = obj; /*`obj` is a screen*/
|
||||
else scr = lv_obj_get_screen(obj); /*get the screen of `obj`*/
|
||||
|
||||
lv_display_t * d;
|
||||
lv_ll_t * disp_head = disp_ll_p;
|
||||
LV_LL_READ(disp_head, d) {
|
||||
uint32_t i;
|
||||
for(i = 0; i < d->screen_cnt; i++) {
|
||||
if(d->screens[i] == scr) return d;
|
||||
}
|
||||
}
|
||||
|
||||
LV_LOG_WARN("No screen found");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_obj_t * lv_obj_get_parent(const lv_obj_t * obj)
|
||||
{
|
||||
if(obj == NULL) return NULL;
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
return obj->parent;
|
||||
}
|
||||
|
||||
lv_obj_t * lv_obj_get_child(const lv_obj_t * obj, int32_t idx)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
if(obj->spec_attr == NULL) return NULL;
|
||||
|
||||
uint32_t idu;
|
||||
if(idx < 0) {
|
||||
idx = obj->spec_attr->child_cnt + idx;
|
||||
if(idx < 0) return NULL;
|
||||
idu = (uint32_t) idx;
|
||||
}
|
||||
else {
|
||||
idu = idx;
|
||||
}
|
||||
|
||||
if(idu >= obj->spec_attr->child_cnt) return NULL;
|
||||
else return obj->spec_attr->children[idx];
|
||||
}
|
||||
|
||||
lv_obj_t * lv_obj_get_child_by_type(const lv_obj_t * obj, int32_t idx, const lv_obj_class_t * class_p)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
if(obj->spec_attr == NULL) return NULL;
|
||||
|
||||
int32_t i;
|
||||
int32_t cnt = (int32_t)obj->spec_attr->child_cnt;
|
||||
if(idx >= 0) {
|
||||
for(i = 0; i < cnt; i++) {
|
||||
if(obj->spec_attr->children[i]->class_p == class_p) {
|
||||
if(idx == 0) return obj->spec_attr->children[i];
|
||||
else idx--;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
idx++; /*-1 means the first child*/
|
||||
for(i = cnt - 1; i >= 0; i--) {
|
||||
if(obj->spec_attr->children[i]->class_p == class_p) {
|
||||
if(idx == 0) return obj->spec_attr->children[i];
|
||||
else idx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_obj_t * lv_obj_get_sibling(const lv_obj_t * obj, int32_t idx)
|
||||
{
|
||||
lv_obj_t * parent = lv_obj_get_parent(obj);
|
||||
int32_t sibling_idx = (int32_t)lv_obj_get_index(obj) + idx;
|
||||
if(sibling_idx < 0) return NULL;
|
||||
|
||||
return lv_obj_get_child(parent, sibling_idx);
|
||||
}
|
||||
|
||||
lv_obj_t * lv_obj_get_sibling_by_type(const lv_obj_t * obj, int32_t idx, const lv_obj_class_t * class_p)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_obj_t * parent = lv_obj_get_parent(obj);
|
||||
int32_t sibling_idx = (int32_t)lv_obj_get_index_by_type(obj, class_p) + idx;
|
||||
if(sibling_idx < 0) return NULL;
|
||||
|
||||
return lv_obj_get_child_by_type(parent, sibling_idx, class_p);
|
||||
}
|
||||
|
||||
uint32_t lv_obj_get_child_count(const lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
if(obj->spec_attr == NULL) return 0;
|
||||
return obj->spec_attr->child_cnt;
|
||||
}
|
||||
|
||||
uint32_t lv_obj_get_child_count_by_type(const lv_obj_t * obj, const lv_obj_class_t * class_p)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
if(obj->spec_attr == NULL) return 0;
|
||||
|
||||
uint32_t i;
|
||||
uint32_t cnt = 0;
|
||||
for(i = 0; i < obj->spec_attr->child_cnt; i++) {
|
||||
if(obj->spec_attr->children[i]->class_p == class_p) cnt++;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
int32_t lv_obj_get_index(const lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_obj_t * parent = lv_obj_get_parent(obj);
|
||||
if(parent == NULL) return -1;
|
||||
|
||||
int32_t i = 0;
|
||||
for(i = 0; i < parent->spec_attr->child_cnt; i++) {
|
||||
if(parent->spec_attr->children[i] == obj) return i;
|
||||
}
|
||||
|
||||
/*Shouldn't reach this point*/
|
||||
LV_ASSERT(0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t lv_obj_get_index_by_type(const lv_obj_t * obj, const lv_obj_class_t * class_p)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_obj_t * parent = lv_obj_get_parent(obj);
|
||||
if(parent == NULL) return 0xFFFFFFFF;
|
||||
|
||||
uint32_t i = 0;
|
||||
uint32_t idx = 0;
|
||||
for(i = 0; i < parent->spec_attr->child_cnt; i++) {
|
||||
lv_obj_t * child = parent->spec_attr->children[i];
|
||||
if(child->class_p == class_p) {
|
||||
if(child == obj) return idx;
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
/*Can happen if there was no children with the given type*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
void lv_obj_tree_walk(lv_obj_t * start_obj, lv_obj_tree_walk_cb_t cb, void * user_data)
|
||||
{
|
||||
walk_core(start_obj, cb, user_data);
|
||||
}
|
||||
|
||||
void lv_obj_dump_tree(lv_obj_t * start_obj)
|
||||
{
|
||||
if(start_obj == NULL) {
|
||||
lv_display_t * disp = lv_display_get_next(NULL);
|
||||
while(disp) {
|
||||
uint32_t i;
|
||||
for(i = 0; i < disp->screen_cnt; i++) {
|
||||
dump_tree_core(disp->screens[i], 0);
|
||||
}
|
||||
disp = lv_display_get_next(disp);
|
||||
}
|
||||
}
|
||||
else {
|
||||
dump_tree_core(start_obj, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void lv_obj_delete_async_cb(void * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_obj_delete(obj);
|
||||
}
|
||||
|
||||
static void obj_indev_reset(lv_indev_t * indev, lv_obj_t * obj)
|
||||
{
|
||||
/* If the input device is already in the release state,
|
||||
* there is no need to wait for the input device to be released
|
||||
*/
|
||||
if(lv_indev_get_state(indev) != LV_INDEV_STATE_RELEASED) {
|
||||
/*Wait for release to avoid accidentally triggering other obj to be clicked*/
|
||||
lv_indev_wait_release(indev);
|
||||
}
|
||||
|
||||
/*Reset the input device*/
|
||||
lv_indev_reset(indev, obj);
|
||||
}
|
||||
|
||||
static void obj_delete_core(lv_obj_t * obj)
|
||||
{
|
||||
if(obj->is_deleting)
|
||||
return;
|
||||
|
||||
obj->is_deleting = true;
|
||||
|
||||
/*Let the user free the resources used in `LV_EVENT_DELETE`*/
|
||||
lv_result_t res = lv_obj_send_event(obj, LV_EVENT_DELETE, NULL);
|
||||
if(res == LV_RESULT_INVALID) {
|
||||
obj->is_deleting = false;
|
||||
return;
|
||||
}
|
||||
|
||||
/*Clean registered event_cb*/
|
||||
if(obj->spec_attr) lv_event_remove_all(&(obj->spec_attr->event_list));
|
||||
|
||||
/*Recursively delete the children*/
|
||||
lv_obj_t * child = lv_obj_get_child(obj, 0);
|
||||
while(child) {
|
||||
obj_delete_core(child);
|
||||
child = lv_obj_get_child(obj, 0);
|
||||
}
|
||||
|
||||
lv_group_t * group = lv_obj_get_group(obj);
|
||||
|
||||
/*Reset all input devices if the object to delete is used*/
|
||||
lv_indev_t * indev = lv_indev_get_next(NULL);
|
||||
while(indev) {
|
||||
lv_indev_type_t indev_type = lv_indev_get_type(indev);
|
||||
if(indev_type == LV_INDEV_TYPE_POINTER || indev_type == LV_INDEV_TYPE_BUTTON) {
|
||||
if(indev->pointer.act_obj == obj || indev->pointer.last_obj == obj || indev->pointer.scroll_obj == obj) {
|
||||
obj_indev_reset(indev, obj);
|
||||
}
|
||||
if(indev->pointer.last_pressed == obj) {
|
||||
indev->pointer.last_pressed = NULL;
|
||||
}
|
||||
if(indev->pointer.last_hovered == obj) {
|
||||
indev->pointer.last_hovered = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if(indev->group == group && obj == lv_indev_get_active_obj()) {
|
||||
obj_indev_reset(indev, obj);
|
||||
}
|
||||
indev = lv_indev_get_next(indev);
|
||||
}
|
||||
|
||||
/*Delete all pending async del-s*/
|
||||
lv_result_t async_cancel_res = LV_RESULT_OK;
|
||||
while(async_cancel_res == LV_RESULT_OK) {
|
||||
async_cancel_res = lv_async_call_cancel(lv_obj_delete_async_cb, obj);
|
||||
}
|
||||
|
||||
/*All children deleted. Now clean up the object specific data*/
|
||||
lv_obj_destruct(obj);
|
||||
|
||||
/*Remove the screen for the screen list*/
|
||||
if(obj->parent == NULL) {
|
||||
lv_display_t * disp = lv_obj_get_display(obj);
|
||||
uint32_t i;
|
||||
/*Find the screen in the list*/
|
||||
for(i = 0; i < disp->screen_cnt; i++) {
|
||||
if(disp->screens[i] == obj) break;
|
||||
}
|
||||
|
||||
uint32_t id = i;
|
||||
for(i = id; i < disp->screen_cnt - 1; i++) {
|
||||
disp->screens[i] = disp->screens[i + 1];
|
||||
}
|
||||
disp->screen_cnt--;
|
||||
disp->screens = lv_realloc(disp->screens, disp->screen_cnt * sizeof(lv_obj_t *));
|
||||
}
|
||||
/*Remove the object from the child list of its parent*/
|
||||
else {
|
||||
int32_t id = lv_obj_get_index(obj);
|
||||
uint16_t i;
|
||||
for(i = id; i < obj->parent->spec_attr->child_cnt - 1; i++) {
|
||||
obj->parent->spec_attr->children[i] = obj->parent->spec_attr->children[i + 1];
|
||||
}
|
||||
obj->parent->spec_attr->child_cnt--;
|
||||
obj->parent->spec_attr->children = lv_realloc(obj->parent->spec_attr->children,
|
||||
obj->parent->spec_attr->child_cnt * sizeof(lv_obj_t *));
|
||||
}
|
||||
|
||||
/*Free the object itself*/
|
||||
lv_free(obj);
|
||||
}
|
||||
|
||||
static lv_obj_tree_walk_res_t walk_core(lv_obj_t * obj, lv_obj_tree_walk_cb_t cb, void * user_data)
|
||||
{
|
||||
lv_obj_tree_walk_res_t res = LV_OBJ_TREE_WALK_NEXT;
|
||||
|
||||
if(obj == NULL) {
|
||||
lv_display_t * disp = lv_display_get_next(NULL);
|
||||
while(disp) {
|
||||
uint32_t i;
|
||||
for(i = 0; i < disp->screen_cnt; i++) {
|
||||
walk_core(disp->screens[i], cb, user_data);
|
||||
}
|
||||
disp = lv_display_get_next(disp);
|
||||
}
|
||||
return LV_OBJ_TREE_WALK_END; /*The value doesn't matter as it wasn't called recursively*/
|
||||
}
|
||||
|
||||
res = cb(obj, user_data);
|
||||
|
||||
if(res == LV_OBJ_TREE_WALK_END) return LV_OBJ_TREE_WALK_END;
|
||||
|
||||
if(res != LV_OBJ_TREE_WALK_SKIP_CHILDREN) {
|
||||
uint32_t i;
|
||||
for(i = 0; i < lv_obj_get_child_count(obj); i++) {
|
||||
res = walk_core(lv_obj_get_child(obj, i), cb, user_data);
|
||||
if(res == LV_OBJ_TREE_WALK_END) return LV_OBJ_TREE_WALK_END;
|
||||
}
|
||||
}
|
||||
return LV_OBJ_TREE_WALK_NEXT;
|
||||
}
|
||||
|
||||
static void dump_tree_core(lv_obj_t * obj, int32_t depth)
|
||||
{
|
||||
#if LV_USE_LOG
|
||||
const char * id;
|
||||
|
||||
#if LV_USE_OBJ_ID
|
||||
char buf[OBJ_DUMP_STRING_LEN];
|
||||
id = lv_obj_stringify_id(obj, buf, sizeof(buf));
|
||||
if(id == NULL) id = "obj0";
|
||||
#else
|
||||
id = "obj0";
|
||||
#endif
|
||||
|
||||
/*id of `obj0` is an invalid id for builtin id*/
|
||||
LV_LOG_USER("parent:%p, obj:%p, id:%s;", (void *)(obj ? obj->parent : NULL), (void *)obj, id);
|
||||
#endif /*LV_USE_LOG*/
|
||||
|
||||
if(obj && obj->spec_attr && obj->spec_attr->child_cnt) {
|
||||
for(uint32_t i = 0; i < obj->spec_attr->child_cnt; i++) {
|
||||
dump_tree_core(lv_obj_get_child(obj, i), depth + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static lv_obj_t * lv_obj_get_first_not_deleting_child(lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
if(obj->spec_attr == NULL) return NULL;
|
||||
|
||||
int32_t i;
|
||||
int32_t cnt = (int32_t)obj->spec_attr->child_cnt;
|
||||
for(i = 0; i < cnt; i++) {
|
||||
if(!obj->spec_attr->children[i]->is_deleting) {
|
||||
return obj->spec_attr->children[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
237
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_tree.h
Normal file
237
software/Power_Pico/Middlewares/LVGL/src/core/lv_obj_tree.h
Normal file
@@ -0,0 +1,237 @@
|
||||
/**
|
||||
* @file lv_obj_tree.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_OBJ_TREE_H
|
||||
#define LV_OBJ_TREE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../misc/lv_types.h"
|
||||
#include "../misc/lv_anim.h"
|
||||
#include "../display/lv_display.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef enum {
|
||||
LV_OBJ_TREE_WALK_NEXT,
|
||||
LV_OBJ_TREE_WALK_SKIP_CHILDREN,
|
||||
LV_OBJ_TREE_WALK_END,
|
||||
} lv_obj_tree_walk_res_t;
|
||||
|
||||
typedef lv_obj_tree_walk_res_t (*lv_obj_tree_walk_cb_t)(lv_obj_t *, void *);
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Delete an object and all of its children.
|
||||
* Also remove the objects from their group and remove all animations (if any).
|
||||
* Send `LV_EVENT_DELETED` to deleted objects.
|
||||
* @param obj pointer to an object
|
||||
*/
|
||||
void lv_obj_delete(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Delete all children of an object.
|
||||
* Also remove the objects from their group and remove all animations (if any).
|
||||
* Send `LV_EVENT_DELETED` to deleted objects.
|
||||
* @param obj pointer to an object
|
||||
*/
|
||||
void lv_obj_clean(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Delete an object after some delay
|
||||
* @param obj pointer to an object
|
||||
* @param delay_ms time to wait before delete in milliseconds
|
||||
*/
|
||||
void lv_obj_delete_delayed(lv_obj_t * obj, uint32_t delay_ms);
|
||||
|
||||
/**
|
||||
* A function to be easily used in animation ready callback to delete an object when the animation is ready
|
||||
* @param a pointer to the animation
|
||||
*/
|
||||
void lv_obj_delete_anim_completed_cb(lv_anim_t * a);
|
||||
|
||||
/**
|
||||
* Helper function for asynchronously deleting objects.
|
||||
* Useful for cases where you can't delete an object directly in an `LV_EVENT_DELETE` handler (i.e. parent).
|
||||
* @param obj object to delete
|
||||
* @see lv_async_call
|
||||
*/
|
||||
void lv_obj_delete_async(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Move the parent of an object. The relative coordinates will be kept.
|
||||
*
|
||||
* @param obj pointer to an object whose parent needs to be changed
|
||||
* @param parent pointer to the new parent
|
||||
*/
|
||||
void lv_obj_set_parent(lv_obj_t * obj, lv_obj_t * parent);
|
||||
|
||||
/**
|
||||
* Swap the positions of two objects.
|
||||
* When used in listboxes, it can be used to sort the listbox items.
|
||||
* @param obj1 pointer to the first object
|
||||
* @param obj2 pointer to the second object
|
||||
*/
|
||||
void lv_obj_swap(lv_obj_t * obj1, lv_obj_t * obj2);
|
||||
|
||||
/**
|
||||
* moves the object to the given index in its parent.
|
||||
* When used in listboxes, it can be used to sort the listbox items.
|
||||
* @param obj pointer to the object to be moved.
|
||||
* @param index new index in parent. -1 to count from the back
|
||||
* @note to move to the background: lv_obj_move_to_index(obj, 0)
|
||||
* @note to move forward (up): lv_obj_move_to_index(obj, lv_obj_get_index(obj) - 1)
|
||||
*/
|
||||
void lv_obj_move_to_index(lv_obj_t * obj, int32_t index);
|
||||
|
||||
/**
|
||||
* Get the screen of an object
|
||||
* @param obj pointer to an object
|
||||
* @return pointer to the object's screen
|
||||
*/
|
||||
lv_obj_t * lv_obj_get_screen(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the display of the object
|
||||
* @param obj pointer to an object
|
||||
* @return pointer to the object's display
|
||||
*/
|
||||
lv_display_t * lv_obj_get_display(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the parent of an object
|
||||
* @param obj pointer to an object
|
||||
* @return the parent of the object. (NULL if `obj` was a screen)
|
||||
*/
|
||||
lv_obj_t * lv_obj_get_parent(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the child of an object by the child's index.
|
||||
* @param obj pointer to an object whose child should be get
|
||||
* @param idx the index of the child.
|
||||
* 0: the oldest (firstly created) child
|
||||
* 1: the second oldest
|
||||
* child count-1: the youngest
|
||||
* -1: the youngest
|
||||
* -2: the second youngest
|
||||
* @return pointer to the child or NULL if the index was invalid
|
||||
*/
|
||||
lv_obj_t * lv_obj_get_child(const lv_obj_t * obj, int32_t idx);
|
||||
|
||||
/**
|
||||
* Get the child of an object by the child's index. Consider the children only with a given type.
|
||||
* @param obj pointer to an object whose child should be get
|
||||
* @param idx the index of the child.
|
||||
* 0: the oldest (firstly created) child
|
||||
* 1: the second oldest
|
||||
* child count-1: the youngest
|
||||
* -1: the youngest
|
||||
* -2: the second youngest
|
||||
* @param class_p the type of the children to check
|
||||
* @return pointer to the child or NULL if the index was invalid
|
||||
*/
|
||||
lv_obj_t * lv_obj_get_child_by_type(const lv_obj_t * obj, int32_t idx,
|
||||
const lv_obj_class_t * class_p);
|
||||
|
||||
/**
|
||||
* Return a sibling of an object
|
||||
* @param obj pointer to an object whose sibling should be get
|
||||
* @param idx 0: `obj` itself
|
||||
* -1: the first older sibling
|
||||
* -2: the next older sibling
|
||||
* 1: the first younger sibling
|
||||
* 2: the next younger sibling
|
||||
* etc
|
||||
* @return pointer to the requested sibling or NULL if there is no such sibling
|
||||
*/
|
||||
lv_obj_t * lv_obj_get_sibling(const lv_obj_t * obj, int32_t idx);
|
||||
|
||||
/**
|
||||
* Return a sibling of an object. Consider the siblings only with a given type.
|
||||
* @param obj pointer to an object whose sibling should be get
|
||||
* @param idx 0: `obj` itself
|
||||
* -1: the first older sibling
|
||||
* -2: the next older sibling
|
||||
* 1: the first younger sibling
|
||||
* 2: the next younger sibling
|
||||
* etc
|
||||
* @param class_p the type of the children to check
|
||||
* @return pointer to the requested sibling or NULL if there is no such sibling
|
||||
*/
|
||||
lv_obj_t * lv_obj_get_sibling_by_type(const lv_obj_t * obj, int32_t idx,
|
||||
const lv_obj_class_t * class_p);
|
||||
|
||||
/**
|
||||
* Get the number of children
|
||||
* @param obj pointer to an object
|
||||
* @return the number of children
|
||||
*/
|
||||
uint32_t lv_obj_get_child_count(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the number of children having a given type.
|
||||
* @param obj pointer to an object
|
||||
* @param class_p the type of the children to check
|
||||
* @return the number of children
|
||||
*/
|
||||
|
||||
uint32_t lv_obj_get_child_count_by_type(const lv_obj_t * obj, const lv_obj_class_t * class_p);
|
||||
|
||||
/**
|
||||
* Get the index of a child.
|
||||
* @param obj pointer to an object
|
||||
* @return the child index of the object.
|
||||
* E.g. 0: the oldest (firstly created child).
|
||||
* (-1 if child could not be found or no parent exists)
|
||||
*/
|
||||
int32_t lv_obj_get_index(const lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the index of a child. Consider the children only with a given type.
|
||||
* @param obj pointer to an object
|
||||
* @param class_p the type of the children to check
|
||||
* @return the child index of the object.
|
||||
* E.g. 0: the oldest (firstly created child with the given class).
|
||||
* (-1 if child could not be found or no parent exists)
|
||||
*/
|
||||
int32_t lv_obj_get_index_by_type(const lv_obj_t * obj, const lv_obj_class_t * class_p);
|
||||
|
||||
/**
|
||||
* Iterate through all children of any object.
|
||||
* @param start_obj start integrating from this object
|
||||
* @param cb call this callback on the objects
|
||||
* @param user_data pointer to any user related data (will be passed to `cb`)
|
||||
*/
|
||||
void lv_obj_tree_walk(lv_obj_t * start_obj, lv_obj_tree_walk_cb_t cb, void * user_data);
|
||||
|
||||
/**
|
||||
* Iterate through all children of any object and print their ID.
|
||||
* @param start_obj start integrating from this object
|
||||
*/
|
||||
void lv_obj_dump_tree(lv_obj_t * start_obj);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_OBJ_TREE_H*/
|
||||
1239
software/Power_Pico/Middlewares/LVGL/src/core/lv_refr.c
Normal file
1239
software/Power_Pico/Middlewares/LVGL/src/core/lv_refr.c
Normal file
File diff suppressed because it is too large
Load Diff
68
software/Power_Pico/Middlewares/LVGL/src/core/lv_refr.h
Normal file
68
software/Power_Pico/Middlewares/LVGL/src/core/lv_refr.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* @file lv_refr.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_REFR_H
|
||||
#define LV_REFR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_obj.h"
|
||||
#include "../display/lv_display.h"
|
||||
#include "../misc/lv_types.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Redraw the invalidated areas now.
|
||||
* Normally the redrawing is periodically executed in `lv_timer_handler` but a long blocking process
|
||||
* can prevent the call of `lv_timer_handler`. In this case if the GUI is updated in the process
|
||||
* (e.g. progress bar) this function can be called when the screen should be updated.
|
||||
* @param disp pointer to display to refresh. NULL to refresh all displays.
|
||||
*/
|
||||
void lv_refr_now(lv_display_t * disp);
|
||||
|
||||
/**
|
||||
* Redrawn on object and all its children using the passed draw context
|
||||
* @param layer pointer to a layer where to draw.
|
||||
* @param obj the start object from the redraw should start
|
||||
*/
|
||||
void lv_obj_redraw(lv_layer_t * layer, lv_obj_t * obj);
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_REFR_H*/
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* @file lv_refr_private.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_REFR_PRIVATE_H
|
||||
#define LV_REFR_PRIVATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_refr.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the screen refresh subsystem
|
||||
*/
|
||||
void lv_refr_init(void);
|
||||
|
||||
/**
|
||||
* Deinitialize the screen refresh subsystem
|
||||
*/
|
||||
void lv_refr_deinit(void);
|
||||
|
||||
/**
|
||||
* Invalidate an area on display to redraw it
|
||||
* @param area_p pointer to area which should be invalidated (NULL: delete the invalidated areas)
|
||||
* @param disp pointer to display where the area should be invalidated (NULL can be used if there is
|
||||
* only one display)
|
||||
*/
|
||||
void lv_inv_area(lv_display_t * disp, const lv_area_t * area_p);
|
||||
|
||||
/**
|
||||
* Get the display which is being refreshed
|
||||
* @return the display being refreshed
|
||||
*/
|
||||
lv_display_t * lv_refr_get_disp_refreshing(void);
|
||||
|
||||
/**
|
||||
* Set the display which is being refreshed
|
||||
* @param disp the display being refreshed
|
||||
*/
|
||||
void lv_refr_set_disp_refreshing(lv_display_t * disp);
|
||||
|
||||
/**
|
||||
* Called periodically to handle the refreshing
|
||||
* @param timer pointer to the timer itself
|
||||
*/
|
||||
void lv_display_refr_timer(lv_timer_t * timer);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_REFR_PRIVATE_H*/
|
||||
1134
software/Power_Pico/Middlewares/LVGL/src/display/lv_display.c
Normal file
1134
software/Power_Pico/Middlewares/LVGL/src/display/lv_display.c
Normal file
File diff suppressed because it is too large
Load Diff
593
software/Power_Pico/Middlewares/LVGL/src/display/lv_display.h
Normal file
593
software/Power_Pico/Middlewares/LVGL/src/display/lv_display.h
Normal file
@@ -0,0 +1,593 @@
|
||||
/**
|
||||
* @file lv_display.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DISPLAY_H
|
||||
#define LV_DISPLAY_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../misc/lv_types.h"
|
||||
#include "../misc/lv_timer.h"
|
||||
#include "../misc/lv_event.h"
|
||||
#include "../misc/lv_color.h"
|
||||
#include "../draw/lv_draw.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#ifndef LV_ATTRIBUTE_FLUSH_READY
|
||||
#define LV_ATTRIBUTE_FLUSH_READY
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef enum {
|
||||
LV_DISPLAY_ROTATION_0 = 0,
|
||||
LV_DISPLAY_ROTATION_90,
|
||||
LV_DISPLAY_ROTATION_180,
|
||||
LV_DISPLAY_ROTATION_270
|
||||
} lv_display_rotation_t;
|
||||
|
||||
typedef enum {
|
||||
/**
|
||||
* Use the buffer(s) to render the screen is smaller parts.
|
||||
* This way the buffers can be smaller then the display to save RAM. At least 1/10 screen size buffer(s) are recommended.
|
||||
*/
|
||||
LV_DISPLAY_RENDER_MODE_PARTIAL,
|
||||
|
||||
/**
|
||||
* The buffer(s) has to be screen sized and LVGL will render into the correct location of the buffer.
|
||||
* This way the buffer always contain the whole image. Only the changed ares will be updated.
|
||||
* With 2 buffers the buffers' content are kept in sync automatically and in flush_cb only address change is required.
|
||||
*/
|
||||
LV_DISPLAY_RENDER_MODE_DIRECT,
|
||||
|
||||
/**
|
||||
* Always redraw the whole screen even if only one pixel has been changed.
|
||||
* With 2 buffers in flush_cb only and address change is required.
|
||||
*/
|
||||
LV_DISPLAY_RENDER_MODE_FULL,
|
||||
} lv_display_render_mode_t;
|
||||
|
||||
typedef enum {
|
||||
LV_SCR_LOAD_ANIM_NONE,
|
||||
LV_SCR_LOAD_ANIM_OVER_LEFT,
|
||||
LV_SCR_LOAD_ANIM_OVER_RIGHT,
|
||||
LV_SCR_LOAD_ANIM_OVER_TOP,
|
||||
LV_SCR_LOAD_ANIM_OVER_BOTTOM,
|
||||
LV_SCR_LOAD_ANIM_MOVE_LEFT,
|
||||
LV_SCR_LOAD_ANIM_MOVE_RIGHT,
|
||||
LV_SCR_LOAD_ANIM_MOVE_TOP,
|
||||
LV_SCR_LOAD_ANIM_MOVE_BOTTOM,
|
||||
LV_SCR_LOAD_ANIM_FADE_IN,
|
||||
LV_SCR_LOAD_ANIM_FADE_ON = LV_SCR_LOAD_ANIM_FADE_IN, /*For backward compatibility*/
|
||||
LV_SCR_LOAD_ANIM_FADE_OUT,
|
||||
LV_SCR_LOAD_ANIM_OUT_LEFT,
|
||||
LV_SCR_LOAD_ANIM_OUT_RIGHT,
|
||||
LV_SCR_LOAD_ANIM_OUT_TOP,
|
||||
LV_SCR_LOAD_ANIM_OUT_BOTTOM,
|
||||
} lv_screen_load_anim_t;
|
||||
|
||||
typedef void (*lv_display_flush_cb_t)(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map);
|
||||
typedef void (*lv_display_flush_wait_cb_t)(lv_display_t * disp);
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Create a new display with the given resolution
|
||||
* @param hor_res horizontal resolution in pixels
|
||||
* @param ver_res vertical resolution in pixels
|
||||
* @return pointer to a display object or `NULL` on error
|
||||
*/
|
||||
lv_display_t * lv_display_create(int32_t hor_res, int32_t ver_res);
|
||||
|
||||
/**
|
||||
* Remove a display
|
||||
* @param disp pointer to display
|
||||
*/
|
||||
void lv_display_delete(lv_display_t * disp);
|
||||
|
||||
/**
|
||||
* Set a default display. The new screens will be created on it by default.
|
||||
* @param disp pointer to a display
|
||||
*/
|
||||
void lv_display_set_default(lv_display_t * disp);
|
||||
|
||||
/**
|
||||
* Get the default display
|
||||
* @return pointer to the default display
|
||||
*/
|
||||
lv_display_t * lv_display_get_default(void);
|
||||
|
||||
/**
|
||||
* Get the next display.
|
||||
* @param disp pointer to the current display. NULL to initialize.
|
||||
* @return the next display or NULL if no more. Gives the first display when the parameter is NULL.
|
||||
*/
|
||||
lv_display_t * lv_display_get_next(lv_display_t * disp);
|
||||
|
||||
/*---------------------
|
||||
* RESOLUTION
|
||||
*--------------------*/
|
||||
|
||||
/**
|
||||
* Sets the resolution of a display. `LV_EVENT_RESOLUTION_CHANGED` event will be sent.
|
||||
* Here the native resolution of the device should be set. If the display will be rotated later with
|
||||
* `lv_display_set_rotation` LVGL will swap the hor. and ver. resolution automatically.
|
||||
* @param disp pointer to a display
|
||||
* @param hor_res the new horizontal resolution
|
||||
* @param ver_res the new vertical resolution
|
||||
*/
|
||||
void lv_display_set_resolution(lv_display_t * disp, int32_t hor_res, int32_t ver_res);
|
||||
|
||||
/**
|
||||
* It's not mandatory to use the whole display for LVGL, however in some cases physical resolution is important.
|
||||
* For example the touchpad still sees whole resolution and the values needs to be converted
|
||||
* to the active LVGL display area.
|
||||
* @param disp pointer to a display
|
||||
* @param hor_res the new physical horizontal resolution, or -1 to assume it's the same as the normal hor. res.
|
||||
* @param ver_res the new physical vertical resolution, or -1 to assume it's the same as the normal hor. res.
|
||||
*/
|
||||
void lv_display_set_physical_resolution(lv_display_t * disp, int32_t hor_res, int32_t ver_res);
|
||||
|
||||
/**
|
||||
* If physical resolution is not the same as the normal resolution
|
||||
* the offset of the active display area can be set here.
|
||||
* @param disp pointer to a display
|
||||
* @param x X offset
|
||||
* @param y Y offset
|
||||
*/
|
||||
void lv_display_set_offset(lv_display_t * disp, int32_t x, int32_t y);
|
||||
|
||||
/**
|
||||
* Set the rotation of this display. LVGL will swap the horizontal and vertical resolutions internally.
|
||||
* @param disp pointer to a display (NULL to use the default display)
|
||||
* @param rotation `LV_DISPLAY_ROTATION_0/90/180/270`
|
||||
*/
|
||||
void lv_display_set_rotation(lv_display_t * disp, lv_display_rotation_t rotation);
|
||||
|
||||
/**
|
||||
* Set the DPI (dot per inch) of the display.
|
||||
* dpi = sqrt(hor_res^2 + ver_res^2) / diagonal"
|
||||
* @param disp pointer to a display
|
||||
* @param dpi the new DPI
|
||||
*/
|
||||
void lv_display_set_dpi(lv_display_t * disp, int32_t dpi);
|
||||
|
||||
/**
|
||||
* Get the horizontal resolution of a display.
|
||||
* @param disp pointer to a display (NULL to use the default display)
|
||||
* @return the horizontal resolution of the display.
|
||||
*/
|
||||
int32_t lv_display_get_horizontal_resolution(const lv_display_t * disp);
|
||||
|
||||
/**
|
||||
* Get the vertical resolution of a display
|
||||
* @param disp pointer to a display (NULL to use the default display)
|
||||
* @return the vertical resolution of the display
|
||||
*/
|
||||
int32_t lv_display_get_vertical_resolution(const lv_display_t * disp);
|
||||
|
||||
/**
|
||||
* Get the physical horizontal resolution of a display
|
||||
* @param disp pointer to a display (NULL to use the default display)
|
||||
* @return the physical horizontal resolution of the display
|
||||
*/
|
||||
int32_t lv_display_get_physical_horizontal_resolution(const lv_display_t * disp);
|
||||
|
||||
/**
|
||||
* Get the physical vertical resolution of a display
|
||||
* @param disp pointer to a display (NULL to use the default display)
|
||||
* @return the physical vertical resolution of the display
|
||||
*/
|
||||
int32_t lv_display_get_physical_vertical_resolution(const lv_display_t * disp);
|
||||
|
||||
/**
|
||||
* Get the horizontal offset from the full / physical display
|
||||
* @param disp pointer to a display (NULL to use the default display)
|
||||
* @return the horizontal offset from the physical display
|
||||
*/
|
||||
int32_t lv_display_get_offset_x(const lv_display_t * disp);
|
||||
|
||||
/**
|
||||
* Get the vertical offset from the full / physical display
|
||||
* @param disp pointer to a display (NULL to use the default display)
|
||||
* @return the horizontal offset from the physical display
|
||||
*/
|
||||
int32_t lv_display_get_offset_y(const lv_display_t * disp);
|
||||
|
||||
/**
|
||||
* Get the current rotation of this display.
|
||||
* @param disp pointer to a display (NULL to use the default display)
|
||||
* @return the current rotation
|
||||
*/
|
||||
lv_display_rotation_t lv_display_get_rotation(lv_display_t * disp);
|
||||
|
||||
/**
|
||||
* Get the DPI of the display
|
||||
* @param disp pointer to a display (NULL to use the default display)
|
||||
* @return dpi of the display
|
||||
*/
|
||||
int32_t lv_display_get_dpi(const lv_display_t * disp);
|
||||
|
||||
/*---------------------
|
||||
* BUFFERING
|
||||
*--------------------*/
|
||||
|
||||
/**
|
||||
* Set the buffers for a display, similarly to `lv_display_set_draw_buffers`, but accept the raw buffer pointers.
|
||||
* For DIRECT/FULL rending modes, the buffer size must be at least
|
||||
* `hor_res * ver_res * lv_color_format_get_size(lv_display_get_color_format(disp))`
|
||||
* @param disp pointer to a display
|
||||
* @param buf1 first buffer
|
||||
* @param buf2 second buffer (can be `NULL`)
|
||||
* @param buf_size buffer size in byte
|
||||
* @param render_mode LV_DISPLAY_RENDER_MODE_PARTIAL/DIRECT/FULL
|
||||
*/
|
||||
void lv_display_set_buffers(lv_display_t * disp, void * buf1, void * buf2, uint32_t buf_size,
|
||||
lv_display_render_mode_t render_mode);
|
||||
|
||||
/**
|
||||
* Set the buffers for a display, accept a draw buffer pointer.
|
||||
* Normally use `lv_display_set_buffers` is enough for most cases.
|
||||
* Use this function when an existing lv_draw_buf_t is available.
|
||||
* @param disp pointer to a display
|
||||
* @param buf1 first buffer
|
||||
* @param buf2 second buffer (can be `NULL`)
|
||||
*/
|
||||
void lv_display_set_draw_buffers(lv_display_t * disp, lv_draw_buf_t * buf1, lv_draw_buf_t * buf2);
|
||||
|
||||
/**
|
||||
* Set display render mode
|
||||
* @param disp pointer to a display
|
||||
* @param render_mode LV_DISPLAY_RENDER_MODE_PARTIAL/DIRECT/FULL
|
||||
*/
|
||||
void lv_display_set_render_mode(lv_display_t * disp, lv_display_render_mode_t render_mode);
|
||||
|
||||
/**
|
||||
* Set the flush callback which will be called to copy the rendered image to the display.
|
||||
* @param disp pointer to a display
|
||||
* @param flush_cb the flush callback (`px_map` contains the rendered image as raw pixel map and it should be copied to `area` on the display)
|
||||
*/
|
||||
void lv_display_set_flush_cb(lv_display_t * disp, lv_display_flush_cb_t flush_cb);
|
||||
|
||||
/**
|
||||
* Set a callback to be used while LVGL is waiting flushing to be finished.
|
||||
* It can do any complex logic to wait, including semaphores, mutexes, polling flags, etc.
|
||||
* If not set the `disp->flushing` flag is used which can be cleared with `lv_display_flush_ready()`
|
||||
* @param disp pointer to a display
|
||||
* @param wait_cb a callback to call while LVGL is waiting for flush ready.
|
||||
* If NULL `lv_display_flush_ready()` can be used to signal that flushing is ready.
|
||||
*/
|
||||
void lv_display_set_flush_wait_cb(lv_display_t * disp, lv_display_flush_wait_cb_t wait_cb);
|
||||
|
||||
/**
|
||||
* Set the color format of the display.
|
||||
* @param disp pointer to a display
|
||||
* @param color_format Possible values are
|
||||
* - LV_COLOR_FORMAT_RGB565
|
||||
* - LV_COLOR_FORMAT_RGB888
|
||||
* - LV_COLOR_FORMAT_XRGB888
|
||||
* - LV_COLOR_FORMAT_ARGB888
|
||||
*@note To change the endianness of the rendered image in case of RGB565 format
|
||||
* (i.e. swap the 2 bytes) call `lv_draw_sw_rgb565_swap` in the flush_cb
|
||||
*/
|
||||
void lv_display_set_color_format(lv_display_t * disp, lv_color_format_t color_format);
|
||||
|
||||
/**
|
||||
* Get the color format of the display
|
||||
* @param disp pointer to a display
|
||||
* @return the color format
|
||||
*/
|
||||
lv_color_format_t lv_display_get_color_format(lv_display_t * disp);
|
||||
|
||||
/**
|
||||
* Enable anti-aliasing for the render engine
|
||||
* @param disp pointer to a display
|
||||
* @param en true/false
|
||||
*/
|
||||
void lv_display_set_antialiasing(lv_display_t * disp, bool en);
|
||||
|
||||
/**
|
||||
* Get if anti-aliasing is enabled for a display or not
|
||||
* @param disp pointer to a display (NULL to use the default display)
|
||||
* @return true/false
|
||||
*/
|
||||
bool lv_display_get_antialiasing(lv_display_t * disp);
|
||||
|
||||
//! @cond Doxygen_Suppress
|
||||
|
||||
/**
|
||||
* Call from the display driver when the flushing is finished
|
||||
* @param disp pointer to display whose `flush_cb` was called
|
||||
*/
|
||||
LV_ATTRIBUTE_FLUSH_READY void lv_display_flush_ready(lv_display_t * disp);
|
||||
|
||||
/**
|
||||
* Tell if it's the last area of the refreshing process.
|
||||
* Can be called from `flush_cb` to execute some special display refreshing if needed when all areas area flushed.
|
||||
* @param disp pointer to display
|
||||
* @return true: it's the last area to flush;
|
||||
* false: there are other areas too which will be refreshed soon
|
||||
*/
|
||||
LV_ATTRIBUTE_FLUSH_READY bool lv_display_flush_is_last(lv_display_t * disp);
|
||||
|
||||
//! @endcond
|
||||
|
||||
bool lv_display_is_double_buffered(lv_display_t * disp);
|
||||
|
||||
/*---------------------
|
||||
* SCREENS
|
||||
*--------------------*/
|
||||
|
||||
/**
|
||||
* Return a pointer to the active screen on a display
|
||||
* @param disp pointer to display which active screen should be get.
|
||||
* (NULL to use the default screen)
|
||||
* @return pointer to the active screen object (loaded by 'lv_screen_load()')
|
||||
*/
|
||||
lv_obj_t * lv_display_get_screen_active(lv_display_t * disp);
|
||||
|
||||
/**
|
||||
* Return with a pointer to the previous screen. Only used during screen transitions.
|
||||
* @param disp pointer to display which previous screen should be get.
|
||||
* (NULL to use the default screen)
|
||||
* @return pointer to the previous screen object or NULL if not used now
|
||||
*/
|
||||
lv_obj_t * lv_display_get_screen_prev(lv_display_t * disp);
|
||||
|
||||
/**
|
||||
* Return the top layer. The top layer is the same on all screens and it is above the normal screen layer.
|
||||
* @param disp pointer to display which top layer should be get. (NULL to use the default screen)
|
||||
* @return pointer to the top layer object
|
||||
*/
|
||||
lv_obj_t * lv_display_get_layer_top(lv_display_t * disp);
|
||||
|
||||
/**
|
||||
* Return the sys. layer. The system layer is the same on all screen and it is above the normal screen and the top layer.
|
||||
* @param disp pointer to display which sys. layer should be retrieved. (NULL to use the default screen)
|
||||
* @return pointer to the sys layer object
|
||||
*/
|
||||
lv_obj_t * lv_display_get_layer_sys(lv_display_t * disp);
|
||||
|
||||
/**
|
||||
* Return the bottom layer. The bottom layer is the same on all screen and it is under the normal screen layer.
|
||||
* It's visible only if the screen is transparent.
|
||||
* @param disp pointer to display (NULL to use the default screen)
|
||||
* @return pointer to the bottom layer object
|
||||
*/
|
||||
lv_obj_t * lv_display_get_layer_bottom(lv_display_t * disp);
|
||||
|
||||
/**
|
||||
* Load a screen on the default display
|
||||
* @param scr pointer to a screen
|
||||
*/
|
||||
void lv_screen_load(struct lv_obj_t * scr);
|
||||
|
||||
/**
|
||||
* Switch screen with animation
|
||||
* @param scr pointer to the new screen to load
|
||||
* @param anim_type type of the animation from `lv_screen_load_anim_t`, e.g. `LV_SCR_LOAD_ANIM_MOVE_LEFT`
|
||||
* @param time time of the animation
|
||||
* @param delay delay before the transition
|
||||
* @param auto_del true: automatically delete the old screen
|
||||
*/
|
||||
void lv_screen_load_anim(lv_obj_t * scr, lv_screen_load_anim_t anim_type, uint32_t time, uint32_t delay,
|
||||
bool auto_del);
|
||||
|
||||
/**
|
||||
* Get the active screen of the default display
|
||||
* @return pointer to the active screen
|
||||
*/
|
||||
lv_obj_t * lv_screen_active(void);
|
||||
|
||||
/**
|
||||
* Get the top layer of the default display
|
||||
* @return pointer to the top layer
|
||||
*/
|
||||
lv_obj_t * lv_layer_top(void);
|
||||
|
||||
/**
|
||||
* Get the system layer of the default display
|
||||
* @return pointer to the sys layer
|
||||
*/
|
||||
lv_obj_t * lv_layer_sys(void);
|
||||
|
||||
/**
|
||||
* Get the bottom layer of the default display
|
||||
* @return pointer to the bottom layer
|
||||
*/
|
||||
lv_obj_t * lv_layer_bottom(void);
|
||||
|
||||
/*---------------------
|
||||
* OTHERS
|
||||
*--------------------*/
|
||||
|
||||
/**
|
||||
* Add an event handler to the display
|
||||
* @param disp pointer to a display
|
||||
* @param event_cb an event callback
|
||||
* @param filter event code to react or `LV_EVENT_ALL`
|
||||
* @param user_data optional user_data
|
||||
*/
|
||||
void lv_display_add_event_cb(lv_display_t * disp, lv_event_cb_t event_cb, lv_event_code_t filter, void * user_data);
|
||||
|
||||
/**
|
||||
* Get the number of event attached to a display
|
||||
* @param disp pointer to a display
|
||||
* @return number of events
|
||||
*/
|
||||
uint32_t lv_display_get_event_count(lv_display_t * disp);
|
||||
|
||||
/**
|
||||
* Get an event descriptor for an event
|
||||
* @param disp pointer to a display
|
||||
* @param index the index of the event
|
||||
* @return the event descriptor
|
||||
*/
|
||||
lv_event_dsc_t * lv_display_get_event_dsc(lv_display_t * disp, uint32_t index);
|
||||
|
||||
/**
|
||||
* Remove an event
|
||||
* @param disp pointer to a display
|
||||
* @param index the index of the event to remove
|
||||
* @return true: and event was removed; false: no event was removed
|
||||
*/
|
||||
bool lv_display_delete_event(lv_display_t * disp, uint32_t index);
|
||||
|
||||
/**
|
||||
* Remove an event_cb with user_data
|
||||
* @param disp pointer to a display
|
||||
* @param event_cb the event_cb of the event to remove
|
||||
* @param user_data user_data
|
||||
* @return the count of the event removed
|
||||
*/
|
||||
uint32_t lv_display_remove_event_cb_with_user_data(lv_display_t * disp, lv_event_cb_t event_cb, void * user_data);
|
||||
|
||||
/**
|
||||
* Send an event to a display
|
||||
* @param disp pointer to a display
|
||||
* @param code an event code. LV_EVENT_...
|
||||
* @param param optional param
|
||||
* @return LV_RESULT_OK: disp wasn't deleted in the event.
|
||||
*/
|
||||
lv_result_t lv_display_send_event(lv_display_t * disp, lv_event_code_t code, void * param);
|
||||
|
||||
/**
|
||||
* Set the theme of a display. If there are no user created widgets yet the screens' theme will be updated
|
||||
* @param disp pointer to a display
|
||||
* @param th pointer to a theme
|
||||
*/
|
||||
void lv_display_set_theme(lv_display_t * disp, lv_theme_t * th);
|
||||
|
||||
/**
|
||||
* Get the theme of a display
|
||||
* @param disp pointer to a display
|
||||
* @return the display's theme (can be NULL)
|
||||
*/
|
||||
lv_theme_t * lv_display_get_theme(lv_display_t * disp);
|
||||
|
||||
/**
|
||||
* Get elapsed time since last user activity on a display (e.g. click)
|
||||
* @param disp pointer to a display (NULL to get the overall smallest inactivity)
|
||||
* @return elapsed ticks (milliseconds) since the last activity
|
||||
*/
|
||||
uint32_t lv_display_get_inactive_time(const lv_display_t * disp);
|
||||
|
||||
/**
|
||||
* Manually trigger an activity on a display
|
||||
* @param disp pointer to a display (NULL to use the default display)
|
||||
*/
|
||||
void lv_display_trigger_activity(lv_display_t * disp);
|
||||
|
||||
/**
|
||||
* Temporarily enable and disable the invalidation of the display.
|
||||
* @param disp pointer to a display (NULL to use the default display)
|
||||
* @param en true: enable invalidation; false: invalidation
|
||||
*/
|
||||
void lv_display_enable_invalidation(lv_display_t * disp, bool en);
|
||||
|
||||
/**
|
||||
* Get display invalidation is enabled.
|
||||
* @param disp pointer to a display (NULL to use the default display)
|
||||
* @return return true if invalidation is enabled
|
||||
*/
|
||||
bool lv_display_is_invalidation_enabled(lv_display_t * disp);
|
||||
|
||||
/**
|
||||
* Get a pointer to the screen refresher timer to
|
||||
* modify its parameters with `lv_timer_...` functions.
|
||||
* @param disp pointer to a display
|
||||
* @return pointer to the display refresher timer. (NULL on error)
|
||||
*/
|
||||
lv_timer_t * lv_display_get_refr_timer(lv_display_t * disp);
|
||||
|
||||
/**
|
||||
* Delete screen refresher timer
|
||||
* @param disp pointer to a display
|
||||
*/
|
||||
void lv_display_delete_refr_timer(lv_display_t * disp);
|
||||
|
||||
void lv_display_set_user_data(lv_display_t * disp, void * user_data);
|
||||
void lv_display_set_driver_data(lv_display_t * disp, void * driver_data);
|
||||
void * lv_display_get_user_data(lv_display_t * disp);
|
||||
void * lv_display_get_driver_data(lv_display_t * disp);
|
||||
lv_draw_buf_t * lv_display_get_buf_active(lv_display_t * disp);
|
||||
|
||||
/**
|
||||
* Rotate an area in-place according to the display's rotation
|
||||
* @param disp pointer to a display
|
||||
* @param area pointer to an area to rotate
|
||||
*/
|
||||
void lv_display_rotate_area(lv_display_t * disp, lv_area_t * area);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/*------------------------------------------------
|
||||
* To improve backward compatibility
|
||||
* Recommended only if you have one display
|
||||
*------------------------------------------------*/
|
||||
|
||||
#ifndef LV_HOR_RES
|
||||
/**
|
||||
* The horizontal resolution of the currently active display.
|
||||
*/
|
||||
#define LV_HOR_RES lv_display_get_horizontal_resolution(lv_display_get_default())
|
||||
#endif
|
||||
|
||||
#ifndef LV_VER_RES
|
||||
/**
|
||||
* The vertical resolution of the currently active display.
|
||||
*/
|
||||
#define LV_VER_RES lv_display_get_vertical_resolution(lv_display_get_default())
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Same as Android's DIP. (Different name is chosen to avoid mistype between LV_DPI and LV_DIP)
|
||||
* 1 dip is 1 px on a 160 DPI screen
|
||||
* 1 dip is 2 px on a 320 DPI screen
|
||||
* https://stackoverflow.com/questions/2025282/what-is-the-difference-between-px-dip-dp-and-sp
|
||||
*/
|
||||
#define LV_DPX_CALC(dpi, n) ((n) == 0 ? 0 :LV_MAX((( (dpi) * (n) + 80) / 160), 1)) /*+80 for rounding*/
|
||||
#define LV_DPX(n) LV_DPX_CALC(lv_display_get_dpi(NULL), n)
|
||||
|
||||
/**
|
||||
* Scale the given number of pixels (a distance or size) relative to a 160 DPI display
|
||||
* considering the DPI of the default display.
|
||||
* It ensures that e.g. `lv_dpx(100)` will have the same physical size regardless to the
|
||||
* DPI of the display.
|
||||
* @param n the number of pixels to scale
|
||||
* @return `n x current_dpi/160`
|
||||
*/
|
||||
int32_t lv_dpx(int32_t n);
|
||||
|
||||
/**
|
||||
* Scale the given number of pixels (a distance or size) relative to a 160 DPI display
|
||||
* considering the DPI of the given display.
|
||||
* It ensures that e.g. `lv_dpx(100)` will have the same physical size regardless to the
|
||||
* DPI of the display.
|
||||
* @param disp a display whose dpi should be considered
|
||||
* @param n the number of pixels to scale
|
||||
* @return `n x current_dpi/160`
|
||||
*/
|
||||
int32_t lv_display_dpx(const lv_display_t * disp, int32_t n);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DISPLAY_H*/
|
||||
@@ -0,0 +1,181 @@
|
||||
/**
|
||||
* @file lv_display_private.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DISPLAY_PRIVATE_H
|
||||
#define LV_DISPLAY_PRIVATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../misc/lv_types.h"
|
||||
#include "../core/lv_obj.h"
|
||||
#include "../draw/lv_draw.h"
|
||||
#include "lv_display.h"
|
||||
|
||||
#if LV_USE_SYSMON
|
||||
#include "../others/sysmon/lv_sysmon_private.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#ifndef LV_INV_BUF_SIZE
|
||||
#define LV_INV_BUF_SIZE 32 /**< Buffer size for invalid areas */
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
struct lv_display_t {
|
||||
|
||||
/*---------------------
|
||||
* Resolution
|
||||
*--------------------*/
|
||||
|
||||
/** Horizontal resolution.*/
|
||||
int32_t hor_res;
|
||||
|
||||
/** Vertical resolution.*/
|
||||
int32_t ver_res;
|
||||
|
||||
/** Horizontal resolution of the full / physical display. Set to -1 for fullscreen mode.*/
|
||||
int32_t physical_hor_res;
|
||||
|
||||
/** Vertical resolution of the full / physical display. Set to -1 for fullscreen mode.*/
|
||||
int32_t physical_ver_res;
|
||||
|
||||
/** Horizontal offset from the full / physical display. Set to 0 for fullscreen mode.*/
|
||||
int32_t offset_x;
|
||||
|
||||
/** Vertical offset from the full / physical display. Set to 0 for fullscreen mode.*/
|
||||
int32_t offset_y;
|
||||
|
||||
/** DPI (dot per inch) of the display. Default value is `LV_DPI_DEF`.*/
|
||||
uint32_t dpi;
|
||||
|
||||
/*---------------------
|
||||
* Buffering
|
||||
*--------------------*/
|
||||
lv_draw_buf_t * buf_1;
|
||||
lv_draw_buf_t * buf_2;
|
||||
|
||||
/** Internal, used by the library*/
|
||||
lv_draw_buf_t * buf_act;
|
||||
|
||||
/** MANDATORY: Write the internal buffer (draw_buf) to the display. 'lv_display_flush_ready()' has to be
|
||||
* called when finished*/
|
||||
lv_display_flush_cb_t flush_cb;
|
||||
|
||||
/**
|
||||
* Used to wait while flushing is ready.
|
||||
* It can do any complex logic to wait, including semaphores, mutexes, polling flags, etc.
|
||||
* If not set `flushing` flag is used which can be cleared with `lv_display_flush_ready()` */
|
||||
lv_display_flush_wait_cb_t flush_wait_cb;
|
||||
|
||||
/** 1: flushing is in progress. (It can't be a bit field because when it's cleared from IRQ
|
||||
* Read-Modify-Write issue might occur) */
|
||||
volatile int flushing;
|
||||
|
||||
/** 1: It was the last chunk to flush. (It can't be a bit field because when it's cleared
|
||||
* from IRQ Read-Modify-Write issue might occur) */
|
||||
volatile int flushing_last;
|
||||
volatile uint32_t last_area : 1; /**< 1: last area is being rendered */
|
||||
volatile uint32_t last_part : 1; /**< 1: last part of the current area is being rendered */
|
||||
|
||||
lv_display_render_mode_t render_mode;
|
||||
uint32_t antialiasing : 1; /**< 1: anti-aliasing is enabled on this display.*/
|
||||
|
||||
/** 1: The current screen rendering is in progress*/
|
||||
uint32_t rendering_in_progress : 1;
|
||||
|
||||
lv_color_format_t color_format;
|
||||
|
||||
/** Invalidated (marked to redraw) areas*/
|
||||
lv_area_t inv_areas[LV_INV_BUF_SIZE];
|
||||
uint8_t inv_area_joined[LV_INV_BUF_SIZE];
|
||||
uint32_t inv_p;
|
||||
int32_t inv_en_cnt;
|
||||
|
||||
/** Double buffer sync areas (redrawn during last refresh) */
|
||||
lv_ll_t sync_areas;
|
||||
|
||||
lv_draw_buf_t _static_buf1; /**< Used when user pass in a raw buffer as display draw buffer */
|
||||
lv_draw_buf_t _static_buf2;
|
||||
/*---------------------
|
||||
* Layer
|
||||
*--------------------*/
|
||||
lv_layer_t * layer_head;
|
||||
void (*layer_init)(lv_display_t * disp, lv_layer_t * layer);
|
||||
void (*layer_deinit)(lv_display_t * disp, lv_layer_t * layer);
|
||||
|
||||
/*---------------------
|
||||
* Screens
|
||||
*--------------------*/
|
||||
|
||||
/** Screens of the display*/
|
||||
lv_obj_t ** screens; /**< Array of screen objects.*/
|
||||
lv_obj_t * sys_layer; /**< @see lv_display_get_layer_sys*/
|
||||
lv_obj_t * top_layer; /**< @see lv_display_get_layer_top*/
|
||||
lv_obj_t * act_scr; /**< Currently active screen on this display*/
|
||||
lv_obj_t * bottom_layer;/**< @see lv_display_get_layer_bottom*/
|
||||
lv_obj_t * prev_scr; /**< Previous screen. Used during screen animations*/
|
||||
lv_obj_t * scr_to_load; /**< The screen prepared to load in lv_screen_load_anim*/
|
||||
uint32_t screen_cnt;
|
||||
uint8_t draw_prev_over_act : 1;/** 1: Draw previous screen over active screen*/
|
||||
uint8_t del_prev : 1; /** 1: Automatically delete the previous screen when the screen load animation is ready*/
|
||||
|
||||
/*---------------------
|
||||
* Others
|
||||
*--------------------*/
|
||||
|
||||
void * driver_data; /**< Custom user data*/
|
||||
|
||||
void * user_data; /**< Custom user data*/
|
||||
|
||||
lv_event_list_t event_list;
|
||||
|
||||
uint32_t rotation : 3; /**< Element of lv_display_rotation_t*/
|
||||
|
||||
lv_theme_t * theme; /**< The theme assigned to the screen*/
|
||||
|
||||
/** A timer which periodically checks the dirty areas and refreshes them*/
|
||||
lv_timer_t * refr_timer;
|
||||
|
||||
/*Miscellaneous data*/
|
||||
uint32_t last_activity_time; /**< Last time when there was activity on this display*/
|
||||
|
||||
/** The area being refreshed*/
|
||||
lv_area_t refreshed_area;
|
||||
|
||||
#if LV_USE_PERF_MONITOR
|
||||
lv_obj_t * perf_label;
|
||||
lv_sysmon_backend_data_t perf_sysmon_backend;
|
||||
lv_sysmon_perf_info_t perf_sysmon_info;
|
||||
#endif
|
||||
|
||||
#if LV_USE_MEM_MONITOR
|
||||
lv_obj_t * mem_label;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DISPLAY_PRIVATE_H*/
|
||||
505
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw.c
Normal file
505
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw.c
Normal file
@@ -0,0 +1,505 @@
|
||||
/**
|
||||
* @file lv_draw.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Modified by NXP in 2024
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../misc/lv_area_private.h"
|
||||
#include "lv_draw_private.h"
|
||||
#include "sw/lv_draw_sw.h"
|
||||
#include "../display/lv_display_private.h"
|
||||
#include "../core/lv_global.h"
|
||||
#include "../core/lv_refr_private.h"
|
||||
#include "../stdlib/lv_string.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define _draw_info LV_GLOBAL_DEFAULT()->draw_info
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static bool is_independent(lv_layer_t * layer, lv_draw_task_t * t_check);
|
||||
|
||||
static inline uint32_t get_layer_size_kb(uint32_t size_byte)
|
||||
{
|
||||
return size_byte < 1024 ? 1 : size_byte >> 10;
|
||||
}
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_init(void)
|
||||
{
|
||||
#if LV_USE_OS
|
||||
lv_thread_sync_init(&_draw_info.sync);
|
||||
#endif
|
||||
}
|
||||
|
||||
void lv_draw_deinit(void)
|
||||
{
|
||||
#if LV_USE_OS
|
||||
lv_thread_sync_delete(&_draw_info.sync);
|
||||
#endif
|
||||
|
||||
lv_draw_unit_t * u = _draw_info.unit_head;
|
||||
while(u) {
|
||||
lv_draw_unit_t * cur_unit = u;
|
||||
u = u->next;
|
||||
|
||||
if(cur_unit->delete_cb) cur_unit->delete_cb(cur_unit);
|
||||
lv_free(cur_unit);
|
||||
}
|
||||
_draw_info.unit_head = NULL;
|
||||
}
|
||||
|
||||
void * lv_draw_create_unit(size_t size)
|
||||
{
|
||||
lv_draw_unit_t * new_unit = lv_malloc_zeroed(size);
|
||||
|
||||
new_unit->next = _draw_info.unit_head;
|
||||
_draw_info.unit_head = new_unit;
|
||||
_draw_info.unit_cnt++;
|
||||
|
||||
return new_unit;
|
||||
}
|
||||
|
||||
lv_draw_task_t * lv_draw_add_task(lv_layer_t * layer, const lv_area_t * coords)
|
||||
{
|
||||
LV_PROFILER_BEGIN;
|
||||
lv_draw_task_t * new_task = lv_malloc_zeroed(sizeof(lv_draw_task_t));
|
||||
|
||||
new_task->area = *coords;
|
||||
new_task->_real_area = *coords;
|
||||
new_task->clip_area = layer->_clip_area;
|
||||
#if LV_DRAW_TRANSFORM_USE_MATRIX
|
||||
new_task->matrix = layer->matrix;
|
||||
#endif
|
||||
new_task->state = LV_DRAW_TASK_STATE_QUEUED;
|
||||
|
||||
/*Find the tail*/
|
||||
if(layer->draw_task_head == NULL) {
|
||||
layer->draw_task_head = new_task;
|
||||
}
|
||||
else {
|
||||
lv_draw_task_t * tail = layer->draw_task_head;
|
||||
while(tail->next) tail = tail->next;
|
||||
|
||||
tail->next = new_task;
|
||||
}
|
||||
|
||||
LV_PROFILER_END;
|
||||
return new_task;
|
||||
}
|
||||
|
||||
void lv_draw_finalize_task_creation(lv_layer_t * layer, lv_draw_task_t * t)
|
||||
{
|
||||
LV_PROFILER_BEGIN;
|
||||
lv_draw_dsc_base_t * base_dsc = t->draw_dsc;
|
||||
base_dsc->layer = layer;
|
||||
|
||||
lv_draw_global_info_t * info = &_draw_info;
|
||||
|
||||
/*Send LV_EVENT_DRAW_TASK_ADDED and dispatch only on the "main" draw_task
|
||||
*and not on the draw tasks added in the event.
|
||||
*Sending LV_EVENT_DRAW_TASK_ADDED events might cause recursive event sends and besides
|
||||
*dispatching might remove the "main" draw task while it's still being used in the event*/
|
||||
|
||||
if(info->task_running == false) {
|
||||
if(base_dsc->obj && lv_obj_has_flag(base_dsc->obj, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS)) {
|
||||
info->task_running = true;
|
||||
lv_obj_send_event(base_dsc->obj, LV_EVENT_DRAW_TASK_ADDED, t);
|
||||
info->task_running = false;
|
||||
}
|
||||
|
||||
/*Let the draw units set their preference score*/
|
||||
t->preference_score = 100;
|
||||
t->preferred_draw_unit_id = 0;
|
||||
lv_draw_unit_t * u = info->unit_head;
|
||||
while(u) {
|
||||
if(u->evaluate_cb) u->evaluate_cb(u, t);
|
||||
u = u->next;
|
||||
}
|
||||
|
||||
lv_draw_dispatch();
|
||||
}
|
||||
else {
|
||||
/*Let the draw units set their preference score*/
|
||||
t->preference_score = 100;
|
||||
t->preferred_draw_unit_id = 0;
|
||||
lv_draw_unit_t * u = info->unit_head;
|
||||
while(u) {
|
||||
if(u->evaluate_cb) u->evaluate_cb(u, t);
|
||||
u = u->next;
|
||||
}
|
||||
}
|
||||
LV_PROFILER_END;
|
||||
}
|
||||
|
||||
void lv_draw_wait_for_finish(void)
|
||||
{
|
||||
#if LV_USE_OS
|
||||
lv_draw_unit_t * u = _draw_info.unit_head;
|
||||
while(u) {
|
||||
if(u->wait_for_finish_cb)
|
||||
u->wait_for_finish_cb(u);
|
||||
u = u->next;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void lv_draw_dispatch(void)
|
||||
{
|
||||
LV_PROFILER_BEGIN;
|
||||
bool task_dispatched = false;
|
||||
lv_display_t * disp = lv_display_get_next(NULL);
|
||||
while(disp) {
|
||||
lv_layer_t * layer = disp->layer_head;
|
||||
while(layer) {
|
||||
if(lv_draw_dispatch_layer(disp, layer))
|
||||
task_dispatched = true;
|
||||
layer = layer->next;
|
||||
}
|
||||
if(!task_dispatched) {
|
||||
lv_draw_wait_for_finish();
|
||||
lv_draw_dispatch_request();
|
||||
}
|
||||
disp = lv_display_get_next(disp);
|
||||
}
|
||||
LV_PROFILER_END;
|
||||
}
|
||||
|
||||
bool lv_draw_dispatch_layer(lv_display_t * disp, lv_layer_t * layer)
|
||||
{
|
||||
LV_PROFILER_BEGIN;
|
||||
/*Remove the finished tasks first*/
|
||||
lv_draw_task_t * t_prev = NULL;
|
||||
lv_draw_task_t * t = layer->draw_task_head;
|
||||
while(t) {
|
||||
lv_draw_task_t * t_next = t->next;
|
||||
if(t->state == LV_DRAW_TASK_STATE_READY) {
|
||||
if(t_prev) t_prev->next = t->next; /*Remove it by assigning the next task to the previous*/
|
||||
else layer->draw_task_head = t_next; /*If it was the head, set the next as head*/
|
||||
|
||||
/*If it was layer drawing free the layer too*/
|
||||
if(t->type == LV_DRAW_TASK_TYPE_LAYER) {
|
||||
lv_draw_image_dsc_t * draw_image_dsc = t->draw_dsc;
|
||||
lv_layer_t * layer_drawn = (lv_layer_t *)draw_image_dsc->src;
|
||||
|
||||
if(layer_drawn->draw_buf) {
|
||||
int32_t h = lv_area_get_height(&layer_drawn->buf_area);
|
||||
uint32_t layer_size_byte = h * layer_drawn->draw_buf->header.stride;
|
||||
|
||||
_draw_info.used_memory_for_layers_kb -= get_layer_size_kb(layer_size_byte);
|
||||
LV_LOG_INFO("Layer memory used: %" LV_PRIu32 " kB\n", _draw_info.used_memory_for_layers_kb);
|
||||
lv_draw_buf_destroy(layer_drawn->draw_buf);
|
||||
layer_drawn->draw_buf = NULL;
|
||||
}
|
||||
|
||||
/*Remove the layer from the display's*/
|
||||
if(disp) {
|
||||
lv_layer_t * l2 = disp->layer_head;
|
||||
while(l2) {
|
||||
if(l2->next == layer_drawn) {
|
||||
l2->next = layer_drawn->next;
|
||||
break;
|
||||
}
|
||||
l2 = l2->next;
|
||||
}
|
||||
|
||||
if(disp->layer_deinit) disp->layer_deinit(disp, layer_drawn);
|
||||
lv_free(layer_drawn);
|
||||
}
|
||||
}
|
||||
lv_draw_label_dsc_t * draw_label_dsc = lv_draw_task_get_label_dsc(t);
|
||||
if(draw_label_dsc && draw_label_dsc->text_local) {
|
||||
lv_free((void *)draw_label_dsc->text);
|
||||
draw_label_dsc->text = NULL;
|
||||
}
|
||||
|
||||
lv_free(t->draw_dsc);
|
||||
lv_free(t);
|
||||
}
|
||||
else {
|
||||
t_prev = t;
|
||||
}
|
||||
t = t_next;
|
||||
}
|
||||
|
||||
bool task_dispatched = false;
|
||||
|
||||
/*This layer is ready, enable blending its buffer*/
|
||||
if(layer->parent && layer->all_tasks_added && layer->draw_task_head == NULL) {
|
||||
/*Find a draw task with TYPE_LAYER in the layer where the src is this layer*/
|
||||
lv_draw_task_t * t_src = layer->parent->draw_task_head;
|
||||
while(t_src) {
|
||||
if(t_src->type == LV_DRAW_TASK_TYPE_LAYER && t_src->state == LV_DRAW_TASK_STATE_WAITING) {
|
||||
lv_draw_image_dsc_t * draw_dsc = t_src->draw_dsc;
|
||||
if(draw_dsc->src == layer) {
|
||||
t_src->state = LV_DRAW_TASK_STATE_QUEUED;
|
||||
lv_draw_dispatch_request();
|
||||
break;
|
||||
}
|
||||
}
|
||||
t_src = t_src->next;
|
||||
}
|
||||
}
|
||||
/*Assign draw tasks to the draw_units*/
|
||||
else {
|
||||
/*Find a draw unit which is not busy and can take at least one task*/
|
||||
/*Let all draw units to pick draw tasks*/
|
||||
lv_draw_unit_t * u = _draw_info.unit_head;
|
||||
while(u) {
|
||||
int32_t taken_cnt = u->dispatch_cb(u, layer);
|
||||
if(taken_cnt != LV_DRAW_UNIT_IDLE) task_dispatched = true;
|
||||
u = u->next;
|
||||
}
|
||||
}
|
||||
|
||||
LV_PROFILER_END;
|
||||
return task_dispatched;
|
||||
}
|
||||
|
||||
void lv_draw_dispatch_wait_for_request(void)
|
||||
{
|
||||
#if LV_USE_OS
|
||||
lv_thread_sync_wait(&_draw_info.sync);
|
||||
#else
|
||||
while(!_draw_info.dispatch_req);
|
||||
_draw_info.dispatch_req = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void lv_draw_dispatch_request(void)
|
||||
{
|
||||
#if LV_USE_OS
|
||||
lv_thread_sync_signal(&_draw_info.sync);
|
||||
#else
|
||||
_draw_info.dispatch_req = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t lv_draw_get_unit_count(void)
|
||||
{
|
||||
return _draw_info.unit_cnt;
|
||||
}
|
||||
|
||||
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());
|
||||
int32_t ver_res = lv_display_get_vertical_resolution(lv_refr_get_disp_refreshing());
|
||||
lv_draw_task_t * t = layer->draw_task_head;
|
||||
if(t->state != LV_DRAW_TASK_STATE_QUEUED &&
|
||||
t->area.x1 <= 0 && t->area.x2 >= hor_res - 1 &&
|
||||
t->area.y1 <= 0 && t->area.y2 >= ver_res - 1) {
|
||||
LV_PROFILER_END;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
lv_draw_task_t * t = t_prev ? t_prev->next : layer->draw_task_head;
|
||||
while(t) {
|
||||
/*Find a queued and independent task*/
|
||||
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) &&
|
||||
is_independent(layer, t)) {
|
||||
LV_PROFILER_END;
|
||||
return t;
|
||||
}
|
||||
t = t->next;
|
||||
}
|
||||
|
||||
LV_PROFILER_END;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t lv_draw_get_dependent_count(lv_draw_task_t * t_check)
|
||||
{
|
||||
if(t_check == NULL) return 0;
|
||||
if(t_check->next == NULL) return 0;
|
||||
|
||||
LV_PROFILER_BEGIN;
|
||||
uint32_t cnt = 0;
|
||||
|
||||
lv_draw_task_t * t = t_check->next;
|
||||
while(t) {
|
||||
if((t->state == LV_DRAW_TASK_STATE_QUEUED || t->state == LV_DRAW_TASK_STATE_WAITING) &&
|
||||
lv_area_is_on(&t_check->area, &t->area)) {
|
||||
cnt++;
|
||||
}
|
||||
|
||||
t = t->next;
|
||||
}
|
||||
LV_PROFILER_END;
|
||||
return cnt;
|
||||
}
|
||||
|
||||
lv_layer_t * lv_draw_layer_create(lv_layer_t * parent_layer, lv_color_format_t color_format, const lv_area_t * area)
|
||||
{
|
||||
lv_display_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_layer_t * new_layer = lv_malloc_zeroed(sizeof(lv_layer_t));
|
||||
LV_ASSERT_MALLOC(new_layer);
|
||||
if(new_layer == NULL) return NULL;
|
||||
|
||||
new_layer->parent = parent_layer;
|
||||
new_layer->_clip_area = *area;
|
||||
new_layer->buf_area = *area;
|
||||
new_layer->phy_clip_area = *area;
|
||||
new_layer->color_format = color_format;
|
||||
|
||||
#if LV_DRAW_TRANSFORM_USE_MATRIX
|
||||
lv_matrix_identity(&new_layer->matrix);
|
||||
#endif
|
||||
|
||||
if(disp->layer_head) {
|
||||
lv_layer_t * tail = disp->layer_head;
|
||||
while(tail->next) tail = tail->next;
|
||||
tail->next = new_layer;
|
||||
}
|
||||
else {
|
||||
disp->layer_head = new_layer;
|
||||
}
|
||||
|
||||
return new_layer;
|
||||
}
|
||||
|
||||
void * lv_draw_layer_alloc_buf(lv_layer_t * layer)
|
||||
{
|
||||
/*If the buffer of the layer is already allocated return it*/
|
||||
if(layer->draw_buf != NULL) {
|
||||
return layer->draw_buf->data;
|
||||
}
|
||||
|
||||
/*If the buffer of the layer is not allocated yet, allocate it now*/
|
||||
int32_t w = lv_area_get_width(&layer->buf_area);
|
||||
int32_t h = lv_area_get_height(&layer->buf_area);
|
||||
uint32_t layer_size_byte = h * lv_draw_buf_width_to_stride(w, layer->color_format);
|
||||
|
||||
layer->draw_buf = lv_draw_buf_create(w, h, layer->color_format, 0);
|
||||
|
||||
if(layer->draw_buf == NULL) {
|
||||
LV_LOG_WARN("Allocating layer buffer failed. Try later");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_draw_info.used_memory_for_layers_kb += get_layer_size_kb(layer_size_byte);
|
||||
LV_LOG_INFO("Layer memory used: %" LV_PRIu32 " kB\n", _draw_info.used_memory_for_layers_kb);
|
||||
|
||||
if(lv_color_format_has_alpha(layer->color_format)) {
|
||||
lv_draw_buf_clear(layer->draw_buf, NULL);
|
||||
}
|
||||
|
||||
return layer->draw_buf->data;
|
||||
}
|
||||
|
||||
void * lv_draw_layer_go_to_xy(lv_layer_t * layer, int32_t x, int32_t y)
|
||||
{
|
||||
return lv_draw_buf_goto_xy(layer->draw_buf, x, y);
|
||||
}
|
||||
|
||||
lv_draw_task_type_t lv_draw_task_get_type(const lv_draw_task_t * t)
|
||||
{
|
||||
return t->type;
|
||||
}
|
||||
|
||||
void * lv_draw_task_get_draw_dsc(const lv_draw_task_t * t)
|
||||
{
|
||||
return t->draw_dsc;
|
||||
}
|
||||
|
||||
void lv_draw_task_get_area(const lv_draw_task_t * t, lv_area_t * area)
|
||||
{
|
||||
*area = t->area;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Check if there are older draw task overlapping the area of `t_check`
|
||||
* @param layer the draw ctx to search in
|
||||
* @param t_check check this task if it overlaps with the older ones
|
||||
* @return true: `t_check` is not overlapping with older tasks so it's independent
|
||||
*/
|
||||
static bool is_independent(lv_layer_t * layer, lv_draw_task_t * t_check)
|
||||
{
|
||||
LV_PROFILER_BEGIN;
|
||||
lv_draw_task_t * t = layer->draw_task_head;
|
||||
|
||||
/*If t_check is outside of the older tasks then it's independent*/
|
||||
while(t && t != t_check) {
|
||||
if(t->state != LV_DRAW_TASK_STATE_READY) {
|
||||
lv_area_t a;
|
||||
if(lv_area_intersect(&a, &t->_real_area, &t_check->_real_area)) {
|
||||
LV_PROFILER_END;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
t = t->next;
|
||||
}
|
||||
LV_PROFILER_END;
|
||||
|
||||
return true;
|
||||
}
|
||||
272
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw.h
Normal file
272
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw.h
Normal file
@@ -0,0 +1,272 @@
|
||||
/**
|
||||
* @file lv_draw.h
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Modified by NXP in 2024
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_H
|
||||
#define LV_DRAW_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_conf_internal.h"
|
||||
|
||||
#include "../misc/lv_types.h"
|
||||
#include "../misc/lv_style.h"
|
||||
#include "../misc/lv_text.h"
|
||||
#include "../misc/lv_profiler.h"
|
||||
#include "../misc/lv_matrix.h"
|
||||
#include "lv_image_decoder.h"
|
||||
#include "../osal/lv_os.h"
|
||||
#include "lv_draw_buf.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_DRAW_UNIT_NONE 0
|
||||
#define LV_DRAW_UNIT_IDLE -1 /**< The draw unit is idle, new dispatching might be requested to try again */
|
||||
|
||||
#if LV_DRAW_TRANSFORM_USE_MATRIX
|
||||
#if !LV_USE_MATRIX
|
||||
#error "LV_DRAW_TRANSFORM_USE_MATRIX requires LV_USE_MATRIX = 1"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef enum {
|
||||
LV_DRAW_TASK_TYPE_NONE = 0,
|
||||
LV_DRAW_TASK_TYPE_FILL,
|
||||
LV_DRAW_TASK_TYPE_BORDER,
|
||||
LV_DRAW_TASK_TYPE_BOX_SHADOW,
|
||||
LV_DRAW_TASK_TYPE_LABEL,
|
||||
LV_DRAW_TASK_TYPE_IMAGE,
|
||||
LV_DRAW_TASK_TYPE_LAYER,
|
||||
LV_DRAW_TASK_TYPE_LINE,
|
||||
LV_DRAW_TASK_TYPE_ARC,
|
||||
LV_DRAW_TASK_TYPE_TRIANGLE,
|
||||
LV_DRAW_TASK_TYPE_MASK_RECTANGLE,
|
||||
LV_DRAW_TASK_TYPE_MASK_BITMAP,
|
||||
LV_DRAW_TASK_TYPE_VECTOR,
|
||||
} lv_draw_task_type_t;
|
||||
|
||||
typedef enum {
|
||||
LV_DRAW_TASK_STATE_WAITING, /*Waiting for something to be finished. E.g. rendering a layer*/
|
||||
LV_DRAW_TASK_STATE_QUEUED,
|
||||
LV_DRAW_TASK_STATE_IN_PROGRESS,
|
||||
LV_DRAW_TASK_STATE_READY,
|
||||
} lv_draw_task_state_t;
|
||||
|
||||
struct lv_layer_t {
|
||||
|
||||
/** Target draw buffer of the layer*/
|
||||
lv_draw_buf_t * draw_buf;
|
||||
|
||||
/** The absolute coordinates of the buffer */
|
||||
lv_area_t buf_area;
|
||||
|
||||
/** The color format of the layer. LV_COLOR_FORMAT_... */
|
||||
lv_color_format_t color_format;
|
||||
|
||||
/**
|
||||
* NEVER USE IT DRAW UNITS. USED INTERNALLY DURING DRAW TASK CREATION.
|
||||
* The current clip area with absolute coordinates, always the same or smaller than `buf_area`
|
||||
* Can be set before new draw tasks are added to indicate the clip area of the draw tasks.
|
||||
* Therefore `lv_draw_add_task()` always saves it in the new draw task to know the clip area when the draw task was added.
|
||||
* During drawing the draw units also sees the saved clip_area and should use it during drawing.
|
||||
* During drawing the layer's clip area shouldn't be used as it might be already changed for other draw tasks.
|
||||
*/
|
||||
lv_area_t _clip_area;
|
||||
|
||||
/**
|
||||
* The physical clipping area relative to the display.
|
||||
*/
|
||||
lv_area_t phy_clip_area;
|
||||
|
||||
#if LV_DRAW_TRANSFORM_USE_MATRIX
|
||||
/** Transform matrix to be applied when rendering the layer */
|
||||
lv_matrix_t matrix;
|
||||
#endif
|
||||
|
||||
/** Linked list of draw tasks */
|
||||
lv_draw_task_t * draw_task_head;
|
||||
|
||||
lv_layer_t * parent;
|
||||
lv_layer_t * next;
|
||||
bool all_tasks_added;
|
||||
void * user_data;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
lv_obj_t * obj;
|
||||
lv_part_t part;
|
||||
uint32_t id1;
|
||||
uint32_t id2;
|
||||
lv_layer_t * layer;
|
||||
size_t dsc_size;
|
||||
void * user_data;
|
||||
} lv_draw_dsc_base_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Used internally to initialize the drawing module
|
||||
*/
|
||||
void lv_draw_init(void);
|
||||
|
||||
/**
|
||||
* Deinitialize the drawing module
|
||||
*/
|
||||
void lv_draw_deinit(void);
|
||||
|
||||
/**
|
||||
* Allocate a new draw unit with the given size and appends it to the list of draw units
|
||||
* @param size the size to allocate. E.g. `sizeof(my_draw_unit_t)`,
|
||||
* where the first element of `my_draw_unit_t` is `lv_draw_unit_t`.
|
||||
*/
|
||||
void * lv_draw_create_unit(size_t size);
|
||||
|
||||
/**
|
||||
* Add an empty draw task to the draw task list of a layer.
|
||||
* @param layer pointer to a layer
|
||||
* @param coords the coordinates of the draw task
|
||||
* @return the created draw task which needs to be
|
||||
* further configured e.g. by added a draw descriptor
|
||||
*/
|
||||
lv_draw_task_t * lv_draw_add_task(lv_layer_t * layer, const lv_area_t * coords);
|
||||
|
||||
/**
|
||||
* Needs to be called when a draw task is created and configured.
|
||||
* It will send an event about the new draw task to the widget
|
||||
* and assign it to a draw unit.
|
||||
* @param layer pointer to a layer
|
||||
* @param t pointer to a draw task
|
||||
*/
|
||||
void lv_draw_finalize_task_creation(lv_layer_t * layer, lv_draw_task_t * t);
|
||||
|
||||
/**
|
||||
* Try dispatching draw tasks to draw units
|
||||
*/
|
||||
void lv_draw_dispatch(void);
|
||||
|
||||
/**
|
||||
* Used internally to try dispatching draw tasks of a specific layer
|
||||
* @param disp pointer to a display on which the dispatching was requested
|
||||
* @param layer pointer to a layer
|
||||
* @return at least one draw task is being rendered (maybe it was taken earlier)
|
||||
*/
|
||||
bool lv_draw_dispatch_layer(lv_display_t * disp, lv_layer_t * layer);
|
||||
|
||||
/**
|
||||
* Wait for a new dispatch request.
|
||||
* It's blocking if `LV_USE_OS == 0` else it yields
|
||||
*/
|
||||
void lv_draw_dispatch_wait_for_request(void);
|
||||
|
||||
/**
|
||||
* Wait for draw finish in case of asynchronous task execution.
|
||||
* If `LV_USE_OS == 0` it just return.
|
||||
*/
|
||||
void lv_draw_wait_for_finish(void);
|
||||
|
||||
/**
|
||||
* When a draw unit finished a draw task it needs to request dispatching
|
||||
* to let LVGL assign a new draw task to it
|
||||
*/
|
||||
void lv_draw_dispatch_request(void);
|
||||
|
||||
/**
|
||||
* Get the total number of draw units.
|
||||
*/
|
||||
uint32_t lv_draw_get_unit_count(void);
|
||||
|
||||
/**
|
||||
* Find and available draw task
|
||||
* @param layer the draw ctx to search in
|
||||
* @param t_prev continue searching from this task
|
||||
* @param draw_unit_id check the task where `preferred_draw_unit_id` equals this value or `LV_DRAW_UNIT_NONE`
|
||||
* @return tan available draw task or NULL if there is no any
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Tell how many draw task are waiting to be drawn on the area of `t_check`.
|
||||
* It can be used to determine if a GPU shall combine many draw tasks into one or not.
|
||||
* If a lot of tasks are waiting for the current ones it makes sense to draw them one-by-one
|
||||
* to not block the dependent tasks' rendering
|
||||
* @param t_check the task whose dependent tasks shall be counted
|
||||
* @return number of tasks depending on `t_check`
|
||||
*/
|
||||
uint32_t lv_draw_get_dependent_count(lv_draw_task_t * t_check);
|
||||
|
||||
/**
|
||||
* Create a new layer on a parent layer
|
||||
* @param parent_layer the parent layer to which the layer will be merged when it's rendered
|
||||
* @param color_format the color format of the layer
|
||||
* @param area the areas of the layer (absolute coordinates)
|
||||
* @return the new target_layer or NULL on error
|
||||
*/
|
||||
lv_layer_t * lv_draw_layer_create(lv_layer_t * parent_layer, lv_color_format_t color_format, const lv_area_t * area);
|
||||
|
||||
/**
|
||||
* Try to allocate a buffer for the layer.
|
||||
* @param layer pointer to a layer
|
||||
* @return pointer to the allocated aligned buffer or NULL on failure
|
||||
*/
|
||||
void * lv_draw_layer_alloc_buf(lv_layer_t * layer);
|
||||
|
||||
/**
|
||||
* Got to a pixel at X and Y coordinate on a layer
|
||||
* @param layer pointer to a layer
|
||||
* @param x the target X coordinate
|
||||
* @param y the target X coordinate
|
||||
* @return `buf` offset to point to the given X and Y coordinate
|
||||
*/
|
||||
void * lv_draw_layer_go_to_xy(lv_layer_t * layer, int32_t x, int32_t y);
|
||||
|
||||
/**
|
||||
* Get the type of a draw task
|
||||
* @param t the draw task to get the type of
|
||||
* @return the draw task type
|
||||
*/
|
||||
lv_draw_task_type_t lv_draw_task_get_type(const lv_draw_task_t * t);
|
||||
|
||||
/**
|
||||
* Get the draw descriptor of a draw task
|
||||
* @param t the draw task to get the draw descriptor of
|
||||
* @return a void pointer to the draw descriptor
|
||||
*/
|
||||
void * lv_draw_task_get_draw_dsc(const lv_draw_task_t * t);
|
||||
|
||||
/**
|
||||
* Get the draw area of a draw task
|
||||
* @param t the draw task to get the draw area of
|
||||
* @param area the destination where the draw area will be stored
|
||||
*/
|
||||
void lv_draw_task_get_area(const lv_draw_task_t * t, lv_area_t * area);
|
||||
|
||||
/**********************
|
||||
* GLOBAL VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_H*/
|
||||
174
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_arc.c
Normal file
174
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_arc.c
Normal file
@@ -0,0 +1,174 @@
|
||||
/**
|
||||
* @file lv_draw_arc.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_private.h"
|
||||
#include "../core/lv_obj.h"
|
||||
#include "lv_draw_arc.h"
|
||||
#include "../core/lv_obj_event.h"
|
||||
#include "../stdlib/lv_string.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_arc_dsc_init(lv_draw_arc_dsc_t * dsc)
|
||||
{
|
||||
lv_memzero(dsc, sizeof(lv_draw_arc_dsc_t));
|
||||
dsc->width = 1;
|
||||
dsc->opa = LV_OPA_COVER;
|
||||
dsc->color = lv_color_black();
|
||||
dsc->base.dsc_size = sizeof(lv_draw_arc_dsc_t);
|
||||
}
|
||||
|
||||
lv_draw_arc_dsc_t * lv_draw_task_get_arc_dsc(lv_draw_task_t * task)
|
||||
{
|
||||
return task->type == LV_DRAW_TASK_TYPE_ARC ? (lv_draw_arc_dsc_t *)task->draw_dsc : NULL;
|
||||
}
|
||||
|
||||
void lv_draw_arc(lv_layer_t * layer, const lv_draw_arc_dsc_t * dsc)
|
||||
{
|
||||
if(dsc->opa <= LV_OPA_MIN) return;
|
||||
if(dsc->width == 0) return;
|
||||
if(dsc->start_angle == dsc->end_angle) return;
|
||||
|
||||
LV_PROFILER_BEGIN;
|
||||
lv_area_t a;
|
||||
a.x1 = dsc->center.x - dsc->radius;
|
||||
a.y1 = dsc->center.y - dsc->radius;
|
||||
a.x2 = dsc->center.x + dsc->radius - 1;
|
||||
a.y2 = dsc->center.y + dsc->radius - 1;
|
||||
lv_draw_task_t * t = lv_draw_add_task(layer, &a);
|
||||
|
||||
t->draw_dsc = lv_malloc(sizeof(*dsc));
|
||||
lv_memcpy(t->draw_dsc, dsc, sizeof(*dsc));
|
||||
t->type = LV_DRAW_TASK_TYPE_ARC;
|
||||
|
||||
lv_draw_finalize_task_creation(layer, t);
|
||||
|
||||
LV_PROFILER_END;
|
||||
}
|
||||
|
||||
void lv_draw_arc_get_area(int32_t x, int32_t y, uint16_t radius, lv_value_precise_t start_angle,
|
||||
lv_value_precise_t end_angle,
|
||||
int32_t w, bool rounded, lv_area_t * area)
|
||||
{
|
||||
int32_t rout = radius;
|
||||
int32_t start_angle_int = (int32_t) start_angle;
|
||||
int32_t end_angle_int = (int32_t) end_angle;
|
||||
|
||||
/*Special case: full arc invalidation */
|
||||
if(end_angle_int == start_angle_int + 360) {
|
||||
area->x1 = x - rout;
|
||||
area->y1 = y - rout;
|
||||
area->x2 = x + rout;
|
||||
area->y2 = y + rout;
|
||||
return;
|
||||
}
|
||||
|
||||
if(start_angle_int > 360) start_angle_int -= 360;
|
||||
if(end_angle_int > 360) end_angle_int -= 360;
|
||||
|
||||
int32_t rin = radius - w;
|
||||
int32_t extra_area = rounded ? w / 2 + 1 : 0;
|
||||
uint8_t start_quarter = start_angle_int / 90;
|
||||
uint8_t end_quarter = end_angle_int / 90;
|
||||
|
||||
/*360 deg still counts as quarter 3 (360 / 90 would be 4)*/
|
||||
if(start_quarter == 4) start_quarter = 3;
|
||||
if(end_quarter == 4) end_quarter = 3;
|
||||
|
||||
if(start_quarter == end_quarter && start_angle_int <= end_angle_int) {
|
||||
if(start_quarter == 0) {
|
||||
area->y1 = y + ((lv_trigo_sin(start_angle_int) * rin) >> LV_TRIGO_SHIFT) - extra_area;
|
||||
area->x2 = x + ((lv_trigo_sin(start_angle_int + 90) * rout) >> LV_TRIGO_SHIFT) + extra_area;
|
||||
|
||||
area->y2 = y + ((lv_trigo_sin(end_angle_int) * rout) >> LV_TRIGO_SHIFT) + extra_area;
|
||||
area->x1 = x + ((lv_trigo_sin(end_angle_int + 90) * rin) >> LV_TRIGO_SHIFT) - extra_area;
|
||||
}
|
||||
else if(start_quarter == 1) {
|
||||
area->y2 = y + ((lv_trigo_sin(start_angle_int) * rout) >> LV_TRIGO_SHIFT) + extra_area;
|
||||
area->x2 = x + ((lv_trigo_sin(start_angle_int + 90) * rin) >> LV_TRIGO_SHIFT) + extra_area;
|
||||
|
||||
area->y1 = y + ((lv_trigo_sin(end_angle_int) * rin) >> LV_TRIGO_SHIFT) - extra_area;
|
||||
area->x1 = x + ((lv_trigo_sin(end_angle_int + 90) * rout) >> LV_TRIGO_SHIFT) - extra_area;
|
||||
}
|
||||
else if(start_quarter == 2) {
|
||||
area->x1 = x + ((lv_trigo_sin(start_angle_int + 90) * rout) >> LV_TRIGO_SHIFT) - extra_area;
|
||||
area->y2 = y + ((lv_trigo_sin(start_angle_int) * rin) >> LV_TRIGO_SHIFT) + extra_area;
|
||||
|
||||
area->y1 = y + ((lv_trigo_sin(end_angle_int) * rout) >> LV_TRIGO_SHIFT) - extra_area;
|
||||
area->x2 = x + ((lv_trigo_sin(end_angle_int + 90) * rin) >> LV_TRIGO_SHIFT) + extra_area;
|
||||
}
|
||||
else if(start_quarter == 3) {
|
||||
area->x1 = x + ((lv_trigo_sin(start_angle_int + 90) * rin) >> LV_TRIGO_SHIFT) - extra_area;
|
||||
area->y1 = y + ((lv_trigo_sin(start_angle_int) * rout) >> LV_TRIGO_SHIFT) - extra_area;
|
||||
|
||||
area->x2 = x + ((lv_trigo_sin(end_angle_int + 90) * rout) >> LV_TRIGO_SHIFT) + extra_area;
|
||||
area->y2 = y + ((lv_trigo_sin(end_angle_int) * rin) >> LV_TRIGO_SHIFT) + extra_area;
|
||||
}
|
||||
}
|
||||
else if(start_quarter == 0 && end_quarter == 1) {
|
||||
area->x1 = x + ((lv_trigo_sin(end_angle_int + 90) * rout) >> LV_TRIGO_SHIFT) - extra_area;
|
||||
area->y1 = y + ((LV_MIN(lv_trigo_sin(end_angle_int),
|
||||
lv_trigo_sin(start_angle_int)) * rin) >> LV_TRIGO_SHIFT) - extra_area;
|
||||
area->x2 = x + ((lv_trigo_sin(start_angle_int + 90) * rout) >> LV_TRIGO_SHIFT) + extra_area;
|
||||
area->y2 = y + rout + extra_area;
|
||||
}
|
||||
else if(start_quarter == 1 && end_quarter == 2) {
|
||||
area->x1 = x - rout - extra_area;
|
||||
area->y1 = y + ((lv_trigo_sin(end_angle_int) * rout) >> LV_TRIGO_SHIFT) - extra_area;
|
||||
area->x2 = x + ((LV_MAX(lv_trigo_sin(start_angle_int + 90),
|
||||
lv_trigo_sin(end_angle_int + 90)) * rin) >> LV_TRIGO_SHIFT) + extra_area;
|
||||
area->y2 = y + ((lv_trigo_sin(start_angle_int) * rout) >> LV_TRIGO_SHIFT) + extra_area;
|
||||
}
|
||||
else if(start_quarter == 2 && end_quarter == 3) {
|
||||
area->x1 = x + ((lv_trigo_sin(start_angle_int + 90) * rout) >> LV_TRIGO_SHIFT) - extra_area;
|
||||
area->y1 = y - rout - extra_area;
|
||||
area->x2 = x + ((lv_trigo_sin(end_angle_int + 90) * rout) >> LV_TRIGO_SHIFT) + extra_area;
|
||||
area->y2 = y + (LV_MAX(lv_trigo_sin(end_angle_int) * rin,
|
||||
lv_trigo_sin(start_angle_int) * rin) >> LV_TRIGO_SHIFT) + extra_area;
|
||||
}
|
||||
else if(start_quarter == 3 && end_quarter == 0) {
|
||||
area->x1 = x + ((LV_MIN(lv_trigo_sin(end_angle_int + 90),
|
||||
lv_trigo_sin(start_angle_int + 90)) * rin) >> LV_TRIGO_SHIFT) - extra_area;
|
||||
area->y1 = y + ((lv_trigo_sin(start_angle_int) * rout) >> LV_TRIGO_SHIFT) - extra_area;
|
||||
area->x2 = x + rout + extra_area;
|
||||
area->y2 = y + ((lv_trigo_sin(end_angle_int) * rout) >> LV_TRIGO_SHIFT) + extra_area;
|
||||
|
||||
}
|
||||
else {
|
||||
area->x1 = x - rout;
|
||||
area->y1 = y - rout;
|
||||
area->x2 = x + rout;
|
||||
area->y2 = y + rout;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
90
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_arc.h
Normal file
90
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_arc.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* @file lv_draw_arc.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_ARC_H
|
||||
#define LV_DRAW_ARC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_conf_internal.h"
|
||||
#include "../misc/lv_color.h"
|
||||
#include "../misc/lv_area.h"
|
||||
#include "../misc/lv_style.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct {
|
||||
lv_draw_dsc_base_t base;
|
||||
|
||||
lv_color_t color;
|
||||
int32_t width;
|
||||
lv_value_precise_t start_angle;
|
||||
lv_value_precise_t end_angle;
|
||||
lv_point_t center;
|
||||
uint16_t radius;
|
||||
const void * img_src;
|
||||
lv_opa_t opa;
|
||||
uint8_t rounded : 1;
|
||||
} lv_draw_arc_dsc_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize an arc draw descriptor.
|
||||
* @param dsc pointer to a draw descriptor
|
||||
*/
|
||||
void lv_draw_arc_dsc_init(lv_draw_arc_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Try to get an arc draw descriptor from a draw task.
|
||||
* @param task draw task
|
||||
* @return the task's draw descriptor or NULL if the task is not of type LV_DRAW_TASK_TYPE_ARC
|
||||
*/
|
||||
lv_draw_arc_dsc_t * lv_draw_task_get_arc_dsc(lv_draw_task_t * task);
|
||||
|
||||
/**
|
||||
* Create an arc draw task.
|
||||
* @param layer pointer to a layer
|
||||
* @param dsc pointer to an initialized draw descriptor variable
|
||||
*/
|
||||
void lv_draw_arc(lv_layer_t * layer, const lv_draw_arc_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Get an area the should be invalidated when the arcs angle changed between start_angle and end_ange
|
||||
* @param x the x coordinate of the center of the arc
|
||||
* @param y the y coordinate of the center of the arc
|
||||
* @param radius the radius of the arc
|
||||
* @param start_angle the start angle of the arc (0 deg on the bottom, 90 deg on the right)
|
||||
* @param end_angle the end angle of the arc
|
||||
* @param w width of the arc
|
||||
* @param rounded true: the arc is rounded
|
||||
* @param area store the area to invalidate here
|
||||
*/
|
||||
void lv_draw_arc_get_area(int32_t x, int32_t y, uint16_t radius, lv_value_precise_t start_angle,
|
||||
lv_value_precise_t end_angle,
|
||||
int32_t w, bool rounded, lv_area_t * area);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_ARC_H*/
|
||||
669
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_buf.c
Normal file
669
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_buf.c
Normal file
@@ -0,0 +1,669 @@
|
||||
/**
|
||||
* @file lv_draw_buf.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_buf_private.h"
|
||||
#include "../misc/lv_types.h"
|
||||
#include "../stdlib/lv_string.h"
|
||||
#include "../core/lv_global.h"
|
||||
#include "../misc/lv_math.h"
|
||||
#include "../misc/lv_area_private.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define default_handlers LV_GLOBAL_DEFAULT()->draw_buf_handlers
|
||||
#define font_draw_buf_handlers LV_GLOBAL_DEFAULT()->font_draw_buf_handlers
|
||||
#define image_cache_draw_buf_handlers LV_GLOBAL_DEFAULT()->image_cache_draw_buf_handlers
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void * buf_malloc(size_t size, lv_color_format_t color_format);
|
||||
static void buf_free(void * buf);
|
||||
static void * buf_align(void * buf, lv_color_format_t color_format);
|
||||
static void * draw_buf_malloc(const lv_draw_buf_handlers_t * handler, size_t size_bytes,
|
||||
lv_color_format_t color_format);
|
||||
static void draw_buf_free(const lv_draw_buf_handlers_t * handler, void * buf);
|
||||
static uint32_t width_to_stride(uint32_t w, lv_color_format_t color_format);
|
||||
static uint32_t _calculate_draw_buf_size(uint32_t w, uint32_t h, lv_color_format_t cf, uint32_t stride);
|
||||
static void draw_buf_get_full_area(const lv_draw_buf_t * draw_buf, lv_area_t * full_area);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_buf_init_handlers(void)
|
||||
{
|
||||
lv_draw_buf_init_with_default_handlers(&default_handlers);
|
||||
lv_draw_buf_init_with_default_handlers(&font_draw_buf_handlers);
|
||||
lv_draw_buf_init_with_default_handlers(&image_cache_draw_buf_handlers);
|
||||
}
|
||||
|
||||
void lv_draw_buf_init_with_default_handlers(lv_draw_buf_handlers_t * handlers)
|
||||
{
|
||||
lv_draw_buf_handlers_init(handlers, buf_malloc, buf_free, buf_align, NULL, NULL, width_to_stride);
|
||||
}
|
||||
|
||||
void lv_draw_buf_handlers_init(lv_draw_buf_handlers_t * handlers,
|
||||
lv_draw_buf_malloc_cb buf_malloc_cb,
|
||||
lv_draw_buf_free_cb buf_free_cb,
|
||||
lv_draw_buf_align_cb align_pointer_cb,
|
||||
lv_draw_buf_cache_operation_cb invalidate_cache_cb,
|
||||
lv_draw_buf_cache_operation_cb flush_cache_cb,
|
||||
lv_draw_buf_width_to_stride_cb width_to_stride_cb)
|
||||
{
|
||||
lv_memzero(handlers, sizeof(lv_draw_buf_handlers_t));
|
||||
handlers->buf_malloc_cb = buf_malloc_cb;
|
||||
handlers->buf_free_cb = buf_free_cb;
|
||||
handlers->align_pointer_cb = align_pointer_cb;
|
||||
handlers->invalidate_cache_cb = invalidate_cache_cb;
|
||||
handlers->flush_cache_cb = flush_cache_cb;
|
||||
handlers->width_to_stride_cb = width_to_stride_cb;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
uint32_t lv_draw_buf_width_to_stride_ex(const lv_draw_buf_handlers_t * handlers, uint32_t w,
|
||||
lv_color_format_t color_format)
|
||||
{
|
||||
if(handlers->width_to_stride_cb) return handlers->width_to_stride_cb(w, color_format);
|
||||
else return 0;
|
||||
}
|
||||
|
||||
void * lv_draw_buf_align(void * data, lv_color_format_t color_format)
|
||||
{
|
||||
return lv_draw_buf_align_ex(&default_handlers, data, color_format);
|
||||
}
|
||||
|
||||
void * lv_draw_buf_align_ex(const lv_draw_buf_handlers_t * handlers, void * data, lv_color_format_t color_format)
|
||||
{
|
||||
if(handlers->align_pointer_cb) return handlers->align_pointer_cb(data, color_format);
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
void lv_draw_buf_invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area)
|
||||
{
|
||||
LV_ASSERT_NULL(draw_buf);
|
||||
LV_ASSERT_NULL(draw_buf->handlers);
|
||||
|
||||
const lv_draw_buf_handlers_t * handlers = draw_buf->handlers;
|
||||
if(!handlers->invalidate_cache_cb) {
|
||||
return;
|
||||
}
|
||||
|
||||
lv_area_t full;
|
||||
if(area == NULL) {
|
||||
draw_buf_get_full_area(draw_buf, &full);
|
||||
area = &full;
|
||||
}
|
||||
|
||||
handlers->invalidate_cache_cb(draw_buf, area);
|
||||
}
|
||||
|
||||
void lv_draw_buf_flush_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area)
|
||||
{
|
||||
LV_ASSERT_NULL(draw_buf);
|
||||
LV_ASSERT_NULL(draw_buf->handlers);
|
||||
|
||||
const lv_draw_buf_handlers_t * handlers = draw_buf->handlers;
|
||||
if(!handlers->flush_cache_cb) {
|
||||
return;
|
||||
}
|
||||
|
||||
lv_area_t full;
|
||||
if(area == NULL) {
|
||||
draw_buf_get_full_area(draw_buf, &full);
|
||||
area = &full;
|
||||
}
|
||||
|
||||
handlers->flush_cache_cb(draw_buf, area);
|
||||
}
|
||||
|
||||
void lv_draw_buf_clear(lv_draw_buf_t * draw_buf, const lv_area_t * a)
|
||||
{
|
||||
LV_ASSERT_NULL(draw_buf);
|
||||
|
||||
const lv_image_header_t * header = &draw_buf->header;
|
||||
uint32_t stride = header->stride;
|
||||
|
||||
if(a == NULL) {
|
||||
uint8_t * buf = lv_draw_buf_goto_xy(draw_buf, 0, 0);
|
||||
lv_memzero(buf, header->h * stride);
|
||||
return;
|
||||
}
|
||||
|
||||
lv_area_t a_draw_buf;
|
||||
a_draw_buf.x1 = 0;
|
||||
a_draw_buf.y1 = 0;
|
||||
a_draw_buf.x2 = draw_buf->header.w - 1;
|
||||
a_draw_buf.y2 = draw_buf->header.h - 1;
|
||||
|
||||
lv_area_t a_clipped;
|
||||
if(!lv_area_intersect(&a_clipped, a, &a_draw_buf)) return;
|
||||
if(lv_area_get_width(&a_clipped) <= 0) return;
|
||||
if(lv_area_get_height(&a_clipped) <= 0) return;
|
||||
|
||||
uint8_t * buf = lv_draw_buf_goto_xy(draw_buf, a_clipped.x1, a_clipped.y1);
|
||||
uint8_t bpp = lv_color_format_get_bpp(header->cf);
|
||||
uint32_t line_length = (lv_area_get_width(&a_clipped) * bpp + 7) >> 3;
|
||||
int32_t y;
|
||||
for(y = a_clipped.y1; y <= a_clipped.y2; y++) {
|
||||
lv_memzero(buf, line_length);
|
||||
buf += stride;
|
||||
}
|
||||
}
|
||||
|
||||
void lv_draw_buf_copy(lv_draw_buf_t * dest, const lv_area_t * dest_area,
|
||||
const lv_draw_buf_t * src, const lv_area_t * src_area)
|
||||
{
|
||||
uint8_t * dest_bufc;
|
||||
uint8_t * src_bufc;
|
||||
int32_t line_width;
|
||||
|
||||
/*Source and dest color format must be same. Color conversion is not supported yet.*/
|
||||
LV_ASSERT_FORMAT_MSG(dest->header.cf == src->header.cf, "Color format mismatch: %d != %d",
|
||||
dest->header.cf, src->header.cf);
|
||||
|
||||
if(dest_area == NULL) line_width = dest->header.w;
|
||||
else line_width = lv_area_get_width(dest_area);
|
||||
|
||||
/* For indexed image, copy the palette if we are copying full image area*/
|
||||
if(dest_area == NULL || src_area == NULL) {
|
||||
if(LV_COLOR_FORMAT_IS_INDEXED(dest->header.cf)) {
|
||||
lv_memcpy(dest->data, src->data, LV_COLOR_INDEXED_PALETTE_SIZE(dest->header.cf) * sizeof(lv_color32_t));
|
||||
}
|
||||
}
|
||||
|
||||
/*Check source and dest area have same width*/
|
||||
if((src_area == NULL && line_width != src->header.w) || \
|
||||
(src_area != NULL && line_width != lv_area_get_width(src_area))) {
|
||||
LV_ASSERT_MSG(0, "Source and destination areas have different width");
|
||||
return;
|
||||
}
|
||||
|
||||
if(src_area) src_bufc = lv_draw_buf_goto_xy(src, src_area->x1, src_area->y1);
|
||||
else src_bufc = lv_draw_buf_goto_xy(src, 0, 0);
|
||||
|
||||
if(dest_area) dest_bufc = lv_draw_buf_goto_xy(dest, dest_area->x1, dest_area->y1);
|
||||
else dest_bufc = lv_draw_buf_goto_xy(dest, 0, 0);
|
||||
|
||||
int32_t start_y, end_y;
|
||||
if(dest_area) {
|
||||
start_y = dest_area->y1;
|
||||
end_y = dest_area->y2;
|
||||
}
|
||||
else {
|
||||
start_y = 0;
|
||||
end_y = dest->header.h - 1;
|
||||
}
|
||||
|
||||
uint32_t dest_stride = dest->header.stride;
|
||||
uint32_t src_stride = src->header.stride;
|
||||
uint32_t line_bytes = (line_width * lv_color_format_get_bpp(dest->header.cf) + 7) >> 3;
|
||||
|
||||
for(; start_y <= end_y; start_y++) {
|
||||
lv_memcpy(dest_bufc, src_bufc, line_bytes);
|
||||
dest_bufc += dest_stride;
|
||||
src_bufc += src_stride;
|
||||
}
|
||||
}
|
||||
|
||||
lv_result_t lv_draw_buf_init(lv_draw_buf_t * draw_buf, uint32_t w, uint32_t h, lv_color_format_t cf, uint32_t stride,
|
||||
void * data, uint32_t data_size)
|
||||
{
|
||||
LV_ASSERT_NULL(draw_buf);
|
||||
if(draw_buf == NULL) return LV_RESULT_INVALID;
|
||||
|
||||
lv_memzero(draw_buf, sizeof(lv_draw_buf_t));
|
||||
if(stride == 0) stride = lv_draw_buf_width_to_stride(w, cf);
|
||||
if(stride * h > data_size) {
|
||||
LV_LOG_WARN("Data size too small, required: %" LV_PRId32 ", provided: %" LV_PRId32, stride * h,
|
||||
data_size);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
lv_image_header_t * header = &draw_buf->header;
|
||||
header->w = w;
|
||||
header->h = h;
|
||||
header->cf = cf;
|
||||
header->stride = stride;
|
||||
header->flags = 0;
|
||||
header->magic = LV_IMAGE_HEADER_MAGIC;
|
||||
|
||||
draw_buf->data = data;
|
||||
draw_buf->unaligned_data = data;
|
||||
draw_buf->handlers = &default_handlers;
|
||||
draw_buf->data_size = data_size;
|
||||
if(lv_draw_buf_align(data, cf) != draw_buf->unaligned_data) {
|
||||
LV_LOG_WARN("Data is not aligned, ignored");
|
||||
}
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_draw_buf_t * lv_draw_buf_create(uint32_t w, uint32_t h, lv_color_format_t cf, uint32_t stride)
|
||||
{
|
||||
return lv_draw_buf_create_ex(&default_handlers, w, h, cf, stride);
|
||||
}
|
||||
|
||||
lv_draw_buf_t * lv_draw_buf_create_ex(const lv_draw_buf_handlers_t * handlers, uint32_t w, uint32_t h,
|
||||
lv_color_format_t cf, uint32_t stride)
|
||||
{
|
||||
lv_draw_buf_t * draw_buf = lv_malloc_zeroed(sizeof(lv_draw_buf_t));
|
||||
LV_ASSERT_MALLOC(draw_buf);
|
||||
if(draw_buf == NULL) return NULL;
|
||||
if(stride == 0) stride = lv_draw_buf_width_to_stride(w, cf);
|
||||
|
||||
uint32_t size = _calculate_draw_buf_size(w, h, cf, stride);
|
||||
|
||||
void * buf = draw_buf_malloc(handlers, size, cf);
|
||||
/*Do not assert here as LVGL or the app might just want to try creating a draw_buf*/
|
||||
if(buf == NULL) {
|
||||
LV_LOG_WARN("No memory: %"LV_PRIu32"x%"LV_PRIu32", cf: %d, stride: %"LV_PRIu32", %"LV_PRIu32"Byte, ",
|
||||
w, h, cf, stride, size);
|
||||
lv_free(draw_buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
draw_buf->header.w = w;
|
||||
draw_buf->header.h = h;
|
||||
draw_buf->header.cf = cf;
|
||||
draw_buf->header.flags = LV_IMAGE_FLAGS_MODIFIABLE | LV_IMAGE_FLAGS_ALLOCATED;
|
||||
draw_buf->header.stride = stride;
|
||||
draw_buf->header.magic = LV_IMAGE_HEADER_MAGIC;
|
||||
draw_buf->data = lv_draw_buf_align(buf, cf);
|
||||
draw_buf->unaligned_data = buf;
|
||||
draw_buf->data_size = size;
|
||||
draw_buf->handlers = handlers;
|
||||
return draw_buf;
|
||||
}
|
||||
|
||||
lv_draw_buf_t * lv_draw_buf_dup(const lv_draw_buf_t * draw_buf)
|
||||
{
|
||||
return lv_draw_buf_dup_ex(&default_handlers, draw_buf);
|
||||
}
|
||||
|
||||
lv_draw_buf_t * lv_draw_buf_dup_ex(const lv_draw_buf_handlers_t * handlers, const lv_draw_buf_t * draw_buf)
|
||||
{
|
||||
const lv_image_header_t * header = &draw_buf->header;
|
||||
lv_draw_buf_t * new_buf = lv_draw_buf_create_ex(handlers, header->w, header->h, header->cf, header->stride);
|
||||
if(new_buf == NULL) return NULL;
|
||||
|
||||
new_buf->header.flags = draw_buf->header.flags;
|
||||
new_buf->header.flags |= LV_IMAGE_FLAGS_MODIFIABLE | LV_IMAGE_FLAGS_ALLOCATED;
|
||||
|
||||
/*Choose the smaller size to copy*/
|
||||
uint32_t size = LV_MIN(draw_buf->data_size, new_buf->data_size);
|
||||
|
||||
/*Copy image data*/
|
||||
lv_memcpy(new_buf->data, draw_buf->data, size);
|
||||
return new_buf;
|
||||
}
|
||||
|
||||
lv_draw_buf_t * lv_draw_buf_reshape(lv_draw_buf_t * draw_buf, lv_color_format_t cf, uint32_t w, uint32_t h,
|
||||
uint32_t stride)
|
||||
{
|
||||
if(draw_buf == NULL) return NULL;
|
||||
|
||||
/*If color format is unknown, keep using the original color format.*/
|
||||
if(cf == LV_COLOR_FORMAT_UNKNOWN) cf = draw_buf->header.cf;
|
||||
if(stride == 0) stride = lv_draw_buf_width_to_stride(w, cf);
|
||||
|
||||
uint32_t size = _calculate_draw_buf_size(w, h, cf, stride);
|
||||
|
||||
if(size > draw_buf->data_size) {
|
||||
LV_LOG_TRACE("Draw buf too small for new shape");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
draw_buf->header.cf = cf;
|
||||
draw_buf->header.w = w;
|
||||
draw_buf->header.h = h;
|
||||
draw_buf->header.stride = stride;
|
||||
|
||||
return draw_buf;
|
||||
}
|
||||
|
||||
void lv_draw_buf_destroy(lv_draw_buf_t * draw_buf)
|
||||
{
|
||||
LV_ASSERT_NULL(draw_buf);
|
||||
if(draw_buf == NULL) return;
|
||||
|
||||
if(draw_buf->header.flags & LV_IMAGE_FLAGS_ALLOCATED) {
|
||||
LV_ASSERT_NULL(draw_buf->handlers);
|
||||
|
||||
const lv_draw_buf_handlers_t * handlers = draw_buf->handlers;
|
||||
draw_buf_free(handlers, draw_buf->unaligned_data);
|
||||
lv_free(draw_buf);
|
||||
}
|
||||
else {
|
||||
LV_LOG_ERROR("draw buffer is not allocated, ignored");
|
||||
}
|
||||
}
|
||||
|
||||
void * lv_draw_buf_goto_xy(const lv_draw_buf_t * buf, uint32_t x, uint32_t y)
|
||||
{
|
||||
LV_ASSERT_NULL(buf);
|
||||
if(buf == NULL) return NULL;
|
||||
|
||||
uint8_t * data = buf->data;
|
||||
|
||||
/*Skip palette*/
|
||||
data += LV_COLOR_INDEXED_PALETTE_SIZE(buf->header.cf) * sizeof(lv_color32_t);
|
||||
data += buf->header.stride * y;
|
||||
|
||||
if(x == 0) return data;
|
||||
|
||||
return data + x * lv_color_format_get_bpp(buf->header.cf) / 8;
|
||||
}
|
||||
|
||||
lv_result_t lv_draw_buf_adjust_stride(lv_draw_buf_t * src, uint32_t stride)
|
||||
{
|
||||
LV_ASSERT_NULL(src);
|
||||
LV_ASSERT_NULL(src->data);
|
||||
if(src == NULL) return LV_RESULT_INVALID;
|
||||
if(src->data == NULL) return LV_RESULT_INVALID;
|
||||
|
||||
const lv_image_header_t * header = &src->header;
|
||||
uint32_t w = header->w;
|
||||
uint32_t h = header->h;
|
||||
|
||||
if(!lv_draw_buf_has_flag(src, LV_IMAGE_FLAGS_MODIFIABLE)) {
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
/*Use global stride*/
|
||||
if(stride == 0) stride = lv_draw_buf_width_to_stride(w, header->cf);
|
||||
|
||||
/*Check if stride already match*/
|
||||
if(header->stride == stride) return LV_RESULT_OK;
|
||||
|
||||
/*Calculate the minimal stride allowed from bpp*/
|
||||
uint32_t bpp = lv_color_format_get_bpp(header->cf);
|
||||
uint32_t min_stride = (w * bpp + 7) >> 3;
|
||||
if(stride < min_stride) {
|
||||
LV_LOG_WARN("New stride is too small. min: %" LV_PRId32, min_stride);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
/*Check if buffer has enough space. */
|
||||
uint32_t new_size = _calculate_draw_buf_size(w, h, header->cf, stride);
|
||||
if(new_size > src->data_size) {
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
uint32_t offset = LV_COLOR_INDEXED_PALETTE_SIZE(header->cf) * 4;
|
||||
|
||||
if(stride > header->stride) {
|
||||
/*Copy from the last line to the first*/
|
||||
uint8_t * src_data = src->data + offset + header->stride * (h - 1);
|
||||
uint8_t * dst_data = src->data + offset + stride * (h - 1);
|
||||
for(uint32_t y = 0; y < h; y++) {
|
||||
lv_memmove(dst_data, src_data, min_stride);
|
||||
src_data -= header->stride;
|
||||
dst_data -= stride;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*Copy from the first line to the last*/
|
||||
uint8_t * src_data = src->data + offset;
|
||||
uint8_t * dst_data = src->data + offset;
|
||||
for(uint32_t y = 0; y < h; y++) {
|
||||
lv_memmove(dst_data, src_data, min_stride);
|
||||
src_data += header->stride;
|
||||
dst_data += stride;
|
||||
}
|
||||
}
|
||||
|
||||
src->header.stride = stride;
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_draw_buf_premultiply(lv_draw_buf_t * draw_buf)
|
||||
{
|
||||
LV_ASSERT_NULL(draw_buf);
|
||||
if(draw_buf == NULL) return LV_RESULT_INVALID;
|
||||
|
||||
if(draw_buf->header.flags & LV_IMAGE_FLAGS_PREMULTIPLIED) return LV_RESULT_INVALID;
|
||||
if((draw_buf->header.flags & LV_IMAGE_FLAGS_MODIFIABLE) == 0) {
|
||||
LV_LOG_WARN("draw buf is not modifiable: 0x%04x", draw_buf->header.flags);
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
|
||||
/*Premultiply color with alpha, do case by case by judging color format*/
|
||||
lv_color_format_t cf = draw_buf->header.cf;
|
||||
if(LV_COLOR_FORMAT_IS_INDEXED(cf)) {
|
||||
int size = LV_COLOR_INDEXED_PALETTE_SIZE(cf);
|
||||
lv_color32_t * palette = (lv_color32_t *)draw_buf->data;
|
||||
for(int i = 0; i < size; i++) {
|
||||
lv_color_premultiply(&palette[i]);
|
||||
}
|
||||
}
|
||||
else if(cf == LV_COLOR_FORMAT_ARGB8888) {
|
||||
uint32_t h = draw_buf->header.h;
|
||||
uint32_t w = draw_buf->header.w;
|
||||
uint32_t stride = draw_buf->header.stride;
|
||||
uint8_t * line = (uint8_t *)draw_buf->data;
|
||||
for(uint32_t y = 0; y < h; y++) {
|
||||
lv_color32_t * pixel = (lv_color32_t *)line;
|
||||
for(uint32_t x = 0; x < w; x++) {
|
||||
lv_color_premultiply(pixel);
|
||||
pixel++;
|
||||
}
|
||||
line += stride;
|
||||
}
|
||||
}
|
||||
else if(cf == LV_COLOR_FORMAT_RGB565A8) {
|
||||
uint32_t h = draw_buf->header.h;
|
||||
uint32_t w = draw_buf->header.w;
|
||||
uint32_t stride = draw_buf->header.stride;
|
||||
uint32_t alpha_stride = stride / 2;
|
||||
uint8_t * line = (uint8_t *)draw_buf->data;
|
||||
lv_opa_t * alpha = (lv_opa_t *)(line + stride * h);
|
||||
for(uint32_t y = 0; y < h; y++) {
|
||||
lv_color16_t * pixel = (lv_color16_t *)line;
|
||||
for(uint32_t x = 0; x < w; x++) {
|
||||
lv_color16_premultiply(pixel, alpha[x]);
|
||||
pixel++;
|
||||
}
|
||||
line += stride;
|
||||
alpha += alpha_stride;
|
||||
}
|
||||
}
|
||||
else if(cf == LV_COLOR_FORMAT_ARGB8565) {
|
||||
uint32_t h = draw_buf->header.h;
|
||||
uint32_t w = draw_buf->header.w;
|
||||
uint32_t stride = draw_buf->header.stride;
|
||||
uint8_t * line = (uint8_t *)draw_buf->data;
|
||||
for(uint32_t y = 0; y < h; y++) {
|
||||
uint8_t * pixel = line;
|
||||
for(uint32_t x = 0; x < w; x++) {
|
||||
uint8_t alpha = pixel[2];
|
||||
lv_color16_premultiply((lv_color16_t *)pixel, alpha);
|
||||
pixel += 3;
|
||||
}
|
||||
line += stride;
|
||||
}
|
||||
}
|
||||
else if(LV_COLOR_FORMAT_IS_ALPHA_ONLY(cf)) {
|
||||
/*Pass*/
|
||||
}
|
||||
else {
|
||||
LV_LOG_WARN("draw buf has no alpha, cf: %d", cf);
|
||||
}
|
||||
|
||||
draw_buf->header.flags |= LV_IMAGE_FLAGS_PREMULTIPLIED;
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
void lv_draw_buf_set_palette(lv_draw_buf_t * draw_buf, uint8_t index, lv_color32_t color)
|
||||
{
|
||||
LV_ASSERT_NULL(draw_buf);
|
||||
if(draw_buf == NULL) return;
|
||||
|
||||
if(!LV_COLOR_FORMAT_IS_INDEXED(draw_buf->header.cf)) {
|
||||
LV_LOG_WARN("Not indexed color format");
|
||||
return;
|
||||
}
|
||||
|
||||
lv_color32_t * palette = (lv_color32_t *)draw_buf->data;
|
||||
palette[index] = color;
|
||||
}
|
||||
|
||||
bool lv_draw_buf_has_flag(const lv_draw_buf_t * draw_buf, lv_image_flags_t flag)
|
||||
{
|
||||
return draw_buf->header.flags & flag;
|
||||
}
|
||||
|
||||
void lv_draw_buf_set_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag)
|
||||
{
|
||||
draw_buf->header.flags |= flag;
|
||||
}
|
||||
|
||||
void lv_draw_buf_clear_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag)
|
||||
{
|
||||
draw_buf->header.flags &= ~flag;
|
||||
}
|
||||
|
||||
void lv_draw_buf_from_image(lv_draw_buf_t * buf, const lv_image_dsc_t * img)
|
||||
{
|
||||
lv_draw_buf_init(buf, img->header.w, img->header.h, img->header.cf, img->header.stride,
|
||||
(void *)img->data, img->data_size);
|
||||
buf->header.flags = img->header.flags;
|
||||
}
|
||||
|
||||
void lv_draw_buf_to_image(const lv_draw_buf_t * buf, lv_image_dsc_t * img)
|
||||
{
|
||||
lv_memcpy((void *)img, buf, sizeof(lv_image_dsc_t));
|
||||
}
|
||||
|
||||
void lv_image_buf_set_palette(lv_image_dsc_t * dsc, uint8_t id, lv_color32_t c)
|
||||
{
|
||||
LV_LOG_WARN("Deprecated API, use lv_draw_buf_set_palette instead.");
|
||||
lv_draw_buf_set_palette((lv_draw_buf_t *)dsc, id, c);
|
||||
}
|
||||
|
||||
void lv_image_buf_free(lv_image_dsc_t * dsc)
|
||||
{
|
||||
LV_LOG_WARN("Deprecated API, use lv_draw_buf_destroy instead.");
|
||||
if(dsc != NULL) {
|
||||
if(dsc->data != NULL)
|
||||
lv_free((void *)dsc->data);
|
||||
|
||||
lv_free((void *)dsc);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void * buf_malloc(size_t size_bytes, lv_color_format_t color_format)
|
||||
{
|
||||
LV_UNUSED(color_format);
|
||||
|
||||
/*Allocate larger memory to be sure it can be aligned as needed*/
|
||||
size_bytes += LV_DRAW_BUF_ALIGN - 1;
|
||||
return lv_malloc(size_bytes);
|
||||
}
|
||||
|
||||
static void buf_free(void * buf)
|
||||
{
|
||||
lv_free(buf);
|
||||
}
|
||||
|
||||
static void * buf_align(void * buf, lv_color_format_t color_format)
|
||||
{
|
||||
LV_UNUSED(color_format);
|
||||
|
||||
uint8_t * buf_u8 = buf;
|
||||
if(buf_u8) {
|
||||
buf_u8 = (uint8_t *)LV_ROUND_UP((lv_uintptr_t)buf_u8, LV_DRAW_BUF_ALIGN);
|
||||
}
|
||||
return buf_u8;
|
||||
}
|
||||
|
||||
static uint32_t width_to_stride(uint32_t w, lv_color_format_t color_format)
|
||||
{
|
||||
uint32_t width_byte;
|
||||
width_byte = w * lv_color_format_get_bpp(color_format);
|
||||
width_byte = (width_byte + 7) >> 3; /*Round up*/
|
||||
|
||||
return LV_ROUND_UP(width_byte, LV_DRAW_BUF_STRIDE_ALIGN);
|
||||
}
|
||||
|
||||
static void * draw_buf_malloc(const lv_draw_buf_handlers_t * handlers, size_t size_bytes,
|
||||
lv_color_format_t color_format)
|
||||
{
|
||||
if(handlers->buf_malloc_cb) return handlers->buf_malloc_cb(size_bytes, color_format);
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
static void draw_buf_free(const lv_draw_buf_handlers_t * handlers, void * buf)
|
||||
{
|
||||
if(handlers->buf_free_cb)
|
||||
handlers->buf_free_cb(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* For given width, height, color format, and stride, calculate the size needed for a new draw buffer.
|
||||
*/
|
||||
static uint32_t _calculate_draw_buf_size(uint32_t w, uint32_t h, lv_color_format_t cf, uint32_t stride)
|
||||
{
|
||||
uint32_t size;
|
||||
|
||||
if(stride == 0) stride = lv_draw_buf_width_to_stride(w, cf);
|
||||
|
||||
size = stride * h;
|
||||
if(cf == LV_COLOR_FORMAT_RGB565A8) {
|
||||
size += (stride / 2) * h; /*A8 mask*/
|
||||
}
|
||||
else if(LV_COLOR_FORMAT_IS_INDEXED(cf)) {
|
||||
/*@todo we have to include palette right before image data*/
|
||||
size += LV_COLOR_INDEXED_PALETTE_SIZE(cf) * 4;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static void draw_buf_get_full_area(const lv_draw_buf_t * draw_buf, lv_area_t * full_area)
|
||||
{
|
||||
const lv_image_header_t * header = &draw_buf->header;
|
||||
lv_area_set(full_area, 0, 0, header->w - 1, header->h - 1);
|
||||
}
|
||||
356
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_buf.h
Normal file
356
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_buf.h
Normal file
@@ -0,0 +1,356 @@
|
||||
/**
|
||||
* @file lv_draw_buf.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_BUF_H
|
||||
#define LV_DRAW_BUF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../misc/lv_types.h"
|
||||
#include "../misc/lv_area.h"
|
||||
#include "../misc/lv_color.h"
|
||||
#include "../stdlib/lv_string.h"
|
||||
#include "lv_image_dsc.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/** Use this value to let LVGL calculate stride automatically */
|
||||
#define LV_STRIDE_AUTO 0
|
||||
LV_EXPORT_CONST_INT(LV_STRIDE_AUTO);
|
||||
|
||||
/**
|
||||
* Stride alignment for draw buffers.
|
||||
* It may vary between different color formats and hardware.
|
||||
* Refine it to suit your needs.
|
||||
*/
|
||||
|
||||
#define LV_DRAW_BUF_STRIDE(w, cf) \
|
||||
LV_ROUND_UP(((w) * LV_COLOR_FORMAT_GET_BPP(cf) + 7) / 8, LV_DRAW_BUF_STRIDE_ALIGN)
|
||||
|
||||
/** Allocate a slightly larger buffer, so we can adjust the start address to meet alignment */
|
||||
#define LV_DRAW_BUF_SIZE(w, h, cf) \
|
||||
(LV_DRAW_BUF_STRIDE(w, cf) * (h) + LV_DRAW_BUF_ALIGN + \
|
||||
LV_COLOR_INDEXED_PALETTE_SIZE(cf) * sizeof(lv_color32_t))
|
||||
|
||||
/**
|
||||
* Define a static draw buffer with the given width, height, and color format.
|
||||
* Stride alignment is set to LV_DRAW_BUF_STRIDE_ALIGN.
|
||||
*
|
||||
* For platform that needs special buffer alignment, call LV_DRAW_BUF_INIT_STATIC.
|
||||
*/
|
||||
#define LV_DRAW_BUF_DEFINE_STATIC(name, _w, _h, _cf) \
|
||||
static uint8_t buf_##name[LV_DRAW_BUF_SIZE(_w, _h, _cf)]; \
|
||||
static lv_draw_buf_t name = { \
|
||||
.header = { \
|
||||
.magic = LV_IMAGE_HEADER_MAGIC, \
|
||||
.cf = (_cf), \
|
||||
.flags = LV_IMAGE_FLAGS_MODIFIABLE, \
|
||||
.w = (_w), \
|
||||
.h = (_h), \
|
||||
.stride = LV_DRAW_BUF_STRIDE(_w, _cf), \
|
||||
.reserved_2 = 0, \
|
||||
}, \
|
||||
.data_size = sizeof(buf_##name), \
|
||||
.data = buf_##name, \
|
||||
.unaligned_data = buf_##name, \
|
||||
}
|
||||
|
||||
#define LV_DRAW_BUF_INIT_STATIC(name) \
|
||||
do { \
|
||||
lv_image_header_t * header = &name.header; \
|
||||
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)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef void * (*lv_draw_buf_malloc_cb)(size_t size, lv_color_format_t color_format);
|
||||
|
||||
typedef void (*lv_draw_buf_free_cb)(void * draw_buf);
|
||||
|
||||
typedef void * (*lv_draw_buf_align_cb)(void * buf, lv_color_format_t color_format);
|
||||
|
||||
typedef void (*lv_draw_buf_cache_operation_cb)(const lv_draw_buf_t * draw_buf, const lv_area_t * area);
|
||||
|
||||
typedef uint32_t (*lv_draw_buf_width_to_stride_cb)(uint32_t w, lv_color_format_t color_format);
|
||||
|
||||
struct lv_draw_buf_t {
|
||||
lv_image_header_t header;
|
||||
uint32_t data_size; /**< Total buf size in bytes */
|
||||
uint8_t * data;
|
||||
void * unaligned_data; /**< Unaligned address of `data`, used internally by lvgl */
|
||||
const lv_draw_buf_handlers_t * handlers; /**< draw buffer alloc/free ops. */
|
||||
};
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the draw buffer with the default handlers.
|
||||
*
|
||||
* @param handlers the draw buffer handlers to set
|
||||
*/
|
||||
void lv_draw_buf_init_with_default_handlers(lv_draw_buf_handlers_t * handlers);
|
||||
|
||||
/**
|
||||
* Initialize the draw buffer with given handlers.
|
||||
*
|
||||
* @param handlers the draw buffer handlers to set
|
||||
* @param buf_malloc_cb the callback to allocate memory for the buffer
|
||||
* @param buf_free_cb the callback to free memory of the buffer
|
||||
* @param align_pointer_cb the callback to align the buffer
|
||||
* @param invalidate_cache_cb the callback to invalidate the cache of the buffer
|
||||
* @param flush_cache_cb the callback to flush buffer
|
||||
* @param width_to_stride_cb the callback to calculate the stride based on the width and color format
|
||||
*/
|
||||
void lv_draw_buf_handlers_init(lv_draw_buf_handlers_t * handlers,
|
||||
lv_draw_buf_malloc_cb buf_malloc_cb,
|
||||
lv_draw_buf_free_cb buf_free_cb,
|
||||
lv_draw_buf_align_cb align_pointer_cb,
|
||||
lv_draw_buf_cache_operation_cb invalidate_cache_cb,
|
||||
lv_draw_buf_cache_operation_cb flush_cache_cb,
|
||||
lv_draw_buf_width_to_stride_cb width_to_stride_cb);
|
||||
|
||||
/**
|
||||
* Get the struct which holds the callbacks for draw buf management.
|
||||
* Custom callback can be set on the returned value
|
||||
* @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
|
||||
* @param buf the data to align
|
||||
* @param color_format the color format of the buffer
|
||||
* @return the aligned buffer
|
||||
*/
|
||||
void * lv_draw_buf_align(void * buf, lv_color_format_t color_format);
|
||||
|
||||
/**
|
||||
* Align the address of a buffer with custom draw buffer handlers.
|
||||
* The buffer needs to be large enough for the real data after alignment
|
||||
* @param handlers the draw buffer handlers
|
||||
* @param buf the data to align
|
||||
* @param color_format the color format of the buffer
|
||||
* @return the aligned buffer
|
||||
*/
|
||||
void * lv_draw_buf_align_ex(const lv_draw_buf_handlers_t * handlers, void * buf, lv_color_format_t color_format);
|
||||
|
||||
/**
|
||||
* Invalidate the cache of the buffer
|
||||
* @param draw_buf the draw buffer needs to be invalidated
|
||||
* @param area the area to invalidate in the buffer,
|
||||
* use NULL to invalidate the whole draw buffer address range
|
||||
*/
|
||||
void lv_draw_buf_invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area);
|
||||
|
||||
/**
|
||||
* Flush the cache of the buffer
|
||||
* @param draw_buf the draw buffer needs to be flushed
|
||||
* @param area the area to flush in the buffer,
|
||||
* use NULL to flush the whole draw buffer address range
|
||||
*/
|
||||
void lv_draw_buf_flush_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area);
|
||||
|
||||
/**
|
||||
* Calculate the stride in bytes based on a width and color format
|
||||
* @param w the width in pixels
|
||||
* @param color_format the color format
|
||||
* @return the stride in bytes
|
||||
*/
|
||||
uint32_t lv_draw_buf_width_to_stride(uint32_t w, lv_color_format_t color_format);
|
||||
|
||||
/**
|
||||
* Calculate the stride in bytes based on a width and color format
|
||||
* @param handlers the draw buffer handlers
|
||||
* @param w the width in pixels
|
||||
* @param color_format the color format
|
||||
* @return the stride in bytes
|
||||
*/
|
||||
uint32_t lv_draw_buf_width_to_stride_ex(const lv_draw_buf_handlers_t * handlers, uint32_t w,
|
||||
lv_color_format_t color_format);
|
||||
|
||||
/**
|
||||
* Clear an area on the buffer
|
||||
* @param draw_buf pointer to draw buffer
|
||||
* @param a the area to clear, or NULL to clear the whole buffer
|
||||
*/
|
||||
void lv_draw_buf_clear(lv_draw_buf_t * draw_buf, const lv_area_t * a);
|
||||
|
||||
/**
|
||||
* Copy an area from a buffer to another
|
||||
* @param dest pointer to the destination draw buffer
|
||||
* @param dest_area the area to copy from the destination buffer, if NULL, use the whole buffer
|
||||
* @param src pointer to the source draw buffer
|
||||
* @param src_area the area to copy from the destination buffer, if NULL, use the whole buffer
|
||||
* @note `dest_area` and `src_area` should have the same width and height
|
||||
* @note `dest` and `src` should have same color format. Color converting is not supported fow now.
|
||||
*/
|
||||
void lv_draw_buf_copy(lv_draw_buf_t * dest, const lv_area_t * dest_area,
|
||||
const lv_draw_buf_t * src, const lv_area_t * src_area);
|
||||
|
||||
/**
|
||||
* Note: Eventually, lv_draw_buf_malloc/free will be kept as private.
|
||||
* For now, we use `create` to distinguish with malloc.
|
||||
*
|
||||
* Create an draw buf by allocating struct for `lv_draw_buf_t` and allocating a buffer for it
|
||||
* that meets specified requirements.
|
||||
*
|
||||
* @param w the buffer width in pixels
|
||||
* @param h the buffer height in pixels
|
||||
* @param cf the color format for image
|
||||
* @param stride the stride in bytes for image. Use 0 for automatic calculation based on
|
||||
* w, cf, and global stride alignment configuration.
|
||||
*/
|
||||
lv_draw_buf_t * lv_draw_buf_create(uint32_t w, uint32_t h, lv_color_format_t cf, uint32_t stride);
|
||||
|
||||
/**
|
||||
* Note: Eventually, lv_draw_buf_malloc/free will be kept as private.
|
||||
* For now, we use `create` to distinguish with malloc.
|
||||
*
|
||||
* Create an draw buf by allocating struct for `lv_draw_buf_t` and allocating a buffer for it
|
||||
* that meets specified requirements.
|
||||
*
|
||||
* @param handlers the draw buffer handlers
|
||||
* @param w the buffer width in pixels
|
||||
* @param h the buffer height in pixels
|
||||
* @param cf the color format for image
|
||||
* @param stride the stride in bytes for image. Use 0 for automatic calculation based on
|
||||
* w, cf, and global stride alignment configuration.
|
||||
*/
|
||||
lv_draw_buf_t * lv_draw_buf_create_ex(const lv_draw_buf_handlers_t * handlers, uint32_t w, uint32_t h,
|
||||
lv_color_format_t cf, uint32_t stride);
|
||||
|
||||
/**
|
||||
* Duplicate a draw buf with same image size, stride and color format. Copy the image data too.
|
||||
* @param draw_buf the draw buf to duplicate
|
||||
* @return the duplicated draw buf on success, NULL if failed
|
||||
*/
|
||||
lv_draw_buf_t * lv_draw_buf_dup(const lv_draw_buf_t * draw_buf);
|
||||
|
||||
/**
|
||||
* Duplicate a draw buf with same image size, stride and color format. Copy the image data too.
|
||||
* @param handlers the draw buffer handlers
|
||||
* @param draw_buf the draw buf to duplicate
|
||||
* @return the duplicated draw buf on success, NULL if failed
|
||||
*/
|
||||
lv_draw_buf_t * lv_draw_buf_dup_ex(const lv_draw_buf_handlers_t * handlers, const lv_draw_buf_t * draw_buf);
|
||||
|
||||
/**
|
||||
* Initialize a draw buf with the given buffer and parameters. Clear draw buffer flag to zero.
|
||||
* @param draw_buf the draw buf to initialize
|
||||
* @param w the buffer width in pixels
|
||||
* @param h the buffer height in pixels
|
||||
* @param cf the color format
|
||||
* @param stride the stride in bytes. Use 0 for automatic calculation
|
||||
* @param data the buffer used for drawing. Unaligned `data` will be aligned internally
|
||||
* @param data_size the size of the buffer in bytes
|
||||
* @return return LV_RESULT_OK on success, LV_RESULT_INVALID otherwise
|
||||
*/
|
||||
lv_result_t lv_draw_buf_init(lv_draw_buf_t * draw_buf, uint32_t w, uint32_t h, lv_color_format_t cf, uint32_t stride,
|
||||
void * data, uint32_t data_size);
|
||||
|
||||
/**
|
||||
* Keep using the existing memory, reshape the draw buffer to the given width and height.
|
||||
* Return NULL if data_size is smaller than the required size.
|
||||
* @param draw_buf pointer to a draw buffer
|
||||
* @param cf the new color format, use 0 or LV_COLOR_FORMAT_UNKNOWN to keep using the original color format.
|
||||
* @param w the new width in pixels
|
||||
* @param h the new height in pixels
|
||||
* @param stride the stride in bytes for image. Use 0 for automatic calculation.
|
||||
*/
|
||||
lv_draw_buf_t * lv_draw_buf_reshape(lv_draw_buf_t * draw_buf, lv_color_format_t cf, uint32_t w, uint32_t h,
|
||||
uint32_t stride);
|
||||
|
||||
/**
|
||||
* Destroy a draw buf by freeing the actual buffer if it's marked as LV_IMAGE_FLAGS_ALLOCATED in header.
|
||||
* Then free the lv_draw_buf_t struct.
|
||||
*
|
||||
* @param draw_buf the draw buffer to destroy
|
||||
*/
|
||||
void lv_draw_buf_destroy(lv_draw_buf_t * draw_buf);
|
||||
|
||||
/**
|
||||
* Return pointer to the buffer at the given coordinates
|
||||
*/
|
||||
void * lv_draw_buf_goto_xy(const lv_draw_buf_t * buf, uint32_t x, uint32_t y);
|
||||
|
||||
/**
|
||||
* Adjust the stride of a draw buf in place.
|
||||
* @param src pointer to a draw buffer
|
||||
* @param stride the new stride in bytes for image. Use LV_STRIDE_AUTO for automatic calculation.
|
||||
* @return LV_RESULT_OK: success or LV_RESULT_INVALID: failed
|
||||
*/
|
||||
lv_result_t lv_draw_buf_adjust_stride(lv_draw_buf_t * src, uint32_t stride);
|
||||
|
||||
/**
|
||||
* Premultiply draw buffer color with alpha channel.
|
||||
* If it's already premultiplied, return directly.
|
||||
* Only color formats with alpha channel will be processed.
|
||||
*
|
||||
* @return LV_RESULT_OK: premultiply success
|
||||
*/
|
||||
lv_result_t lv_draw_buf_premultiply(lv_draw_buf_t * draw_buf);
|
||||
|
||||
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_clear_flag(lv_draw_buf_t * draw_buf, lv_image_flags_t flag);
|
||||
|
||||
/**
|
||||
* As of now, draw buf share same definition as `lv_image_dsc_t`.
|
||||
* And is interchangeable with `lv_image_dsc_t`.
|
||||
*/
|
||||
|
||||
void lv_draw_buf_from_image(lv_draw_buf_t * buf, const lv_image_dsc_t * img);
|
||||
|
||||
void lv_draw_buf_to_image(const lv_draw_buf_t * buf, lv_image_dsc_t * img);
|
||||
|
||||
/**
|
||||
* Set the palette color of an indexed image. Valid only for `LV_COLOR_FORMAT_I1/2/4/8`
|
||||
* @param draw_buf pointer to an image descriptor
|
||||
* @param index the palette color to set:
|
||||
* - for `LV_COLOR_FORMAT_I1`: 0..1
|
||||
* - for `LV_COLOR_FORMAT_I2`: 0..3
|
||||
* - for `LV_COLOR_FORMAT_I4`: 0..15
|
||||
* - for `LV_COLOR_FORMAT_I8`: 0..255
|
||||
* @param color the color to set in lv_color32_t format
|
||||
*/
|
||||
void lv_draw_buf_set_palette(lv_draw_buf_t * draw_buf, uint8_t index, lv_color32_t color);
|
||||
|
||||
/**
|
||||
* @deprecated Use lv_draw_buf_set_palette instead.
|
||||
*/
|
||||
void lv_image_buf_set_palette(lv_image_dsc_t * dsc, uint8_t id, lv_color32_t c);
|
||||
|
||||
/**
|
||||
* @deprecated Use lv_draw_buffer_create/destroy instead.
|
||||
* Free the data pointer and dsc struct of an image.
|
||||
*/
|
||||
void lv_image_buf_free(lv_image_dsc_t * dsc);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_BUF_H*/
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* @file lv_draw_buf_private.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_BUF_PRIVATE_H
|
||||
#define LV_DRAW_BUF_PRIVATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_buf.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
struct lv_draw_buf_handlers_t {
|
||||
lv_draw_buf_malloc_cb buf_malloc_cb;
|
||||
lv_draw_buf_free_cb buf_free_cb;
|
||||
lv_draw_buf_align_cb align_pointer_cb;
|
||||
lv_draw_buf_cache_operation_cb invalidate_cache_cb;
|
||||
lv_draw_buf_cache_operation_cb flush_cache_cb;
|
||||
lv_draw_buf_width_to_stride_cb width_to_stride_cb;
|
||||
};
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Called internally to initialize the draw_buf_handlers in lv_global
|
||||
*/
|
||||
void lv_draw_buf_init_handlers(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_BUF_PRIVATE_H*/
|
||||
314
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_image.c
Normal file
314
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_image.c
Normal file
@@ -0,0 +1,314 @@
|
||||
/**
|
||||
* @file lv_draw_img.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_image_private.h"
|
||||
#include "../misc/lv_area_private.h"
|
||||
#include "lv_image_decoder_private.h"
|
||||
#include "lv_draw_private.h"
|
||||
#include "../display/lv_display.h"
|
||||
#include "../misc/lv_log.h"
|
||||
#include "../misc/lv_math.h"
|
||||
#include "../core/lv_refr.h"
|
||||
#include "../stdlib/lv_mem.h"
|
||||
#include "../stdlib/lv_string.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void img_decode_and_draw(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc,
|
||||
lv_image_decoder_dsc_t * decoder_dsc, lv_area_t * relative_decoded_area,
|
||||
const lv_area_t * img_area, const lv_area_t * clipped_img_area,
|
||||
lv_draw_image_core_cb draw_core_cb);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_image_dsc_init(lv_draw_image_dsc_t * dsc)
|
||||
{
|
||||
lv_memzero(dsc, sizeof(lv_draw_image_dsc_t));
|
||||
dsc->recolor = lv_color_black();
|
||||
dsc->opa = LV_OPA_COVER;
|
||||
dsc->scale_x = LV_SCALE_NONE;
|
||||
dsc->scale_y = LV_SCALE_NONE;
|
||||
dsc->antialias = LV_COLOR_DEPTH > 8 ? 1 : 0;
|
||||
dsc->image_area.x2 = LV_COORD_MIN; /*Indicate invalid area by default by setting a negative size*/
|
||||
dsc->base.dsc_size = sizeof(lv_draw_image_dsc_t);
|
||||
}
|
||||
|
||||
lv_draw_image_dsc_t * lv_draw_task_get_image_dsc(lv_draw_task_t * task)
|
||||
{
|
||||
return task->type == LV_DRAW_TASK_TYPE_IMAGE ? (lv_draw_image_dsc_t *)task->draw_dsc : NULL;
|
||||
}
|
||||
|
||||
void lv_draw_layer(lv_layer_t * layer, const lv_draw_image_dsc_t * dsc, const lv_area_t * coords)
|
||||
{
|
||||
if(dsc->scale_x <= 0 || dsc->scale_y <= 0) {
|
||||
/* NOT draw if scale is negative or zero */
|
||||
return;
|
||||
}
|
||||
|
||||
lv_draw_task_t * t = lv_draw_add_task(layer, coords);
|
||||
|
||||
t->draw_dsc = lv_malloc(sizeof(*dsc));
|
||||
lv_memcpy(t->draw_dsc, dsc, sizeof(*dsc));
|
||||
t->type = LV_DRAW_TASK_TYPE_LAYER;
|
||||
t->state = LV_DRAW_TASK_STATE_WAITING;
|
||||
|
||||
lv_image_buf_get_transformed_area(&t->_real_area, lv_area_get_width(coords), lv_area_get_height(coords),
|
||||
dsc->rotation, dsc->scale_x, dsc->scale_y, &dsc->pivot);
|
||||
lv_area_move(&t->_real_area, coords->x1, coords->y1);
|
||||
|
||||
lv_layer_t * layer_to_draw = (lv_layer_t *)dsc->src;
|
||||
layer_to_draw->all_tasks_added = true;
|
||||
|
||||
lv_draw_finalize_task_creation(layer, t);
|
||||
}
|
||||
|
||||
void lv_draw_image(lv_layer_t * layer, const lv_draw_image_dsc_t * dsc, const lv_area_t * coords)
|
||||
{
|
||||
if(dsc->src == NULL) {
|
||||
LV_LOG_WARN("Image draw: src is NULL");
|
||||
return;
|
||||
}
|
||||
if(dsc->opa <= LV_OPA_MIN) return;
|
||||
|
||||
if(dsc->scale_x <= 0 || dsc->scale_y <= 0) {
|
||||
/* NOT draw if scale is negative or zero */
|
||||
return;
|
||||
}
|
||||
|
||||
LV_PROFILER_BEGIN;
|
||||
|
||||
lv_draw_image_dsc_t * new_image_dsc = lv_malloc(sizeof(*dsc));
|
||||
lv_memcpy(new_image_dsc, dsc, sizeof(*dsc));
|
||||
lv_result_t res = lv_image_decoder_get_info(new_image_dsc->src, &new_image_dsc->header);
|
||||
if(res != LV_RESULT_OK) {
|
||||
LV_LOG_WARN("Couldn't get info about the image");
|
||||
lv_free(new_image_dsc);
|
||||
return;
|
||||
}
|
||||
|
||||
lv_draw_task_t * t = lv_draw_add_task(layer, coords);
|
||||
t->draw_dsc = new_image_dsc;
|
||||
t->type = LV_DRAW_TASK_TYPE_IMAGE;
|
||||
|
||||
lv_image_buf_get_transformed_area(&t->_real_area, lv_area_get_width(coords), lv_area_get_height(coords),
|
||||
dsc->rotation, dsc->scale_x, dsc->scale_y, &dsc->pivot);
|
||||
lv_area_move(&t->_real_area, coords->x1, coords->y1);
|
||||
|
||||
lv_draw_finalize_task_creation(layer, t);
|
||||
LV_PROFILER_END;
|
||||
}
|
||||
|
||||
lv_image_src_t lv_image_src_get_type(const void * src)
|
||||
{
|
||||
if(src == NULL) return LV_IMAGE_SRC_UNKNOWN;
|
||||
const uint8_t * u8_p = src;
|
||||
|
||||
/*The first byte shows the type of the image source*/
|
||||
if(u8_p[0] >= 0x20 && u8_p[0] <= 0x7F) {
|
||||
return LV_IMAGE_SRC_FILE; /*If it's an ASCII character then it's file name*/
|
||||
}
|
||||
else if(u8_p[0] >= 0x80) {
|
||||
return LV_IMAGE_SRC_SYMBOL; /*Symbols begins after 0x7F*/
|
||||
}
|
||||
else {
|
||||
return LV_IMAGE_SRC_VARIABLE; /*`lv_image_dsc_t` is draw to the first byte < 0x20*/
|
||||
}
|
||||
}
|
||||
|
||||
void lv_draw_image_normal_helper(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc,
|
||||
const lv_area_t * coords, lv_draw_image_core_cb draw_core_cb)
|
||||
{
|
||||
if(draw_core_cb == NULL) {
|
||||
LV_LOG_WARN("draw_core_cb is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
lv_area_t draw_area;
|
||||
lv_area_copy(&draw_area, coords);
|
||||
if(draw_dsc->rotation || draw_dsc->scale_x != LV_SCALE_NONE || draw_dsc->scale_y != LV_SCALE_NONE) {
|
||||
int32_t w = lv_area_get_width(coords);
|
||||
int32_t h = lv_area_get_height(coords);
|
||||
|
||||
lv_image_buf_get_transformed_area(&draw_area, w, h, draw_dsc->rotation, draw_dsc->scale_x, draw_dsc->scale_y,
|
||||
&draw_dsc->pivot);
|
||||
|
||||
draw_area.x1 += coords->x1;
|
||||
draw_area.y1 += coords->y1;
|
||||
draw_area.x2 += coords->x1;
|
||||
draw_area.y2 += coords->y1;
|
||||
}
|
||||
|
||||
lv_area_t clipped_img_area;
|
||||
if(!lv_area_intersect(&clipped_img_area, &draw_area, draw_unit->clip_area)) {
|
||||
return;
|
||||
}
|
||||
|
||||
lv_image_decoder_dsc_t decoder_dsc;
|
||||
lv_result_t res = lv_image_decoder_open(&decoder_dsc, draw_dsc->src, NULL);
|
||||
if(res != LV_RESULT_OK) {
|
||||
LV_LOG_ERROR("Failed to open image");
|
||||
return;
|
||||
}
|
||||
|
||||
img_decode_and_draw(draw_unit, draw_dsc, &decoder_dsc, NULL, coords, &clipped_img_area, draw_core_cb);
|
||||
|
||||
lv_image_decoder_close(&decoder_dsc);
|
||||
}
|
||||
|
||||
void lv_draw_image_tiled_helper(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc,
|
||||
const lv_area_t * coords, lv_draw_image_core_cb draw_core_cb)
|
||||
{
|
||||
if(draw_core_cb == NULL) {
|
||||
LV_LOG_WARN("draw_core_cb is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
lv_image_decoder_dsc_t decoder_dsc;
|
||||
lv_result_t res = lv_image_decoder_open(&decoder_dsc, draw_dsc->src, NULL);
|
||||
if(res != LV_RESULT_OK) {
|
||||
LV_LOG_ERROR("Failed to open image");
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t img_w = draw_dsc->header.w;
|
||||
int32_t img_h = draw_dsc->header.h;
|
||||
|
||||
lv_area_t tile_area;
|
||||
if(lv_area_get_width(&draw_dsc->image_area) >= 0) {
|
||||
tile_area = draw_dsc->image_area;
|
||||
}
|
||||
else {
|
||||
tile_area = *coords;
|
||||
}
|
||||
lv_area_set_width(&tile_area, img_w);
|
||||
lv_area_set_height(&tile_area, img_h);
|
||||
|
||||
int32_t tile_x_start = tile_area.x1;
|
||||
|
||||
lv_area_t relative_decoded_area = {
|
||||
.x1 = LV_COORD_MIN,
|
||||
.y1 = LV_COORD_MIN,
|
||||
.x2 = LV_COORD_MIN,
|
||||
.y2 = LV_COORD_MIN,
|
||||
};
|
||||
|
||||
while(tile_area.y1 <= coords->y2) {
|
||||
while(tile_area.x1 <= coords->x2) {
|
||||
|
||||
lv_area_t clipped_img_area;
|
||||
if(lv_area_intersect(&clipped_img_area, &tile_area, coords)) {
|
||||
img_decode_and_draw(draw_unit, draw_dsc, &decoder_dsc, &relative_decoded_area, &tile_area, &clipped_img_area,
|
||||
draw_core_cb);
|
||||
}
|
||||
|
||||
tile_area.x1 += img_w;
|
||||
tile_area.x2 += img_w;
|
||||
}
|
||||
|
||||
tile_area.y1 += img_h;
|
||||
tile_area.y2 += img_h;
|
||||
tile_area.x1 = tile_x_start;
|
||||
tile_area.x2 = tile_x_start + img_w - 1;
|
||||
}
|
||||
|
||||
lv_image_decoder_close(&decoder_dsc);
|
||||
}
|
||||
|
||||
void lv_image_buf_get_transformed_area(lv_area_t * res, int32_t w, int32_t h, int32_t angle,
|
||||
uint16_t scale_x, uint16_t scale_y, const lv_point_t * pivot)
|
||||
{
|
||||
if(angle == 0 && scale_x == LV_SCALE_NONE && scale_y == LV_SCALE_NONE) {
|
||||
res->x1 = 0;
|
||||
res->y1 = 0;
|
||||
res->x2 = w - 1;
|
||||
res->y2 = h - 1;
|
||||
return;
|
||||
}
|
||||
|
||||
lv_point_t p[4] = {
|
||||
{0, 0},
|
||||
{w, 0},
|
||||
{0, h},
|
||||
{w, h},
|
||||
};
|
||||
lv_point_transform(&p[0], angle, scale_x, scale_y, pivot, true);
|
||||
lv_point_transform(&p[1], angle, scale_x, scale_y, pivot, true);
|
||||
lv_point_transform(&p[2], angle, scale_x, scale_y, pivot, true);
|
||||
lv_point_transform(&p[3], angle, scale_x, scale_y, pivot, true);
|
||||
res->x1 = LV_MIN4(p[0].x, p[1].x, p[2].x, p[3].x);
|
||||
res->x2 = LV_MAX4(p[0].x, p[1].x, p[2].x, p[3].x) - 1;
|
||||
res->y1 = LV_MIN4(p[0].y, p[1].y, p[2].y, p[3].y);
|
||||
res->y2 = LV_MAX4(p[0].y, p[1].y, p[2].y, p[3].y) - 1;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void img_decode_and_draw(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc,
|
||||
lv_image_decoder_dsc_t * decoder_dsc, lv_area_t * relative_decoded_area,
|
||||
const lv_area_t * img_area, const lv_area_t * clipped_img_area,
|
||||
lv_draw_image_core_cb draw_core_cb)
|
||||
{
|
||||
lv_draw_image_sup_t sup;
|
||||
sup.alpha_color = draw_dsc->recolor;
|
||||
sup.palette = decoder_dsc->palette;
|
||||
sup.palette_size = decoder_dsc->palette_size;
|
||||
|
||||
/*The whole image is available, just draw it*/
|
||||
if(decoder_dsc->decoded && (relative_decoded_area == NULL || relative_decoded_area->x1 == LV_COORD_MIN)) {
|
||||
draw_core_cb(draw_unit, draw_dsc, decoder_dsc, &sup, img_area, clipped_img_area);
|
||||
}
|
||||
/*Draw in smaller pieces*/
|
||||
else {
|
||||
lv_area_t relative_full_area_to_decode = *clipped_img_area;
|
||||
lv_area_move(&relative_full_area_to_decode, -img_area->x1, -img_area->y1);
|
||||
lv_area_t tmp;
|
||||
if(relative_decoded_area == NULL) relative_decoded_area = &tmp;
|
||||
relative_decoded_area->x1 = LV_COORD_MIN;
|
||||
relative_decoded_area->y1 = LV_COORD_MIN;
|
||||
relative_decoded_area->x2 = LV_COORD_MIN;
|
||||
relative_decoded_area->y2 = LV_COORD_MIN;
|
||||
lv_result_t res = LV_RESULT_OK;
|
||||
|
||||
while(res == LV_RESULT_OK) {
|
||||
res = lv_image_decoder_get_area(decoder_dsc, &relative_full_area_to_decode, relative_decoded_area);
|
||||
|
||||
lv_area_t absolute_decoded_area = *relative_decoded_area;
|
||||
lv_area_move(&absolute_decoded_area, img_area->x1, img_area->y1);
|
||||
if(res == LV_RESULT_OK) {
|
||||
/*Limit draw area to the current decoded area and draw the image*/
|
||||
lv_area_t clipped_img_area_sub;
|
||||
if(lv_area_intersect(&clipped_img_area_sub, clipped_img_area, &absolute_decoded_area)) {
|
||||
draw_core_cb(draw_unit, draw_dsc, decoder_dsc, &sup,
|
||||
&absolute_decoded_area, &clipped_img_area_sub);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
129
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_image.h
Normal file
129
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_image.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/**
|
||||
* @file lv_draw_image.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_IMAGE_H
|
||||
#define LV_DRAW_IMAGE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw.h"
|
||||
#include "lv_image_decoder.h"
|
||||
#include "lv_draw_buf.h"
|
||||
#include "../misc/lv_style.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
typedef struct lv_draw_image_dsc_t {
|
||||
lv_draw_dsc_base_t base;
|
||||
|
||||
const void * src;
|
||||
lv_image_header_t header;
|
||||
|
||||
int32_t rotation;
|
||||
int32_t scale_x;
|
||||
int32_t scale_y;
|
||||
int32_t skew_x;
|
||||
int32_t skew_y;
|
||||
lv_point_t pivot;
|
||||
|
||||
lv_color_t recolor;
|
||||
lv_opa_t recolor_opa;
|
||||
|
||||
lv_opa_t opa;
|
||||
lv_blend_mode_t blend_mode : 4;
|
||||
|
||||
uint16_t antialias : 1;
|
||||
uint16_t tile : 1;
|
||||
lv_draw_image_sup_t * sup;
|
||||
|
||||
/** Used to indicate the entire original, non-clipped area where the image is to be drawn.
|
||||
* This is important for:
|
||||
* 1. Layer rendering, where it might happen that only a smaller area of the layer is rendered.
|
||||
* 2. Tiled images, where the target draw area is larger than the image to be tiled.
|
||||
*/
|
||||
lv_area_t image_area;
|
||||
|
||||
int32_t clip_radius;
|
||||
|
||||
const lv_image_dsc_t * bitmap_mask_src;
|
||||
} lv_draw_image_dsc_t;
|
||||
|
||||
/**
|
||||
* PErform the actual rendering of a decoded image
|
||||
* @param draw_unit pointer to a draw unit
|
||||
* @param draw_dsc the draw descriptor of the image
|
||||
* @param decoder_dsc pointer to the decoded image's descriptor
|
||||
* @param sup supplementary data
|
||||
* @param img_coords the absolute coordinates of the image
|
||||
* @param clipped_img_area the absolute clip coordinates
|
||||
*/
|
||||
typedef void (*lv_draw_image_core_cb)(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc,
|
||||
const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup,
|
||||
const lv_area_t * img_coords, const lv_area_t * clipped_img_area);
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize an image draw descriptor.
|
||||
* @param dsc pointer to a draw descriptor
|
||||
*/
|
||||
void lv_draw_image_dsc_init(lv_draw_image_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Try to get an image draw descriptor from a draw task.
|
||||
* @param task draw task
|
||||
* @return the task's draw descriptor or NULL if the task is not of type LV_DRAW_TASK_TYPE_IMAGE
|
||||
*/
|
||||
lv_draw_image_dsc_t * lv_draw_task_get_image_dsc(lv_draw_task_t * task);
|
||||
|
||||
/**
|
||||
* Create an image draw task
|
||||
* @param layer pointer to a layer
|
||||
* @param dsc pointer to an initialized draw descriptor
|
||||
* @param coords the coordinates of the image
|
||||
* @note `coords` can be small than the real image area
|
||||
* (if only a part of the image is rendered)
|
||||
* or can be larger (in case of tiled images). .
|
||||
*/
|
||||
void lv_draw_image(lv_layer_t * layer, const lv_draw_image_dsc_t * dsc, const lv_area_t * coords);
|
||||
|
||||
/**
|
||||
* Create a draw task to blend a layer to another layer
|
||||
* @param layer pointer to a layer
|
||||
* @param dsc pointer to an initialized draw descriptor
|
||||
* @param coords the coordinates of the layer.
|
||||
* @note `coords` can be small than the total widget area from which the layer is created
|
||||
* (if only a part of the widget was rendered to a layer)
|
||||
*/
|
||||
void lv_draw_layer(lv_layer_t * layer, const lv_draw_image_dsc_t * dsc, const lv_area_t * coords);
|
||||
|
||||
/**
|
||||
* Get the type of an image source
|
||||
* @param src pointer to an image source:
|
||||
* - pointer to an 'lv_image_t' variable (image stored internally and compiled into the code)
|
||||
* - a path to a file (e.g. "S:/folder/image.bin")
|
||||
* - or a symbol (e.g. LV_SYMBOL_CLOSE)
|
||||
* @return type of the image source LV_IMAGE_SRC_VARIABLE/FILE/SYMBOL/UNKNOWN
|
||||
*/
|
||||
lv_image_src_t lv_image_src_get_type(const void * src);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_IMAGE_H*/
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* @file lv_draw_image_private.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_IMAGE_PRIVATE_H
|
||||
#define LV_DRAW_IMAGE_PRIVATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_image.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
struct lv_draw_image_sup_t {
|
||||
lv_color_t alpha_color;
|
||||
const lv_color32_t * palette;
|
||||
uint32_t palette_size : 9;
|
||||
};
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Can be used by draw units to handle the decoding and
|
||||
* prepare everything for the actual image rendering
|
||||
* @param draw_unit pointer to a draw unit
|
||||
* @param draw_dsc the draw descriptor of the image
|
||||
* @param coords the absolute coordinates of the image
|
||||
* @param draw_core_cb a callback to perform the actual rendering
|
||||
*/
|
||||
void lv_draw_image_normal_helper(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc,
|
||||
const lv_area_t * coords, lv_draw_image_core_cb draw_core_cb);
|
||||
|
||||
/**
|
||||
* Can be used by draw units for TILED images to handle the decoding and
|
||||
* prepare everything for the actual image rendering
|
||||
* @param draw_unit pointer to a draw unit
|
||||
* @param draw_dsc the draw descriptor of the image
|
||||
* @param coords the absolute coordinates of the image
|
||||
* @param draw_core_cb a callback to perform the actual rendering
|
||||
*/
|
||||
void lv_draw_image_tiled_helper(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc,
|
||||
const lv_area_t * coords, lv_draw_image_core_cb draw_core_cb);
|
||||
|
||||
/**
|
||||
* Get the area of a rectangle if its rotated and scaled
|
||||
* @param res store the coordinates here
|
||||
* @param w width of the rectangle to transform
|
||||
* @param h height of the rectangle to transform
|
||||
* @param angle angle of rotation
|
||||
* @param scale_x zoom in x direction, (256 no zoom)
|
||||
* @param scale_y zoom in y direction, (256 no zoom)
|
||||
* @param pivot x,y pivot coordinates of rotation
|
||||
*/
|
||||
void lv_image_buf_get_transformed_area(lv_area_t * res, int32_t w, int32_t h, int32_t angle,
|
||||
uint16_t scale_x, uint16_t scale_y, const lv_point_t * pivot);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_IMAGE_PRIVATE_H*/
|
||||
446
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_label.c
Normal file
446
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_label.c
Normal file
@@ -0,0 +1,446 @@
|
||||
/**
|
||||
* @file lv_draw_label.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_label_private.h"
|
||||
#include "lv_draw_private.h"
|
||||
#include "../misc/lv_area_private.h"
|
||||
#include "lv_draw_vector_private.h"
|
||||
#include "lv_draw_rect_private.h"
|
||||
#include "../core/lv_obj.h"
|
||||
#include "../misc/lv_math.h"
|
||||
#include "../core/lv_obj_event.h"
|
||||
#include "../misc/lv_bidi_private.h"
|
||||
#include "../misc/lv_text_private.h"
|
||||
#include "../misc/lv_assert.h"
|
||||
#include "../stdlib/lv_mem.h"
|
||||
#include "../stdlib/lv_string.h"
|
||||
#include "../core/lv_global.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LABEL_RECOLOR_PAR_LENGTH 6
|
||||
#define LV_LABEL_HINT_UPDATE_TH 1024 /*Update the "hint" if the label's y coordinates have changed more then this*/
|
||||
|
||||
#define font_draw_buf_handlers &(LV_GLOBAL_DEFAULT()->font_draw_buf_handlers)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void draw_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * dsc, const lv_point_t * pos,
|
||||
const lv_font_t * font, uint32_t letter, lv_draw_glyph_cb_t cb);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_label_dsc_init(lv_draw_label_dsc_t * dsc)
|
||||
{
|
||||
lv_memzero(dsc, sizeof(lv_draw_label_dsc_t));
|
||||
dsc->opa = LV_OPA_COVER;
|
||||
dsc->color = lv_color_black();
|
||||
dsc->font = LV_FONT_DEFAULT;
|
||||
dsc->sel_start = LV_DRAW_LABEL_NO_TXT_SEL;
|
||||
dsc->sel_end = LV_DRAW_LABEL_NO_TXT_SEL;
|
||||
dsc->sel_color = lv_color_black();
|
||||
dsc->sel_bg_color = lv_palette_main(LV_PALETTE_BLUE);
|
||||
dsc->bidi_dir = LV_BASE_DIR_LTR;
|
||||
dsc->base.dsc_size = sizeof(lv_draw_label_dsc_t);
|
||||
}
|
||||
|
||||
lv_draw_label_dsc_t * lv_draw_task_get_label_dsc(lv_draw_task_t * task)
|
||||
{
|
||||
return task->type == LV_DRAW_TASK_TYPE_LABEL ? (lv_draw_label_dsc_t *)task->draw_dsc : NULL;
|
||||
}
|
||||
|
||||
void lv_draw_glyph_dsc_init(lv_draw_glyph_dsc_t * dsc)
|
||||
{
|
||||
lv_memzero(dsc, sizeof(lv_draw_glyph_dsc_t));
|
||||
}
|
||||
|
||||
void LV_ATTRIBUTE_FAST_MEM lv_draw_label(lv_layer_t * layer, const lv_draw_label_dsc_t * dsc,
|
||||
const lv_area_t * coords)
|
||||
{
|
||||
if(dsc->opa <= LV_OPA_MIN) return;
|
||||
if(dsc->text == NULL || dsc->text[0] == '\0') return;
|
||||
if(dsc->font == NULL) {
|
||||
LV_LOG_WARN("dsc->font == NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
LV_PROFILER_BEGIN;
|
||||
lv_draw_task_t * t = lv_draw_add_task(layer, coords);
|
||||
|
||||
t->draw_dsc = lv_malloc(sizeof(*dsc));
|
||||
lv_memcpy(t->draw_dsc, dsc, sizeof(*dsc));
|
||||
t->type = LV_DRAW_TASK_TYPE_LABEL;
|
||||
|
||||
/*The text is stored in a local variable so malloc memory for it*/
|
||||
if(dsc->text_local) {
|
||||
lv_draw_label_dsc_t * new_dsc = t->draw_dsc;
|
||||
new_dsc->text = lv_strdup(dsc->text);
|
||||
}
|
||||
|
||||
lv_draw_finalize_task_creation(layer, t);
|
||||
LV_PROFILER_END;
|
||||
}
|
||||
|
||||
void LV_ATTRIBUTE_FAST_MEM lv_draw_character(lv_layer_t * layer, lv_draw_label_dsc_t * dsc,
|
||||
const lv_point_t * point, uint32_t unicode_letter)
|
||||
{
|
||||
if(dsc->opa <= LV_OPA_MIN) return;
|
||||
if(dsc->font == NULL) {
|
||||
LV_LOG_WARN("dsc->font == NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
if(lv_text_is_marker(unicode_letter)) return;
|
||||
|
||||
LV_PROFILER_BEGIN;
|
||||
|
||||
lv_font_glyph_dsc_t g;
|
||||
lv_font_get_glyph_dsc(dsc->font, &g, unicode_letter, 0);
|
||||
|
||||
lv_area_t a;
|
||||
a.x1 = point->x;
|
||||
a.y1 = point->y;
|
||||
a.x2 = a.x1 + g.adv_w;
|
||||
a.y2 = a.y1 + lv_font_get_line_height(g.resolved_font ? g.resolved_font : dsc->font);
|
||||
|
||||
/*lv_draw_label needs UTF8 text so convert the Unicode character to an UTF8 string */
|
||||
uint32_t letter_buf[2];
|
||||
letter_buf[0] = lv_text_unicode_to_encoded(unicode_letter);
|
||||
letter_buf[1] = '\0';
|
||||
|
||||
const char * letter_buf_char = (const char *)letter_buf;
|
||||
|
||||
#if LV_BIG_ENDIAN_SYSTEM
|
||||
while(*letter_buf_char == 0) ++letter_buf_char;
|
||||
#endif
|
||||
|
||||
dsc->text = letter_buf_char;
|
||||
dsc->text_local = 1;
|
||||
|
||||
lv_draw_label(layer, dsc, &a);
|
||||
LV_PROFILER_END;
|
||||
}
|
||||
|
||||
void lv_draw_label_iterate_characters(lv_draw_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc,
|
||||
const lv_area_t * coords,
|
||||
lv_draw_glyph_cb_t cb)
|
||||
{
|
||||
const lv_font_t * font = dsc->font;
|
||||
int32_t w;
|
||||
|
||||
lv_area_t clipped_area;
|
||||
bool clip_ok = lv_area_intersect(&clipped_area, coords, draw_unit->clip_area);
|
||||
if(!clip_ok) return;
|
||||
|
||||
lv_text_align_t align = dsc->align;
|
||||
lv_base_dir_t base_dir = dsc->bidi_dir;
|
||||
|
||||
lv_bidi_calculate_align(&align, &base_dir, dsc->text);
|
||||
|
||||
if((dsc->flag & LV_TEXT_FLAG_EXPAND) == 0) {
|
||||
/*Normally use the label's width as width*/
|
||||
w = lv_area_get_width(coords);
|
||||
}
|
||||
else {
|
||||
/*If EXPAND is enabled then not limit the text's width to the object's width*/
|
||||
lv_point_t p;
|
||||
lv_text_get_size(&p, dsc->text, dsc->font, dsc->letter_space, dsc->line_space, LV_COORD_MAX,
|
||||
dsc->flag);
|
||||
w = p.x;
|
||||
}
|
||||
|
||||
int32_t line_height_font = lv_font_get_line_height(font);
|
||||
int32_t line_height = line_height_font + dsc->line_space;
|
||||
|
||||
/*Init variables for the first line*/
|
||||
int32_t line_width = 0;
|
||||
lv_point_t pos;
|
||||
lv_point_set(&pos, coords->x1, coords->y1);
|
||||
|
||||
int32_t x_ofs = 0;
|
||||
int32_t y_ofs = 0;
|
||||
x_ofs = dsc->ofs_x;
|
||||
y_ofs = dsc->ofs_y;
|
||||
pos.y += y_ofs;
|
||||
|
||||
uint32_t line_start = 0;
|
||||
int32_t last_line_start = -1;
|
||||
|
||||
/*Check the hint to use the cached info*/
|
||||
if(dsc->hint && y_ofs == 0 && coords->y1 < 0) {
|
||||
/*If the label changed too much recalculate the hint.*/
|
||||
if(LV_ABS(dsc->hint->coord_y - coords->y1) > LV_LABEL_HINT_UPDATE_TH - 2 * line_height) {
|
||||
dsc->hint->line_start = -1;
|
||||
}
|
||||
last_line_start = dsc->hint->line_start;
|
||||
}
|
||||
|
||||
/*Use the hint if it's valid*/
|
||||
if(dsc->hint && last_line_start >= 0) {
|
||||
line_start = last_line_start;
|
||||
pos.y += dsc->hint->y;
|
||||
}
|
||||
|
||||
uint32_t line_end = line_start + lv_text_get_next_line(&dsc->text[line_start], font, dsc->letter_space, w, NULL,
|
||||
dsc->flag);
|
||||
|
||||
/*Go the first visible line*/
|
||||
while(pos.y + line_height_font < draw_unit->clip_area->y1) {
|
||||
/*Go to next line*/
|
||||
line_start = line_end;
|
||||
line_end += lv_text_get_next_line(&dsc->text[line_start], font, dsc->letter_space, w, NULL, dsc->flag);
|
||||
pos.y += line_height;
|
||||
|
||||
/*Save at the threshold coordinate*/
|
||||
if(dsc->hint && pos.y >= -LV_LABEL_HINT_UPDATE_TH && dsc->hint->line_start < 0) {
|
||||
dsc->hint->line_start = line_start;
|
||||
dsc->hint->y = pos.y - coords->y1;
|
||||
dsc->hint->coord_y = coords->y1;
|
||||
}
|
||||
|
||||
if(dsc->text[line_start] == '\0') return;
|
||||
}
|
||||
|
||||
/*Align to middle*/
|
||||
if(align == LV_TEXT_ALIGN_CENTER) {
|
||||
line_width = lv_text_get_width(&dsc->text[line_start], line_end - line_start, font, dsc->letter_space);
|
||||
|
||||
pos.x += (lv_area_get_width(coords) - line_width) / 2;
|
||||
|
||||
}
|
||||
/*Align to the right*/
|
||||
else if(align == LV_TEXT_ALIGN_RIGHT) {
|
||||
line_width = lv_text_get_width(&dsc->text[line_start], line_end - line_start, font, dsc->letter_space);
|
||||
pos.x += lv_area_get_width(coords) - line_width;
|
||||
}
|
||||
|
||||
uint32_t sel_start = dsc->sel_start;
|
||||
uint32_t sel_end = dsc->sel_end;
|
||||
if(sel_start > sel_end) {
|
||||
uint32_t tmp = sel_start;
|
||||
sel_start = sel_end;
|
||||
sel_end = tmp;
|
||||
}
|
||||
|
||||
lv_area_t bg_coords;
|
||||
lv_draw_glyph_dsc_t draw_letter_dsc;
|
||||
lv_draw_glyph_dsc_init(&draw_letter_dsc);
|
||||
draw_letter_dsc.opa = dsc->opa;
|
||||
draw_letter_dsc.bg_coords = &bg_coords;
|
||||
draw_letter_dsc.color = dsc->color;
|
||||
|
||||
lv_draw_fill_dsc_t fill_dsc;
|
||||
lv_draw_fill_dsc_init(&fill_dsc);
|
||||
fill_dsc.opa = dsc->opa;
|
||||
int32_t underline_width = font->underline_thickness ? font->underline_thickness : 1;
|
||||
int32_t line_start_x;
|
||||
uint32_t i;
|
||||
int32_t letter_w;
|
||||
|
||||
/*Write out all lines*/
|
||||
while(dsc->text[line_start] != '\0') {
|
||||
pos.x += x_ofs;
|
||||
line_start_x = pos.x;
|
||||
|
||||
/*Write all letter of a line*/
|
||||
i = 0;
|
||||
#if LV_USE_BIDI
|
||||
char * bidi_txt = lv_malloc(line_end - line_start + 1);
|
||||
LV_ASSERT_MALLOC(bidi_txt);
|
||||
lv_bidi_process_paragraph(dsc->text + line_start, bidi_txt, line_end - line_start, base_dir, NULL, 0);
|
||||
#else
|
||||
const char * bidi_txt = dsc->text + line_start;
|
||||
#endif
|
||||
|
||||
while(i < line_end - line_start) {
|
||||
uint32_t logical_char_pos = 0;
|
||||
if(sel_start != 0xFFFF && sel_end != 0xFFFF) {
|
||||
#if LV_USE_BIDI
|
||||
logical_char_pos = lv_text_encoded_get_char_id(dsc->text, line_start);
|
||||
uint32_t t = lv_text_encoded_get_char_id(bidi_txt, i);
|
||||
logical_char_pos += lv_bidi_get_logical_pos(bidi_txt, NULL, line_end - line_start, base_dir, t, NULL);
|
||||
#else
|
||||
logical_char_pos = lv_text_encoded_get_char_id(dsc->text, line_start + i);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t letter;
|
||||
uint32_t letter_next;
|
||||
lv_text_encoded_letter_next_2(bidi_txt, &letter, &letter_next, &i);
|
||||
|
||||
letter_w = lv_font_get_glyph_width(font, letter, letter_next);
|
||||
|
||||
/*Always set the bg_coordinates for placeholder drawing*/
|
||||
bg_coords.x1 = pos.x;
|
||||
bg_coords.y1 = pos.y;
|
||||
bg_coords.x2 = pos.x + letter_w - 1;
|
||||
bg_coords.y2 = pos.y + line_height - 1;
|
||||
|
||||
if(i >= line_end - line_start) {
|
||||
if(dsc->decor & LV_TEXT_DECOR_UNDERLINE) {
|
||||
lv_area_t fill_area;
|
||||
fill_area.x1 = line_start_x;
|
||||
fill_area.x2 = pos.x + letter_w - 1;
|
||||
fill_area.y1 = pos.y + font->line_height - font->base_line - font->underline_position;
|
||||
fill_area.y2 = fill_area.y1 + underline_width - 1;
|
||||
|
||||
fill_dsc.color = dsc->color;
|
||||
cb(draw_unit, NULL, &fill_dsc, &fill_area);
|
||||
}
|
||||
if(dsc->decor & LV_TEXT_DECOR_STRIKETHROUGH) {
|
||||
lv_area_t fill_area;
|
||||
fill_area.x1 = line_start_x;
|
||||
fill_area.x2 = pos.x + letter_w - 1;
|
||||
fill_area.y1 = pos.y + (font->line_height - font->base_line) * 2 / 3 + font->underline_thickness / 2;
|
||||
fill_area.y2 = fill_area.y1 + underline_width - 1;
|
||||
|
||||
fill_dsc.color = dsc->color;
|
||||
cb(draw_unit, NULL, &fill_dsc, &fill_area);
|
||||
}
|
||||
}
|
||||
|
||||
if(sel_start != 0xFFFF && sel_end != 0xFFFF && logical_char_pos >= sel_start && logical_char_pos < sel_end) {
|
||||
draw_letter_dsc.color = dsc->sel_color;
|
||||
fill_dsc.color = dsc->sel_bg_color;
|
||||
cb(draw_unit, NULL, &fill_dsc, &bg_coords);
|
||||
}
|
||||
else {
|
||||
draw_letter_dsc.color = dsc->color;
|
||||
}
|
||||
|
||||
draw_letter(draw_unit, &draw_letter_dsc, &pos, font, letter, cb);
|
||||
|
||||
if(letter_w > 0) {
|
||||
pos.x += letter_w + dsc->letter_space;
|
||||
}
|
||||
}
|
||||
|
||||
#if LV_USE_BIDI
|
||||
lv_free(bidi_txt);
|
||||
bidi_txt = NULL;
|
||||
#endif
|
||||
/*Go to next line*/
|
||||
line_start = line_end;
|
||||
line_end += lv_text_get_next_line(&dsc->text[line_start], font, dsc->letter_space, w, NULL, dsc->flag);
|
||||
|
||||
pos.x = coords->x1;
|
||||
/*Align to middle*/
|
||||
if(align == LV_TEXT_ALIGN_CENTER) {
|
||||
line_width =
|
||||
lv_text_get_width(&dsc->text[line_start], line_end - line_start, font, dsc->letter_space);
|
||||
|
||||
pos.x += (lv_area_get_width(coords) - line_width) / 2;
|
||||
}
|
||||
/*Align to the right*/
|
||||
else if(align == LV_TEXT_ALIGN_RIGHT) {
|
||||
line_width =
|
||||
lv_text_get_width(&dsc->text[line_start], line_end - line_start, font, dsc->letter_space);
|
||||
pos.x += lv_area_get_width(coords) - line_width;
|
||||
}
|
||||
|
||||
/*Go the next line position*/
|
||||
pos.y += line_height;
|
||||
|
||||
if(pos.y > draw_unit->clip_area->y2) break;
|
||||
}
|
||||
|
||||
if(draw_letter_dsc._draw_buf) lv_draw_buf_destroy(draw_letter_dsc._draw_buf);
|
||||
|
||||
LV_ASSERT_MEM_INTEGRITY();
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void draw_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * dsc, const lv_point_t * pos,
|
||||
const lv_font_t * font, uint32_t letter, lv_draw_glyph_cb_t cb)
|
||||
{
|
||||
lv_font_glyph_dsc_t g;
|
||||
|
||||
if(lv_text_is_marker(letter)) /*Markers are valid letters but should not be rendered.*/
|
||||
return;
|
||||
|
||||
LV_PROFILER_BEGIN;
|
||||
bool g_ret = lv_font_get_glyph_dsc(font, &g, letter, '\0');
|
||||
if(g_ret == false) {
|
||||
/*Add warning if the dsc is not found*/
|
||||
LV_LOG_WARN("lv_draw_letter: glyph dsc. not found for U+%" LV_PRIX32, letter);
|
||||
}
|
||||
|
||||
/*Don't draw anything if the character is empty. E.g. space*/
|
||||
if((g.box_h == 0) || (g.box_w == 0)) {
|
||||
LV_PROFILER_END;
|
||||
return;
|
||||
}
|
||||
|
||||
lv_area_t letter_coords;
|
||||
letter_coords.x1 = pos->x + g.ofs_x;
|
||||
letter_coords.x2 = letter_coords.x1 + g.box_w - 1;
|
||||
letter_coords.y1 = pos->y + (font->line_height - font->base_line) - g.box_h - g.ofs_y;
|
||||
letter_coords.y2 = letter_coords.y1 + g.box_h - 1;
|
||||
|
||||
/*If the letter is completely out of mask don't draw it*/
|
||||
if(lv_area_is_out(&letter_coords, draw_unit->clip_area, 0) &&
|
||||
lv_area_is_out(dsc->bg_coords, draw_unit->clip_area, 0)) {
|
||||
LV_PROFILER_END;
|
||||
return;
|
||||
}
|
||||
|
||||
if(g.resolved_font) {
|
||||
lv_draw_buf_t * draw_buf = NULL;
|
||||
if(LV_FONT_GLYPH_FORMAT_NONE < g.format && g.format < LV_FONT_GLYPH_FORMAT_IMAGE) {
|
||||
/*Only check draw buf for bitmap glyph*/
|
||||
draw_buf = lv_draw_buf_reshape(dsc->_draw_buf, 0, g.box_w, g.box_h, LV_STRIDE_AUTO);
|
||||
if(draw_buf == NULL) {
|
||||
if(dsc->_draw_buf) lv_draw_buf_destroy(dsc->_draw_buf);
|
||||
|
||||
uint32_t h = g.box_h;
|
||||
if(h * g.box_w < 64) h *= 2; /*Alloc a slightly larger buffer*/
|
||||
draw_buf = lv_draw_buf_create_ex(font_draw_buf_handlers, g.box_w, h, LV_COLOR_FORMAT_A8, LV_STRIDE_AUTO);
|
||||
LV_ASSERT_MALLOC(draw_buf);
|
||||
draw_buf->header.h = g.box_h;
|
||||
dsc->_draw_buf = draw_buf;
|
||||
}
|
||||
}
|
||||
|
||||
dsc->glyph_data = (void *) lv_font_get_glyph_bitmap(&g, draw_buf);
|
||||
dsc->format = dsc->glyph_data ? g.format : LV_FONT_GLYPH_FORMAT_NONE;
|
||||
}
|
||||
else {
|
||||
dsc->format = LV_FONT_GLYPH_FORMAT_NONE;
|
||||
}
|
||||
|
||||
dsc->letter_coords = &letter_coords;
|
||||
dsc->g = &g;
|
||||
cb(draw_unit, dsc, NULL, NULL);
|
||||
|
||||
lv_font_glyph_release_draw_data(&g);
|
||||
|
||||
LV_PROFILER_END;
|
||||
}
|
||||
140
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_label.h
Normal file
140
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_label.h
Normal file
@@ -0,0 +1,140 @@
|
||||
/**
|
||||
* @file lv_draw_label.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_LABEL_H
|
||||
#define LV_DRAW_LABEL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw.h"
|
||||
#include "lv_draw_rect.h"
|
||||
#include "../misc/lv_bidi.h"
|
||||
#include "../misc/lv_text.h"
|
||||
#include "../misc/lv_color.h"
|
||||
#include "../misc/lv_style.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_DRAW_LABEL_NO_TXT_SEL (0xFFFF)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct {
|
||||
lv_draw_dsc_base_t base;
|
||||
|
||||
const char * text;
|
||||
const lv_font_t * font;
|
||||
uint32_t sel_start;
|
||||
uint32_t sel_end;
|
||||
lv_color_t color;
|
||||
lv_color_t sel_color;
|
||||
lv_color_t sel_bg_color;
|
||||
int32_t line_space;
|
||||
int32_t letter_space;
|
||||
int32_t ofs_x;
|
||||
int32_t ofs_y;
|
||||
lv_opa_t opa;
|
||||
lv_base_dir_t bidi_dir;
|
||||
lv_text_align_t align;
|
||||
lv_text_flag_t flag;
|
||||
lv_text_decor_t decor : 3;
|
||||
lv_blend_mode_t blend_mode : 3;
|
||||
/**
|
||||
* < 1: malloc buffer and copy `text` there.
|
||||
* 0: `text` is const and it's pointer will be valid during rendering.*/
|
||||
uint8_t text_local : 1;
|
||||
lv_draw_label_hint_t * hint;
|
||||
} lv_draw_label_dsc_t;
|
||||
|
||||
/**
|
||||
* Passed as a parameter to `lv_draw_label_iterate_characters` to
|
||||
* draw the characters one by one
|
||||
* @param draw_unit pointer to a draw unit
|
||||
* @param dsc pointer to `lv_draw_glyph_dsc_t` to describe the character to draw
|
||||
* if NULL don't draw character
|
||||
* @param fill_dsc pointer to a fill descriptor to draw a background for the character or
|
||||
* underline or strike through
|
||||
* if NULL do not fill anything
|
||||
* @param fill_area the area to fill
|
||||
* if NULL do not fill anything
|
||||
*/
|
||||
typedef void(*lv_draw_glyph_cb_t)(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * dsc, lv_draw_fill_dsc_t * fill_dsc,
|
||||
const lv_area_t * fill_area);
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize a label draw descriptor
|
||||
* @param dsc pointer to a draw descriptor
|
||||
*/
|
||||
void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_label_dsc_init(lv_draw_label_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Try to get a label draw descriptor from a draw task.
|
||||
* @param task draw task
|
||||
* @return the task's draw descriptor or NULL if the task is not of type LV_DRAW_TASK_TYPE_LABEL
|
||||
*/
|
||||
lv_draw_label_dsc_t * lv_draw_task_get_label_dsc(lv_draw_task_t * task);
|
||||
|
||||
/**
|
||||
* Initialize a glyph draw descriptor.
|
||||
* Used internally.
|
||||
* @param dsc pointer to a draw descriptor
|
||||
*/
|
||||
void lv_draw_glyph_dsc_init(lv_draw_glyph_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Crate a draw task to render a text
|
||||
* @param layer pointer to a layer
|
||||
* @param dsc pointer to draw descriptor
|
||||
* @param coords coordinates of the character
|
||||
*/
|
||||
void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_label(lv_layer_t * layer, const lv_draw_label_dsc_t * dsc,
|
||||
const lv_area_t * coords);
|
||||
|
||||
/**
|
||||
* Crate a draw task to render a single character
|
||||
* @param layer pointer to a layer
|
||||
* @param dsc pointer to draw descriptor
|
||||
* @param point position of the label
|
||||
* @param unicode_letter the letter to draw
|
||||
*/
|
||||
void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_character(lv_layer_t * layer, lv_draw_label_dsc_t * dsc,
|
||||
const lv_point_t * point, uint32_t unicode_letter);
|
||||
|
||||
/**
|
||||
* Should be used during rendering the characters to get the position and other
|
||||
* parameters of the characters
|
||||
* @param draw_unit pointer to a draw unit
|
||||
* @param dsc pointer to draw descriptor
|
||||
* @param coords coordinates of the label
|
||||
* @param cb a callback to call to draw each glyphs one by one
|
||||
*/
|
||||
void lv_draw_label_iterate_characters(lv_draw_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc,
|
||||
const lv_area_t * coords, lv_draw_glyph_cb_t cb);
|
||||
|
||||
/***********************
|
||||
* GLOBAL VARIABLES
|
||||
***********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_LABEL_H*/
|
||||
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* @file lv_draw_label_private.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_LABEL_PRIVATE_H
|
||||
#define LV_DRAW_LABEL_PRIVATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_label.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/** Store some info to speed up drawing of very large texts
|
||||
* It takes a lot of time to get the first visible character because
|
||||
* all the previous characters needs to be checked to calculate the positions.
|
||||
* This structure stores an earlier (e.g. at -1000 px) coordinate and the index of that line.
|
||||
* Therefore the calculations can start from here.*/
|
||||
struct lv_draw_label_hint_t {
|
||||
/** Index of the line at `y` coordinate*/
|
||||
int32_t line_start;
|
||||
|
||||
/** Give the `y` coordinate of the first letter at `line start` index. Relative to the label's coordinates*/
|
||||
int32_t y;
|
||||
|
||||
/** The 'y1' coordinate of the label when the hint was saved.
|
||||
* Used to invalidate the hint if the label has moved too much.*/
|
||||
int32_t coord_y;
|
||||
};
|
||||
|
||||
struct lv_draw_glyph_dsc_t {
|
||||
void * glyph_data; /**< Depends on `format` field, it could be image source or draw buf of bitmap or vector data. */
|
||||
lv_font_glyph_format_t format;
|
||||
const lv_area_t * letter_coords;
|
||||
const lv_area_t * bg_coords;
|
||||
const lv_font_glyph_dsc_t * g;
|
||||
lv_color_t color;
|
||||
lv_opa_t opa;
|
||||
lv_draw_buf_t * _draw_buf; /**< a shared draw buf for get_bitmap, do not use it directly, use glyph_data instead */
|
||||
};
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_LABEL_PRIVATE_H*/
|
||||
77
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_line.c
Normal file
77
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_line.c
Normal file
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* @file lv_draw_line.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_private.h"
|
||||
#include "../core/lv_refr.h"
|
||||
#include "../misc/lv_math.h"
|
||||
#include "../misc/lv_types.h"
|
||||
#include "../stdlib/lv_string.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void LV_ATTRIBUTE_FAST_MEM lv_draw_line_dsc_init(lv_draw_line_dsc_t * dsc)
|
||||
{
|
||||
lv_memzero(dsc, sizeof(lv_draw_line_dsc_t));
|
||||
dsc->width = 1;
|
||||
dsc->opa = LV_OPA_COVER;
|
||||
dsc->color = lv_color_black();
|
||||
dsc->base.dsc_size = sizeof(lv_draw_line_dsc_t);
|
||||
}
|
||||
|
||||
lv_draw_line_dsc_t * lv_draw_task_get_line_dsc(lv_draw_task_t * task)
|
||||
{
|
||||
return task->type == LV_DRAW_TASK_TYPE_LINE ? (lv_draw_line_dsc_t *)task->draw_dsc : NULL;
|
||||
}
|
||||
|
||||
void LV_ATTRIBUTE_FAST_MEM lv_draw_line(lv_layer_t * layer, const lv_draw_line_dsc_t * dsc)
|
||||
{
|
||||
if(dsc->width == 0) return;
|
||||
if(dsc->opa <= LV_OPA_MIN) return;
|
||||
|
||||
LV_PROFILER_BEGIN;
|
||||
lv_area_t a;
|
||||
a.x1 = (int32_t)LV_MIN(dsc->p1.x, dsc->p2.x) - dsc->width;
|
||||
a.x2 = (int32_t)LV_MAX(dsc->p1.x, dsc->p2.x) + dsc->width;
|
||||
a.y1 = (int32_t)LV_MIN(dsc->p1.y, dsc->p2.y) - dsc->width;
|
||||
a.y2 = (int32_t)LV_MAX(dsc->p1.y, dsc->p2.y) + dsc->width;
|
||||
|
||||
lv_draw_task_t * t = lv_draw_add_task(layer, &a);
|
||||
|
||||
t->draw_dsc = lv_malloc(sizeof(*dsc));
|
||||
lv_memcpy(t->draw_dsc, dsc, sizeof(*dsc));
|
||||
t->type = LV_DRAW_TASK_TYPE_LINE;
|
||||
|
||||
lv_draw_finalize_task_creation(layer, t);
|
||||
LV_PROFILER_END;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
76
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_line.h
Normal file
76
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_line.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* @file lv_draw_line.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_LINE_H
|
||||
#define LV_DRAW_LINE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_conf_internal.h"
|
||||
#include "../misc/lv_color.h"
|
||||
#include "../misc/lv_area.h"
|
||||
#include "../misc/lv_style.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef struct {
|
||||
lv_draw_dsc_base_t base;
|
||||
|
||||
lv_point_precise_t p1;
|
||||
lv_point_precise_t p2;
|
||||
lv_color_t color;
|
||||
int32_t width;
|
||||
int32_t dash_width;
|
||||
int32_t dash_gap;
|
||||
lv_opa_t opa;
|
||||
lv_blend_mode_t blend_mode : 2;
|
||||
uint8_t round_start : 1;
|
||||
uint8_t round_end : 1;
|
||||
uint8_t raw_end : 1; /**< Do not bother with perpendicular line ending if it's not visible for any reason */
|
||||
} lv_draw_line_dsc_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize a line draw descriptor
|
||||
* @param dsc pointer to a draw descriptor
|
||||
*/
|
||||
void lv_draw_line_dsc_init(lv_draw_line_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Try to get a line draw descriptor from a draw task.
|
||||
* @param task draw task
|
||||
* @return the task's draw descriptor or NULL if the task is not of type LV_DRAW_TASK_TYPE_LINE
|
||||
*/
|
||||
lv_draw_line_dsc_t * lv_draw_task_get_line_dsc(lv_draw_task_t * task);
|
||||
|
||||
/**
|
||||
* Create a line draw task
|
||||
* @param layer pointer to a layer
|
||||
* @param dsc pointer to an initialized `lv_draw_line_dsc_t` variable
|
||||
*/
|
||||
void lv_draw_line(lv_layer_t * layer, const lv_draw_line_dsc_t * dsc);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_LINE_H*/
|
||||
81
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_mask.c
Normal file
81
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_mask.c
Normal file
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* @file lv_draw_mask.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_mask_private.h"
|
||||
#include "lv_draw_private.h"
|
||||
#include "../core/lv_refr.h"
|
||||
#include "../misc/lv_math.h"
|
||||
#include "../misc/lv_types.h"
|
||||
#include "../stdlib/lv_string.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void LV_ATTRIBUTE_FAST_MEM lv_draw_mask_rect_dsc_init(lv_draw_mask_rect_dsc_t * dsc)
|
||||
{
|
||||
lv_memzero(dsc, sizeof(lv_draw_mask_rect_dsc_t));
|
||||
}
|
||||
|
||||
lv_draw_mask_rect_dsc_t * lv_draw_task_get_mask_rect_dsc(lv_draw_task_t * task)
|
||||
{
|
||||
return task->type == LV_DRAW_TASK_TYPE_MASK_RECTANGLE ? (lv_draw_mask_rect_dsc_t *)task->draw_dsc : NULL;
|
||||
}
|
||||
|
||||
void LV_ATTRIBUTE_FAST_MEM lv_draw_mask_rect(lv_layer_t * layer, const lv_draw_mask_rect_dsc_t * dsc)
|
||||
{
|
||||
if(!lv_color_format_has_alpha(layer->color_format)) {
|
||||
LV_LOG_WARN("Only layers with alpha channel can be masked");
|
||||
return;
|
||||
}
|
||||
LV_PROFILER_BEGIN;
|
||||
|
||||
lv_draw_task_t * t = lv_draw_add_task(layer, &layer->buf_area);
|
||||
|
||||
t->draw_dsc = lv_malloc(sizeof(*dsc));
|
||||
lv_memcpy(t->draw_dsc, dsc, sizeof(*dsc));
|
||||
t->type = LV_DRAW_TASK_TYPE_MASK_RECTANGLE;
|
||||
|
||||
lv_draw_dsc_base_t * base_dsc = t->draw_dsc;
|
||||
base_dsc->layer = layer;
|
||||
|
||||
if(base_dsc->obj && lv_obj_has_flag(base_dsc->obj, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS)) {
|
||||
/*Disable sending LV_EVENT_DRAW_TASK_ADDED first to avoid triggering recursive
|
||||
*event calls due draw task adds in the event*/
|
||||
lv_obj_remove_flag(base_dsc->obj, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS);
|
||||
lv_obj_send_event(dsc->base.obj, LV_EVENT_DRAW_TASK_ADDED, t);
|
||||
lv_obj_add_flag(base_dsc->obj, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS);
|
||||
}
|
||||
|
||||
lv_draw_finalize_task_creation(layer, t);
|
||||
LV_PROFILER_END;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
56
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_mask.h
Normal file
56
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_mask.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* @file lv_draw_mask.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_MASK_H
|
||||
#define LV_DRAW_MASK_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../misc/lv_color.h"
|
||||
#include "../misc/lv_area.h"
|
||||
#include "../misc/lv_style.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize a rectangle mask draw descriptor.
|
||||
* @param dsc pointer to a draw descriptor
|
||||
*/
|
||||
void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_mask_rect_dsc_init(lv_draw_mask_rect_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Try to get a rectangle mask draw descriptor from a draw task.
|
||||
* @param task draw task
|
||||
* @return the task's draw descriptor or NULL if the task is not of type LV_DRAW_TASK_TYPE_MASK_RECTANGLE
|
||||
*/
|
||||
lv_draw_mask_rect_dsc_t * lv_draw_task_get_mask_rect_dsc(lv_draw_task_t * task);
|
||||
|
||||
/**
|
||||
* Create a draw task to mask a rectangle from the buffer
|
||||
* @param layer pointer to a layer
|
||||
* @param dsc pointer to a draw descriptor
|
||||
*/
|
||||
void lv_draw_mask_rect(lv_layer_t * layer, const lv_draw_mask_rect_dsc_t * dsc);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_MASK_H*/
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* @file lv_draw_mask_private.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_MASK_PRIVATE_H
|
||||
#define LV_DRAW_MASK_PRIVATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_mask.h"
|
||||
#include "lv_draw.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
struct lv_draw_mask_rect_dsc_t {
|
||||
lv_draw_dsc_base_t base;
|
||||
|
||||
lv_area_t area;
|
||||
int32_t radius;
|
||||
};
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_MASK_PRIVATE_H*/
|
||||
196
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_private.h
Normal file
196
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_private.h
Normal file
@@ -0,0 +1,196 @@
|
||||
/**
|
||||
* @file lv_draw_private.h
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Modified by NXP in 2024
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_PRIVATE_H
|
||||
#define LV_DRAW_PRIVATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
struct lv_draw_task_t {
|
||||
lv_draw_task_t * next;
|
||||
|
||||
lv_draw_task_type_t type;
|
||||
|
||||
/**
|
||||
* The area where to draw
|
||||
*/
|
||||
lv_area_t area;
|
||||
|
||||
/**
|
||||
* The real draw area. E.g. for shadow, outline, or transformed images it's different from `area`
|
||||
*/
|
||||
lv_area_t _real_area;
|
||||
|
||||
/** The original area which is updated*/
|
||||
lv_area_t clip_area_original;
|
||||
|
||||
/**
|
||||
* The clip area of the layer is saved here when the draw task is created.
|
||||
* As the clip area of the layer can be changed as new draw tasks are added its current value needs to be saved.
|
||||
* Therefore during drawing the layer's clip area shouldn't be used as it might be already changed for other draw tasks.
|
||||
*/
|
||||
lv_area_t clip_area;
|
||||
|
||||
#if LV_DRAW_TRANSFORM_USE_MATRIX
|
||||
/** Transform matrix to be applied when rendering the layer */
|
||||
lv_matrix_t matrix;
|
||||
#endif
|
||||
|
||||
volatile int state; /** int instead of lv_draw_task_state_t to be sure its atomic */
|
||||
|
||||
void * draw_dsc;
|
||||
|
||||
/**
|
||||
* The ID of the draw_unit which should take this task
|
||||
*/
|
||||
uint8_t preferred_draw_unit_id;
|
||||
|
||||
/**
|
||||
* Set to which extent `preferred_draw_unit_id` is good at this task.
|
||||
* 80: means 20% better (faster) than software rendering
|
||||
* 100: the default value
|
||||
* 110: means 10% worse (slower) than software rendering
|
||||
*/
|
||||
uint8_t preference_score;
|
||||
|
||||
};
|
||||
|
||||
struct lv_draw_mask_t {
|
||||
void * user_data;
|
||||
};
|
||||
|
||||
struct lv_draw_unit_t {
|
||||
lv_draw_unit_t * next;
|
||||
|
||||
/**
|
||||
* The target_layer on which drawing should happen
|
||||
*/
|
||||
lv_layer_t * target_layer;
|
||||
|
||||
const lv_area_t * clip_area;
|
||||
|
||||
/**
|
||||
* Called to try to assign a draw task to itself.
|
||||
* `lv_draw_get_next_available_task` can be used to get an independent draw task.
|
||||
* A draw task should be assign only if the draw unit can draw it too
|
||||
* @param draw_unit pointer to the draw unit
|
||||
* @param layer pointer to a layer on which the draw task should be drawn
|
||||
* @return >=0: The number of taken draw task:
|
||||
* 0 means the task has not yet been completed.
|
||||
* 1 means a new task has been accepted.
|
||||
* -1: The draw unit wanted to work on a task but couldn't do that
|
||||
* due to some errors (e.g. out of memory).
|
||||
* It signals that LVGL should call the dispatcher later again
|
||||
* to let draw unit try to start the rendering again.
|
||||
*/
|
||||
int32_t (*dispatch_cb)(lv_draw_unit_t * draw_unit, lv_layer_t * layer);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param draw_unit
|
||||
* @param task
|
||||
* @return
|
||||
*/
|
||||
int32_t (*evaluate_cb)(lv_draw_unit_t * draw_unit, lv_draw_task_t * task);
|
||||
|
||||
/**
|
||||
* Called to signal the unit to complete all tasks in order to return their ready status.
|
||||
* This callback can be implemented in case of asynchronous task processing.
|
||||
* Below is an example to show the difference between synchronous and asynchronous:
|
||||
*
|
||||
* Synchronous:
|
||||
* LVGL thread DRAW thread HW
|
||||
*
|
||||
* task1 --> submit --> Receive task1
|
||||
* wait_for_finish()
|
||||
* <-- task1->state = READY <-- Complete task1
|
||||
* task2 --> submit --> Receive task2
|
||||
* wait_for_finish()
|
||||
* task2->state = READY <-- Complete task2
|
||||
* task3 --> submit --> Receive task3
|
||||
* wait_for_finish()
|
||||
* <-- task3->state = READY <-- Complete task3
|
||||
* task4 --> submit --> Receive task4
|
||||
* wait_for_finish()
|
||||
* <-- task4->state = READY <-- Complete task4
|
||||
* NO MORE TASKS
|
||||
*
|
||||
*
|
||||
* Asynchronous:
|
||||
* LVGL thread DRAW thread HW
|
||||
* is IDLE
|
||||
* task1 --> queue task1
|
||||
* submit --> Receive task1
|
||||
* task2 --> queue task2 is BUSY (with task1)
|
||||
* task3 --> queue task3 still BUSY (with task1)
|
||||
* task4 --> queue task4 becomes IDLE
|
||||
* <-- task1->state = READY <-- Complete task1
|
||||
* submit --> Receive task2, task3, task4
|
||||
* NO MORE TASKS
|
||||
* wait_for_finish_cb() wait_for_finish()
|
||||
* <-- Complete task2, task3, task4
|
||||
* <-- task2->state = READY <--
|
||||
* <-- task3->state = READY <--
|
||||
* <-- task4->state = READY <--
|
||||
*
|
||||
* @param draw_unit
|
||||
* @return
|
||||
*/
|
||||
int32_t (*wait_for_finish_cb)(lv_draw_unit_t * draw_unit);
|
||||
|
||||
/**
|
||||
* Called to delete draw unit.
|
||||
* @param draw_unit
|
||||
* @return
|
||||
*/
|
||||
int32_t (*delete_cb)(lv_draw_unit_t * draw_unit);
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
lv_draw_unit_t * unit_head;
|
||||
uint32_t unit_cnt;
|
||||
uint32_t used_memory_for_layers_kb;
|
||||
#if LV_USE_OS
|
||||
lv_thread_sync_t sync;
|
||||
#else
|
||||
int dispatch_req;
|
||||
#endif
|
||||
lv_mutex_t circle_cache_mutex;
|
||||
bool task_running;
|
||||
} lv_draw_global_info_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_PRIVATE_H*/
|
||||
302
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_rect.c
Normal file
302
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_rect.c
Normal file
@@ -0,0 +1,302 @@
|
||||
/**
|
||||
* @file lv_draw_rect.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_rect_private.h"
|
||||
#include "lv_draw_private.h"
|
||||
#include "../core/lv_obj.h"
|
||||
#include "../misc/lv_assert.h"
|
||||
#include "../core/lv_obj_event.h"
|
||||
#include "../stdlib/lv_string.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void LV_ATTRIBUTE_FAST_MEM lv_draw_rect_dsc_init(lv_draw_rect_dsc_t * dsc)
|
||||
{
|
||||
lv_memzero(dsc, sizeof(lv_draw_rect_dsc_t));
|
||||
dsc->bg_color = lv_color_white();
|
||||
dsc->bg_grad.stops[0].color = lv_color_white();
|
||||
dsc->bg_grad.stops[1].color = lv_color_black();
|
||||
dsc->bg_grad.stops[1].frac = 0xFF;
|
||||
dsc->bg_grad.stops_count = 2;
|
||||
dsc->border_color = lv_color_black();
|
||||
dsc->shadow_color = lv_color_black();
|
||||
dsc->bg_image_symbol_font = LV_FONT_DEFAULT;
|
||||
dsc->bg_opa = LV_OPA_COVER;
|
||||
dsc->bg_image_opa = LV_OPA_COVER;
|
||||
dsc->outline_opa = LV_OPA_COVER;
|
||||
dsc->border_opa = LV_OPA_COVER;
|
||||
dsc->shadow_opa = LV_OPA_COVER;
|
||||
dsc->border_side = LV_BORDER_SIDE_FULL;
|
||||
}
|
||||
|
||||
void lv_draw_fill_dsc_init(lv_draw_fill_dsc_t * dsc)
|
||||
{
|
||||
lv_memzero(dsc, sizeof(*dsc));
|
||||
dsc->opa = LV_OPA_COVER;
|
||||
dsc->base.dsc_size = sizeof(lv_draw_fill_dsc_t);
|
||||
}
|
||||
|
||||
lv_draw_fill_dsc_t * lv_draw_task_get_fill_dsc(lv_draw_task_t * task)
|
||||
{
|
||||
return task->type == LV_DRAW_TASK_TYPE_FILL ? (lv_draw_fill_dsc_t *)task->draw_dsc : NULL;
|
||||
}
|
||||
|
||||
void lv_draw_border_dsc_init(lv_draw_border_dsc_t * dsc)
|
||||
{
|
||||
lv_memzero(dsc, sizeof(*dsc));
|
||||
dsc->opa = LV_OPA_COVER;
|
||||
dsc->side = LV_BORDER_SIDE_FULL;
|
||||
dsc->base.dsc_size = sizeof(lv_draw_border_dsc_t);
|
||||
}
|
||||
|
||||
lv_draw_border_dsc_t * lv_draw_task_get_border_dsc(lv_draw_task_t * task)
|
||||
{
|
||||
return task->type == LV_DRAW_TASK_TYPE_BORDER ? (lv_draw_border_dsc_t *)task->draw_dsc : NULL;
|
||||
}
|
||||
|
||||
void lv_draw_box_shadow_dsc_init(lv_draw_box_shadow_dsc_t * dsc)
|
||||
{
|
||||
lv_memzero(dsc, sizeof(*dsc));
|
||||
dsc->opa = LV_OPA_COVER;
|
||||
dsc->base.dsc_size = sizeof(lv_draw_box_shadow_dsc_t);
|
||||
}
|
||||
|
||||
lv_draw_box_shadow_dsc_t * lv_draw_task_get_box_shadow_dsc(lv_draw_task_t * task)
|
||||
{
|
||||
return task->type == LV_DRAW_TASK_TYPE_BOX_SHADOW ? (lv_draw_box_shadow_dsc_t *)task->draw_dsc : NULL;
|
||||
}
|
||||
|
||||
void lv_draw_rect(lv_layer_t * layer, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords)
|
||||
{
|
||||
|
||||
LV_PROFILER_BEGIN;
|
||||
bool has_shadow;
|
||||
bool has_fill;
|
||||
bool has_border;
|
||||
bool has_outline;
|
||||
bool has_bg_img;
|
||||
|
||||
if(dsc->shadow_width == 0 ||
|
||||
dsc->shadow_opa <= LV_OPA_MIN ||
|
||||
(dsc->shadow_width == 1 && dsc->shadow_spread <= 0 &&
|
||||
dsc->shadow_offset_x == 0 && dsc->shadow_offset_y == 0)) {
|
||||
has_shadow = false;
|
||||
}
|
||||
else {
|
||||
has_shadow = true;
|
||||
}
|
||||
|
||||
if(dsc->bg_opa <= LV_OPA_MIN) has_fill = false;
|
||||
else has_fill = true;
|
||||
|
||||
if(dsc->bg_image_opa <= LV_OPA_MIN || dsc->bg_image_src == NULL) has_bg_img = false;
|
||||
else has_bg_img = true;
|
||||
|
||||
if(dsc->border_opa <= LV_OPA_MIN
|
||||
|| dsc->border_width == 0
|
||||
|| dsc->border_post == true
|
||||
|| dsc->border_side == LV_BORDER_SIDE_NONE) has_border = false;
|
||||
else has_border = true;
|
||||
|
||||
if(dsc->outline_opa <= LV_OPA_MIN || dsc->outline_width == 0) has_outline = false;
|
||||
else has_outline = true;
|
||||
|
||||
bool bg_cover = true;
|
||||
if(dsc->bg_opa < LV_OPA_COVER) bg_cover = false;
|
||||
else if(dsc->bg_grad.dir != LV_GRAD_DIR_NONE) {
|
||||
uint32_t s;
|
||||
for(s = 0; s < dsc->bg_grad.stops_count; s++) {
|
||||
if(dsc->bg_grad.stops[s].opa != LV_OPA_COVER) {
|
||||
bg_cover = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lv_draw_task_t * t;
|
||||
|
||||
/*Shadow*/
|
||||
if(has_shadow) {
|
||||
/*Check whether the shadow is visible*/
|
||||
t = lv_draw_add_task(layer, coords);
|
||||
lv_draw_box_shadow_dsc_t * shadow_dsc = lv_malloc(sizeof(lv_draw_box_shadow_dsc_t));
|
||||
t->draw_dsc = shadow_dsc;
|
||||
lv_area_increase(&t->_real_area, dsc->shadow_spread, dsc->shadow_spread);
|
||||
lv_area_increase(&t->_real_area, dsc->shadow_width, dsc->shadow_width);
|
||||
lv_area_move(&t->_real_area, dsc->shadow_offset_x, dsc->shadow_offset_y);
|
||||
shadow_dsc->base = dsc->base;
|
||||
shadow_dsc->base.dsc_size = sizeof(lv_draw_box_shadow_dsc_t);
|
||||
shadow_dsc->radius = dsc->radius;
|
||||
shadow_dsc->color = dsc->shadow_color;
|
||||
shadow_dsc->width = dsc->shadow_width;
|
||||
shadow_dsc->spread = dsc->shadow_spread;
|
||||
shadow_dsc->opa = dsc->shadow_opa;
|
||||
shadow_dsc->ofs_x = dsc->shadow_offset_x;
|
||||
shadow_dsc->ofs_y = dsc->shadow_offset_y;
|
||||
shadow_dsc->bg_cover = bg_cover;
|
||||
t->type = LV_DRAW_TASK_TYPE_BOX_SHADOW;
|
||||
lv_draw_finalize_task_creation(layer, t);
|
||||
}
|
||||
|
||||
/*Background*/
|
||||
if(has_fill) {
|
||||
lv_area_t bg_coords = *coords;
|
||||
/*If the border fully covers make the bg area 1px smaller to avoid artifacts on the corners*/
|
||||
if(dsc->border_width > 1 && dsc->border_opa >= LV_OPA_MAX && dsc->radius != 0) {
|
||||
bg_coords.x1 += (dsc->border_side & LV_BORDER_SIDE_LEFT) ? 1 : 0;
|
||||
bg_coords.y1 += (dsc->border_side & LV_BORDER_SIDE_TOP) ? 1 : 0;
|
||||
bg_coords.x2 -= (dsc->border_side & LV_BORDER_SIDE_RIGHT) ? 1 : 0;
|
||||
bg_coords.y2 -= (dsc->border_side & LV_BORDER_SIDE_BOTTOM) ? 1 : 0;
|
||||
}
|
||||
|
||||
t = lv_draw_add_task(layer, &bg_coords);
|
||||
lv_draw_fill_dsc_t * bg_dsc = lv_malloc(sizeof(lv_draw_fill_dsc_t));
|
||||
lv_draw_fill_dsc_init(bg_dsc);
|
||||
t->draw_dsc = bg_dsc;
|
||||
bg_dsc->base = dsc->base;
|
||||
bg_dsc->base.dsc_size = sizeof(lv_draw_fill_dsc_t);
|
||||
bg_dsc->radius = dsc->radius;
|
||||
bg_dsc->color = dsc->bg_color;
|
||||
bg_dsc->grad = dsc->bg_grad;
|
||||
bg_dsc->opa = dsc->bg_opa;
|
||||
t->type = LV_DRAW_TASK_TYPE_FILL;
|
||||
|
||||
lv_draw_finalize_task_creation(layer, t);
|
||||
}
|
||||
|
||||
/*Background image*/
|
||||
if(has_bg_img) {
|
||||
lv_image_src_t src_type = lv_image_src_get_type(dsc->bg_image_src);
|
||||
lv_result_t res = LV_RESULT_OK;
|
||||
lv_image_header_t header;
|
||||
if(src_type == LV_IMAGE_SRC_VARIABLE || src_type == LV_IMAGE_SRC_FILE) {
|
||||
res = lv_image_decoder_get_info(dsc->bg_image_src, &header);
|
||||
}
|
||||
else if(src_type == LV_IMAGE_SRC_UNKNOWN) {
|
||||
res = LV_RESULT_INVALID;
|
||||
}
|
||||
else {
|
||||
lv_memzero(&header, sizeof(header));
|
||||
}
|
||||
|
||||
if(res == LV_RESULT_OK) {
|
||||
if(src_type == LV_IMAGE_SRC_VARIABLE || src_type == LV_IMAGE_SRC_FILE) {
|
||||
|
||||
if(dsc->bg_image_tiled) {
|
||||
t = lv_draw_add_task(layer, coords);
|
||||
}
|
||||
else {
|
||||
lv_area_t a = {0, 0, header.w - 1, header.h - 1};
|
||||
lv_area_align(coords, &a, LV_ALIGN_CENTER, 0, 0);
|
||||
t = lv_draw_add_task(layer, &a);
|
||||
}
|
||||
|
||||
lv_draw_image_dsc_t * bg_image_dsc = lv_malloc(sizeof(lv_draw_image_dsc_t));
|
||||
lv_draw_image_dsc_init(bg_image_dsc);
|
||||
t->draw_dsc = bg_image_dsc;
|
||||
bg_image_dsc->base = dsc->base;
|
||||
bg_image_dsc->base.dsc_size = sizeof(lv_draw_image_dsc_t);
|
||||
bg_image_dsc->src = dsc->bg_image_src;
|
||||
bg_image_dsc->opa = dsc->bg_image_opa;
|
||||
bg_image_dsc->recolor = dsc->bg_image_recolor;
|
||||
bg_image_dsc->recolor_opa = dsc->bg_image_recolor_opa;
|
||||
bg_image_dsc->tile = dsc->bg_image_tiled;
|
||||
bg_image_dsc->header = header;
|
||||
bg_image_dsc->clip_radius = dsc->radius;
|
||||
t->type = LV_DRAW_TASK_TYPE_IMAGE;
|
||||
lv_draw_finalize_task_creation(layer, t);
|
||||
}
|
||||
else {
|
||||
lv_point_t s;
|
||||
lv_text_get_size(&s, dsc->bg_image_src, dsc->bg_image_symbol_font, 0, 0, LV_COORD_MAX, LV_TEXT_FLAG_NONE);
|
||||
|
||||
lv_area_t a = {0, 0, s.x - 1, s.y - 1};
|
||||
lv_area_align(coords, &a, LV_ALIGN_CENTER, 0, 0);
|
||||
t = lv_draw_add_task(layer, &a);
|
||||
|
||||
lv_draw_label_dsc_t * bg_label_dsc = lv_malloc(sizeof(lv_draw_label_dsc_t));
|
||||
lv_draw_label_dsc_init(bg_label_dsc);
|
||||
t->draw_dsc = bg_label_dsc;
|
||||
bg_label_dsc->base = dsc->base;
|
||||
bg_label_dsc->base.dsc_size = sizeof(lv_draw_label_dsc_t);
|
||||
bg_label_dsc->color = dsc->bg_image_recolor;
|
||||
bg_label_dsc->font = dsc->bg_image_symbol_font;
|
||||
bg_label_dsc->text = dsc->bg_image_src;
|
||||
t->type = LV_DRAW_TASK_TYPE_LABEL;
|
||||
lv_draw_finalize_task_creation(layer, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*Border*/
|
||||
if(has_border) {
|
||||
t = lv_draw_add_task(layer, coords);
|
||||
lv_draw_border_dsc_t * border_dsc = lv_malloc(sizeof(lv_draw_border_dsc_t));
|
||||
t->draw_dsc = border_dsc;
|
||||
border_dsc->base = dsc->base;
|
||||
border_dsc->base.dsc_size = sizeof(lv_draw_border_dsc_t);
|
||||
border_dsc->radius = dsc->radius;
|
||||
border_dsc->color = dsc->border_color;
|
||||
border_dsc->opa = dsc->border_opa;
|
||||
border_dsc->width = dsc->border_width;
|
||||
border_dsc->side = dsc->border_side;
|
||||
t->type = LV_DRAW_TASK_TYPE_BORDER;
|
||||
lv_draw_finalize_task_creation(layer, t);
|
||||
}
|
||||
|
||||
/*Outline*/
|
||||
if(has_outline) {
|
||||
lv_area_t outline_coords = *coords;
|
||||
lv_area_increase(&outline_coords, dsc->outline_width + dsc->outline_pad, dsc->outline_width + dsc->outline_pad);
|
||||
t = lv_draw_add_task(layer, &outline_coords);
|
||||
lv_draw_border_dsc_t * outline_dsc = lv_malloc(sizeof(lv_draw_border_dsc_t));
|
||||
t->draw_dsc = outline_dsc;
|
||||
lv_area_increase(&t->_real_area, dsc->outline_width, dsc->outline_width);
|
||||
lv_area_increase(&t->_real_area, dsc->outline_pad, dsc->outline_pad);
|
||||
outline_dsc->base = dsc->base;
|
||||
outline_dsc->base.dsc_size = sizeof(lv_draw_border_dsc_t);
|
||||
outline_dsc->radius = dsc->radius == LV_RADIUS_CIRCLE ? LV_RADIUS_CIRCLE : dsc->radius + dsc->outline_width +
|
||||
dsc->outline_pad;
|
||||
outline_dsc->color = dsc->outline_color;
|
||||
outline_dsc->opa = dsc->outline_opa;
|
||||
outline_dsc->width = dsc->outline_width;
|
||||
outline_dsc->side = LV_BORDER_SIDE_FULL;
|
||||
t->type = LV_DRAW_TASK_TYPE_BORDER;
|
||||
lv_draw_finalize_task_creation(layer, t);
|
||||
}
|
||||
|
||||
LV_ASSERT_MEM_INTEGRITY();
|
||||
|
||||
LV_PROFILER_END;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
174
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_rect.h
Normal file
174
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_rect.h
Normal file
@@ -0,0 +1,174 @@
|
||||
/**
|
||||
* @file lv_draw_rect.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_RECT_H
|
||||
#define LV_DRAW_RECT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw.h"
|
||||
#include "../misc/lv_color.h"
|
||||
#include "../misc/lv_area.h"
|
||||
#include "../misc/lv_style.h"
|
||||
#include "sw/lv_draw_sw_gradient.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define LV_RADIUS_CIRCLE 0x7FFF /**< A very big radius to always draw as circle*/
|
||||
LV_EXPORT_CONST_INT(LV_RADIUS_CIRCLE);
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct {
|
||||
lv_draw_dsc_base_t base;
|
||||
|
||||
int32_t radius;
|
||||
|
||||
/*Background*/
|
||||
lv_opa_t bg_opa;
|
||||
lv_color_t bg_color; /**< First element of a gradient is a color, so it maps well here*/
|
||||
lv_grad_dsc_t bg_grad;
|
||||
|
||||
/*Background img*/
|
||||
const void * bg_image_src;
|
||||
const void * bg_image_symbol_font;
|
||||
lv_color_t bg_image_recolor;
|
||||
lv_opa_t bg_image_opa;
|
||||
lv_opa_t bg_image_recolor_opa;
|
||||
uint8_t bg_image_tiled;
|
||||
|
||||
/*Border*/
|
||||
lv_color_t border_color;
|
||||
int32_t border_width;
|
||||
lv_opa_t border_opa;
|
||||
lv_border_side_t border_side : 5;
|
||||
uint8_t border_post : 1; /*The border will be drawn later*/
|
||||
|
||||
/*Outline*/
|
||||
lv_color_t outline_color;
|
||||
int32_t outline_width;
|
||||
int32_t outline_pad;
|
||||
lv_opa_t outline_opa;
|
||||
|
||||
/*Shadow*/
|
||||
lv_color_t shadow_color;
|
||||
int32_t shadow_width;
|
||||
int32_t shadow_offset_x;
|
||||
int32_t shadow_offset_y;
|
||||
int32_t shadow_spread;
|
||||
lv_opa_t shadow_opa;
|
||||
} lv_draw_rect_dsc_t;
|
||||
|
||||
typedef struct {
|
||||
lv_draw_dsc_base_t base;
|
||||
|
||||
int32_t radius;
|
||||
|
||||
lv_opa_t opa;
|
||||
lv_color_t color;
|
||||
lv_grad_dsc_t grad;
|
||||
} lv_draw_fill_dsc_t;
|
||||
|
||||
typedef struct {
|
||||
lv_draw_dsc_base_t base;
|
||||
|
||||
int32_t radius;
|
||||
|
||||
lv_color_t color;
|
||||
int32_t width;
|
||||
lv_opa_t opa;
|
||||
lv_border_side_t side : 5;
|
||||
|
||||
} lv_draw_border_dsc_t;
|
||||
|
||||
typedef struct {
|
||||
lv_draw_dsc_base_t base;
|
||||
|
||||
int32_t radius;
|
||||
|
||||
lv_color_t color;
|
||||
int32_t width;
|
||||
int32_t spread;
|
||||
int32_t ofs_x;
|
||||
int32_t ofs_y;
|
||||
lv_opa_t opa;
|
||||
uint8_t bg_cover : 1;
|
||||
} lv_draw_box_shadow_dsc_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize a rectangle draw descriptor.
|
||||
* @param dsc pointer to a draw descriptor
|
||||
*/
|
||||
void /* LV_ATTRIBUTE_FAST_MEM */ lv_draw_rect_dsc_init(lv_draw_rect_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Initialize a fill draw descriptor.
|
||||
* @param dsc pointer to a draw descriptor
|
||||
*/
|
||||
void lv_draw_fill_dsc_init(lv_draw_fill_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Try to get a fill draw descriptor from a draw task.
|
||||
* @param task draw task
|
||||
* @return the task's draw descriptor or NULL if the task is not of type LV_DRAW_TASK_TYPE_FILL
|
||||
*/
|
||||
lv_draw_fill_dsc_t * lv_draw_task_get_fill_dsc(lv_draw_task_t * task);
|
||||
|
||||
/**
|
||||
* Initialize a border draw descriptor.
|
||||
* @param dsc pointer to a draw descriptor
|
||||
*/
|
||||
void lv_draw_border_dsc_init(lv_draw_border_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Try to get a border draw descriptor from a draw task.
|
||||
* @param task draw task
|
||||
* @return the task's draw descriptor or NULL if the task is not of type LV_DRAW_TASK_TYPE_BORDER
|
||||
*/
|
||||
lv_draw_border_dsc_t * lv_draw_task_get_border_dsc(lv_draw_task_t * task);
|
||||
|
||||
/**
|
||||
* Initialize a box shadow draw descriptor.
|
||||
* @param dsc pointer to a draw descriptor
|
||||
*/
|
||||
void lv_draw_box_shadow_dsc_init(lv_draw_box_shadow_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Try to get a box shadow draw descriptor from a draw task.
|
||||
* @param task draw task
|
||||
* @return the task's draw descriptor or NULL if the task is not of type LV_DRAW_TASK_TYPE_BOX_SHADOW
|
||||
*/
|
||||
lv_draw_box_shadow_dsc_t * lv_draw_task_get_box_shadow_dsc(lv_draw_task_t * task);
|
||||
|
||||
/**
|
||||
* The rectangle is a wrapper for fill, border, bg. image and box shadow.
|
||||
* Internally fill, border, image and box shadow draw tasks will be created.
|
||||
* @param layer pointer to a layer
|
||||
* @param dsc pointer to an initialized draw descriptor variable
|
||||
* @param coords the coordinates of the rectangle
|
||||
*/
|
||||
void lv_draw_rect(lv_layer_t * layer, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_RECT_H*/
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* @file lv_draw_rect_private.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_RECT_PRIVATE_H
|
||||
#define LV_DRAW_RECT_PRIVATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_rect.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_RECT_PRIVATE_H*/
|
||||
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* @file lv_draw_triangle.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_triangle_private.h"
|
||||
#include "lv_draw_private.h"
|
||||
#include "../core/lv_obj.h"
|
||||
#include "../misc/lv_math.h"
|
||||
#include "../stdlib/lv_mem.h"
|
||||
#include "../stdlib/lv_string.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_triangle_dsc_init(lv_draw_triangle_dsc_t * dsc)
|
||||
{
|
||||
LV_PROFILER_BEGIN;
|
||||
lv_memzero(dsc, sizeof(lv_draw_triangle_dsc_t));
|
||||
dsc->bg_color = lv_color_white();
|
||||
dsc->bg_grad.stops[0].color = lv_color_white();
|
||||
dsc->bg_grad.stops[1].color = lv_color_black();
|
||||
dsc->bg_grad.stops[1].frac = 0xFF;
|
||||
dsc->bg_grad.stops_count = 2;
|
||||
dsc->bg_opa = LV_OPA_COVER;
|
||||
dsc->base.dsc_size = sizeof(lv_draw_triangle_dsc_t);
|
||||
LV_PROFILER_END;
|
||||
}
|
||||
|
||||
lv_draw_triangle_dsc_t * lv_draw_task_get_triangle_dsc(lv_draw_task_t * task)
|
||||
{
|
||||
return task->type == LV_DRAW_TASK_TYPE_TRIANGLE ? (lv_draw_triangle_dsc_t *)task->draw_dsc : NULL;
|
||||
}
|
||||
|
||||
void lv_draw_triangle(lv_layer_t * layer, const lv_draw_triangle_dsc_t * dsc)
|
||||
{
|
||||
if(dsc->bg_opa <= LV_OPA_MIN) return;
|
||||
|
||||
LV_PROFILER_BEGIN;
|
||||
lv_area_t a;
|
||||
a.x1 = (int32_t)LV_MIN3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x);
|
||||
a.y1 = (int32_t)LV_MIN3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y);
|
||||
a.x2 = (int32_t)LV_MAX3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x);
|
||||
a.y2 = (int32_t)LV_MAX3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y);
|
||||
|
||||
lv_draw_task_t * t = lv_draw_add_task(layer, &a);
|
||||
|
||||
t->draw_dsc = lv_malloc(sizeof(*dsc));
|
||||
lv_memcpy(t->draw_dsc, dsc, sizeof(*dsc));
|
||||
t->type = LV_DRAW_TASK_TYPE_TRIANGLE;
|
||||
|
||||
lv_draw_finalize_task_creation(layer, t);
|
||||
LV_PROFILER_END;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* @file lv_draw_triangle.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_TRIANGLE_H
|
||||
#define LV_DRAW_TRIANGLE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_rect.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef struct {
|
||||
lv_draw_dsc_base_t base;
|
||||
|
||||
lv_opa_t bg_opa;
|
||||
lv_color_t bg_color;
|
||||
lv_grad_dsc_t bg_grad;
|
||||
|
||||
lv_point_precise_t p[3];
|
||||
} lv_draw_triangle_dsc_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize a triangle draw descriptor
|
||||
* @param draw_dsc pointer to a draw descriptor
|
||||
*/
|
||||
void lv_draw_triangle_dsc_init(lv_draw_triangle_dsc_t * draw_dsc);
|
||||
|
||||
/**
|
||||
* Try to get a triangle draw descriptor from a draw task.
|
||||
* @param task draw task
|
||||
* @return the task's draw descriptor or NULL if the task is not of type LV_DRAW_TASK_TYPE_TRIANGLE
|
||||
*/
|
||||
lv_draw_triangle_dsc_t * lv_draw_task_get_triangle_dsc(lv_draw_task_t * task);
|
||||
|
||||
/**
|
||||
* Create a triangle draw task
|
||||
* @param layer pointer to a layer
|
||||
* @param draw_dsc pointer to an initialized `lv_draw_triangle_dsc_t` object
|
||||
*/
|
||||
void lv_draw_triangle(lv_layer_t * layer, const lv_draw_triangle_dsc_t * draw_dsc);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_TRIANGLE_H*/
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* @file lv_draw_triangle_private.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_TRIANGLE_PRIVATE_H
|
||||
#define LV_DRAW_TRIANGLE_PRIVATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_triangle.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_TRIANGLE_PRIVATE_H*/
|
||||
804
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_vector.c
Normal file
804
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_vector.c
Normal file
@@ -0,0 +1,804 @@
|
||||
/**
|
||||
* @file lv_draw_vector.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_draw_vector_private.h"
|
||||
#include "../misc/lv_area_private.h"
|
||||
#include "lv_draw_private.h"
|
||||
|
||||
#if LV_USE_VECTOR_GRAPHIC
|
||||
|
||||
#include "../misc/lv_ll.h"
|
||||
#include "../misc/lv_types.h"
|
||||
#include "../stdlib/lv_string.h"
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
#define MATH_PI 3.14159265358979323846f
|
||||
#define MATH_HALF_PI 1.57079632679489661923f
|
||||
|
||||
#define DEG_TO_RAD 0.017453292519943295769236907684886f
|
||||
#define RAD_TO_DEG 57.295779513082320876798154814105f
|
||||
|
||||
#define MATH_RADIANS(deg) ((deg) * DEG_TO_RAD)
|
||||
#define MATH_DEGREES(rad) ((rad) * RAD_TO_DEG)
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.1415926f
|
||||
#endif
|
||||
|
||||
#define CHECK_AND_RESIZE_PATH_CONTAINER(P, N) \
|
||||
do { \
|
||||
if ((lv_array_size(&(P)->ops) + (N)) > lv_array_capacity(&(P)->ops)) { \
|
||||
lv_array_resize(&(P)->ops, ((P)->ops.capacity << 1)); \
|
||||
} \
|
||||
if ((lv_array_size(&(P)->points) + (N)) > lv_array_capacity(&(P)->points)) { \
|
||||
lv_array_resize(&(P)->points, ((P)->points.capacity << 1)); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct {
|
||||
lv_vector_path_t * path;
|
||||
lv_vector_draw_dsc_t dsc;
|
||||
} lv_vector_draw_task;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void _copy_draw_dsc(lv_vector_draw_dsc_t * dst, const lv_vector_draw_dsc_t * src)
|
||||
{
|
||||
lv_memcpy(&(dst->fill_dsc), &(src->fill_dsc), sizeof(lv_vector_fill_dsc_t));
|
||||
|
||||
dst->stroke_dsc.style = src->stroke_dsc.style;
|
||||
dst->stroke_dsc.color = src->stroke_dsc.color;
|
||||
dst->stroke_dsc.opa = src->stroke_dsc.opa;
|
||||
dst->stroke_dsc.width = src->stroke_dsc.width;
|
||||
dst->stroke_dsc.cap = src->stroke_dsc.cap;
|
||||
dst->stroke_dsc.join = src->stroke_dsc.join;
|
||||
dst->stroke_dsc.miter_limit = src->stroke_dsc.miter_limit;
|
||||
lv_array_copy(&(dst->stroke_dsc.dash_pattern), &(src->stroke_dsc.dash_pattern));
|
||||
dst->stroke_dsc.gradient.style = src->stroke_dsc.gradient.style;
|
||||
dst->stroke_dsc.gradient.cx = src->stroke_dsc.gradient.cx;
|
||||
dst->stroke_dsc.gradient.cy = src->stroke_dsc.gradient.cy;
|
||||
dst->stroke_dsc.gradient.cr = src->stroke_dsc.gradient.cr;
|
||||
dst->stroke_dsc.gradient.spread = src->fill_dsc.gradient.spread;
|
||||
lv_memcpy(&(dst->stroke_dsc.gradient), &(src->stroke_dsc.gradient), sizeof(lv_vector_gradient_t));
|
||||
lv_memcpy(&(dst->stroke_dsc.matrix), &(src->stroke_dsc.matrix), sizeof(lv_matrix_t));
|
||||
|
||||
dst->blend_mode = src->blend_mode;
|
||||
lv_memcpy(&(dst->matrix), &(src->matrix), sizeof(lv_matrix_t));
|
||||
lv_area_copy(&(dst->scissor_area), &(src->scissor_area));
|
||||
}
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_matrix_transform_point(const lv_matrix_t * matrix, lv_fpoint_t * point)
|
||||
{
|
||||
float x = point->x;
|
||||
float y = point->y;
|
||||
|
||||
point->x = x * matrix->m[0][0] + y * matrix->m[1][0] + matrix->m[0][2];
|
||||
point->y = x * matrix->m[0][1] + y * matrix->m[1][1] + matrix->m[1][2];
|
||||
}
|
||||
|
||||
void lv_matrix_transform_path(const lv_matrix_t * matrix, lv_vector_path_t * path)
|
||||
{
|
||||
lv_fpoint_t * pt = lv_array_front(&path->points);
|
||||
uint32_t size = lv_array_size(&path->points);
|
||||
for(uint32_t i = 0; i < size; i++) {
|
||||
lv_matrix_transform_point(matrix, &pt[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* path functions */
|
||||
lv_vector_path_t * lv_vector_path_create(lv_vector_path_quality_t quality)
|
||||
{
|
||||
lv_vector_path_t * path = lv_malloc(sizeof(lv_vector_path_t));
|
||||
LV_ASSERT_MALLOC(path);
|
||||
lv_memzero(path, sizeof(lv_vector_path_t));
|
||||
path->quality = quality;
|
||||
lv_array_init(&path->ops, 8, sizeof(lv_vector_path_op_t));
|
||||
lv_array_init(&path->points, 8, sizeof(lv_fpoint_t));
|
||||
return path;
|
||||
}
|
||||
|
||||
void lv_vector_path_copy(lv_vector_path_t * target_path, const lv_vector_path_t * path)
|
||||
{
|
||||
target_path->quality = path->quality;
|
||||
lv_array_copy(&target_path->ops, &path->ops);
|
||||
lv_array_copy(&target_path->points, &path->points);
|
||||
}
|
||||
|
||||
void lv_vector_path_clear(lv_vector_path_t * path)
|
||||
{
|
||||
lv_array_clear(&path->ops);
|
||||
lv_array_clear(&path->points);
|
||||
}
|
||||
|
||||
void lv_vector_path_delete(lv_vector_path_t * path)
|
||||
{
|
||||
lv_array_deinit(&path->ops);
|
||||
lv_array_deinit(&path->points);
|
||||
lv_free(path);
|
||||
}
|
||||
|
||||
void lv_vector_path_move_to(lv_vector_path_t * path, const lv_fpoint_t * p)
|
||||
{
|
||||
CHECK_AND_RESIZE_PATH_CONTAINER(path, 1);
|
||||
|
||||
lv_vector_path_op_t op = LV_VECTOR_PATH_OP_MOVE_TO;
|
||||
lv_array_push_back(&path->ops, &op);
|
||||
lv_array_push_back(&path->points, p);
|
||||
}
|
||||
|
||||
void lv_vector_path_line_to(lv_vector_path_t * path, const lv_fpoint_t * p)
|
||||
{
|
||||
if(lv_array_is_empty(&path->ops)) {
|
||||
/*first op must be move_to*/
|
||||
return;
|
||||
}
|
||||
|
||||
CHECK_AND_RESIZE_PATH_CONTAINER(path, 1);
|
||||
|
||||
lv_vector_path_op_t op = LV_VECTOR_PATH_OP_LINE_TO;
|
||||
lv_array_push_back(&path->ops, &op);
|
||||
lv_array_push_back(&path->points, p);
|
||||
}
|
||||
|
||||
void lv_vector_path_quad_to(lv_vector_path_t * path, const lv_fpoint_t * p1, const lv_fpoint_t * p2)
|
||||
{
|
||||
if(lv_array_is_empty(&path->ops)) {
|
||||
/*first op must be move_to*/
|
||||
return;
|
||||
}
|
||||
|
||||
CHECK_AND_RESIZE_PATH_CONTAINER(path, 2);
|
||||
|
||||
lv_vector_path_op_t op = LV_VECTOR_PATH_OP_QUAD_TO;
|
||||
lv_array_push_back(&path->ops, &op);
|
||||
lv_array_push_back(&path->points, p1);
|
||||
lv_array_push_back(&path->points, p2);
|
||||
}
|
||||
|
||||
void lv_vector_path_cubic_to(lv_vector_path_t * path, const lv_fpoint_t * p1, const lv_fpoint_t * p2,
|
||||
const lv_fpoint_t * p3)
|
||||
{
|
||||
if(lv_array_is_empty(&path->ops)) {
|
||||
/*first op must be move_to*/
|
||||
return;
|
||||
}
|
||||
|
||||
CHECK_AND_RESIZE_PATH_CONTAINER(path, 3);
|
||||
|
||||
lv_vector_path_op_t op = LV_VECTOR_PATH_OP_CUBIC_TO;
|
||||
lv_array_push_back(&path->ops, &op);
|
||||
lv_array_push_back(&path->points, p1);
|
||||
lv_array_push_back(&path->points, p2);
|
||||
lv_array_push_back(&path->points, p3);
|
||||
}
|
||||
|
||||
void lv_vector_path_close(lv_vector_path_t * path)
|
||||
{
|
||||
if(lv_array_is_empty(&path->ops)) {
|
||||
/*first op must be move_to*/
|
||||
return;
|
||||
}
|
||||
|
||||
CHECK_AND_RESIZE_PATH_CONTAINER(path, 1);
|
||||
|
||||
lv_vector_path_op_t op = LV_VECTOR_PATH_OP_CLOSE;
|
||||
lv_array_push_back(&path->ops, &op);
|
||||
}
|
||||
|
||||
void lv_vector_path_get_bounding(const lv_vector_path_t * path, lv_area_t * area)
|
||||
{
|
||||
LV_ASSERT_NULL(path);
|
||||
LV_ASSERT_NULL(area);
|
||||
|
||||
uint32_t len = lv_array_size(&path->points);
|
||||
if(len == 0) {
|
||||
lv_memzero(area, sizeof(lv_area_t));
|
||||
return;
|
||||
}
|
||||
|
||||
lv_fpoint_t * p = lv_array_front(&path->points);
|
||||
float x1 = p[0].x;
|
||||
float x2 = p[0].x;
|
||||
float y1 = p[0].y;
|
||||
float y2 = p[0].y;
|
||||
|
||||
for(uint32_t i = 1; i < len; i++) {
|
||||
if(p[i].x < x1) x1 = p[i].x;
|
||||
if(p[i].y < y1) y1 = p[i].y;
|
||||
if(p[i].x > x2) x2 = p[i].x;
|
||||
if(p[i].y > y2) y2 = p[i].y;
|
||||
}
|
||||
|
||||
area->x1 = (int32_t)x1;
|
||||
area->y1 = (int32_t)y1;
|
||||
area->x2 = (int32_t)x2;
|
||||
area->y2 = (int32_t)y2;
|
||||
}
|
||||
|
||||
void lv_vector_path_append_rect(lv_vector_path_t * path, const lv_area_t * rect, float rx, float ry)
|
||||
{
|
||||
float x = rect->x1;
|
||||
float y = rect->y1;
|
||||
float w = (float)lv_area_get_width(rect);
|
||||
float h = (float)lv_area_get_height(rect);
|
||||
|
||||
float hw = w * 0.5f;
|
||||
float hh = h * 0.5f;
|
||||
|
||||
if(rx > hw) rx = hw;
|
||||
if(ry > hh) ry = hh;
|
||||
|
||||
if(rx == 0 && ry == 0) {
|
||||
lv_fpoint_t pt = {x, y};
|
||||
lv_vector_path_move_to(path, &pt);
|
||||
pt.x += w;
|
||||
lv_vector_path_line_to(path, &pt);
|
||||
pt.y += h;
|
||||
lv_vector_path_line_to(path, &pt);
|
||||
pt.x -= w;
|
||||
lv_vector_path_line_to(path, &pt);
|
||||
lv_vector_path_close(path);
|
||||
}
|
||||
else if(rx == hw && ry == hh) {
|
||||
lv_fpoint_t pt = {x + w * 0.5f, y + h * 0.5f};
|
||||
lv_vector_path_append_circle(path, &pt, rx, ry);
|
||||
}
|
||||
else {
|
||||
float hrx = rx * 0.5f;
|
||||
float hry = ry * 0.5f;
|
||||
lv_fpoint_t pt, pt2, pt3;
|
||||
|
||||
pt.x = x + rx;
|
||||
pt.y = y;
|
||||
lv_vector_path_move_to(path, &pt);
|
||||
|
||||
pt.x = x + w - rx;
|
||||
pt.y = y;
|
||||
lv_vector_path_line_to(path, &pt);
|
||||
|
||||
pt.x = x + w - rx + hrx;
|
||||
pt.y = y;
|
||||
pt2.x = x + w;
|
||||
pt2.y = y + ry - hry;
|
||||
pt3.x = x + w;
|
||||
pt3.y = y + ry;
|
||||
lv_vector_path_cubic_to(path, &pt, &pt2, &pt3);
|
||||
|
||||
pt.x = x + w;
|
||||
pt.y = y + h - ry;
|
||||
lv_vector_path_line_to(path, &pt);
|
||||
|
||||
pt.x = x + w;
|
||||
pt.y = y + h - ry + hry;
|
||||
pt2.x = x + w - rx + hrx;
|
||||
pt2.y = y + h;
|
||||
pt3.x = x + w - rx;
|
||||
pt3.y = y + h;
|
||||
lv_vector_path_cubic_to(path, &pt, &pt2, &pt3);
|
||||
|
||||
pt.x = x + rx;
|
||||
pt.y = y + h;
|
||||
lv_vector_path_line_to(path, &pt);
|
||||
|
||||
pt.x = x + rx - hrx;
|
||||
pt.y = y + h;
|
||||
pt2.x = x;
|
||||
pt2.y = y + h - ry + hry;
|
||||
pt3.x = x;
|
||||
pt3.y = y + h - ry;
|
||||
lv_vector_path_cubic_to(path, &pt, &pt2, &pt3);
|
||||
|
||||
pt.x = x;
|
||||
pt.y = y + ry;
|
||||
lv_vector_path_line_to(path, &pt);
|
||||
|
||||
pt.x = x;
|
||||
pt.y = y + ry - hry;
|
||||
pt2.x = x + rx - hrx;
|
||||
pt2.y = y;
|
||||
pt3.x = x + rx;
|
||||
pt3.y = y;
|
||||
lv_vector_path_cubic_to(path, &pt, &pt2, &pt3);
|
||||
lv_vector_path_close(path);
|
||||
}
|
||||
}
|
||||
|
||||
void lv_vector_path_append_circle(lv_vector_path_t * path, const lv_fpoint_t * c, float rx, float ry)
|
||||
{
|
||||
float krx = rx * 0.552284f;
|
||||
float kry = ry * 0.552284f;
|
||||
float cx = c->x;
|
||||
float cy = c->y;
|
||||
|
||||
lv_fpoint_t pt, pt2, pt3;
|
||||
pt.x = cx;
|
||||
pt.y = cy - ry;
|
||||
lv_vector_path_move_to(path, &pt);
|
||||
|
||||
pt.x = cx + krx;
|
||||
pt.y = cy - ry;
|
||||
pt2.x = cx + rx;
|
||||
pt2.y = cy - kry;
|
||||
pt3.x = cx + rx;
|
||||
pt3.y = cy;
|
||||
lv_vector_path_cubic_to(path, &pt, &pt2, &pt3);
|
||||
|
||||
pt.x = cx + rx;
|
||||
pt.y = cy + kry;
|
||||
pt2.x = cx + krx;
|
||||
pt2.y = cy + ry;
|
||||
pt3.x = cx;
|
||||
pt3.y = cy + ry;
|
||||
lv_vector_path_cubic_to(path, &pt, &pt2, &pt3);
|
||||
|
||||
pt.x = cx - krx;
|
||||
pt.y = cy + ry;
|
||||
pt2.x = cx - rx;
|
||||
pt2.y = cy + kry;
|
||||
pt3.x = cx - rx;
|
||||
pt3.y = cy;
|
||||
lv_vector_path_cubic_to(path, &pt, &pt2, &pt3);
|
||||
|
||||
pt.x = cx - rx;
|
||||
pt.y = cy - kry;
|
||||
pt2.x = cx - krx;
|
||||
pt2.y = cy - ry;
|
||||
pt3.x = cx;
|
||||
pt3.y = cy - ry;
|
||||
lv_vector_path_cubic_to(path, &pt, &pt2, &pt3);
|
||||
|
||||
lv_vector_path_close(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a arc to the path
|
||||
* @param path pointer to a path
|
||||
* @param c pointer to a `lv_fpoint_t` variable for center of the circle
|
||||
* @param radius the radius for arc
|
||||
* @param start_angle the start angle for arc
|
||||
* @param sweep the sweep angle for arc, could be negative
|
||||
* @param pie true: draw a pie, false: draw a arc
|
||||
*/
|
||||
void lv_vector_path_append_arc(lv_vector_path_t * path, const lv_fpoint_t * c, float radius, float start_angle,
|
||||
float sweep, bool pie)
|
||||
{
|
||||
float cx = c->x;
|
||||
float cy = c->y;
|
||||
|
||||
/* just circle */
|
||||
if(sweep >= 360.0f || sweep <= -360.0f) {
|
||||
lv_vector_path_append_circle(path, c, radius, radius);
|
||||
return;
|
||||
}
|
||||
|
||||
start_angle = MATH_RADIANS(start_angle);
|
||||
sweep = MATH_RADIANS(sweep);
|
||||
|
||||
int n_curves = (int)ceil(fabsf(sweep / MATH_HALF_PI));
|
||||
float sweep_sign = sweep < 0 ? -1.f : 1.f;
|
||||
float fract = fmodf(sweep, MATH_HALF_PI);
|
||||
fract = (fabsf(fract) < FLT_EPSILON) ? MATH_HALF_PI * sweep_sign : fract;
|
||||
|
||||
/* Start from here */
|
||||
lv_fpoint_t start = {
|
||||
.x = radius * cosf(start_angle),
|
||||
.y = radius * sinf(start_angle),
|
||||
};
|
||||
|
||||
if(pie) {
|
||||
lv_vector_path_move_to(path, &(lv_fpoint_t) {
|
||||
cx, cy
|
||||
});
|
||||
lv_vector_path_line_to(path, &(lv_fpoint_t) {
|
||||
start.x + cx, start.y + cy
|
||||
});
|
||||
}
|
||||
|
||||
for(int i = 0; i < n_curves; ++i) {
|
||||
float end_angle = start_angle + ((i != n_curves - 1) ? MATH_HALF_PI * sweep_sign : fract);
|
||||
float end_x = radius * cosf(end_angle);
|
||||
float end_y = radius * sinf(end_angle);
|
||||
|
||||
/* variables needed to calculate bezier control points */
|
||||
|
||||
/** get bezier control points using article:
|
||||
* (http://itc.ktu.lt/index.php/ITC/article/view/11812/6479)
|
||||
*/
|
||||
float ax = start.x;
|
||||
float ay = start.y;
|
||||
float bx = end_x;
|
||||
float by = end_y;
|
||||
float q1 = ax * ax + ay * ay;
|
||||
float q2 = ax * bx + ay * by + q1;
|
||||
float k2 = (4.0f / 3.0f) * ((sqrtf(2 * q1 * q2) - q2) / (ax * by - ay * bx));
|
||||
|
||||
/* Next start point is the current end point */
|
||||
start.x = end_x;
|
||||
start.y = end_y;
|
||||
|
||||
end_x += cx;
|
||||
end_y += cy;
|
||||
|
||||
lv_fpoint_t ctrl1 = {ax - k2 * ay + cx, ay + k2 * ax + cy};
|
||||
lv_fpoint_t ctrl2 = {bx + k2 * by + cx, by - k2 * bx + cy};
|
||||
lv_fpoint_t end = {end_x, end_y};
|
||||
lv_vector_path_cubic_to(path, &ctrl1, &ctrl2, &end);
|
||||
start_angle = end_angle;
|
||||
}
|
||||
|
||||
if(pie) {
|
||||
lv_vector_path_close(path);
|
||||
}
|
||||
}
|
||||
|
||||
void lv_vector_path_append_path(lv_vector_path_t * path, const lv_vector_path_t * subpath)
|
||||
{
|
||||
uint32_t ops_size = lv_array_size(&path->ops);
|
||||
uint32_t nops_size = lv_array_size(&subpath->ops);
|
||||
uint32_t point_size = lv_array_size(&path->points);
|
||||
uint32_t npoint_size = lv_array_size(&subpath->points);
|
||||
|
||||
lv_array_concat(&path->ops, &subpath->ops);
|
||||
path->ops.size = ops_size + nops_size;
|
||||
|
||||
lv_array_concat(&path->points, &subpath->points);
|
||||
path->points.size = point_size + npoint_size;
|
||||
}
|
||||
|
||||
/* draw dsc functions */
|
||||
|
||||
lv_vector_dsc_t * lv_vector_dsc_create(lv_layer_t * layer)
|
||||
{
|
||||
lv_vector_dsc_t * dsc = lv_malloc(sizeof(lv_vector_dsc_t));
|
||||
LV_ASSERT_MALLOC(dsc);
|
||||
lv_memzero(dsc, sizeof(lv_vector_dsc_t));
|
||||
|
||||
dsc->layer = layer;
|
||||
|
||||
lv_vector_fill_dsc_t * fill_dsc = &(dsc->current_dsc.fill_dsc);
|
||||
fill_dsc->style = LV_VECTOR_DRAW_STYLE_SOLID;
|
||||
fill_dsc->color = lv_color_to_32(lv_color_black(), 0xFF);
|
||||
fill_dsc->opa = LV_OPA_COVER;
|
||||
fill_dsc->fill_rule = LV_VECTOR_FILL_NONZERO;
|
||||
lv_matrix_identity(&(fill_dsc->matrix)); /*identity matrix*/
|
||||
|
||||
lv_vector_stroke_dsc_t * stroke_dsc = &(dsc->current_dsc.stroke_dsc);
|
||||
stroke_dsc->style = LV_VECTOR_DRAW_STYLE_SOLID;
|
||||
stroke_dsc->color = lv_color_to_32(lv_color_black(), 0xFF);
|
||||
stroke_dsc->opa = LV_OPA_0; /*default no stroke*/
|
||||
stroke_dsc->width = 1.0f;
|
||||
stroke_dsc->cap = LV_VECTOR_STROKE_CAP_BUTT;
|
||||
stroke_dsc->join = LV_VECTOR_STROKE_JOIN_MITER;
|
||||
stroke_dsc->miter_limit = 4.0f;
|
||||
lv_matrix_identity(&(stroke_dsc->matrix)); /*identity matrix*/
|
||||
|
||||
dsc->current_dsc.blend_mode = LV_VECTOR_BLEND_SRC_OVER;
|
||||
dsc->current_dsc.scissor_area = layer->_clip_area;
|
||||
lv_matrix_identity(&(dsc->current_dsc.matrix)); /*identity matrix*/
|
||||
dsc->tasks.task_list = NULL;
|
||||
return dsc;
|
||||
}
|
||||
|
||||
void lv_vector_dsc_delete(lv_vector_dsc_t * dsc)
|
||||
{
|
||||
if(dsc->tasks.task_list) {
|
||||
lv_ll_t * task_list = dsc->tasks.task_list;
|
||||
lv_vector_for_each_destroy_tasks(task_list, NULL, NULL);
|
||||
dsc->tasks.task_list = NULL;
|
||||
}
|
||||
lv_array_deinit(&(dsc->current_dsc.stroke_dsc.dash_pattern));
|
||||
lv_free(dsc);
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_blend_mode(lv_vector_dsc_t * dsc, lv_vector_blend_t blend)
|
||||
{
|
||||
dsc->current_dsc.blend_mode = blend;
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_transform(lv_vector_dsc_t * dsc, const lv_matrix_t * matrix)
|
||||
{
|
||||
lv_memcpy(&(dsc->current_dsc.matrix), matrix, sizeof(lv_matrix_t));
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_fill_color(lv_vector_dsc_t * dsc, lv_color_t color)
|
||||
{
|
||||
dsc->current_dsc.fill_dsc.style = LV_VECTOR_DRAW_STYLE_SOLID;
|
||||
dsc->current_dsc.fill_dsc.color = lv_color_to_32(color, 0xFF);
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_fill_color32(lv_vector_dsc_t * dsc, lv_color32_t color)
|
||||
{
|
||||
dsc->current_dsc.fill_dsc.style = LV_VECTOR_DRAW_STYLE_SOLID;
|
||||
dsc->current_dsc.fill_dsc.color = color;
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_fill_opa(lv_vector_dsc_t * dsc, lv_opa_t opa)
|
||||
{
|
||||
dsc->current_dsc.fill_dsc.opa = opa;
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_fill_rule(lv_vector_dsc_t * dsc, lv_vector_fill_t rule)
|
||||
{
|
||||
dsc->current_dsc.fill_dsc.fill_rule = rule;
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_fill_image(lv_vector_dsc_t * dsc, const lv_draw_image_dsc_t * img_dsc)
|
||||
{
|
||||
dsc->current_dsc.fill_dsc.style = LV_VECTOR_DRAW_STYLE_PATTERN;
|
||||
lv_memcpy(&(dsc->current_dsc.fill_dsc.img_dsc), img_dsc, sizeof(lv_draw_image_dsc_t));
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_fill_linear_gradient(lv_vector_dsc_t * dsc, float x1, float y1, float x2, float y2)
|
||||
{
|
||||
dsc->current_dsc.fill_dsc.style = LV_VECTOR_DRAW_STYLE_GRADIENT;
|
||||
dsc->current_dsc.fill_dsc.gradient.style = LV_VECTOR_GRADIENT_STYLE_LINEAR;
|
||||
dsc->current_dsc.fill_dsc.gradient.x1 = x1;
|
||||
dsc->current_dsc.fill_dsc.gradient.y1 = y1;
|
||||
dsc->current_dsc.fill_dsc.gradient.x2 = x2;
|
||||
dsc->current_dsc.fill_dsc.gradient.y2 = y2;
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_fill_radial_gradient(lv_vector_dsc_t * dsc, float cx, float cy, float radius)
|
||||
{
|
||||
dsc->current_dsc.fill_dsc.style = LV_VECTOR_DRAW_STYLE_GRADIENT;
|
||||
dsc->current_dsc.fill_dsc.gradient.style = LV_VECTOR_GRADIENT_STYLE_RADIAL;
|
||||
dsc->current_dsc.fill_dsc.gradient.cx = cx;
|
||||
dsc->current_dsc.fill_dsc.gradient.cy = cy;
|
||||
dsc->current_dsc.fill_dsc.gradient.cr = radius;
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_fill_gradient_spread(lv_vector_dsc_t * dsc, lv_vector_gradient_spread_t spread)
|
||||
{
|
||||
dsc->current_dsc.fill_dsc.gradient.spread = spread;
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_fill_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_gradient_stop_t * stops,
|
||||
uint16_t count)
|
||||
{
|
||||
if(count > LV_GRADIENT_MAX_STOPS) {
|
||||
LV_LOG_WARN("Gradient stops limited: %d, max: %d", count, LV_GRADIENT_MAX_STOPS);
|
||||
count = LV_GRADIENT_MAX_STOPS;
|
||||
}
|
||||
|
||||
lv_memcpy(&(dsc->current_dsc.fill_dsc.gradient.stops), stops, sizeof(lv_gradient_stop_t) * count);
|
||||
dsc->current_dsc.fill_dsc.gradient.stops_count = count;
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_fill_transform(lv_vector_dsc_t * dsc, const lv_matrix_t * matrix)
|
||||
{
|
||||
lv_memcpy(&(dsc->current_dsc.fill_dsc.matrix), matrix, sizeof(lv_matrix_t));
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_stroke_transform(lv_vector_dsc_t * dsc, const lv_matrix_t * matrix)
|
||||
{
|
||||
lv_memcpy(&(dsc->current_dsc.stroke_dsc.matrix), matrix, sizeof(lv_matrix_t));
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_stroke_color32(lv_vector_dsc_t * dsc, lv_color32_t color)
|
||||
{
|
||||
dsc->current_dsc.stroke_dsc.style = LV_VECTOR_DRAW_STYLE_SOLID;
|
||||
dsc->current_dsc.stroke_dsc.color = color;
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_stroke_color(lv_vector_dsc_t * dsc, lv_color_t color)
|
||||
{
|
||||
dsc->current_dsc.stroke_dsc.style = LV_VECTOR_DRAW_STYLE_SOLID;
|
||||
dsc->current_dsc.stroke_dsc.color = lv_color_to_32(color, 0xFF);
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_stroke_opa(lv_vector_dsc_t * dsc, lv_opa_t opa)
|
||||
{
|
||||
dsc->current_dsc.stroke_dsc.opa = opa;
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_stroke_width(lv_vector_dsc_t * dsc, float width)
|
||||
{
|
||||
dsc->current_dsc.stroke_dsc.width = width;
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_stroke_dash(lv_vector_dsc_t * dsc, float * dash_pattern, uint16_t dash_count)
|
||||
{
|
||||
lv_array_t * dash_array = &(dsc->current_dsc.stroke_dsc.dash_pattern);
|
||||
if(dash_pattern) {
|
||||
lv_array_clear(dash_array);
|
||||
if(lv_array_capacity(dash_array) == 0) {
|
||||
lv_array_init(dash_array, dash_count, sizeof(float));
|
||||
}
|
||||
else {
|
||||
lv_array_resize(dash_array, dash_count);
|
||||
}
|
||||
for(uint16_t i = 0; i < dash_count; i++) {
|
||||
lv_array_push_back(dash_array, &dash_pattern[i]);
|
||||
}
|
||||
}
|
||||
else { /*clear dash*/
|
||||
lv_array_clear(dash_array);
|
||||
}
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_stroke_cap(lv_vector_dsc_t * dsc, lv_vector_stroke_cap_t cap)
|
||||
{
|
||||
dsc->current_dsc.stroke_dsc.cap = cap;
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_stroke_join(lv_vector_dsc_t * dsc, lv_vector_stroke_join_t join)
|
||||
{
|
||||
dsc->current_dsc.stroke_dsc.join = join;
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_stroke_miter_limit(lv_vector_dsc_t * dsc, uint16_t miter_limit)
|
||||
{
|
||||
dsc->current_dsc.stroke_dsc.miter_limit = miter_limit;
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_stroke_linear_gradient(lv_vector_dsc_t * dsc, float x1, float y1, float x2, float y2)
|
||||
{
|
||||
dsc->current_dsc.stroke_dsc.style = LV_VECTOR_DRAW_STYLE_GRADIENT;
|
||||
dsc->current_dsc.stroke_dsc.gradient.style = LV_VECTOR_GRADIENT_STYLE_LINEAR;
|
||||
dsc->current_dsc.stroke_dsc.gradient.x1 = x1;
|
||||
dsc->current_dsc.stroke_dsc.gradient.y1 = y1;
|
||||
dsc->current_dsc.stroke_dsc.gradient.x2 = x2;
|
||||
dsc->current_dsc.stroke_dsc.gradient.y2 = y2;
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_stroke_radial_gradient(lv_vector_dsc_t * dsc, float cx, float cy, float radius)
|
||||
{
|
||||
dsc->current_dsc.stroke_dsc.style = LV_VECTOR_DRAW_STYLE_GRADIENT;
|
||||
dsc->current_dsc.stroke_dsc.gradient.style = LV_VECTOR_GRADIENT_STYLE_RADIAL;
|
||||
dsc->current_dsc.stroke_dsc.gradient.cx = cx;
|
||||
dsc->current_dsc.stroke_dsc.gradient.cy = cy;
|
||||
dsc->current_dsc.stroke_dsc.gradient.cr = radius;
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_stroke_gradient_spread(lv_vector_dsc_t * dsc, lv_vector_gradient_spread_t spread)
|
||||
{
|
||||
dsc->current_dsc.stroke_dsc.gradient.spread = spread;
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_stroke_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_gradient_stop_t * stops,
|
||||
uint16_t count)
|
||||
{
|
||||
if(count > LV_GRADIENT_MAX_STOPS) {
|
||||
LV_LOG_WARN("Gradient stops limited: %d, max: %d", count, LV_GRADIENT_MAX_STOPS);
|
||||
count = LV_GRADIENT_MAX_STOPS;
|
||||
}
|
||||
|
||||
lv_memcpy(&(dsc->current_dsc.stroke_dsc.gradient.stops), stops, sizeof(lv_gradient_stop_t) * count);
|
||||
dsc->current_dsc.stroke_dsc.gradient.stops_count = count;
|
||||
}
|
||||
|
||||
/* draw functions */
|
||||
void lv_vector_dsc_add_path(lv_vector_dsc_t * dsc, const lv_vector_path_t * path)
|
||||
{
|
||||
lv_area_t rect;
|
||||
if(!lv_area_intersect(&rect, &(dsc->layer->_clip_area), &(dsc->current_dsc.scissor_area))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(dsc->current_dsc.fill_dsc.opa == 0
|
||||
&& dsc->current_dsc.stroke_dsc.opa == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!dsc->tasks.task_list) {
|
||||
dsc->tasks.task_list = lv_malloc(sizeof(lv_ll_t));
|
||||
LV_ASSERT_MALLOC(dsc->tasks.task_list);
|
||||
lv_ll_init(dsc->tasks.task_list, sizeof(lv_vector_draw_task));
|
||||
}
|
||||
|
||||
lv_vector_draw_task * new_task = (lv_vector_draw_task *)lv_ll_ins_tail(dsc->tasks.task_list);
|
||||
lv_memset(new_task, 0, sizeof(lv_vector_draw_task));
|
||||
|
||||
new_task->path = lv_vector_path_create(0);
|
||||
|
||||
_copy_draw_dsc(&(new_task->dsc), &(dsc->current_dsc));
|
||||
lv_vector_path_copy(new_task->path, path);
|
||||
new_task->dsc.scissor_area = rect;
|
||||
}
|
||||
|
||||
void lv_vector_clear_area(lv_vector_dsc_t * dsc, const lv_area_t * rect)
|
||||
{
|
||||
lv_area_t r;
|
||||
if(!lv_area_intersect(&r, &(dsc->layer->_clip_area), &(dsc->current_dsc.scissor_area))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!dsc->tasks.task_list) {
|
||||
dsc->tasks.task_list = lv_malloc(sizeof(lv_ll_t));
|
||||
LV_ASSERT_MALLOC(dsc->tasks.task_list);
|
||||
lv_ll_init(dsc->tasks.task_list, sizeof(lv_vector_draw_task));
|
||||
}
|
||||
|
||||
lv_vector_draw_task * new_task = (lv_vector_draw_task *)lv_ll_ins_tail(dsc->tasks.task_list);
|
||||
lv_memset(new_task, 0, sizeof(lv_vector_draw_task));
|
||||
|
||||
new_task->dsc.fill_dsc.color = dsc->current_dsc.fill_dsc.color;
|
||||
new_task->dsc.fill_dsc.opa = dsc->current_dsc.fill_dsc.opa;
|
||||
lv_area_copy(&(new_task->dsc.scissor_area), rect);
|
||||
}
|
||||
|
||||
void lv_draw_vector(lv_vector_dsc_t * dsc)
|
||||
{
|
||||
if(!dsc->tasks.task_list) {
|
||||
return;
|
||||
}
|
||||
|
||||
lv_layer_t * layer = dsc->layer;
|
||||
|
||||
lv_draw_task_t * t = lv_draw_add_task(layer, &(layer->_clip_area));
|
||||
t->type = LV_DRAW_TASK_TYPE_VECTOR;
|
||||
t->draw_dsc = lv_malloc(sizeof(lv_draw_vector_task_dsc_t));
|
||||
lv_memcpy(t->draw_dsc, &(dsc->tasks), sizeof(lv_draw_vector_task_dsc_t));
|
||||
lv_draw_finalize_task_creation(layer, t);
|
||||
dsc->tasks.task_list = NULL;
|
||||
}
|
||||
|
||||
/* draw dsc transform */
|
||||
void lv_vector_dsc_identity(lv_vector_dsc_t * dsc)
|
||||
{
|
||||
lv_matrix_identity(&(dsc->current_dsc.matrix)); /*identity matrix*/
|
||||
}
|
||||
|
||||
void lv_vector_dsc_scale(lv_vector_dsc_t * dsc, float scale_x, float scale_y)
|
||||
{
|
||||
lv_matrix_scale(&(dsc->current_dsc.matrix), scale_x, scale_y);
|
||||
}
|
||||
|
||||
void lv_vector_dsc_rotate(lv_vector_dsc_t * dsc, float degree)
|
||||
{
|
||||
lv_matrix_rotate(&(dsc->current_dsc.matrix), degree);
|
||||
}
|
||||
|
||||
void lv_vector_dsc_translate(lv_vector_dsc_t * dsc, float tx, float ty)
|
||||
{
|
||||
lv_matrix_translate(&(dsc->current_dsc.matrix), tx, ty);
|
||||
}
|
||||
|
||||
void lv_vector_dsc_skew(lv_vector_dsc_t * dsc, float skew_x, float skew_y)
|
||||
{
|
||||
lv_matrix_skew(&(dsc->current_dsc.matrix), skew_x, skew_y);
|
||||
}
|
||||
|
||||
void lv_vector_for_each_destroy_tasks(lv_ll_t * task_list, vector_draw_task_cb cb, void * data)
|
||||
{
|
||||
lv_vector_draw_task * task = lv_ll_get_head(task_list);
|
||||
lv_vector_draw_task * next_task = NULL;
|
||||
|
||||
while(task != NULL) {
|
||||
next_task = lv_ll_get_next(task_list, task);
|
||||
lv_ll_remove(task_list, task);
|
||||
|
||||
if(cb) {
|
||||
cb(data, task->path, &(task->dsc));
|
||||
}
|
||||
|
||||
if(task->path) {
|
||||
lv_vector_path_delete(task->path);
|
||||
}
|
||||
lv_array_deinit(&(task->dsc.stroke_dsc.dash_pattern));
|
||||
|
||||
lv_free(task);
|
||||
task = next_task;
|
||||
}
|
||||
lv_free(task_list);
|
||||
}
|
||||
#endif /* LV_USE_VECTOR_GRAPHIC */
|
||||
489
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_vector.h
Normal file
489
software/Power_Pico/Middlewares/LVGL/src/draw/lv_draw_vector.h
Normal file
@@ -0,0 +1,489 @@
|
||||
/**
|
||||
* @file lv_draw_vector.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_VECTOR_H
|
||||
#define LV_DRAW_VECTOR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../misc/lv_array.h"
|
||||
#include "../misc/lv_matrix.h"
|
||||
#include "lv_draw_image.h"
|
||||
|
||||
#if LV_USE_VECTOR_GRAPHIC
|
||||
|
||||
#if !LV_USE_MATRIX
|
||||
#error "lv_draw_vector needs LV_USE_MATRIX = 1"
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef enum {
|
||||
LV_VECTOR_FILL_NONZERO = 0,
|
||||
LV_VECTOR_FILL_EVENODD,
|
||||
} lv_vector_fill_t;
|
||||
|
||||
typedef enum {
|
||||
LV_VECTOR_STROKE_CAP_BUTT = 0,
|
||||
LV_VECTOR_STROKE_CAP_SQUARE,
|
||||
LV_VECTOR_STROKE_CAP_ROUND,
|
||||
} lv_vector_stroke_cap_t;
|
||||
|
||||
typedef enum {
|
||||
LV_VECTOR_STROKE_JOIN_MITER = 0,
|
||||
LV_VECTOR_STROKE_JOIN_BEVEL,
|
||||
LV_VECTOR_STROKE_JOIN_ROUND,
|
||||
} lv_vector_stroke_join_t;
|
||||
|
||||
typedef enum {
|
||||
LV_VECTOR_PATH_QUALITY_MEDIUM = 0, /* default*/
|
||||
LV_VECTOR_PATH_QUALITY_HIGH,
|
||||
LV_VECTOR_PATH_QUALITY_LOW,
|
||||
} lv_vector_path_quality_t;
|
||||
|
||||
typedef enum {
|
||||
LV_VECTOR_BLEND_SRC_OVER = 0,
|
||||
LV_VECTOR_BLEND_SRC_IN,
|
||||
LV_VECTOR_BLEND_DST_OVER,
|
||||
LV_VECTOR_BLEND_DST_IN,
|
||||
LV_VECTOR_BLEND_SCREEN,
|
||||
LV_VECTOR_BLEND_MULTIPLY,
|
||||
LV_VECTOR_BLEND_NONE,
|
||||
LV_VECTOR_BLEND_ADDITIVE,
|
||||
LV_VECTOR_BLEND_SUBTRACTIVE,
|
||||
} lv_vector_blend_t;
|
||||
|
||||
typedef enum {
|
||||
LV_VECTOR_PATH_OP_MOVE_TO = 0,
|
||||
LV_VECTOR_PATH_OP_LINE_TO,
|
||||
LV_VECTOR_PATH_OP_QUAD_TO,
|
||||
LV_VECTOR_PATH_OP_CUBIC_TO,
|
||||
LV_VECTOR_PATH_OP_CLOSE,
|
||||
} lv_vector_path_op_t;
|
||||
|
||||
typedef enum {
|
||||
LV_VECTOR_DRAW_STYLE_SOLID = 0,
|
||||
LV_VECTOR_DRAW_STYLE_PATTERN,
|
||||
LV_VECTOR_DRAW_STYLE_GRADIENT,
|
||||
} lv_vector_draw_style_t;
|
||||
|
||||
typedef enum {
|
||||
LV_VECTOR_GRADIENT_SPREAD_PAD = 0,
|
||||
LV_VECTOR_GRADIENT_SPREAD_REPEAT,
|
||||
LV_VECTOR_GRADIENT_SPREAD_REFLECT,
|
||||
} lv_vector_gradient_spread_t;
|
||||
|
||||
typedef enum {
|
||||
LV_VECTOR_GRADIENT_STYLE_LINEAR = 0,
|
||||
LV_VECTOR_GRADIENT_STYLE_RADIAL,
|
||||
} lv_vector_gradient_style_t;
|
||||
|
||||
struct lv_fpoint_t {
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Transform the coordinates of a point using given matrix
|
||||
* @param matrix pointer to a matrix
|
||||
* @param point pointer to a point
|
||||
*/
|
||||
void lv_matrix_transform_point(const lv_matrix_t * matrix, lv_fpoint_t * point);
|
||||
|
||||
/**
|
||||
* Transform all the coordinates of a path using given matrix
|
||||
* @param matrix pointer to a matrix
|
||||
* @param path pointer to a path
|
||||
*/
|
||||
void lv_matrix_transform_path(const lv_matrix_t * matrix, lv_vector_path_t * path);
|
||||
|
||||
/**
|
||||
* Create a vector graphic path object
|
||||
* @param quality the quality hint of path
|
||||
* @return pointer to the created path object
|
||||
*/
|
||||
lv_vector_path_t * lv_vector_path_create(lv_vector_path_quality_t quality);
|
||||
|
||||
/**
|
||||
* Copy a path data to another
|
||||
* @param target_path pointer to a path
|
||||
* @param path pointer to source path
|
||||
*/
|
||||
void lv_vector_path_copy(lv_vector_path_t * target_path, const lv_vector_path_t * path);
|
||||
|
||||
/**
|
||||
* Clear path data
|
||||
* @param path pointer to a path
|
||||
*/
|
||||
void lv_vector_path_clear(lv_vector_path_t * path);
|
||||
|
||||
/**
|
||||
* Delete the graphic path object
|
||||
* @param path pointer to a path
|
||||
*/
|
||||
void lv_vector_path_delete(lv_vector_path_t * path);
|
||||
|
||||
/**
|
||||
* Begin a new sub path and set a point to path
|
||||
* @param path pointer to a path
|
||||
* @param p pointer to a `lv_fpoint_t` variable
|
||||
*/
|
||||
void lv_vector_path_move_to(lv_vector_path_t * path, const lv_fpoint_t * p);
|
||||
|
||||
/**
|
||||
* Add a line to the path from last point to the point
|
||||
* @param path pointer to a path
|
||||
* @param p pointer to a `lv_fpoint_t` variable
|
||||
*/
|
||||
void lv_vector_path_line_to(lv_vector_path_t * path, const lv_fpoint_t * p);
|
||||
|
||||
/**
|
||||
* Add a quadratic bezier line to the path from last point to the point
|
||||
* @param path pointer to a path
|
||||
* @param p1 pointer to a `lv_fpoint_t` variable for control point
|
||||
* @param p2 pointer to a `lv_fpoint_t` variable for end point
|
||||
*/
|
||||
void lv_vector_path_quad_to(lv_vector_path_t * path, const lv_fpoint_t * p1, const lv_fpoint_t * p2);
|
||||
|
||||
/**
|
||||
* Add a cubic bezier line to the path from last point to the point
|
||||
* @param path pointer to a path
|
||||
* @param p1 pointer to a `lv_fpoint_t` variable for first control point
|
||||
* @param p2 pointer to a `lv_fpoint_t` variable for second control point
|
||||
* @param p3 pointer to a `lv_fpoint_t` variable for end point
|
||||
*/
|
||||
void lv_vector_path_cubic_to(lv_vector_path_t * path, const lv_fpoint_t * p1, const lv_fpoint_t * p2,
|
||||
const lv_fpoint_t * p3);
|
||||
|
||||
/**
|
||||
* Close the sub path
|
||||
* @param path pointer to a path
|
||||
*/
|
||||
void lv_vector_path_close(lv_vector_path_t * path);
|
||||
|
||||
/**
|
||||
* Get the bounding box of a path
|
||||
* @param path pointer to a path
|
||||
* @param area pointer to a `lv_area_t` variable for bounding box
|
||||
*/
|
||||
void lv_vector_path_get_bounding(const lv_vector_path_t * path, lv_area_t * area);
|
||||
|
||||
/**
|
||||
* Add a rectangle to the path
|
||||
* @param path pointer to a path
|
||||
* @param rect pointer to a `lv_area_t` variable
|
||||
* @param rx the horizontal radius for rounded rectangle
|
||||
* @param ry the vertical radius for rounded rectangle
|
||||
*/
|
||||
void lv_vector_path_append_rect(lv_vector_path_t * path, const lv_area_t * rect, float rx, float ry);
|
||||
|
||||
/**
|
||||
* Add a circle to the path
|
||||
* @param path pointer to a path
|
||||
* @param c pointer to a `lv_fpoint_t` variable for center of the circle
|
||||
* @param rx the horizontal radius for circle
|
||||
* @param ry the vertical radius for circle
|
||||
*/
|
||||
void lv_vector_path_append_circle(lv_vector_path_t * path, const lv_fpoint_t * c, float rx, float ry);
|
||||
|
||||
/**
|
||||
* Add a arc to the path
|
||||
* @param path pointer to a path
|
||||
* @param c pointer to a `lv_fpoint_t` variable for center of the circle
|
||||
* @param radius the radius for arc
|
||||
* @param start_angle the start angle for arc
|
||||
* @param sweep the sweep angle for arc, could be negative
|
||||
* @param pie true: draw a pie, false: draw a arc
|
||||
*/
|
||||
void lv_vector_path_append_arc(lv_vector_path_t * path, const lv_fpoint_t * c, float radius, float start_angle,
|
||||
float sweep, bool pie);
|
||||
|
||||
/**
|
||||
* Add an sub path to the path
|
||||
* @param path pointer to a path
|
||||
* @param subpath pointer to another path which will be added
|
||||
*/
|
||||
void lv_vector_path_append_path(lv_vector_path_t * path, const lv_vector_path_t * subpath);
|
||||
|
||||
/**
|
||||
* Create a vector graphic descriptor
|
||||
* @param layer pointer to a layer
|
||||
* @return pointer to the created descriptor
|
||||
*/
|
||||
lv_vector_dsc_t * lv_vector_dsc_create(lv_layer_t * layer);
|
||||
|
||||
/**
|
||||
* Delete the vector graphic descriptor
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
*/
|
||||
void lv_vector_dsc_delete(lv_vector_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Set a matrix to current transformation matrix
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param matrix pointer to a matrix
|
||||
*/
|
||||
void lv_vector_dsc_set_transform(lv_vector_dsc_t * dsc, const lv_matrix_t * matrix);
|
||||
|
||||
/**
|
||||
* Set blend mode for descriptor
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param blend the blend mode to be set in `lv_vector_blend_t`
|
||||
*/
|
||||
void lv_vector_dsc_set_blend_mode(lv_vector_dsc_t * dsc, lv_vector_blend_t blend);
|
||||
|
||||
/**
|
||||
* Set fill color for descriptor
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param color the color to be set in lv_color32_t format
|
||||
*/
|
||||
void lv_vector_dsc_set_fill_color32(lv_vector_dsc_t * dsc, lv_color32_t color);
|
||||
|
||||
/**
|
||||
* Set fill color for descriptor
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param color the color to be set in lv_color_t format
|
||||
*/
|
||||
void lv_vector_dsc_set_fill_color(lv_vector_dsc_t * dsc, lv_color_t color);
|
||||
|
||||
/**
|
||||
* Set fill opacity for descriptor
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param opa the opacity to be set in lv_opa_t format
|
||||
*/
|
||||
void lv_vector_dsc_set_fill_opa(lv_vector_dsc_t * dsc, lv_opa_t opa);
|
||||
|
||||
/**
|
||||
* Set fill rule for descriptor
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param rule the fill rule to be set in lv_vector_fill_t format
|
||||
*/
|
||||
void lv_vector_dsc_set_fill_rule(lv_vector_dsc_t * dsc, lv_vector_fill_t rule);
|
||||
|
||||
/**
|
||||
* Set fill image for descriptor
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param img_dsc pointer to a `lv_draw_image_dsc_t` variable
|
||||
*/
|
||||
void lv_vector_dsc_set_fill_image(lv_vector_dsc_t * dsc, const lv_draw_image_dsc_t * img_dsc);
|
||||
|
||||
/**
|
||||
* Set fill linear gradient for descriptor
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param x1 the x for start point
|
||||
* @param y1 the y for start point
|
||||
* @param x2 the x for end point
|
||||
* @param y2 the y for end point
|
||||
*/
|
||||
void lv_vector_dsc_set_fill_linear_gradient(lv_vector_dsc_t * dsc, float x1, float y1, float x2, float y2);
|
||||
|
||||
/**
|
||||
|
||||
* Set fill radial gradient radius for descriptor
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param cx the x for center of the circle
|
||||
* @param cy the y for center of the circle
|
||||
* @param radius the radius for circle
|
||||
*/
|
||||
void lv_vector_dsc_set_fill_radial_gradient(lv_vector_dsc_t * dsc, float cx, float cy, float radius);
|
||||
|
||||
/**
|
||||
* Set fill radial gradient spread for descriptor
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param spread the gradient spread to be set in lv_vector_gradient_spread_t format
|
||||
*/
|
||||
void lv_vector_dsc_set_fill_gradient_spread(lv_vector_dsc_t * dsc, lv_vector_gradient_spread_t spread);
|
||||
|
||||
/**
|
||||
* Set fill gradient color stops for descriptor
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param stops an array of `lv_gradient_stop_t` variables
|
||||
* @param count the number of stops in the array, range: 0..LV_GRADIENT_MAX_STOPS
|
||||
*/
|
||||
void lv_vector_dsc_set_fill_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_gradient_stop_t * stops,
|
||||
uint16_t count);
|
||||
|
||||
/**
|
||||
* Set a matrix to current fill transformation matrix
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param matrix pointer to a matrix
|
||||
*/
|
||||
void lv_vector_dsc_set_fill_transform(lv_vector_dsc_t * dsc, const lv_matrix_t * matrix);
|
||||
|
||||
/**
|
||||
* Set stroke color for descriptor
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param color the color to be set in lv_color32_t format
|
||||
*/
|
||||
void lv_vector_dsc_set_stroke_color32(lv_vector_dsc_t * dsc, lv_color32_t color);
|
||||
|
||||
/**
|
||||
* Set stroke color for descriptor
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param color the color to be set in lv_color_t format
|
||||
*/
|
||||
void lv_vector_dsc_set_stroke_color(lv_vector_dsc_t * dsc, lv_color_t color);
|
||||
|
||||
/**
|
||||
* Set stroke opacity for descriptor
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param opa the opacity to be set in lv_opa_t format
|
||||
*/
|
||||
void lv_vector_dsc_set_stroke_opa(lv_vector_dsc_t * dsc, lv_opa_t opa);
|
||||
|
||||
/**
|
||||
* Set stroke line width for descriptor
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param width the stroke line width
|
||||
*/
|
||||
void lv_vector_dsc_set_stroke_width(lv_vector_dsc_t * dsc, float width);
|
||||
|
||||
/**
|
||||
* Set stroke line dash pattern for descriptor
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param dash_pattern an array of values that specify the segments of dash line
|
||||
* @param dash_count the length of dash pattern array
|
||||
*/
|
||||
void lv_vector_dsc_set_stroke_dash(lv_vector_dsc_t * dsc, float * dash_pattern, uint16_t dash_count);
|
||||
|
||||
/**
|
||||
* Set stroke line cap style for descriptor
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param cap the line cap to be set in lv_vector_stroke_cap_t format
|
||||
*/
|
||||
void lv_vector_dsc_set_stroke_cap(lv_vector_dsc_t * dsc, lv_vector_stroke_cap_t cap);
|
||||
|
||||
/**
|
||||
* Set stroke line join style for descriptor
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param join the line join to be set in lv_vector_stroke_join_t format
|
||||
*/
|
||||
void lv_vector_dsc_set_stroke_join(lv_vector_dsc_t * dsc, lv_vector_stroke_join_t join);
|
||||
|
||||
/**
|
||||
* Set stroke miter limit for descriptor
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param miter_limit the stroke miter_limit
|
||||
*/
|
||||
void lv_vector_dsc_set_stroke_miter_limit(lv_vector_dsc_t * dsc, uint16_t miter_limit);
|
||||
|
||||
/**
|
||||
* Set stroke linear gradient for descriptor
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param x1 the x for start point
|
||||
* @param y1 the y for start point
|
||||
* @param x2 the x for end point
|
||||
* @param y2 the y for end point
|
||||
*/
|
||||
void lv_vector_dsc_set_stroke_linear_gradient(lv_vector_dsc_t * dsc, float x1, float y1, float x2, float y2);
|
||||
/**
|
||||
* Set stroke radial gradient for descriptor
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param cx the x for center of the circle
|
||||
* @param cy the y for center of the circle
|
||||
* @param radius the radius for circle
|
||||
*/
|
||||
void lv_vector_dsc_set_stroke_radial_gradient(lv_vector_dsc_t * dsc, float cx, float cy, float radius);
|
||||
|
||||
/**
|
||||
* Set stroke color stops for descriptor
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param spread the gradient spread to be set in lv_vector_gradient_spread_t format
|
||||
*/
|
||||
void lv_vector_dsc_set_stroke_gradient_spread(lv_vector_dsc_t * dsc, lv_vector_gradient_spread_t spread);
|
||||
|
||||
/**
|
||||
* Set stroke color stops for descriptor
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param stops an array of `lv_gradient_stop_t` variables
|
||||
* @param count the number of stops in the array
|
||||
*/
|
||||
void lv_vector_dsc_set_stroke_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_gradient_stop_t * stops,
|
||||
uint16_t count);
|
||||
|
||||
/**
|
||||
* Set a matrix to current stroke transformation matrix
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param matrix pointer to a matrix
|
||||
*/
|
||||
void lv_vector_dsc_set_stroke_transform(lv_vector_dsc_t * dsc, const lv_matrix_t * matrix);
|
||||
|
||||
/**
|
||||
* Set current transformation matrix to identity matrix
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
*/
|
||||
void lv_vector_dsc_identity(lv_vector_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Change the scale factor of current transformation matrix
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param scale_x the scale factor for the X direction
|
||||
* @param scale_y the scale factor for the Y direction
|
||||
*/
|
||||
void lv_vector_dsc_scale(lv_vector_dsc_t * dsc, float scale_x, float scale_y);
|
||||
|
||||
/**
|
||||
* Rotate current transformation matrix with origin
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param degree angle to rotate
|
||||
*/
|
||||
void lv_vector_dsc_rotate(lv_vector_dsc_t * dsc, float degree);
|
||||
|
||||
/**
|
||||
* Translate current transformation matrix to new position
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param tx the amount of translate in x direction
|
||||
* @param tx the amount of translate in y direction
|
||||
*/
|
||||
void lv_vector_dsc_translate(lv_vector_dsc_t * dsc, float tx, float ty);
|
||||
|
||||
/**
|
||||
* Change the skew factor of current transformation matrix
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param skew_x the skew factor for x direction
|
||||
* @param skew_y the skew factor for y direction
|
||||
*/
|
||||
void lv_vector_dsc_skew(lv_vector_dsc_t * dsc, float skew_x, float skew_y);
|
||||
|
||||
/**
|
||||
* Add a graphic path to the draw list
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param path pointer to a path
|
||||
*/
|
||||
void lv_vector_dsc_add_path(lv_vector_dsc_t * dsc, const lv_vector_path_t * path);
|
||||
|
||||
/**
|
||||
* Clear a rectangle area use current fill color
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param rect the area to clear in the buffer
|
||||
*/
|
||||
void lv_vector_clear_area(lv_vector_dsc_t * dsc, const lv_area_t * rect);
|
||||
|
||||
/**
|
||||
* Draw all the vector graphic paths
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
*/
|
||||
void lv_draw_vector(lv_vector_dsc_t * dsc);
|
||||
|
||||
/* Traverser for task list */
|
||||
typedef void (*vector_draw_task_cb)(void * ctx, const lv_vector_path_t * path, const lv_vector_draw_dsc_t * dsc);
|
||||
|
||||
#endif /* LV_USE_VECTOR_GRAPHIC */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* LV_DRAW_VECTOR_H */
|
||||
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* @file lv_draw_vector_private.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_VECTOR_PRIVATE_H
|
||||
#define LV_DRAW_VECTOR_PRIVATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_vector.h"
|
||||
|
||||
#if LV_USE_VECTOR_GRAPHIC
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
struct lv_vector_path_t {
|
||||
lv_vector_path_quality_t quality;
|
||||
lv_array_t ops;
|
||||
lv_array_t points;
|
||||
};
|
||||
|
||||
struct lv_vector_gradient_t {
|
||||
lv_vector_gradient_style_t style;
|
||||
lv_gradient_stop_t stops[LV_GRADIENT_MAX_STOPS]; /**< A gradient stop array */
|
||||
uint16_t stops_count; /**< The number of used stops in the array */
|
||||
float x1;
|
||||
float y1;
|
||||
float x2;
|
||||
float y2;
|
||||
float cx;
|
||||
float cy;
|
||||
float cr;
|
||||
lv_vector_gradient_spread_t spread;
|
||||
};
|
||||
|
||||
struct lv_vector_fill_dsc_t {
|
||||
lv_vector_draw_style_t style;
|
||||
lv_color32_t color;
|
||||
lv_opa_t opa;
|
||||
lv_vector_fill_t fill_rule;
|
||||
lv_draw_image_dsc_t img_dsc;
|
||||
lv_vector_gradient_t gradient;
|
||||
lv_matrix_t matrix;
|
||||
};
|
||||
|
||||
struct lv_vector_stroke_dsc_t {
|
||||
lv_vector_draw_style_t style;
|
||||
lv_color32_t color;
|
||||
lv_opa_t opa;
|
||||
float width;
|
||||
lv_array_t dash_pattern;
|
||||
lv_vector_stroke_cap_t cap;
|
||||
lv_vector_stroke_join_t join;
|
||||
uint16_t miter_limit;
|
||||
lv_vector_gradient_t gradient;
|
||||
lv_matrix_t matrix;
|
||||
};
|
||||
|
||||
struct lv_vector_draw_dsc_t {
|
||||
lv_vector_fill_dsc_t fill_dsc;
|
||||
lv_vector_stroke_dsc_t stroke_dsc;
|
||||
lv_matrix_t matrix;
|
||||
lv_vector_blend_t blend_mode;
|
||||
lv_area_t scissor_area;
|
||||
};
|
||||
|
||||
struct lv_draw_vector_task_dsc_t {
|
||||
lv_draw_dsc_base_t base;
|
||||
lv_ll_t * task_list; /*draw task list.*/
|
||||
};
|
||||
|
||||
struct lv_vector_dsc_t {
|
||||
lv_layer_t * layer;
|
||||
lv_vector_draw_dsc_t current_dsc;
|
||||
/* private data */
|
||||
lv_draw_vector_task_dsc_t tasks;
|
||||
};
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
void lv_vector_for_each_destroy_tasks(lv_ll_t * task_list, vector_draw_task_cb cb, void * data);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /* LV_USE_VECTOR_GRAPHIC */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_VECTOR_PRIVATE_H*/
|
||||
415
software/Power_Pico/Middlewares/LVGL/src/draw/lv_image_decoder.c
Normal file
415
software/Power_Pico/Middlewares/LVGL/src/draw/lv_image_decoder.c
Normal file
@@ -0,0 +1,415 @@
|
||||
/**
|
||||
* @file lv_image_decoder.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_image_decoder_private.h"
|
||||
#include "../misc/lv_assert.h"
|
||||
#include "../draw/lv_draw_image.h"
|
||||
#include "../misc/lv_ll.h"
|
||||
#include "../stdlib/lv_string.h"
|
||||
#include "../core/lv_global.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define img_decoder_ll_p &(LV_GLOBAL_DEFAULT()->img_decoder_ll)
|
||||
#define img_cache_p (LV_GLOBAL_DEFAULT()->img_cache)
|
||||
#define img_header_cache_p (LV_GLOBAL_DEFAULT()->img_header_cache)
|
||||
#define image_cache_draw_buf_handlers &(LV_GLOBAL_DEFAULT()->image_cache_draw_buf_handlers)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static uint32_t img_width_to_stride(lv_image_header_t * header);
|
||||
|
||||
/**
|
||||
* Get the header info of an image source, and return the a pointer to the decoder that can open it.
|
||||
* @param dsc Image descriptor containing the source and type of the image and other info.
|
||||
* @param header The header of the image
|
||||
* @return The decoder that can open the image source or NULL if not found (or can't open it).
|
||||
*/
|
||||
static lv_image_decoder_t * image_decoder_get_info(lv_image_decoder_dsc_t * dsc, lv_image_header_t * header);
|
||||
|
||||
static lv_result_t try_cache(lv_image_decoder_dsc_t * dsc);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the image decoder module
|
||||
*/
|
||||
void lv_image_decoder_init(uint32_t image_cache_size, uint32_t image_header_count)
|
||||
{
|
||||
lv_ll_init(img_decoder_ll_p, sizeof(lv_image_decoder_t));
|
||||
|
||||
/*Initialize the cache*/
|
||||
lv_image_cache_init(image_cache_size);
|
||||
lv_image_header_cache_init(image_header_count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deinitialize the image decoder module
|
||||
*/
|
||||
void lv_image_decoder_deinit(void)
|
||||
{
|
||||
lv_cache_destroy(img_cache_p, NULL);
|
||||
lv_cache_destroy(img_header_cache_p, NULL);
|
||||
|
||||
lv_ll_clear(img_decoder_ll_p);
|
||||
}
|
||||
|
||||
lv_result_t lv_image_decoder_get_info(const void * src, lv_image_header_t * header)
|
||||
{
|
||||
lv_image_decoder_dsc_t dsc;
|
||||
lv_memzero(&dsc, sizeof(lv_image_decoder_dsc_t));
|
||||
dsc.src = src;
|
||||
dsc.src_type = lv_image_src_get_type(src);
|
||||
|
||||
lv_image_decoder_t * decoder = image_decoder_get_info(&dsc, header);
|
||||
if(decoder == NULL) return LV_RESULT_INVALID;
|
||||
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
lv_result_t lv_image_decoder_open(lv_image_decoder_dsc_t * dsc, const void * src, const lv_image_decoder_args_t * args)
|
||||
{
|
||||
lv_memzero(dsc, sizeof(lv_image_decoder_dsc_t));
|
||||
|
||||
if(src == NULL) return LV_RESULT_INVALID;
|
||||
dsc->src = src;
|
||||
dsc->src_type = lv_image_src_get_type(src);
|
||||
|
||||
if(lv_image_cache_is_enabled()) {
|
||||
dsc->cache = img_cache_p;
|
||||
/*Try cache first, unless we are told to ignore cache.*/
|
||||
if(!(args && args->no_cache)) {
|
||||
/*
|
||||
* Check the cache first
|
||||
* If the image is found in the cache, just return it.*/
|
||||
if(try_cache(dsc) == LV_RESULT_OK) return LV_RESULT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/*Find the decoder that can open the image source, and get the header info in the same time.*/
|
||||
dsc->decoder = image_decoder_get_info(dsc, &dsc->header);
|
||||
if(dsc->decoder == NULL) return LV_RESULT_INVALID;
|
||||
|
||||
/*Make a copy of args*/
|
||||
dsc->args = args ? *args : (lv_image_decoder_args_t) {
|
||||
.stride_align = LV_DRAW_BUF_STRIDE_ALIGN != 1,
|
||||
.premultiply = false,
|
||||
.no_cache = false,
|
||||
.use_indexed = false,
|
||||
.flush_cache = false,
|
||||
};
|
||||
|
||||
/*
|
||||
* We assume that if a decoder can get the info, it can open the image.
|
||||
* If decoder open failed, free the source and return error.
|
||||
* If decoder open succeed, add the image to cache if enabled.
|
||||
* */
|
||||
lv_result_t res = dsc->decoder->open_cb(dsc->decoder, dsc);
|
||||
|
||||
/* Flush the D-Cache if enabled and the image was successfully opened */
|
||||
if(dsc->args.flush_cache && res == LV_RESULT_OK && dsc->decoded != NULL) {
|
||||
lv_draw_buf_flush_cache(dsc->decoded, NULL);
|
||||
LV_LOG_INFO("Flushed D-cache: src %p (%s) (W%d x H%d, data: %p cf: %d)",
|
||||
src,
|
||||
dsc->src_type == LV_IMAGE_SRC_FILE ? (const char *)src : "c-array",
|
||||
dsc->decoded->header.w,
|
||||
dsc->decoded->header.h,
|
||||
(void *)dsc->decoded->data,
|
||||
dsc->decoded->header.cf);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
lv_result_t lv_image_decoder_get_area(lv_image_decoder_dsc_t * dsc, const lv_area_t * full_area,
|
||||
lv_area_t * decoded_area)
|
||||
{
|
||||
lv_result_t res = LV_RESULT_INVALID;
|
||||
if(dsc->decoder->get_area_cb) res = dsc->decoder->get_area_cb(dsc->decoder, dsc, full_area, decoded_area);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void lv_image_decoder_close(lv_image_decoder_dsc_t * dsc)
|
||||
{
|
||||
if(dsc->decoder) {
|
||||
if(dsc->decoder->close_cb) dsc->decoder->close_cb(dsc->decoder, dsc);
|
||||
|
||||
if(lv_image_cache_is_enabled() && dsc->cache && dsc->cache_entry) {
|
||||
/*Decoded data is in cache, release it from cache's callback*/
|
||||
lv_cache_release(dsc->cache, dsc->cache_entry, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new image decoder
|
||||
* @return pointer to the new image decoder
|
||||
*/
|
||||
lv_image_decoder_t * lv_image_decoder_create(void)
|
||||
{
|
||||
lv_image_decoder_t * decoder;
|
||||
decoder = lv_ll_ins_head(img_decoder_ll_p);
|
||||
LV_ASSERT_MALLOC(decoder);
|
||||
if(decoder == NULL) return NULL;
|
||||
|
||||
lv_memzero(decoder, sizeof(lv_image_decoder_t));
|
||||
|
||||
return decoder;
|
||||
}
|
||||
|
||||
void lv_image_decoder_delete(lv_image_decoder_t * decoder)
|
||||
{
|
||||
lv_ll_remove(img_decoder_ll_p, decoder);
|
||||
lv_free(decoder);
|
||||
}
|
||||
|
||||
lv_image_decoder_t * lv_image_decoder_get_next(lv_image_decoder_t * decoder)
|
||||
{
|
||||
if(decoder == NULL)
|
||||
return lv_ll_get_head(img_decoder_ll_p);
|
||||
else
|
||||
return lv_ll_get_next(img_decoder_ll_p, decoder);
|
||||
}
|
||||
|
||||
void lv_image_decoder_set_info_cb(lv_image_decoder_t * decoder, lv_image_decoder_info_f_t info_cb)
|
||||
{
|
||||
decoder->info_cb = info_cb;
|
||||
}
|
||||
|
||||
void lv_image_decoder_set_open_cb(lv_image_decoder_t * decoder, lv_image_decoder_open_f_t open_cb)
|
||||
{
|
||||
decoder->open_cb = open_cb;
|
||||
}
|
||||
|
||||
void lv_image_decoder_set_get_area_cb(lv_image_decoder_t * decoder, lv_image_decoder_get_area_cb_t get_area_cb)
|
||||
{
|
||||
decoder->get_area_cb = get_area_cb;
|
||||
}
|
||||
|
||||
void lv_image_decoder_set_close_cb(lv_image_decoder_t * decoder, lv_image_decoder_close_f_t close_cb)
|
||||
{
|
||||
decoder->close_cb = close_cb;
|
||||
}
|
||||
|
||||
lv_cache_entry_t * lv_image_decoder_add_to_cache(lv_image_decoder_t * decoder,
|
||||
lv_image_cache_data_t * search_key,
|
||||
const lv_draw_buf_t * decoded, void * user_data)
|
||||
{
|
||||
lv_cache_entry_t * cache_entry = lv_cache_add(img_cache_p, search_key, NULL);
|
||||
if(cache_entry == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_image_cache_data_t * cached_data;
|
||||
cached_data = lv_cache_entry_get_data(cache_entry);
|
||||
|
||||
/*Set the cache entry to decoder data*/
|
||||
cached_data->decoded = decoded;
|
||||
if(cached_data->src_type == LV_IMAGE_SRC_FILE) {
|
||||
cached_data->src = lv_strdup(cached_data->src);
|
||||
}
|
||||
cached_data->user_data = user_data; /*Need to free data on cache invalidate instead of decoder_close*/
|
||||
cached_data->decoder = decoder;
|
||||
|
||||
return cache_entry;
|
||||
}
|
||||
|
||||
lv_draw_buf_t * lv_image_decoder_post_process(lv_image_decoder_dsc_t * dsc, lv_draw_buf_t * decoded)
|
||||
{
|
||||
if(decoded == NULL) return NULL; /*No need to adjust*/
|
||||
|
||||
lv_image_decoder_args_t * args = &dsc->args;
|
||||
if(args->stride_align && decoded->header.cf != LV_COLOR_FORMAT_RGB565A8) {
|
||||
uint32_t stride_expect = lv_draw_buf_width_to_stride(decoded->header.w, decoded->header.cf);
|
||||
if(decoded->header.stride != stride_expect) {
|
||||
LV_LOG_TRACE("Stride mismatch");
|
||||
lv_result_t res = lv_draw_buf_adjust_stride(decoded, stride_expect);
|
||||
if(res != LV_RESULT_OK) {
|
||||
lv_draw_buf_t * aligned = lv_draw_buf_create_ex(image_cache_draw_buf_handlers, decoded->header.w, decoded->header.h,
|
||||
decoded->header.cf, stride_expect);
|
||||
if(aligned == NULL) {
|
||||
LV_LOG_ERROR("No memory for Stride adjust.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_draw_buf_copy(aligned, NULL, decoded, NULL);
|
||||
decoded = aligned;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*Premultiply alpha channel*/
|
||||
if(args->premultiply
|
||||
&& !LV_COLOR_FORMAT_IS_ALPHA_ONLY(decoded->header.cf)
|
||||
&& lv_color_format_has_alpha(decoded->header.cf)
|
||||
&& !lv_draw_buf_has_flag(decoded, LV_IMAGE_FLAGS_PREMULTIPLIED) /*Hasn't done yet*/
|
||||
) {
|
||||
LV_LOG_TRACE("Alpha premultiply.");
|
||||
if(lv_draw_buf_has_flag(decoded, LV_IMAGE_FLAGS_MODIFIABLE)) {
|
||||
/*Do it directly*/
|
||||
lv_draw_buf_premultiply(decoded);
|
||||
}
|
||||
else {
|
||||
decoded = lv_draw_buf_dup_ex(image_cache_draw_buf_handlers, decoded);
|
||||
if(decoded == NULL) {
|
||||
LV_LOG_ERROR("No memory for premultiplying.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_draw_buf_premultiply(decoded);
|
||||
}
|
||||
}
|
||||
|
||||
return decoded;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static lv_image_decoder_t * image_decoder_get_info(lv_image_decoder_dsc_t * dsc, lv_image_header_t * header)
|
||||
{
|
||||
lv_memzero(header, sizeof(lv_image_header_t));
|
||||
|
||||
const void * src = dsc->src;
|
||||
lv_image_src_t src_type = dsc->src_type;
|
||||
|
||||
if(src_type == LV_IMAGE_SRC_VARIABLE) {
|
||||
const lv_image_dsc_t * img_dsc = src;
|
||||
if(img_dsc->data == NULL) return NULL;
|
||||
}
|
||||
|
||||
if(src_type == LV_IMAGE_SRC_FILE) LV_LOG_TRACE("Try to find decoder for %s", (const char *)src);
|
||||
else LV_LOG_TRACE("Try to find decoder for %p", src);
|
||||
|
||||
lv_image_decoder_t * decoder;
|
||||
bool is_header_cache_enabled = lv_image_header_cache_is_enabled();
|
||||
|
||||
if(is_header_cache_enabled && src_type == LV_IMAGE_SRC_FILE) {
|
||||
lv_image_header_cache_data_t search_key;
|
||||
search_key.src_type = src_type;
|
||||
search_key.src = src;
|
||||
|
||||
lv_cache_entry_t * entry = lv_cache_acquire(img_header_cache_p, &search_key, NULL);
|
||||
|
||||
if(entry) {
|
||||
lv_image_header_cache_data_t * cached_data = lv_cache_entry_get_data(entry);
|
||||
*header = cached_data->header;
|
||||
decoder = cached_data->decoder;
|
||||
lv_cache_release(img_header_cache_p, entry, NULL);
|
||||
|
||||
LV_LOG_TRACE("Found decoder %s in header cache", decoder->name);
|
||||
return decoder;
|
||||
}
|
||||
}
|
||||
|
||||
if(src_type == LV_IMAGE_SRC_FILE) {
|
||||
lv_fs_res_t fs_res = lv_fs_open(&dsc->file, src, LV_FS_MODE_RD);
|
||||
if(fs_res != LV_FS_RES_OK) {
|
||||
LV_LOG_ERROR("File open failed: %" LV_PRIu32, (uint32_t)fs_res);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*Search the decoders*/
|
||||
lv_image_decoder_t * decoder_prev = NULL;
|
||||
LV_LL_READ(img_decoder_ll_p, decoder) {
|
||||
/*Info and Open callbacks are required*/
|
||||
if(decoder->info_cb && decoder->open_cb) {
|
||||
lv_fs_seek(&dsc->file, 0, LV_FS_SEEK_SET);
|
||||
lv_result_t res = decoder->info_cb(decoder, dsc, header);
|
||||
|
||||
if(decoder_prev) LV_LOG_TRACE("Can't open image with decoder %s. Trying next decoder.", decoder_prev->name);
|
||||
|
||||
if(res == LV_RESULT_OK) {
|
||||
if(header->stride == 0) {
|
||||
LV_LOG_INFO("Image decoder didn't set stride. Calculate it from width.");
|
||||
header->stride = img_width_to_stride(header);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
decoder_prev = decoder;
|
||||
}
|
||||
}
|
||||
|
||||
if(decoder == NULL) LV_LOG_TRACE("No decoder found");
|
||||
else LV_LOG_TRACE("Found decoder %s", decoder->name);
|
||||
|
||||
if(src_type == LV_IMAGE_SRC_FILE) {
|
||||
lv_fs_close(&dsc->file);
|
||||
}
|
||||
|
||||
if(is_header_cache_enabled && src_type == LV_IMAGE_SRC_FILE && decoder) {
|
||||
lv_cache_entry_t * entry;
|
||||
lv_image_header_cache_data_t search_key;
|
||||
search_key.src_type = src_type;
|
||||
search_key.src = lv_strdup(src);
|
||||
search_key.decoder = decoder;
|
||||
search_key.header = *header;
|
||||
entry = lv_cache_add(img_header_cache_p, &search_key, NULL);
|
||||
|
||||
if(entry == NULL) {
|
||||
if(src_type == LV_IMAGE_SRC_FILE) lv_free((void *)search_key.src);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_cache_release(img_header_cache_p, entry, NULL);
|
||||
}
|
||||
|
||||
return decoder;
|
||||
}
|
||||
|
||||
static uint32_t img_width_to_stride(lv_image_header_t * header)
|
||||
{
|
||||
if(header->cf == LV_COLOR_FORMAT_RGB565A8) {
|
||||
return header->w * 2;
|
||||
}
|
||||
else {
|
||||
return ((uint32_t)header->w * lv_color_format_get_bpp(header->cf) + 7) >> 3;
|
||||
}
|
||||
}
|
||||
|
||||
static lv_result_t try_cache(lv_image_decoder_dsc_t * dsc)
|
||||
{
|
||||
lv_cache_t * cache = dsc->cache;
|
||||
|
||||
lv_image_cache_data_t search_key;
|
||||
search_key.src_type = dsc->src_type;
|
||||
search_key.src = dsc->src;
|
||||
|
||||
lv_cache_entry_t * entry = lv_cache_acquire(cache, &search_key, NULL);
|
||||
|
||||
if(entry) {
|
||||
lv_image_cache_data_t * cached_data = lv_cache_entry_get_data(entry);
|
||||
dsc->decoded = cached_data->decoded;
|
||||
dsc->decoder = (lv_image_decoder_t *)cached_data->decoder;
|
||||
dsc->cache_entry = entry; /*Save the cache to release it in decoder_close*/
|
||||
return LV_RESULT_OK;
|
||||
}
|
||||
|
||||
return LV_RESULT_INVALID;
|
||||
}
|
||||
194
software/Power_Pico/Middlewares/LVGL/src/draw/lv_image_decoder.h
Normal file
194
software/Power_Pico/Middlewares/LVGL/src/draw/lv_image_decoder.h
Normal file
@@ -0,0 +1,194 @@
|
||||
/**
|
||||
* @file lv_image_decoder.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_IMAGE_DECODER_H
|
||||
#define LV_IMAGE_DECODER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_conf_internal.h"
|
||||
|
||||
#include "lv_draw_buf.h"
|
||||
#include "../misc/lv_fs.h"
|
||||
#include "../misc/lv_types.h"
|
||||
#include "../misc/lv_area.h"
|
||||
#include "../misc/cache/lv_cache.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Source of image.*/
|
||||
typedef enum {
|
||||
LV_IMAGE_SRC_VARIABLE, /** Binary/C variable*/
|
||||
LV_IMAGE_SRC_FILE, /** File in filesystem*/
|
||||
LV_IMAGE_SRC_SYMBOL, /** Symbol (@ref lv_symbol_def.h)*/
|
||||
LV_IMAGE_SRC_UNKNOWN, /** Unknown source*/
|
||||
} lv_image_src_t;
|
||||
|
||||
/**
|
||||
* Get info from an image and store in the `header`
|
||||
* @param decoder pointer to decoder object
|
||||
* @param dsc pointer to decoder descriptor
|
||||
* @param header store the info here
|
||||
* @return LV_RESULT_OK: info written correctly; LV_RESULT_INVALID: failed
|
||||
*/
|
||||
typedef lv_result_t (*lv_image_decoder_info_f_t)(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc,
|
||||
lv_image_header_t * header);
|
||||
|
||||
/**
|
||||
* Open an image for decoding. Prepare it as it is required to read it later
|
||||
* @param decoder pointer to the decoder the function associated with
|
||||
* @param dsc pointer to decoder descriptor. `src`, `color` are already initialized in it.
|
||||
*/
|
||||
typedef lv_result_t (*lv_image_decoder_open_f_t)(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Decode `full_area` pixels incrementally by calling in a loop. Set `decoded_area` values to `LV_COORD_MIN` on first call.
|
||||
* Required only if the "open" function can't return with the whole decoded pixel array.
|
||||
* @param decoder pointer to the decoder the function associated with
|
||||
* @param dsc pointer to decoder descriptor
|
||||
* @param full_area input parameter. the full area to decode after enough subsequent calls
|
||||
* @param decoded_area input+output parameter. set the values to `LV_COORD_MIN` for the first call and to reset decoding.
|
||||
* the decoded area is stored here after each call.
|
||||
* @return LV_RESULT_OK: ok; LV_RESULT_INVALID: failed or there is nothing left to decode
|
||||
*/
|
||||
typedef lv_result_t (*lv_image_decoder_get_area_cb_t)(lv_image_decoder_t * decoder,
|
||||
lv_image_decoder_dsc_t * dsc,
|
||||
const lv_area_t * full_area, lv_area_t * decoded_area);
|
||||
|
||||
/**
|
||||
* Close the pending decoding. Free resources etc.
|
||||
* @param decoder pointer to the decoder the function associated with
|
||||
* @param dsc pointer to decoder descriptor
|
||||
*/
|
||||
typedef void (*lv_image_decoder_close_f_t)(lv_image_decoder_t * decoder, lv_image_decoder_dsc_t * dsc);
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Get information about an image.
|
||||
* Try the created image decoder one by one. Once one is able to get info that info will be used.
|
||||
* @param src the image source. Can be
|
||||
* 1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_drv_register()`)
|
||||
* 2) Variable: Pointer to an `lv_image_dsc_t` variable
|
||||
* 3) Symbol: E.g. `LV_SYMBOL_OK`
|
||||
* @param header the image info will be stored here
|
||||
* @return LV_RESULT_OK: success; LV_RESULT_INVALID: wasn't able to get info about the image
|
||||
*/
|
||||
lv_result_t lv_image_decoder_get_info(const void * src, lv_image_header_t * header);
|
||||
|
||||
/**
|
||||
* Open an image.
|
||||
* Try the created image decoders one by one. Once one is able to open the image that decoder is saved in `dsc`
|
||||
* @param dsc describes a decoding session. Simply a pointer to an `lv_image_decoder_dsc_t` variable.
|
||||
* @param src the image source. Can be
|
||||
* 1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_drv_register())`)
|
||||
* 2) Variable: Pointer to an `lv_image_dsc_t` variable
|
||||
* 3) Symbol: E.g. `LV_SYMBOL_OK`
|
||||
* @param args args about how the image should be opened.
|
||||
* @return LV_RESULT_OK: opened the image. `dsc->decoded` and `dsc->header` are set.
|
||||
* LV_RESULT_INVALID: none of the registered image decoders were able to open the image.
|
||||
*/
|
||||
lv_result_t lv_image_decoder_open(lv_image_decoder_dsc_t * dsc, const void * src, const lv_image_decoder_args_t * args);
|
||||
|
||||
/**
|
||||
* Decode `full_area` pixels incrementally by calling in a loop. Set `decoded_area` to `LV_COORD_MIN` on first call.
|
||||
* @param dsc image decoder descriptor
|
||||
* @param full_area input parameter. the full area to decode after enough subsequent calls
|
||||
* @param decoded_area input+output parameter. set the values to `LV_COORD_MIN` for the first call and to reset decoding.
|
||||
* the decoded area is stored here after each call.
|
||||
* @return LV_RESULT_OK: success; LV_RESULT_INVALID: an error occurred or there is nothing left to decode
|
||||
*/
|
||||
lv_result_t lv_image_decoder_get_area(lv_image_decoder_dsc_t * dsc, const lv_area_t * full_area,
|
||||
lv_area_t * decoded_area);
|
||||
|
||||
/**
|
||||
* Close a decoding session
|
||||
* @param dsc pointer to `lv_image_decoder_dsc_t` used in `lv_image_decoder_open`
|
||||
*/
|
||||
void lv_image_decoder_close(lv_image_decoder_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Create a new image decoder
|
||||
* @return pointer to the new image decoder
|
||||
*/
|
||||
lv_image_decoder_t * lv_image_decoder_create(void);
|
||||
|
||||
/**
|
||||
* Delete an image decoder
|
||||
* @param decoder pointer to an image decoder
|
||||
*/
|
||||
void lv_image_decoder_delete(lv_image_decoder_t * decoder);
|
||||
|
||||
/**
|
||||
* Get the next image decoder in the linked list of image decoders
|
||||
* @param decoder pointer to an image decoder or NULL to get the first one
|
||||
* @return the next image decoder or NULL if no more image decoder exists
|
||||
*/
|
||||
lv_image_decoder_t * lv_image_decoder_get_next(lv_image_decoder_t * decoder);
|
||||
|
||||
/**
|
||||
* Set a callback to get information about the image
|
||||
* @param decoder pointer to an image decoder
|
||||
* @param info_cb a function to collect info about an image (fill an `lv_image_header_t` struct)
|
||||
*/
|
||||
void lv_image_decoder_set_info_cb(lv_image_decoder_t * decoder, lv_image_decoder_info_f_t info_cb);
|
||||
|
||||
/**
|
||||
* Set a callback to open an image
|
||||
* @param decoder pointer to an image decoder
|
||||
* @param open_cb a function to open an image
|
||||
*/
|
||||
void lv_image_decoder_set_open_cb(lv_image_decoder_t * decoder, lv_image_decoder_open_f_t open_cb);
|
||||
|
||||
/**
|
||||
* Set a callback to a decoded line of an image
|
||||
* @param decoder pointer to an image decoder
|
||||
* @param read_line_cb a function to read a line of an image
|
||||
*/
|
||||
void lv_image_decoder_set_get_area_cb(lv_image_decoder_t * decoder, lv_image_decoder_get_area_cb_t read_line_cb);
|
||||
|
||||
/**
|
||||
* Set a callback to close a decoding session. E.g. close files and free other resources.
|
||||
* @param decoder pointer to an image decoder
|
||||
* @param close_cb a function to close a decoding session
|
||||
*/
|
||||
void lv_image_decoder_set_close_cb(lv_image_decoder_t * decoder, lv_image_decoder_close_f_t close_cb);
|
||||
|
||||
lv_cache_entry_t * lv_image_decoder_add_to_cache(lv_image_decoder_t * decoder,
|
||||
lv_image_cache_data_t * search_key,
|
||||
const lv_draw_buf_t * decoded, void * user_data);
|
||||
|
||||
/**
|
||||
* Check the decoded image, make any modification if decoder `args` requires.
|
||||
* @note A new draw buf will be allocated if provided `decoded` is not modifiable or stride mismatch etc.
|
||||
* @param dsc pointer to a decoder descriptor
|
||||
* @param decoded pointer to a decoded image to post process to meet dsc->args requirement.
|
||||
* @return post processed draw buffer, when it differs with `decoded`, it's newly allocated.
|
||||
*/
|
||||
lv_draw_buf_t * lv_image_decoder_post_process(lv_image_decoder_dsc_t * dsc, lv_draw_buf_t * decoded);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_IMAGE_DECODER_H*/
|
||||
@@ -0,0 +1,142 @@
|
||||
/**
|
||||
* @file lv_image_decoder_private.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_IMAGE_DECODER_PRIVATE_H
|
||||
#define LV_IMAGE_DECODER_PRIVATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_image_decoder.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Image decoder args.
|
||||
* It determines how to decoder an image, e.g. whether to premultiply the alpha or not.
|
||||
* It should be passed to lv_img_decoder_open() function. If NULL is provided, default
|
||||
* args are used.
|
||||
*
|
||||
* Default args:
|
||||
* all field are zero or false.
|
||||
*/
|
||||
struct lv_image_decoder_args_t {
|
||||
bool stride_align; /**< Whether stride should be aligned */
|
||||
bool premultiply; /**< Whether image should be premultiplied or not after decoding */
|
||||
bool no_cache; /**< When set, decoded image won't be put to cache, and decoder open will also ignore cache. */
|
||||
bool use_indexed; /**< Decoded indexed image as is. Convert to ARGB8888 if false. */
|
||||
bool flush_cache; /**< Whether to flush the data cache after decoding */
|
||||
};
|
||||
|
||||
struct lv_image_decoder_t {
|
||||
lv_image_decoder_info_f_t info_cb;
|
||||
lv_image_decoder_open_f_t open_cb;
|
||||
lv_image_decoder_get_area_cb_t get_area_cb;
|
||||
lv_image_decoder_close_f_t close_cb;
|
||||
|
||||
const char * name;
|
||||
|
||||
void * user_data;
|
||||
};
|
||||
|
||||
struct lv_image_cache_data_t {
|
||||
lv_cache_slot_size_t slot;
|
||||
|
||||
const void * src;
|
||||
lv_image_src_t src_type;
|
||||
|
||||
const lv_draw_buf_t * decoded;
|
||||
const lv_image_decoder_t * decoder;
|
||||
void * user_data;
|
||||
};
|
||||
|
||||
struct lv_image_header_cache_data_t {
|
||||
const void * src;
|
||||
lv_image_src_t src_type;
|
||||
|
||||
lv_image_header_t header;
|
||||
lv_image_decoder_t * decoder;
|
||||
};
|
||||
|
||||
/**Describe an image decoding session. Stores data about the decoding*/
|
||||
struct lv_image_decoder_dsc_t {
|
||||
/**The decoder which was able to open the image source*/
|
||||
lv_image_decoder_t * decoder;
|
||||
|
||||
/**A copy of parameters of how this image is decoded*/
|
||||
lv_image_decoder_args_t args;
|
||||
|
||||
/**The image source. A file path like "S:my_img.png" or pointer to an `lv_image_dsc_t` variable*/
|
||||
const void * src;
|
||||
|
||||
/**Type of the source: file or variable. Can be set in `open` function if required*/
|
||||
lv_image_src_t src_type;
|
||||
|
||||
lv_fs_file_t file;
|
||||
|
||||
/**Info about the opened image: color format, size, etc. MUST be set in `open` function*/
|
||||
lv_image_header_t header;
|
||||
|
||||
/** Pointer to a draw buffer where the image's data (pixels) are stored in a decoded, plain format.
|
||||
* MUST be set in `open` or `get_area_cb`function*/
|
||||
const lv_draw_buf_t * decoded;
|
||||
|
||||
const lv_color32_t * palette;
|
||||
uint32_t palette_size;
|
||||
|
||||
/** How much time did it take to open the image. [ms]
|
||||
* If not set `lv_image_cache` will measure and set the time to open*/
|
||||
uint32_t time_to_open;
|
||||
|
||||
/**A text to display instead of the image when the image can't be opened.
|
||||
* Can be set in `open` function or set NULL.*/
|
||||
const char * error_msg;
|
||||
|
||||
lv_cache_t * cache;
|
||||
|
||||
/**Point to cache entry information*/
|
||||
lv_cache_entry_t * cache_entry;
|
||||
|
||||
/**Store any custom data here is required*/
|
||||
void * user_data;
|
||||
};
|
||||
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the image decoder module
|
||||
* @param image_cache_size Image cache size in bytes. 0 to disable cache.
|
||||
* @param image_header_count Number of header cache entries. 0 to disable header cache.
|
||||
*/
|
||||
void lv_image_decoder_init(uint32_t image_cache_size, uint32_t image_header_count);
|
||||
|
||||
/**
|
||||
* Deinitialize the image decoder module
|
||||
*/
|
||||
void lv_image_decoder_deinit(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_IMAGE_DECODER_PRIVATE_H*/
|
||||
141
software/Power_Pico/Middlewares/LVGL/src/draw/lv_image_dsc.h
Normal file
141
software/Power_Pico/Middlewares/LVGL/src/draw/lv_image_dsc.h
Normal file
@@ -0,0 +1,141 @@
|
||||
/**
|
||||
* @file lv_image_dsc.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_IMAGE_DSC_H
|
||||
#define LV_IMAGE_DSC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lv_conf_internal.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/** Magic number for lvgl image, 9 means lvgl version 9
|
||||
* It must be neither a valid ASCII character nor larger than 0x80. See `lv_image_src_get_type`.
|
||||
*/
|
||||
#define LV_IMAGE_HEADER_MAGIC (0x19)
|
||||
LV_EXPORT_CONST_INT(LV_IMAGE_HEADER_MAGIC);
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef enum lv_image_flags_t {
|
||||
/**
|
||||
* For RGB map of the image data, mark if it's pre-multiplied with alpha.
|
||||
* For indexed image, this bit indicated palette data is pre-multiplied with alpha.
|
||||
*/
|
||||
LV_IMAGE_FLAGS_PREMULTIPLIED = 0x0001,
|
||||
/**
|
||||
* The image data is compressed, so decoder needs to decode image firstly.
|
||||
* If this flag is set, the whole image will be decompressed upon decode, and
|
||||
* `get_area_cb` won't be necessary.
|
||||
*/
|
||||
LV_IMAGE_FLAGS_COMPRESSED = 0x0008,
|
||||
|
||||
/*Below flags are applicable only for draw buffer header.*/
|
||||
|
||||
/**
|
||||
* The image is allocated from heap, thus should be freed after use.
|
||||
*/
|
||||
LV_IMAGE_FLAGS_ALLOCATED = 0x0010,
|
||||
|
||||
/**
|
||||
* If the image data is malloced and can be processed in place.
|
||||
* In image decoder post processing, this flag means we modify it in-place.
|
||||
*/
|
||||
LV_IMAGE_FLAGS_MODIFIABLE = 0x0020,
|
||||
|
||||
/**
|
||||
* Flags reserved for user, lvgl won't use these bits.
|
||||
*/
|
||||
LV_IMAGE_FLAGS_USER1 = 0x0100,
|
||||
LV_IMAGE_FLAGS_USER2 = 0x0200,
|
||||
LV_IMAGE_FLAGS_USER3 = 0x0400,
|
||||
LV_IMAGE_FLAGS_USER4 = 0x0800,
|
||||
LV_IMAGE_FLAGS_USER5 = 0x1000,
|
||||
LV_IMAGE_FLAGS_USER6 = 0x2000,
|
||||
LV_IMAGE_FLAGS_USER7 = 0x4000,
|
||||
LV_IMAGE_FLAGS_USER8 = 0x8000,
|
||||
} lv_image_flags_t;
|
||||
|
||||
typedef enum {
|
||||
LV_IMAGE_COMPRESS_NONE = 0,
|
||||
LV_IMAGE_COMPRESS_RLE, /**< LVGL custom RLE compression */
|
||||
LV_IMAGE_COMPRESS_LZ4,
|
||||
} lv_image_compress_t;
|
||||
|
||||
#if LV_BIG_ENDIAN_SYSTEM
|
||||
typedef struct {
|
||||
uint32_t reserved_2: 16; /**< Reserved to be used later*/
|
||||
uint32_t stride: 16; /**< Number of bytes in a row*/
|
||||
uint32_t h: 16;
|
||||
uint32_t w: 16;
|
||||
uint32_t flags: 16; /**< Image flags, see `lv_image_flags_t`*/
|
||||
uint32_t cf : 8; /**< Color format: See `lv_color_format_t`*/
|
||||
uint32_t magic: 8; /**< Magic number. Must be LV_IMAGE_HEADER_MAGIC*/
|
||||
} lv_image_header_t;
|
||||
#else
|
||||
typedef struct {
|
||||
uint32_t magic: 8; /**< Magic number. Must be LV_IMAGE_HEADER_MAGIC*/
|
||||
uint32_t cf : 8; /**< Color format: See `lv_color_format_t`*/
|
||||
uint32_t flags: 16; /**< Image flags, see `lv_image_flags_t`*/
|
||||
|
||||
uint32_t w: 16;
|
||||
uint32_t h: 16;
|
||||
uint32_t stride: 16; /**< Number of bytes in a row*/
|
||||
uint32_t reserved_2: 16; /**< Reserved to be used later*/
|
||||
} lv_image_header_t;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
void * buf;
|
||||
uint32_t stride; /**< Number of bytes in a row*/
|
||||
} lv_yuv_plane_t;
|
||||
|
||||
typedef union {
|
||||
lv_yuv_plane_t yuv; /**< packed format*/
|
||||
struct {
|
||||
lv_yuv_plane_t y;
|
||||
lv_yuv_plane_t u;
|
||||
lv_yuv_plane_t v;
|
||||
} planar; /**< planar format with 3 plane*/
|
||||
struct {
|
||||
lv_yuv_plane_t y;
|
||||
lv_yuv_plane_t uv;
|
||||
} semi_planar; /**< planar format with 2 plane*/
|
||||
} lv_yuv_buf_t;
|
||||
|
||||
/**
|
||||
* Struct to describe a constant image resource.
|
||||
* It's similar to lv_draw_buf_t, but the data is constant.
|
||||
*/
|
||||
typedef struct {
|
||||
lv_image_header_t header; /**< A header describing the basics of the image*/
|
||||
uint32_t data_size; /**< Size of the image in bytes*/
|
||||
const uint8_t * data; /**< Pointer to the data of the image*/
|
||||
const void * reserved; /**< A reserved field to make it has same size as lv_draw_buf_t*/
|
||||
} lv_image_dsc_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_IMAGE_DSC_H*/
|
||||
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* @file lv_draw_buf_pxp.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2023-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#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"
|
||||
#include "lv_pxp_utils.h"
|
||||
|
||||
#include "lvgl_support.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area)
|
||||
{
|
||||
const lv_image_header_t * header = &draw_buf->header;
|
||||
uint32_t stride = header->stride;
|
||||
lv_color_format_t cf = header->cf;
|
||||
|
||||
if(area->y1 == 0) {
|
||||
uint32_t size = stride * lv_area_get_height(area);
|
||||
|
||||
/* Invalidate full buffer. */
|
||||
DEMO_CleanInvalidateCacheByAddr((void *)draw_buf->data, size);
|
||||
return;
|
||||
}
|
||||
|
||||
const uint8_t * buf_u8 = draw_buf->data;
|
||||
/* ARM require a 32 byte aligned address. */
|
||||
uint8_t align_bytes = 32;
|
||||
uint8_t bits_per_pixel = lv_color_format_get_bpp(cf);
|
||||
|
||||
uint16_t align_pixels = align_bytes * 8 / bits_per_pixel;
|
||||
uint16_t offset_x = 0;
|
||||
|
||||
if(area->x1 >= (int32_t)(area->x1 % align_pixels)) {
|
||||
uint16_t shift_x = area->x1 - (area->x1 % align_pixels);
|
||||
|
||||
offset_x = area->x1 - shift_x;
|
||||
buf_u8 += (shift_x * bits_per_pixel) / 8;
|
||||
}
|
||||
|
||||
if(area->y1) {
|
||||
uint16_t shift_y = area->y1;
|
||||
|
||||
buf_u8 += shift_y * stride;
|
||||
}
|
||||
|
||||
/* Area to clear can start from a different offset in buffer.
|
||||
* Invalidate the area line by line.
|
||||
*/
|
||||
uint16_t line_pixels = offset_x + lv_area_get_width(area);
|
||||
uint16_t line_size = (line_pixels * bits_per_pixel) / 8;
|
||||
uint16_t area_height = lv_area_get_height(area);
|
||||
|
||||
for(uint16_t y = 0; y < area_height; y++) {
|
||||
const void * line_addr = buf_u8 + y * stride;
|
||||
|
||||
DEMO_CleanInvalidateCacheByAddr((void *)line_addr, line_size);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DRAW_PXP*/
|
||||
#endif /*LV_USE_PXP*/
|
||||
@@ -0,0 +1,498 @@
|
||||
/**
|
||||
* @file lv_draw_pxp.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2022-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_pxp.h"
|
||||
|
||||
#if LV_USE_PXP
|
||||
#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP
|
||||
#include "lv_pxp_cfg.h"
|
||||
#include "lv_pxp_utils.h"
|
||||
|
||||
#if LV_USE_PARALLEL_DRAW_DEBUG
|
||||
#include "../../../core/lv_global.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define DRAW_UNIT_ID_PXP 3
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/*
|
||||
* Evaluate a task and set the score and preferred PXP unit.
|
||||
* Return 1 if task is preferred, 0 otherwise (task is not supported).
|
||||
*/
|
||||
static int32_t _pxp_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task);
|
||||
|
||||
/*
|
||||
* Dispatch a task to the PXP unit.
|
||||
* Return 1 if task was dispatched, 0 otherwise (task not supported).
|
||||
*/
|
||||
static int32_t _pxp_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer);
|
||||
|
||||
/*
|
||||
* Delete the PXP draw unit.
|
||||
*/
|
||||
static int32_t _pxp_delete(lv_draw_unit_t * draw_unit);
|
||||
|
||||
#if LV_USE_PXP_DRAW_THREAD
|
||||
static void _pxp_render_thread_cb(void * ptr);
|
||||
#endif
|
||||
|
||||
static void _pxp_execute_drawing(lv_draw_pxp_unit_t * u);
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
#if LV_USE_PARALLEL_DRAW_DEBUG
|
||||
#define _draw_info LV_GLOBAL_DEFAULT()->draw_info
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
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));
|
||||
draw_pxp_unit->base_unit.evaluate_cb = _pxp_evaluate;
|
||||
draw_pxp_unit->base_unit.dispatch_cb = _pxp_dispatch;
|
||||
draw_pxp_unit->base_unit.delete_cb = _pxp_delete;
|
||||
|
||||
#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)
|
||||
{
|
||||
lv_pxp_deinit();
|
||||
}
|
||||
|
||||
void lv_draw_pxp_rotate(const void * src_buf, void * dest_buf, int32_t src_width, int32_t src_height,
|
||||
int32_t src_stride, int32_t dest_stride, lv_display_rotation_t rotation,
|
||||
lv_color_format_t cf)
|
||||
{
|
||||
lv_pxp_reset();
|
||||
|
||||
/* 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_270:
|
||||
pxp_rotation = kPXP_Rotate90;
|
||||
break;
|
||||
case LV_DISPLAY_ROTATION_180:
|
||||
pxp_rotation = kPXP_Rotate180;
|
||||
break;
|
||||
case LV_DISPLAY_ROTATION_90:
|
||||
pxp_rotation = kPXP_Rotate270;
|
||||
break;
|
||||
default:
|
||||
pxp_rotation = kPXP_Rotate0;
|
||||
break;
|
||||
}
|
||||
PXP_SetRotateConfig(PXP_ID, kPXP_RotateOutputBuffer, pxp_rotation, kPXP_FlipDisable);
|
||||
|
||||
/*Simple blit, no effect - Disable PS buffer*/
|
||||
PXP_SetProcessSurfacePosition(PXP_ID, 0xFFFFU, 0xFFFFU, 0U, 0U);
|
||||
|
||||
/*AS buffer - source image*/
|
||||
pxp_as_buffer_config_t asBufferConfig = {
|
||||
.pixelFormat = pxp_get_as_px_format(cf),
|
||||
.bufferAddr = (uint32_t)src_buf,
|
||||
.pitchBytes = src_stride
|
||||
};
|
||||
PXP_SetAlphaSurfaceBufferConfig(PXP_ID, &asBufferConfig);
|
||||
PXP_SetAlphaSurfacePosition(PXP_ID, 0U, 0U, src_width - 1U, src_height - 1U);
|
||||
PXP_EnableAlphaSurfaceOverlayColorKey(PXP_ID, false);
|
||||
|
||||
/*Output buffer.*/
|
||||
pxp_output_buffer_config_t outputBufferConfig = {
|
||||
.pixelFormat = pxp_get_out_px_format(cf),
|
||||
.interlacedMode = kPXP_OutputProgressive,
|
||||
.buffer0Addr = (uint32_t)dest_buf,
|
||||
.buffer1Addr = (uint32_t)0U,
|
||||
.pitchBytes = dest_stride,
|
||||
.width = src_width,
|
||||
.height = src_height
|
||||
};
|
||||
PXP_SetOutputBufferConfig(PXP_ID, &outputBufferConfig);
|
||||
|
||||
lv_pxp_run();
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
#if LV_USE_DRAW_PXP
|
||||
static inline bool _pxp_src_cf_supported(lv_color_format_t cf)
|
||||
{
|
||||
bool is_cf_supported = false;
|
||||
|
||||
switch(cf) {
|
||||
case LV_COLOR_FORMAT_RGB565:
|
||||
case LV_COLOR_FORMAT_ARGB8888:
|
||||
case LV_COLOR_FORMAT_XRGB8888:
|
||||
is_cf_supported = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return is_cf_supported;
|
||||
}
|
||||
|
||||
static inline bool _pxp_dest_cf_supported(lv_color_format_t cf)
|
||||
{
|
||||
bool is_cf_supported = false;
|
||||
|
||||
switch(cf) {
|
||||
case LV_COLOR_FORMAT_RGB565:
|
||||
case LV_COLOR_FORMAT_RGB888:
|
||||
case LV_COLOR_FORMAT_ARGB8888:
|
||||
case LV_COLOR_FORMAT_XRGB8888:
|
||||
is_cf_supported = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return is_cf_supported;
|
||||
}
|
||||
|
||||
static bool _pxp_draw_img_supported(const lv_draw_image_dsc_t * draw_dsc)
|
||||
{
|
||||
const lv_image_dsc_t * img_dsc = draw_dsc->src;
|
||||
|
||||
bool has_recolor = (draw_dsc->recolor_opa > LV_OPA_MIN);
|
||||
bool has_transform = (draw_dsc->rotation != 0 || draw_dsc->scale_x != LV_SCALE_NONE ||
|
||||
draw_dsc->scale_y != LV_SCALE_NONE);
|
||||
|
||||
/* Recolor and transformation are not supported at the same time. */
|
||||
if(has_recolor && has_transform)
|
||||
return false;
|
||||
|
||||
bool has_opa = (draw_dsc->opa < (lv_opa_t)LV_OPA_MAX);
|
||||
bool src_has_alpha = (img_dsc->header.cf == LV_COLOR_FORMAT_ARGB8888);
|
||||
|
||||
/*
|
||||
* Recolor or transformation for images w/ opa or alpha channel can't
|
||||
* be obtained in a single PXP configuration. Two steps are required.
|
||||
*/
|
||||
if((has_recolor || has_transform) && (has_opa || src_has_alpha))
|
||||
return false;
|
||||
|
||||
/* PXP can only rotate at 90x angles. */
|
||||
if(draw_dsc->rotation % 900)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* PXP is set to process 16x16 blocks to optimize the system for memory
|
||||
* bandwidth and image processing time.
|
||||
* The output engine essentially truncates any output pixels after the
|
||||
* desired number of pixels has been written.
|
||||
* When rotating a source image and the output is not divisible by the block
|
||||
* size, the incorrect pixels could be truncated and the final output image
|
||||
* can look shifted.
|
||||
*
|
||||
* No combination of rotate with flip, scaling or decimation is possible
|
||||
* if buffer is unaligned.
|
||||
*/
|
||||
if(has_transform && (img_dsc->header.w % 16 || img_dsc->header.h % 16))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int32_t _pxp_evaluate(lv_draw_unit_t * u, lv_draw_task_t * t)
|
||||
{
|
||||
LV_UNUSED(u);
|
||||
|
||||
const lv_draw_dsc_base_t * draw_dsc_base = (lv_draw_dsc_base_t *) t->draw_dsc;
|
||||
|
||||
if(!_pxp_dest_cf_supported(draw_dsc_base->layer->color_format))
|
||||
return 0;
|
||||
|
||||
switch(t->type) {
|
||||
case LV_DRAW_TASK_TYPE_FILL: {
|
||||
const lv_draw_fill_dsc_t * draw_dsc = (lv_draw_fill_dsc_t *) t->draw_dsc;
|
||||
|
||||
/* Most simple case: just a plain rectangle (no radius, no gradient). */
|
||||
if((draw_dsc->radius != 0) || (draw_dsc->grad.dir != (lv_grad_dir_t)LV_GRAD_DIR_NONE))
|
||||
return 0;
|
||||
|
||||
if(t->preference_score > 70) {
|
||||
t->preference_score = 70;
|
||||
t->preferred_draw_unit_id = DRAW_UNIT_ID_PXP;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
case LV_DRAW_TASK_TYPE_LAYER: {
|
||||
const lv_draw_image_dsc_t * draw_dsc = (lv_draw_image_dsc_t *) t->draw_dsc;
|
||||
lv_layer_t * layer_to_draw = (lv_layer_t *)draw_dsc->src;
|
||||
|
||||
if(!_pxp_src_cf_supported(layer_to_draw->color_format))
|
||||
return 0;
|
||||
|
||||
if(!_pxp_draw_img_supported(draw_dsc))
|
||||
return 0;
|
||||
|
||||
if(t->preference_score > 70) {
|
||||
t->preference_score = 70;
|
||||
t->preferred_draw_unit_id = DRAW_UNIT_ID_PXP;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
case LV_DRAW_TASK_TYPE_IMAGE: {
|
||||
lv_draw_image_dsc_t * draw_dsc = (lv_draw_image_dsc_t *) t->draw_dsc;
|
||||
const lv_image_dsc_t * img_dsc = draw_dsc->src;
|
||||
|
||||
if(draw_dsc->tile)
|
||||
return 0;
|
||||
|
||||
if((!_pxp_src_cf_supported(img_dsc->header.cf)) ||
|
||||
(!pxp_buf_aligned(img_dsc->data, img_dsc->header.stride)))
|
||||
return 0;
|
||||
|
||||
if(!_pxp_draw_img_supported(draw_dsc))
|
||||
return 0;
|
||||
|
||||
if(t->preference_score > 70) {
|
||||
t->preference_score = 70;
|
||||
t->preferred_draw_unit_id = DRAW_UNIT_ID_PXP;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t _pxp_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer)
|
||||
{
|
||||
lv_draw_pxp_unit_t * draw_pxp_unit = (lv_draw_pxp_unit_t *) draw_unit;
|
||||
|
||||
/* Return immediately if it's busy with draw task. */
|
||||
if(draw_pxp_unit->task_act)
|
||||
return 0;
|
||||
|
||||
/* Try to get an ready to draw. */
|
||||
lv_draw_task_t * t = lv_draw_get_next_available_task(layer, NULL, DRAW_UNIT_ID_PXP);
|
||||
|
||||
if(t == NULL || t->preferred_draw_unit_id != DRAW_UNIT_ID_PXP)
|
||||
return LV_DRAW_UNIT_IDLE;
|
||||
|
||||
if(lv_draw_layer_alloc_buf(layer) == NULL)
|
||||
return LV_DRAW_UNIT_IDLE;
|
||||
|
||||
t->state = LV_DRAW_TASK_STATE_IN_PROGRESS;
|
||||
draw_pxp_unit->base_unit.target_layer = layer;
|
||||
draw_pxp_unit->base_unit.clip_area = &t->clip_area;
|
||||
draw_pxp_unit->task_act = t;
|
||||
|
||||
#if LV_USE_PXP_DRAW_THREAD
|
||||
/* Let the render thread work. */
|
||||
if(draw_pxp_unit->inited)
|
||||
lv_thread_sync_signal(&draw_pxp_unit->sync);
|
||||
#else
|
||||
_pxp_execute_drawing(draw_pxp_unit);
|
||||
|
||||
draw_pxp_unit->task_act->state = LV_DRAW_TASK_STATE_READY;
|
||||
draw_pxp_unit->task_act = NULL;
|
||||
|
||||
/* The draw unit is free now. Request a new dispatching as it can get a new task. */
|
||||
lv_draw_dispatch_request();
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int32_t _pxp_delete(lv_draw_unit_t * draw_unit)
|
||||
{
|
||||
#if LV_USE_PXP_DRAW_THREAD
|
||||
lv_draw_pxp_unit_t * draw_pxp_unit = (lv_draw_pxp_unit_t *) draw_unit;
|
||||
|
||||
LV_LOG_INFO("Cancel PXP draw thread.");
|
||||
draw_pxp_unit->exit_status = true;
|
||||
|
||||
if(draw_pxp_unit->inited)
|
||||
lv_thread_sync_signal(&draw_pxp_unit->sync);
|
||||
|
||||
lv_result_t res = lv_thread_delete(&draw_pxp_unit->thread);
|
||||
|
||||
return res;
|
||||
#else
|
||||
LV_UNUSED(draw_unit);
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void _pxp_execute_drawing(lv_draw_pxp_unit_t * u)
|
||||
{
|
||||
lv_draw_task_t * t = u->task_act;
|
||||
lv_draw_unit_t * draw_unit = (lv_draw_unit_t *)u;
|
||||
lv_layer_t * layer = draw_unit->target_layer;
|
||||
lv_draw_buf_t * draw_buf = layer->draw_buf;
|
||||
|
||||
lv_area_t draw_area;
|
||||
if(!lv_area_intersect(&draw_area, &t->area, draw_unit->clip_area))
|
||||
return; /*Fully clipped, nothing to do*/
|
||||
|
||||
/* Make area relative to the buffer */
|
||||
lv_area_move(&draw_area, -layer->buf_area.x1, -layer->buf_area.y1);
|
||||
|
||||
/* Invalidate only the drawing area */
|
||||
lv_draw_buf_invalidate_cache(draw_buf, &draw_area);
|
||||
|
||||
switch(t->type) {
|
||||
case LV_DRAW_TASK_TYPE_FILL:
|
||||
lv_draw_pxp_fill(draw_unit, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_IMAGE:
|
||||
lv_draw_pxp_img(draw_unit, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_LAYER:
|
||||
lv_draw_pxp_layer(draw_unit, t->draw_dsc, &t->area);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#if LV_USE_PARALLEL_DRAW_DEBUG
|
||||
/*Layers manage it for themselves*/
|
||||
if(t->type != LV_DRAW_TASK_TYPE_LAYER) {
|
||||
lv_area_t draw_area;
|
||||
if(!lv_area_intersect(&draw_area, &t->area, u->base_unit.clip_area))
|
||||
return;
|
||||
|
||||
int32_t idx = 0;
|
||||
lv_draw_unit_t * draw_unit_tmp = _draw_info.unit_head;
|
||||
while(draw_unit_tmp != (lv_draw_unit_t *)u) {
|
||||
draw_unit_tmp = draw_unit_tmp->next;
|
||||
idx++;
|
||||
}
|
||||
lv_draw_rect_dsc_t rect_dsc;
|
||||
lv_draw_rect_dsc_init(&rect_dsc);
|
||||
rect_dsc.bg_color = lv_palette_main(idx % LV_PALETTE_LAST);
|
||||
rect_dsc.border_color = rect_dsc.bg_color;
|
||||
rect_dsc.bg_opa = LV_OPA_10;
|
||||
rect_dsc.border_opa = LV_OPA_80;
|
||||
rect_dsc.border_width = 1;
|
||||
lv_draw_sw_fill((lv_draw_unit_t *)u, &rect_dsc, &draw_area);
|
||||
|
||||
lv_point_t txt_size;
|
||||
lv_text_get_size(&txt_size, "W", LV_FONT_DEFAULT, 0, 0, 100, LV_TEXT_FLAG_NONE);
|
||||
|
||||
lv_area_t txt_area;
|
||||
txt_area.x1 = draw_area.x1;
|
||||
txt_area.y1 = draw_area.y1;
|
||||
txt_area.x2 = draw_area.x1 + txt_size.x - 1;
|
||||
txt_area.y2 = draw_area.y1 + txt_size.y - 1;
|
||||
|
||||
lv_draw_rect_dsc_init(&rect_dsc);
|
||||
rect_dsc.bg_color = lv_color_white();
|
||||
lv_draw_sw_fill((lv_draw_unit_t *)u, &rect_dsc, &txt_area);
|
||||
|
||||
char buf[8];
|
||||
lv_snprintf(buf, sizeof(buf), "%d", idx);
|
||||
lv_draw_label_dsc_t label_dsc;
|
||||
lv_draw_label_dsc_init(&label_dsc);
|
||||
label_dsc.color = lv_color_black();
|
||||
label_dsc.text = buf;
|
||||
lv_draw_sw_label((lv_draw_unit_t *)u, &label_dsc, &txt_area);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if LV_USE_PXP_DRAW_THREAD
|
||||
static void _pxp_render_thread_cb(void * ptr)
|
||||
{
|
||||
lv_draw_pxp_unit_t * u = ptr;
|
||||
|
||||
lv_thread_sync_init(&u->sync);
|
||||
u->inited = true;
|
||||
|
||||
while(1) {
|
||||
/* Wait for sync if there is no task set. */
|
||||
while(u->task_act == NULL) {
|
||||
if(u->exit_status)
|
||||
break;
|
||||
|
||||
lv_thread_sync_wait(&u->sync);
|
||||
}
|
||||
|
||||
if(u->exit_status) {
|
||||
LV_LOG_INFO("Ready to exit PXP draw thread.");
|
||||
break;
|
||||
}
|
||||
|
||||
_pxp_execute_drawing(u);
|
||||
|
||||
/* Signal the ready state to dispatcher. */
|
||||
u->task_act->state = LV_DRAW_TASK_STATE_READY;
|
||||
|
||||
/* Cleanup. */
|
||||
u->task_act = NULL;
|
||||
|
||||
/* The draw unit is free now. Request a new dispatching as it can get a new task. */
|
||||
lv_draw_dispatch_request();
|
||||
}
|
||||
|
||||
u->inited = false;
|
||||
lv_thread_sync_delete(&u->sync);
|
||||
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*/
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* @file lv_draw_pxp.h
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2022-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_PXP_H
|
||||
#define LV_DRAW_PXP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../../lv_conf_internal.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
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef lv_draw_sw_unit_t lv_draw_pxp_unit_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
void lv_draw_pxp_init(void);
|
||||
|
||||
void lv_draw_pxp_deinit(void);
|
||||
|
||||
void lv_draw_pxp_rotate(const void * src_buf, void * dest_buf, int32_t src_width, int32_t src_height,
|
||||
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);
|
||||
|
||||
void lv_draw_pxp_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dsc,
|
||||
const lv_area_t * coords);
|
||||
|
||||
void lv_draw_pxp_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc,
|
||||
const lv_area_t * coords);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
#endif /*LV_USE_DRAW_PXP*/
|
||||
#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/
|
||||
#endif /*LV_USE_PXP*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_PXP_H*/
|
||||
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
* @file lv_draw_pxp_fill.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2020-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_pxp.h"
|
||||
|
||||
#if LV_USE_PXP
|
||||
#if LV_USE_DRAW_PXP
|
||||
#include "lv_pxp_cfg.h"
|
||||
#include "lv_pxp_utils.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void _pxp_fill(uint8_t * dest_buf, const lv_area_t * dest_area, int32_t dest_stride,
|
||||
lv_color_format_t dest_cf, const lv_draw_fill_dsc_t * dsc);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_pxp_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc,
|
||||
const lv_area_t * coords)
|
||||
{
|
||||
if(dsc->opa <= (lv_opa_t)LV_OPA_MIN)
|
||||
return;
|
||||
|
||||
lv_layer_t * layer = draw_unit->target_layer;
|
||||
lv_draw_buf_t * draw_buf = layer->draw_buf;
|
||||
|
||||
lv_area_t rel_coords;
|
||||
lv_area_copy(&rel_coords, coords);
|
||||
lv_area_move(&rel_coords, -layer->buf_area.x1, -layer->buf_area.y1);
|
||||
|
||||
lv_area_t rel_clip_area;
|
||||
lv_area_copy(&rel_clip_area, draw_unit->clip_area);
|
||||
lv_area_move(&rel_clip_area, -layer->buf_area.x1, -layer->buf_area.y1);
|
||||
|
||||
lv_area_t blend_area;
|
||||
if(!lv_area_intersect(&blend_area, &rel_coords, &rel_clip_area))
|
||||
return; /*Fully clipped, nothing to do*/
|
||||
|
||||
_pxp_fill(draw_buf->data, &blend_area, draw_buf->header.stride, draw_buf->header.cf, dsc);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void _pxp_fill(uint8_t * dest_buf, const lv_area_t * dest_area, int32_t dest_stride,
|
||||
lv_color_format_t dest_cf, const lv_draw_fill_dsc_t * dsc)
|
||||
{
|
||||
int32_t dest_w = lv_area_get_width(dest_area);
|
||||
int32_t dest_h = lv_area_get_height(dest_area);
|
||||
|
||||
lv_pxp_reset();
|
||||
|
||||
uint8_t px_size = lv_color_format_get_size(dest_cf);
|
||||
|
||||
/*OUT buffer configure*/
|
||||
pxp_output_buffer_config_t outputConfig = {
|
||||
.pixelFormat = pxp_get_out_px_format(dest_cf),
|
||||
.interlacedMode = kPXP_OutputProgressive,
|
||||
.buffer0Addr = (uint32_t)(dest_buf + dest_stride * dest_area->y1 + px_size * dest_area->x1),
|
||||
.buffer1Addr = (uint32_t)NULL,
|
||||
.pitchBytes = dest_stride,
|
||||
.width = dest_w,
|
||||
.height = dest_h
|
||||
};
|
||||
|
||||
PXP_SetOutputBufferConfig(PXP_ID, &outputConfig);
|
||||
|
||||
if(dsc->opa >= (lv_opa_t)LV_OPA_MAX) {
|
||||
/*Simple color fill without opacity - AS disabled*/
|
||||
PXP_SetAlphaSurfacePosition(PXP_ID, 0xFFFFU, 0xFFFFU, 0U, 0U);
|
||||
|
||||
}
|
||||
else {
|
||||
/*Fill with opacity - AS used as source (same as OUT)*/
|
||||
pxp_as_buffer_config_t asBufferConfig = {
|
||||
.pixelFormat = pxp_get_as_px_format(dest_cf),
|
||||
.bufferAddr = outputConfig.buffer0Addr,
|
||||
.pitchBytes = outputConfig.pitchBytes
|
||||
};
|
||||
|
||||
PXP_SetAlphaSurfaceBufferConfig(PXP_ID, &asBufferConfig);
|
||||
PXP_SetAlphaSurfacePosition(PXP_ID, 0U, 0U, dest_w - 1U, dest_h - 1U);
|
||||
}
|
||||
|
||||
/*Disable PS, use as color generator*/
|
||||
PXP_SetProcessSurfacePosition(PXP_ID, 0xFFFFU, 0xFFFFU, 0U, 0U);
|
||||
PXP_SetProcessSurfaceBackGroundColor(PXP_ID, lv_color_to_u32(dsc->color));
|
||||
|
||||
/**
|
||||
* Configure Porter-Duff blending - src settings are unused for fill without opacity (opa = 0xff).
|
||||
*
|
||||
* Note: srcFactorMode and dstFactorMode are inverted in fsl_pxp.h:
|
||||
* srcFactorMode is actually applied on PS alpha value
|
||||
* dstFactorMode is actually applied on AS alpha value
|
||||
*/
|
||||
pxp_porter_duff_config_t pdConfig = {
|
||||
.enable = 1,
|
||||
.dstColorMode = kPXP_PorterDuffColorNoAlpha,
|
||||
.srcColorMode = kPXP_PorterDuffColorNoAlpha,
|
||||
.dstGlobalAlphaMode = kPXP_PorterDuffGlobalAlpha,
|
||||
.srcGlobalAlphaMode = kPXP_PorterDuffGlobalAlpha,
|
||||
.dstFactorMode = kPXP_PorterDuffFactorStraight,
|
||||
.srcFactorMode = (dsc->opa >= (lv_opa_t)LV_OPA_MAX) ? kPXP_PorterDuffFactorStraight : kPXP_PorterDuffFactorInversed,
|
||||
.dstGlobalAlpha = dsc->opa,
|
||||
.srcGlobalAlpha = dsc->opa,
|
||||
.dstAlphaMode = kPXP_PorterDuffAlphaStraight, /*don't care*/
|
||||
.srcAlphaMode = kPXP_PorterDuffAlphaStraight /*don't care*/
|
||||
};
|
||||
|
||||
PXP_SetPorterDuffConfig(PXP_ID, &pdConfig);
|
||||
|
||||
lv_pxp_run();
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DRAW_PXP*/
|
||||
#endif /*LV_USE_PXP*/
|
||||
@@ -0,0 +1,367 @@
|
||||
/**
|
||||
* @file lv_draw_pxp_img.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2020-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_pxp.h"
|
||||
|
||||
#if LV_USE_PXP
|
||||
#if LV_USE_DRAW_PXP
|
||||
#include "lv_pxp_cfg.h"
|
||||
#include "lv_pxp_utils.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/* Blit w/ recolor for images w/o opa and alpha channel */
|
||||
static void _pxp_blit_recolor(uint8_t * dest_buf, const lv_area_t * dest_area, int32_t dest_stride,
|
||||
lv_color_format_t dest_cf, const uint8_t * src_buf, const lv_area_t * src_area,
|
||||
int32_t src_stride, lv_color_format_t src_cf, const lv_draw_image_dsc_t * dsc);
|
||||
|
||||
/* Blit w/ transformation for images w/o opa and alpha channel */
|
||||
static void _pxp_blit_transform(uint8_t * dest_buf, const lv_area_t * dest_area, int32_t dest_stride,
|
||||
lv_color_format_t dest_cf, const uint8_t * src_buf, const lv_area_t * src_area,
|
||||
int32_t src_stride, lv_color_format_t src_cf, const lv_draw_image_dsc_t * dsc);
|
||||
|
||||
/* Blit simple w/ opa and alpha channel */
|
||||
static void _pxp_blit(uint8_t * dest_buf, const lv_area_t * dest_area, int32_t dest_stride,
|
||||
lv_color_format_t dest_cf, const uint8_t * src_buf, const lv_area_t * src_area,
|
||||
int32_t src_stride, lv_color_format_t src_cf, lv_opa_t opa);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_pxp_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dsc,
|
||||
const lv_area_t * coords)
|
||||
{
|
||||
if(dsc->opa <= (lv_opa_t)LV_OPA_MIN)
|
||||
return;
|
||||
|
||||
lv_layer_t * layer = draw_unit->target_layer;
|
||||
lv_draw_buf_t * draw_buf = layer->draw_buf;
|
||||
const lv_image_dsc_t * img_dsc = dsc->src;
|
||||
|
||||
lv_area_t rel_coords;
|
||||
lv_area_copy(&rel_coords, coords);
|
||||
lv_area_move(&rel_coords, -layer->buf_area.x1, -layer->buf_area.y1);
|
||||
|
||||
lv_area_t rel_clip_area;
|
||||
lv_area_copy(&rel_clip_area, draw_unit->clip_area);
|
||||
lv_area_move(&rel_clip_area, -layer->buf_area.x1, -layer->buf_area.y1);
|
||||
|
||||
lv_area_t blend_area;
|
||||
bool has_transform = (dsc->rotation != 0 || dsc->scale_x != LV_SCALE_NONE || dsc->scale_y != LV_SCALE_NONE);
|
||||
if(has_transform)
|
||||
lv_area_copy(&blend_area, &rel_coords);
|
||||
else if(!lv_area_intersect(&blend_area, &rel_coords, &rel_clip_area))
|
||||
return; /*Fully clipped, nothing to do*/
|
||||
|
||||
const uint8_t * src_buf = img_dsc->data;
|
||||
|
||||
lv_area_t src_area;
|
||||
src_area.x1 = blend_area.x1 - (coords->x1 - layer->buf_area.x1);
|
||||
src_area.y1 = blend_area.y1 - (coords->y1 - layer->buf_area.y1);
|
||||
src_area.x2 = src_area.x1 + lv_area_get_width(coords) - 1;
|
||||
src_area.y2 = src_area.y1 + lv_area_get_height(coords) - 1;
|
||||
int32_t src_stride = img_dsc->header.stride;
|
||||
lv_color_format_t src_cf = img_dsc->header.cf;
|
||||
|
||||
uint8_t * dest_buf = draw_buf->data;
|
||||
int32_t dest_stride = draw_buf->header.stride;
|
||||
lv_color_format_t dest_cf = draw_buf->header.cf;
|
||||
bool has_recolor = (dsc->recolor_opa > LV_OPA_MIN);
|
||||
|
||||
if(has_recolor && !has_transform)
|
||||
_pxp_blit_recolor(dest_buf, &blend_area, dest_stride, dest_cf,
|
||||
src_buf, &src_area, src_stride, src_cf, dsc);
|
||||
else if(has_transform)
|
||||
_pxp_blit_transform(dest_buf, &blend_area, dest_stride, dest_cf,
|
||||
src_buf, &src_area, src_stride, src_cf, dsc);
|
||||
else
|
||||
_pxp_blit(dest_buf, &blend_area, dest_stride, dest_cf,
|
||||
src_buf, &src_area, src_stride, src_cf, dsc->opa);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void _pxp_blit_recolor(uint8_t * dest_buf, const lv_area_t * dest_area, int32_t dest_stride,
|
||||
lv_color_format_t dest_cf, const uint8_t * src_buf, const lv_area_t * src_area,
|
||||
int32_t src_stride, lv_color_format_t src_cf, const lv_draw_image_dsc_t * dsc)
|
||||
{
|
||||
|
||||
int32_t dest_w = lv_area_get_width(dest_area);
|
||||
int32_t dest_h = lv_area_get_height(dest_area);
|
||||
int32_t src_w = lv_area_get_width(src_area);
|
||||
int32_t src_h = lv_area_get_height(src_area);
|
||||
|
||||
bool src_has_alpha = (src_cf == LV_COLOR_FORMAT_ARGB8888);
|
||||
uint8_t src_px_size = lv_color_format_get_size(src_cf);
|
||||
uint8_t dest_px_size = lv_color_format_get_size(dest_cf);
|
||||
|
||||
lv_pxp_reset();
|
||||
|
||||
/*AS buffer - source image*/
|
||||
pxp_as_buffer_config_t asBufferConfig = {
|
||||
.pixelFormat = pxp_get_as_px_format(src_cf),
|
||||
.bufferAddr = (uint32_t)(src_buf + src_stride * src_area->y1 + src_px_size * src_area->x1),
|
||||
.pitchBytes = src_stride
|
||||
};
|
||||
PXP_SetAlphaSurfaceBufferConfig(PXP_ID, &asBufferConfig);
|
||||
PXP_SetAlphaSurfacePosition(PXP_ID, 0U, 0U, src_w - 1U, src_h - 1U);
|
||||
|
||||
/*Disable PS, use as color generator*/
|
||||
PXP_SetProcessSurfacePosition(PXP_ID, 0xFFFFU, 0xFFFFU, 0U, 0U);
|
||||
PXP_SetProcessSurfaceBackGroundColor(PXP_ID, lv_color_to_u32(dsc->recolor));
|
||||
|
||||
/*Output buffer*/
|
||||
pxp_output_buffer_config_t outputBufferConfig = {
|
||||
.pixelFormat = pxp_get_out_px_format(dest_cf),
|
||||
.interlacedMode = kPXP_OutputProgressive,
|
||||
.buffer0Addr = (uint32_t)(dest_buf + dest_stride * dest_area->y1 + dest_px_size * dest_area->x1),
|
||||
.buffer1Addr = (uint32_t)0U,
|
||||
.pitchBytes = dest_stride,
|
||||
.width = dest_w,
|
||||
.height = dest_h
|
||||
};
|
||||
PXP_SetOutputBufferConfig(PXP_ID, &outputBufferConfig);
|
||||
|
||||
/**
|
||||
* Configure Porter-Duff blending.
|
||||
*
|
||||
* Note: srcFactorMode and dstFactorMode are inverted in fsl_pxp.h:
|
||||
* srcFactorMode is actually applied on PS alpha value
|
||||
* dstFactorMode is actually applied on AS alpha value
|
||||
*/
|
||||
pxp_porter_duff_config_t pdConfig = {
|
||||
.enable = 1,
|
||||
.dstColorMode = kPXP_PorterDuffColorWithAlpha,
|
||||
.srcColorMode = kPXP_PorterDuffColorWithAlpha,
|
||||
.dstGlobalAlphaMode = kPXP_PorterDuffGlobalAlpha,
|
||||
.srcGlobalAlphaMode = src_has_alpha ? kPXP_PorterDuffLocalAlpha : kPXP_PorterDuffGlobalAlpha,
|
||||
.dstFactorMode = kPXP_PorterDuffFactorStraight,
|
||||
.srcFactorMode = kPXP_PorterDuffFactorInversed,
|
||||
.dstGlobalAlpha = dsc->recolor_opa,
|
||||
.srcGlobalAlpha = 0xff,
|
||||
.dstAlphaMode = kPXP_PorterDuffAlphaStraight, /*don't care*/
|
||||
.srcAlphaMode = kPXP_PorterDuffAlphaStraight
|
||||
};
|
||||
PXP_SetPorterDuffConfig(PXP_ID, &pdConfig);
|
||||
|
||||
lv_pxp_run();
|
||||
}
|
||||
|
||||
static void _pxp_blit_transform(uint8_t * dest_buf, const lv_area_t * dest_area, int32_t dest_stride,
|
||||
lv_color_format_t dest_cf, const uint8_t * src_buf, const lv_area_t * src_area,
|
||||
int32_t src_stride, lv_color_format_t src_cf, const lv_draw_image_dsc_t * dsc)
|
||||
{
|
||||
int32_t src_w = lv_area_get_width(src_area);
|
||||
int32_t src_h = lv_area_get_height(src_area);
|
||||
int32_t dest_w = lv_area_get_width(dest_area);
|
||||
int32_t dest_h = lv_area_get_height(dest_area);
|
||||
|
||||
lv_point_t pivot = dsc->pivot;
|
||||
/*The offsets are now relative to the transformation result with pivot ULC*/
|
||||
int32_t piv_offset_x = 0;
|
||||
int32_t piv_offset_y = 0;
|
||||
|
||||
int32_t trim_x = 0;
|
||||
int32_t trim_y = 0;
|
||||
|
||||
bool has_rotation = (dsc->rotation != 0);
|
||||
bool has_scale = (dsc->scale_x != LV_SCALE_NONE || dsc->scale_y != LV_SCALE_NONE);
|
||||
uint8_t src_px_size = lv_color_format_get_size(src_cf);
|
||||
uint8_t dest_px_size = lv_color_format_get_size(dest_cf);
|
||||
|
||||
lv_pxp_reset();
|
||||
|
||||
if(has_rotation) {
|
||||
/*Convert rotation angle and calculate offsets caused by pivot*/
|
||||
pxp_rotate_degree_t pxp_angle;
|
||||
switch(dsc->rotation) {
|
||||
case 0:
|
||||
pxp_angle = kPXP_Rotate0;
|
||||
piv_offset_x = 0;
|
||||
piv_offset_y = 0;
|
||||
break;
|
||||
case 900:
|
||||
pxp_angle = kPXP_Rotate90;
|
||||
piv_offset_x = pivot.x + pivot.y - src_h;
|
||||
piv_offset_y = pivot.y - pivot.x;
|
||||
break;
|
||||
case 1800:
|
||||
pxp_angle = kPXP_Rotate180;
|
||||
piv_offset_x = 2 * pivot.x - src_w;
|
||||
piv_offset_y = 2 * pivot.y - src_h;
|
||||
break;
|
||||
case 2700:
|
||||
pxp_angle = kPXP_Rotate270;
|
||||
piv_offset_x = pivot.x - pivot.y;
|
||||
piv_offset_y = pivot.x + pivot.y - src_w;
|
||||
break;
|
||||
default:
|
||||
pxp_angle = kPXP_Rotate0;
|
||||
piv_offset_x = 0;
|
||||
piv_offset_y = 0;
|
||||
}
|
||||
/*PS buffer rotation and decimation does not function at the same time*/
|
||||
PXP_SetRotateConfig(PXP_ID, kPXP_RotateOutputBuffer, pxp_angle, kPXP_FlipDisable);
|
||||
}
|
||||
|
||||
if(has_scale) {
|
||||
float fp_scale_x = (float)dsc->scale_x / LV_SCALE_NONE;
|
||||
float fp_scale_y = (float)dsc->scale_y / LV_SCALE_NONE;
|
||||
int32_t int_scale_x = (int32_t)fp_scale_x;
|
||||
int32_t int_scale_y = (int32_t)fp_scale_y;
|
||||
|
||||
/*Any scale_factor in (k, k + 1] will result in a trim equal to k*/
|
||||
trim_x = (fp_scale_x == int_scale_x) ? int_scale_x - 1 : int_scale_x;
|
||||
trim_y = (fp_scale_y == int_scale_y) ? int_scale_y - 1 : int_scale_y;
|
||||
|
||||
dest_w = src_w * fp_scale_x + trim_x;
|
||||
dest_h = src_h * fp_scale_y + trim_y;
|
||||
|
||||
/*Final pivot offset = scale_factor * rotation_pivot_offset + scaling_pivot_offset*/
|
||||
piv_offset_x = floorf(fp_scale_x * piv_offset_x) - floorf((fp_scale_x - 1) * pivot.x);
|
||||
piv_offset_y = floorf(fp_scale_y * piv_offset_y) - floorf((fp_scale_y - 1) * pivot.y);
|
||||
}
|
||||
|
||||
/*PS buffer - source image*/
|
||||
pxp_ps_buffer_config_t psBufferConfig = {
|
||||
.pixelFormat = pxp_get_ps_px_format(src_cf),
|
||||
.swapByte = false,
|
||||
.bufferAddr = (uint32_t)(src_buf + src_stride * src_area->y1 + src_px_size * src_area->x1),
|
||||
.bufferAddrU = 0,
|
||||
.bufferAddrV = 0,
|
||||
.pitchBytes = src_stride
|
||||
};
|
||||
PXP_SetProcessSurfaceBufferConfig(PXP_ID, &psBufferConfig);
|
||||
PXP_SetProcessSurfacePosition(PXP_ID, 0U, 0U, dest_w - trim_x - 1U, dest_h - trim_y - 1U);
|
||||
|
||||
if(has_scale)
|
||||
PXP_SetProcessSurfaceScaler(PXP_ID, src_w, src_h, dest_w, dest_h);
|
||||
|
||||
/*AS disabled */
|
||||
PXP_SetAlphaSurfacePosition(PXP_ID, 0xFFFFU, 0xFFFFU, 0U, 0U);
|
||||
|
||||
/*Output buffer*/
|
||||
pxp_output_buffer_config_t outputBufferConfig = {
|
||||
.pixelFormat = pxp_get_out_px_format(dest_cf),
|
||||
.interlacedMode = kPXP_OutputProgressive,
|
||||
.buffer0Addr = (uint32_t)(dest_buf + dest_stride * (dest_area->y1 + piv_offset_y) + dest_px_size * (dest_area->x1 + piv_offset_x)),
|
||||
.buffer1Addr = (uint32_t)0U,
|
||||
.pitchBytes = dest_stride,
|
||||
.width = dest_w - trim_x,
|
||||
.height = dest_h - trim_y
|
||||
};
|
||||
PXP_SetOutputBufferConfig(PXP_ID, &outputBufferConfig);
|
||||
|
||||
lv_pxp_run();
|
||||
}
|
||||
|
||||
static void _pxp_blit(uint8_t * dest_buf, const lv_area_t * dest_area, int32_t dest_stride,
|
||||
lv_color_format_t dest_cf, const uint8_t * src_buf, const lv_area_t * src_area,
|
||||
int32_t src_stride, lv_color_format_t src_cf, lv_opa_t opa)
|
||||
{
|
||||
int32_t dest_w = lv_area_get_width(dest_area);
|
||||
int32_t dest_h = lv_area_get_height(dest_area);
|
||||
int32_t src_w = lv_area_get_width(src_area);
|
||||
int32_t src_h = lv_area_get_height(src_area);
|
||||
|
||||
bool src_has_alpha = (src_cf == LV_COLOR_FORMAT_ARGB8888);
|
||||
uint8_t src_px_size = lv_color_format_get_size(src_cf);
|
||||
uint8_t dest_px_size = lv_color_format_get_size(dest_cf);
|
||||
|
||||
lv_pxp_reset();
|
||||
|
||||
pxp_as_blend_config_t asBlendConfig = {
|
||||
.alpha = opa,
|
||||
.invertAlpha = false,
|
||||
.alphaMode = kPXP_AlphaRop,
|
||||
.ropMode = kPXP_RopMergeAs
|
||||
};
|
||||
|
||||
if(opa >= (lv_opa_t)LV_OPA_MAX && !src_has_alpha) {
|
||||
/*Simple blit, no effect - Disable PS buffer*/
|
||||
PXP_SetProcessSurfacePosition(PXP_ID, 0xFFFFU, 0xFFFFU, 0U, 0U);
|
||||
}
|
||||
else {
|
||||
/*PS must be enabled to fetch background pixels.
|
||||
PS and OUT buffers are the same, blend will be done in-place*/
|
||||
pxp_ps_buffer_config_t psBufferConfig = {
|
||||
.pixelFormat = pxp_get_ps_px_format(dest_cf),
|
||||
.swapByte = false,
|
||||
.bufferAddr = (uint32_t)(dest_buf + dest_stride * dest_area->y1 + dest_px_size * dest_area->x1),
|
||||
.bufferAddrU = 0U,
|
||||
.bufferAddrV = 0U,
|
||||
.pitchBytes = dest_stride
|
||||
};
|
||||
|
||||
if(opa >= (lv_opa_t)LV_OPA_MAX)
|
||||
asBlendConfig.alphaMode = src_has_alpha ? kPXP_AlphaEmbedded : kPXP_AlphaOverride;
|
||||
else
|
||||
asBlendConfig.alphaMode = src_has_alpha ? kPXP_AlphaMultiply : kPXP_AlphaOverride;
|
||||
|
||||
PXP_SetProcessSurfaceBufferConfig(PXP_ID, &psBufferConfig);
|
||||
PXP_SetProcessSurfacePosition(PXP_ID, 0U, 0U, dest_w - 1U, dest_h - 1U);
|
||||
}
|
||||
|
||||
/*AS buffer - source image*/
|
||||
pxp_as_buffer_config_t asBufferConfig = {
|
||||
.pixelFormat = pxp_get_as_px_format(src_cf),
|
||||
.bufferAddr = (uint32_t)(src_buf + src_stride * src_area->y1 + src_px_size * src_area->x1),
|
||||
.pitchBytes = src_stride
|
||||
};
|
||||
PXP_SetAlphaSurfaceBufferConfig(PXP_ID, &asBufferConfig);
|
||||
PXP_SetAlphaSurfacePosition(PXP_ID, 0U, 0U, src_w - 1U, src_h - 1U);
|
||||
PXP_SetAlphaSurfaceBlendConfig(PXP_ID, &asBlendConfig);
|
||||
PXP_EnableAlphaSurfaceOverlayColorKey(PXP_ID, false);
|
||||
|
||||
/*Output buffer.*/
|
||||
pxp_output_buffer_config_t outputBufferConfig = {
|
||||
.pixelFormat = pxp_get_out_px_format(dest_cf),
|
||||
.interlacedMode = kPXP_OutputProgressive,
|
||||
.buffer0Addr = (uint32_t)(dest_buf + dest_stride * dest_area->y1 + dest_px_size * dest_area->x1),
|
||||
.buffer1Addr = (uint32_t)0U,
|
||||
.pitchBytes = dest_stride,
|
||||
.width = dest_w,
|
||||
.height = dest_h
|
||||
};
|
||||
PXP_SetOutputBufferConfig(PXP_ID, &outputBufferConfig);
|
||||
|
||||
lv_pxp_run();
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DRAW_PXP*/
|
||||
#endif /*LV_USE_PXP*/
|
||||
@@ -0,0 +1,158 @@
|
||||
/**
|
||||
* @file lv_draw_pxp_layer.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2023-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_pxp.h"
|
||||
|
||||
#if LV_USE_PXP
|
||||
#if LV_USE_DRAW_PXP
|
||||
|
||||
#include "../../../stdlib/lv_string.h"
|
||||
#if LV_USE_PARALLEL_DRAW_DEBUG
|
||||
#include "../../../core/lv_global.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
#if LV_USE_PARALLEL_DRAW_DEBUG
|
||||
#define _draw_info LV_GLOBAL_DEFAULT()->draw_info
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_pxp_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc,
|
||||
const lv_area_t * coords)
|
||||
{
|
||||
lv_layer_t * layer_to_draw = (lv_layer_t *)draw_dsc->src;
|
||||
const lv_draw_buf_t * draw_buf = layer_to_draw->draw_buf;
|
||||
|
||||
/* It can happen that nothing was draw on a layer and therefore its buffer is not allocated.
|
||||
* In this case just return.
|
||||
*/
|
||||
if(draw_buf == NULL)
|
||||
return;
|
||||
|
||||
const lv_area_t area_to_draw = {
|
||||
.x1 = 0,
|
||||
.y1 = 0,
|
||||
.x2 = draw_buf->header.w - 1,
|
||||
.y2 = draw_buf->header.h - 1
|
||||
};
|
||||
lv_draw_buf_invalidate_cache(draw_buf, &area_to_draw);
|
||||
|
||||
lv_draw_image_dsc_t new_draw_dsc = *draw_dsc;
|
||||
new_draw_dsc.src = draw_buf;
|
||||
lv_draw_pxp_img(draw_unit, &new_draw_dsc, coords);
|
||||
|
||||
#if LV_USE_LAYER_DEBUG || LV_USE_PARALLEL_DRAW_DEBUG
|
||||
lv_area_t area_rot;
|
||||
lv_area_copy(&area_rot, coords);
|
||||
if(draw_dsc->rotation || draw_dsc->scale_x != LV_SCALE_NONE || draw_dsc->scale_y != LV_SCALE_NONE) {
|
||||
int32_t w = lv_area_get_width(coords);
|
||||
int32_t h = lv_area_get_height(coords);
|
||||
|
||||
lv_image_buf_get_transformed_area(&area_rot, w, h, draw_dsc->rotation, draw_dsc->scale_x, draw_dsc->scale_y,
|
||||
&draw_dsc->pivot);
|
||||
|
||||
area_rot.x1 += coords->x1;
|
||||
area_rot.y1 += coords->y1;
|
||||
area_rot.x2 += coords->x1;
|
||||
area_rot.y2 += coords->y1;
|
||||
}
|
||||
lv_area_t draw_area;
|
||||
if(!lv_area_intersect(&draw_area, &area_rot, draw_unit->clip_area)) return;
|
||||
#endif
|
||||
|
||||
#if LV_USE_LAYER_DEBUG
|
||||
lv_draw_fill_dsc_t fill_dsc;
|
||||
lv_draw_fill_dsc_init(&fill_dsc);
|
||||
fill_dsc.color = lv_color_hex(layer_to_draw->color_format == LV_COLOR_FORMAT_ARGB8888 ? 0xff0000 : 0x00ff00);
|
||||
fill_dsc.opa = LV_OPA_20;
|
||||
lv_draw_sw_fill(draw_unit, &fill_dsc, &area_rot);
|
||||
|
||||
lv_draw_border_dsc_t border_dsc;
|
||||
lv_draw_border_dsc_init(&border_dsc);
|
||||
border_dsc.color = fill_dsc.color;
|
||||
border_dsc.opa = LV_OPA_60;
|
||||
border_dsc.width = 2;
|
||||
lv_draw_sw_border(draw_unit, &border_dsc, &area_rot);
|
||||
|
||||
#endif
|
||||
|
||||
#if LV_USE_PARALLEL_DRAW_DEBUG
|
||||
uint32_t idx = 0;
|
||||
lv_draw_unit_t * draw_unit_tmp = _draw_info.unit_head;
|
||||
while(draw_unit_tmp != draw_unit) {
|
||||
draw_unit_tmp = draw_unit_tmp->next;
|
||||
idx++;
|
||||
}
|
||||
|
||||
lv_draw_fill_dsc_t fill_dsc;
|
||||
lv_draw_rect_dsc_init(&fill_dsc);
|
||||
fill_dsc.color = lv_palette_main(idx % LV_PALETTE_LAST);
|
||||
fill_dsc.opa = LV_OPA_10;
|
||||
lv_draw_sw_fill(draw_unit, &fill_dsc, &area_rot);
|
||||
|
||||
lv_draw_border_dsc_t border_dsc;
|
||||
lv_draw_border_dsc_init(&border_dsc);
|
||||
border_dsc.color = lv_palette_main(idx % LV_PALETTE_LAST);
|
||||
border_dsc.opa = LV_OPA_100;
|
||||
border_dsc.width = 2;
|
||||
lv_draw_sw_border(draw_unit, &border_dsc, &area_rot);
|
||||
|
||||
lv_point_t txt_size;
|
||||
lv_text_get_size(&txt_size, "W", LV_FONT_DEFAULT, 0, 0, 100, LV_TEXT_FLAG_NONE);
|
||||
|
||||
lv_area_t txt_area;
|
||||
txt_area.x1 = draw_area.x1;
|
||||
txt_area.x2 = draw_area.x1 + txt_size.x - 1;
|
||||
txt_area.y2 = draw_area.y2;
|
||||
txt_area.y1 = draw_area.y2 - txt_size.y + 1;
|
||||
|
||||
lv_draw_fill_dsc_init(&fill_dsc);
|
||||
fill_dsc.color = lv_color_black();
|
||||
lv_draw_sw_fill(draw_unit, &fill_dsc, &txt_area);
|
||||
|
||||
char buf[8];
|
||||
lv_snprintf(buf, sizeof(buf), "%d", idx);
|
||||
lv_draw_label_dsc_t label_dsc;
|
||||
lv_draw_label_dsc_init(&label_dsc);
|
||||
label_dsc.color = lv_color_white();
|
||||
label_dsc.text = buf;
|
||||
lv_draw_sw_label(draw_unit, &label_dsc, &txt_area);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DRAW_PXP*/
|
||||
#endif /*LV_USE_PXP*/
|
||||
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* @file lv_pxp_cfg.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2020-2023 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_pxp_cfg.h"
|
||||
|
||||
#if LV_USE_PXP
|
||||
#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP
|
||||
#include "lv_pxp_osa.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
static pxp_cfg_t * _pxp_cfg;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_pxp_init(void)
|
||||
{
|
||||
_pxp_cfg = pxp_get_default_cfg();
|
||||
|
||||
PXP_Init(PXP_ID);
|
||||
|
||||
PXP_EnableCsc1(PXP_ID, false); /*Disable CSC1, it is enabled by default.*/
|
||||
PXP_SetProcessBlockSize(PXP_ID, kPXP_BlockSize16); /*Block size 16x16 for higher performance*/
|
||||
|
||||
PXP_EnableInterrupts(PXP_ID, kPXP_CompleteInterruptEnable);
|
||||
|
||||
_pxp_cfg->pxp_interrupt_init();
|
||||
}
|
||||
|
||||
void lv_pxp_deinit(void)
|
||||
{
|
||||
_pxp_cfg->pxp_interrupt_deinit();
|
||||
PXP_DisableInterrupts(PXP_ID, kPXP_CompleteInterruptEnable);
|
||||
PXP_Deinit(PXP_ID);
|
||||
}
|
||||
|
||||
void lv_pxp_reset(void)
|
||||
{
|
||||
PXP_ResetControl(PXP_ID);
|
||||
|
||||
PXP_EnableCsc1(PXP_ID, false); /*Disable CSC1, it is enabled by default.*/
|
||||
PXP_SetProcessBlockSize(PXP_ID, kPXP_BlockSize16); /*Block size 16x16 for higher performance*/
|
||||
}
|
||||
|
||||
void lv_pxp_run(void)
|
||||
{
|
||||
_pxp_cfg->pxp_run();
|
||||
_pxp_cfg->pxp_wait();
|
||||
}
|
||||
|
||||
void lv_pxp_wait(void)
|
||||
{
|
||||
_pxp_cfg->pxp_wait();
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/
|
||||
#endif /*LV_USE_PXP*/
|
||||
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
* @file lv_pxp_cfg.h
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2020-2023 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef LV_PXP_CFG_H
|
||||
#define LV_PXP_CFG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_PXP
|
||||
#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP
|
||||
#include "fsl_cache.h"
|
||||
#include "fsl_pxp.h"
|
||||
|
||||
#include "../../../misc/lv_log.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/** PXP module instance to use*/
|
||||
#define PXP_ID PXP
|
||||
|
||||
/** PXP interrupt line ID*/
|
||||
#define PXP_IRQ_ID PXP_IRQn
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* NXP PXP device configuration.
|
||||
*/
|
||||
typedef struct {
|
||||
/** Callback for PXP interrupt initialization*/
|
||||
void (*pxp_interrupt_init)(void);
|
||||
|
||||
/** Callback for PXP interrupt de-initialization*/
|
||||
void (*pxp_interrupt_deinit)(void);
|
||||
|
||||
/** Callback for PXP start*/
|
||||
void (*pxp_run)(void);
|
||||
|
||||
/** Callback for waiting of PXP completion*/
|
||||
void (*pxp_wait)(void);
|
||||
} pxp_cfg_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Reset and initialize PXP device. This function should be called as a part
|
||||
* of display init sequence.
|
||||
*/
|
||||
void lv_pxp_init(void);
|
||||
|
||||
/**
|
||||
* Disable PXP device. Should be called during display deinit sequence.
|
||||
*/
|
||||
void lv_pxp_deinit(void);
|
||||
|
||||
/**
|
||||
* Reset PXP device.
|
||||
*/
|
||||
void lv_pxp_reset(void);
|
||||
|
||||
/**
|
||||
* Clear cache and start PXP.
|
||||
*/
|
||||
void lv_pxp_run(void);
|
||||
|
||||
/**
|
||||
* Wait for PXP completion.
|
||||
*/
|
||||
void lv_pxp_wait(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/
|
||||
#endif /*LV_USE_PXP*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_PXP_CFG_H*/
|
||||
@@ -0,0 +1,188 @@
|
||||
/**
|
||||
* @file lv_pxp_osa.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2020, 2022-2023 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_pxp_osa.h"
|
||||
|
||||
#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"
|
||||
#include "fsl_pxp.h"
|
||||
|
||||
#if defined(SDK_OS_FREE_RTOS)
|
||||
#include "FreeRTOS.h"
|
||||
#endif
|
||||
|
||||
#if defined(__ZEPHYR__)
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/irq.h>
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* PXP interrupt initialization.
|
||||
*/
|
||||
static void _pxp_interrupt_init(void);
|
||||
|
||||
/**
|
||||
* PXP interrupt de-initialization.
|
||||
*/
|
||||
static void _pxp_interrupt_deinit(void);
|
||||
|
||||
/**
|
||||
* Start the PXP job.
|
||||
*/
|
||||
static void _pxp_run(void);
|
||||
|
||||
/**
|
||||
* Wait for PXP completion.
|
||||
*/
|
||||
static void _pxp_wait(void);
|
||||
|
||||
#if defined(__ZEPHYR__)
|
||||
/**
|
||||
* Interrupt handler for Zephyr IRQ
|
||||
*/
|
||||
static void _pxp_zephyr_irq_handler(void *);
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
#if LV_USE_OS
|
||||
static lv_thread_sync_t pxp_sync;
|
||||
#endif
|
||||
static volatile bool ucPXPIdle;
|
||||
|
||||
static pxp_cfg_t _pxp_default_cfg = {
|
||||
.pxp_interrupt_init = _pxp_interrupt_init,
|
||||
.pxp_interrupt_deinit = _pxp_interrupt_deinit,
|
||||
.pxp_run = _pxp_run,
|
||||
.pxp_wait = _pxp_wait,
|
||||
};
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void PXP_IRQHandler(void)
|
||||
{
|
||||
if(kPXP_CompleteFlag & PXP_GetStatusFlags(PXP_ID)) {
|
||||
PXP_ClearStatusFlags(PXP_ID, kPXP_CompleteFlag);
|
||||
#if LV_USE_OS
|
||||
lv_thread_sync_signal_isr(&pxp_sync);
|
||||
#else
|
||||
ucPXPIdle = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
pxp_cfg_t * pxp_get_default_cfg(void)
|
||||
{
|
||||
return &_pxp_default_cfg;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#if defined(__ZEPHYR__)
|
||||
static void _pxp_zephyr_irq_handler(void *)
|
||||
{
|
||||
PXP_IRQHandler();
|
||||
}
|
||||
#endif
|
||||
|
||||
static void _pxp_interrupt_init(void)
|
||||
{
|
||||
#if LV_USE_OS
|
||||
if(lv_thread_sync_init(&pxp_sync) != LV_RESULT_OK) {
|
||||
PXP_ASSERT_MSG(false, "Failed to init thread_sync.");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__ZEPHYR__)
|
||||
IRQ_CONNECT(DT_IRQN(DT_NODELABEL(pxp)), CONFIG_LV_Z_PXP_INTERRUPT_PRIORITY, _pxp_zephyr_irq_handler, NULL, 0);
|
||||
irq_enable(DT_IRQN(DT_NODELABEL(pxp)));
|
||||
#elif defined(SDK_OS_FREE_RTOS)
|
||||
NVIC_SetPriority(PXP_IRQ_ID, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1);
|
||||
#endif
|
||||
|
||||
#if !defined(__ZEPHYR__)
|
||||
NVIC_EnableIRQ(PXP_IRQ_ID);
|
||||
#endif
|
||||
|
||||
ucPXPIdle = true;
|
||||
}
|
||||
|
||||
static void _pxp_interrupt_deinit(void)
|
||||
{
|
||||
#if defined(__ZEPHYR__)
|
||||
irq_disable(DT_IRQN(DT_NODELABEL(pxp)));
|
||||
#else
|
||||
NVIC_DisableIRQ(PXP_IRQ_ID);
|
||||
#endif
|
||||
|
||||
#if LV_USE_OS
|
||||
lv_thread_sync_delete(&pxp_sync);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to start PXP job.
|
||||
*/
|
||||
static void _pxp_run(void)
|
||||
{
|
||||
ucPXPIdle = false;
|
||||
|
||||
PXP_EnableInterrupts(PXP_ID, kPXP_CompleteInterruptEnable);
|
||||
PXP_Start(PXP_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to wait for PXP completion.
|
||||
*/
|
||||
static void _pxp_wait(void)
|
||||
{
|
||||
if(ucPXPIdle == true)
|
||||
return;
|
||||
#if LV_USE_OS
|
||||
if(lv_thread_sync_wait(&pxp_sync) == LV_RESULT_OK)
|
||||
ucPXPIdle = true;
|
||||
#else
|
||||
while(ucPXPIdle == false) {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/
|
||||
#endif /*LV_USE_PXP*/
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* @file lv_pxp_osa.h
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2020, 2022-2023 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef LV_PXP_OSA_H
|
||||
#define LV_PXP_OSA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_PXP
|
||||
#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP
|
||||
#include "lv_pxp_cfg.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* PXP device interrupt handler. Used to check PXP task completion status.
|
||||
*/
|
||||
void PXP_IRQHandler(void);
|
||||
|
||||
/**
|
||||
* Get the PXP default configuration.
|
||||
*/
|
||||
pxp_cfg_t * pxp_get_default_cfg(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/
|
||||
#endif /*LV_USE_PXP*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_PXP_OSA_H*/
|
||||
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
* @file lv_pxp_utils.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2023-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_pxp_utils.h"
|
||||
|
||||
#if LV_USE_PXP
|
||||
#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
pxp_output_pixel_format_t pxp_get_out_px_format(lv_color_format_t cf)
|
||||
{
|
||||
pxp_output_pixel_format_t out_px_format = kPXP_OutputPixelFormatRGB565;
|
||||
|
||||
switch(cf) {
|
||||
case LV_COLOR_FORMAT_RGB565:
|
||||
out_px_format = kPXP_OutputPixelFormatRGB565;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_RGB888:
|
||||
out_px_format = kPXP_OutputPixelFormatRGB888P;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_ARGB8888:
|
||||
out_px_format = kPXP_OutputPixelFormatARGB8888;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_XRGB8888:
|
||||
out_px_format = kPXP_OutputPixelFormatRGB888;
|
||||
break;
|
||||
|
||||
default:
|
||||
PXP_ASSERT_MSG(false, "Unsupported color format.");
|
||||
break;
|
||||
}
|
||||
|
||||
return out_px_format;
|
||||
}
|
||||
|
||||
pxp_as_pixel_format_t pxp_get_as_px_format(lv_color_format_t cf)
|
||||
{
|
||||
pxp_as_pixel_format_t as_px_format = kPXP_AsPixelFormatRGB565;
|
||||
|
||||
switch(cf) {
|
||||
case LV_COLOR_FORMAT_RGB565:
|
||||
as_px_format = kPXP_AsPixelFormatRGB565;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_RGB888:
|
||||
PXP_ASSERT_MSG(false, "Unsupported color format.");
|
||||
break;
|
||||
case LV_COLOR_FORMAT_ARGB8888:
|
||||
as_px_format = kPXP_AsPixelFormatARGB8888;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_XRGB8888:
|
||||
as_px_format = kPXP_AsPixelFormatRGB888;
|
||||
break;
|
||||
|
||||
default:
|
||||
PXP_ASSERT_MSG(false, "Unsupported color format.");
|
||||
break;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
switch(cf) {
|
||||
case LV_COLOR_FORMAT_RGB565:
|
||||
ps_px_format = kPXP_PsPixelFormatRGB565;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_RGB888:
|
||||
PXP_ASSERT_MSG(false, "Unsupported color format.");
|
||||
break;
|
||||
case LV_COLOR_FORMAT_ARGB8888:
|
||||
#if (!(defined(FSL_FEATURE_PXP_HAS_NO_EXTEND_PIXEL_FORMAT) && FSL_FEATURE_PXP_HAS_NO_EXTEND_PIXEL_FORMAT)) && \
|
||||
(!(defined(FSL_FEATURE_PXP_V3) && FSL_FEATURE_PXP_V3))
|
||||
ps_px_format = kPXP_PsPixelFormatARGB8888;
|
||||
#else
|
||||
PXP_ASSERT_MSG(false, "Unsupported color format.");
|
||||
#endif
|
||||
break;
|
||||
case LV_COLOR_FORMAT_XRGB8888:
|
||||
#if (!(defined(FSL_FEATURE_PXP_HAS_NO_EXTEND_PIXEL_FORMAT) && FSL_FEATURE_PXP_HAS_NO_EXTEND_PIXEL_FORMAT)) && \
|
||||
(!(defined(FSL_FEATURE_PXP_V3) && FSL_FEATURE_PXP_V3))
|
||||
ps_px_format = kPXP_PsPixelFormatARGB8888;
|
||||
#else
|
||||
ps_px_format = kPXP_PsPixelFormatRGB888;
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
PXP_ASSERT_MSG(false, "Unsupported color format.");
|
||||
break;
|
||||
}
|
||||
|
||||
return ps_px_format;
|
||||
}
|
||||
|
||||
bool pxp_buf_aligned(const void * buf, uint32_t stride)
|
||||
{
|
||||
/* Test for pointer alignment */
|
||||
if((uintptr_t)buf % 64)
|
||||
return false;
|
||||
|
||||
/* Test for invalid stride (no stride alignment required) */
|
||||
if(stride == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_PXP*/
|
||||
#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/
|
||||
#endif /*LV_USE_PXP*/
|
||||
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* @file lv_pxp_utils.h
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2023-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef LV_PXP_UTILS_H
|
||||
#define LV_PXP_UTILS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_PXP
|
||||
#if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP
|
||||
#include "fsl_pxp.h"
|
||||
#include "../../../misc/lv_color.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#if LV_USE_PXP_ASSERT
|
||||
#define PXP_ASSERT(expr) LV_ASSERT(expr)
|
||||
#else
|
||||
#define PXP_ASSERT(expr)
|
||||
#endif
|
||||
|
||||
#define PXP_ASSERT_MSG(expr, msg) \
|
||||
do { \
|
||||
if(!(expr)) { \
|
||||
LV_LOG_ERROR(msg); \
|
||||
PXP_ASSERT(false); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
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);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_PXP*/
|
||||
#endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/
|
||||
#endif /*LV_USE_PXP*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_PXP_UTILS_H*/
|
||||
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
* @file lv_draw_buf_vglite.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2023-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_vglite.h"
|
||||
|
||||
#if LV_USE_DRAW_VGLITE
|
||||
#include "../../lv_draw_buf_private.h"
|
||||
#include "lv_vglite_buf.h"
|
||||
#include "lv_vglite_utils.h"
|
||||
|
||||
#include "lvgl_support.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
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
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void _invalidate_cache(const lv_draw_buf_t * draw_buf, const lv_area_t * area)
|
||||
{
|
||||
const lv_image_header_t * header = &draw_buf->header;
|
||||
uint32_t stride = header->stride;
|
||||
lv_color_format_t cf = header->cf;
|
||||
|
||||
if(area->y1 == 0) {
|
||||
uint32_t size = stride * lv_area_get_height(area);
|
||||
|
||||
/* Invalidate full buffer. */
|
||||
DEMO_CleanInvalidateCacheByAddr((void *)draw_buf->data, size);
|
||||
return;
|
||||
}
|
||||
|
||||
const uint8_t * buf_u8 = draw_buf->data;
|
||||
/* ARM require a 32 byte aligned address. */
|
||||
uint8_t align_bytes = 32;
|
||||
uint8_t bits_per_pixel = lv_color_format_get_bpp(cf);
|
||||
|
||||
uint16_t align_pixels = align_bytes * 8 / bits_per_pixel;
|
||||
uint16_t offset_x = 0;
|
||||
|
||||
if(area->x1 >= (int32_t)(area->x1 % align_pixels)) {
|
||||
uint16_t shift_x = area->x1 - (area->x1 % align_pixels);
|
||||
|
||||
offset_x = area->x1 - shift_x;
|
||||
buf_u8 += (shift_x * bits_per_pixel) / 8;
|
||||
}
|
||||
|
||||
if(area->y1) {
|
||||
uint16_t shift_y = area->y1;
|
||||
|
||||
buf_u8 += shift_y * stride;
|
||||
}
|
||||
|
||||
/* Area to clear can start from a different offset in buffer.
|
||||
* Invalidate the area line by line.
|
||||
*/
|
||||
uint16_t line_pixels = offset_x + lv_area_get_width(area);
|
||||
uint16_t line_size = (line_pixels * bits_per_pixel) / 8;
|
||||
uint16_t area_height = lv_area_get_height(area);
|
||||
|
||||
for(uint16_t y = 0; y < area_height; y++) {
|
||||
const void * line_addr = buf_u8 + y * stride;
|
||||
|
||||
DEMO_CleanInvalidateCacheByAddr((void *)line_addr, line_size);
|
||||
}
|
||||
}
|
||||
|
||||
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*/
|
||||
@@ -0,0 +1,594 @@
|
||||
/**
|
||||
* @file lv_draw_vglite.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2023-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_vglite.h"
|
||||
|
||||
#if LV_USE_DRAW_VGLITE
|
||||
#include "lv_vglite_buf.h"
|
||||
#include "lv_vglite_utils.h"
|
||||
|
||||
#include "../../../core/lv_global.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define DRAW_UNIT_ID_VGLITE 2
|
||||
|
||||
#if LV_USE_VGLITE_DRAW_ASYNC
|
||||
#define VGLITE_TASK_BUF_SIZE 100
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
#if LV_USE_VGLITE_DRAW_ASYNC
|
||||
/**
|
||||
* Structure of pending vglite draw task
|
||||
*/
|
||||
typedef struct _vglite_draw_task_t {
|
||||
lv_draw_task_t * task;
|
||||
bool flushed;
|
||||
} vglite_draw_tasks_t;
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/*
|
||||
* Evaluate a task and set the score and preferred VGLite draw unit.
|
||||
* Return 1 if task is preferred, 0 otherwise (task is not supported).
|
||||
*/
|
||||
static int32_t _vglite_evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task);
|
||||
|
||||
/*
|
||||
* Dispatch (assign) a task to VGLite draw unit (itself).
|
||||
* Return 1 if task was dispatched, 0 otherwise (task not supported).
|
||||
*/
|
||||
static int32_t _vglite_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer);
|
||||
|
||||
/*
|
||||
* Wait for VG-Lite draw unit to finish.
|
||||
*/
|
||||
#if LV_USE_VGLITE_DRAW_ASYNC
|
||||
static int32_t _vglite_wait_for_finish(lv_draw_unit_t * draw_unit);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Delete the VGLite draw unit.
|
||||
*/
|
||||
static int32_t _vglite_delete(lv_draw_unit_t * draw_unit);
|
||||
|
||||
#if LV_USE_VGLITE_DRAW_THREAD
|
||||
static void _vglite_render_thread_cb(void * ptr);
|
||||
#endif
|
||||
|
||||
static void _vglite_execute_drawing(lv_draw_vglite_unit_t * u);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
#define _draw_info LV_GLOBAL_DEFAULT()->draw_info
|
||||
|
||||
#if LV_USE_VGLITE_DRAW_ASYNC
|
||||
/*
|
||||
* Circular buffer to hold the queued and the flushed tasks.
|
||||
* Two indexes, _head and _tail, are used to signal the beginning
|
||||
* and the end of the valid tasks that are pending.
|
||||
*/
|
||||
static vglite_draw_tasks_t _draw_task_buf[VGLITE_TASK_BUF_SIZE];
|
||||
static volatile int _head = 0;
|
||||
static volatile int _tail = 0;
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_vglite_init(void)
|
||||
{
|
||||
lv_draw_buf_vglite_init_handlers();
|
||||
|
||||
lv_draw_vglite_unit_t * draw_vglite_unit = lv_draw_create_unit(sizeof(lv_draw_vglite_unit_t));
|
||||
draw_vglite_unit->base_unit.evaluate_cb = _vglite_evaluate;
|
||||
draw_vglite_unit->base_unit.dispatch_cb = _vglite_dispatch;
|
||||
#if LV_USE_VGLITE_DRAW_ASYNC
|
||||
draw_vglite_unit->base_unit.wait_for_finish_cb = _vglite_wait_for_finish;
|
||||
#endif
|
||||
draw_vglite_unit->base_unit.delete_cb = _vglite_delete;
|
||||
|
||||
#if LV_USE_VGLITE_DRAW_THREAD
|
||||
lv_thread_init(&draw_vglite_unit->thread, LV_THREAD_PRIO_HIGH, _vglite_render_thread_cb, 2 * 1024, draw_vglite_unit);
|
||||
#endif
|
||||
}
|
||||
|
||||
void lv_draw_vglite_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static inline bool _vglite_src_cf_supported(lv_color_format_t cf)
|
||||
{
|
||||
bool is_cf_supported = false;
|
||||
|
||||
switch(cf) {
|
||||
#if CHIPID == 0x255 || CHIPID == 0x555
|
||||
case LV_COLOR_FORMAT_I1:
|
||||
case LV_COLOR_FORMAT_I2:
|
||||
case LV_COLOR_FORMAT_I4:
|
||||
case LV_COLOR_FORMAT_I8:
|
||||
#endif
|
||||
case LV_COLOR_FORMAT_A4:
|
||||
case LV_COLOR_FORMAT_A8:
|
||||
case LV_COLOR_FORMAT_L8:
|
||||
case LV_COLOR_FORMAT_RGB565:
|
||||
#if CHIPID == 0x555
|
||||
case LV_COLOR_FORMAT_RGB565A8:
|
||||
case LV_COLOR_FORMAT_RGB888:
|
||||
#endif
|
||||
case LV_COLOR_FORMAT_ARGB8888:
|
||||
case LV_COLOR_FORMAT_XRGB8888:
|
||||
is_cf_supported = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return is_cf_supported;
|
||||
}
|
||||
|
||||
static inline bool _vglite_dest_cf_supported(lv_color_format_t cf)
|
||||
{
|
||||
bool is_cf_supported = false;
|
||||
|
||||
switch(cf) {
|
||||
case LV_COLOR_FORMAT_A8:
|
||||
#if CHIPID == 0x255 || CHIPID == 0x555
|
||||
case LV_COLOR_FORMAT_L8:
|
||||
#endif
|
||||
case LV_COLOR_FORMAT_RGB565:
|
||||
#if CHIPID == 0x555
|
||||
case LV_COLOR_FORMAT_RGB565A8:
|
||||
case LV_COLOR_FORMAT_RGB888:
|
||||
#endif
|
||||
case LV_COLOR_FORMAT_ARGB8888:
|
||||
case LV_COLOR_FORMAT_XRGB8888:
|
||||
is_cf_supported = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return is_cf_supported;
|
||||
}
|
||||
|
||||
static int32_t _vglite_evaluate(lv_draw_unit_t * u, lv_draw_task_t * t)
|
||||
{
|
||||
LV_UNUSED(u);
|
||||
|
||||
const lv_draw_dsc_base_t * draw_dsc_base = (lv_draw_dsc_base_t *) t->draw_dsc;
|
||||
|
||||
if(!_vglite_dest_cf_supported(draw_dsc_base->layer->color_format))
|
||||
return 0;
|
||||
|
||||
switch(t->type) {
|
||||
case LV_DRAW_TASK_TYPE_FILL:
|
||||
if(t->preference_score > 80) {
|
||||
t->preference_score = 80;
|
||||
t->preferred_draw_unit_id = DRAW_UNIT_ID_VGLITE;
|
||||
}
|
||||
return 1;
|
||||
|
||||
case LV_DRAW_TASK_TYPE_LINE:
|
||||
case LV_DRAW_TASK_TYPE_ARC:
|
||||
case LV_DRAW_TASK_TYPE_TRIANGLE:
|
||||
if(t->preference_score > 90) {
|
||||
t->preference_score = 90;
|
||||
t->preferred_draw_unit_id = DRAW_UNIT_ID_VGLITE;
|
||||
}
|
||||
return 1;
|
||||
|
||||
case LV_DRAW_TASK_TYPE_LABEL:
|
||||
if(t->preference_score > 95) {
|
||||
t->preference_score = 95;
|
||||
t->preferred_draw_unit_id = DRAW_UNIT_ID_VGLITE;
|
||||
}
|
||||
return 1;
|
||||
|
||||
case LV_DRAW_TASK_TYPE_BORDER: {
|
||||
if(t->preference_score > 90) {
|
||||
t->preference_score = 90;
|
||||
t->preferred_draw_unit_id = DRAW_UNIT_ID_VGLITE;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
case LV_DRAW_TASK_TYPE_LAYER: {
|
||||
const lv_draw_image_dsc_t * draw_dsc = (lv_draw_image_dsc_t *) t->draw_dsc;
|
||||
lv_layer_t * layer_to_draw = (lv_layer_t *)draw_dsc->src;
|
||||
|
||||
#if LV_USE_VGLITE_BLIT_SPLIT
|
||||
bool has_transform = (draw_dsc->rotation != 0 || draw_dsc->scale_x != LV_SCALE_NONE ||
|
||||
draw_dsc->scale_y != LV_SCALE_NONE);
|
||||
#endif
|
||||
if(!_vglite_src_cf_supported(layer_to_draw->color_format)
|
||||
#if LV_USE_VGLITE_BLIT_SPLIT
|
||||
|| has_transform
|
||||
#endif
|
||||
)
|
||||
return 0;
|
||||
|
||||
if(t->preference_score > 80) {
|
||||
t->preference_score = 80;
|
||||
t->preferred_draw_unit_id = DRAW_UNIT_ID_VGLITE;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
case LV_DRAW_TASK_TYPE_IMAGE: {
|
||||
lv_draw_image_dsc_t * draw_dsc = (lv_draw_image_dsc_t *) t->draw_dsc;
|
||||
const lv_image_dsc_t * img_dsc = draw_dsc->src;
|
||||
|
||||
#if LV_USE_VGLITE_BLIT_SPLIT
|
||||
bool has_transform = (draw_dsc->rotation != 0 || draw_dsc->scale_x != LV_SCALE_NONE ||
|
||||
draw_dsc->scale_y != LV_SCALE_NONE);
|
||||
#endif
|
||||
|
||||
if((!_vglite_src_cf_supported(img_dsc->header.cf))
|
||||
#if LV_USE_VGLITE_BLIT_SPLIT
|
||||
|| has_transform
|
||||
#endif
|
||||
|| (!vglite_src_buf_aligned(img_dsc->data, img_dsc->header.stride, img_dsc->header.cf))
|
||||
)
|
||||
return 0;
|
||||
|
||||
if(t->preference_score > 80) {
|
||||
t->preference_score = 80;
|
||||
t->preferred_draw_unit_id = DRAW_UNIT_ID_VGLITE;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t _vglite_dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer)
|
||||
{
|
||||
lv_draw_vglite_unit_t * draw_vglite_unit = (lv_draw_vglite_unit_t *) draw_unit;
|
||||
|
||||
/* Return immediately if it's busy with draw task. */
|
||||
if(draw_vglite_unit->task_act)
|
||||
return 0;
|
||||
|
||||
/* Try to get an ready to draw. */
|
||||
lv_draw_task_t * t = lv_draw_get_next_available_task(layer, NULL, DRAW_UNIT_ID_VGLITE);
|
||||
|
||||
if(t == NULL)
|
||||
return LV_DRAW_UNIT_IDLE;
|
||||
|
||||
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. */
|
||||
t->state = LV_DRAW_TASK_STATE_READY;
|
||||
/* Request a new dispatching as it can get a new task. */
|
||||
lv_draw_dispatch_request();
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(lv_draw_layer_alloc_buf(layer) == NULL)
|
||||
return LV_DRAW_UNIT_IDLE;
|
||||
|
||||
t->state = LV_DRAW_TASK_STATE_IN_PROGRESS;
|
||||
draw_vglite_unit->base_unit.target_layer = layer;
|
||||
draw_vglite_unit->base_unit.clip_area = &t->clip_area;
|
||||
draw_vglite_unit->task_act = t;
|
||||
|
||||
#if LV_USE_VGLITE_DRAW_THREAD
|
||||
/* Let the render thread work. */
|
||||
if(draw_vglite_unit->inited)
|
||||
lv_thread_sync_signal(&draw_vglite_unit->sync);
|
||||
#else
|
||||
_vglite_execute_drawing(draw_vglite_unit);
|
||||
|
||||
draw_vglite_unit->task_act->state = LV_DRAW_TASK_STATE_READY;
|
||||
draw_vglite_unit->task_act = NULL;
|
||||
|
||||
/* The draw unit is free now. Request a new dispatching as it can get a new task. */
|
||||
lv_draw_dispatch_request();
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if LV_USE_VGLITE_DRAW_ASYNC
|
||||
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
|
||||
|
||||
static int32_t _vglite_delete(lv_draw_unit_t * draw_unit)
|
||||
{
|
||||
#if LV_USE_VGLITE_DRAW_THREAD
|
||||
lv_draw_vglite_unit_t * draw_vglite_unit = (lv_draw_vglite_unit_t *) draw_unit;
|
||||
|
||||
LV_LOG_INFO("Cancel VGLite draw thread.");
|
||||
draw_vglite_unit->exit_status = true;
|
||||
|
||||
if(draw_vglite_unit->inited)
|
||||
lv_thread_sync_signal(&draw_vglite_unit->sync);
|
||||
|
||||
lv_result_t res = lv_thread_delete(&draw_vglite_unit->thread);
|
||||
|
||||
return res;
|
||||
#else
|
||||
LV_UNUSED(draw_unit);
|
||||
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void _vglite_execute_drawing(lv_draw_vglite_unit_t * u)
|
||||
{
|
||||
lv_draw_task_t * t = u->task_act;
|
||||
lv_draw_unit_t * draw_unit = (lv_draw_unit_t *)u;
|
||||
lv_layer_t * layer = draw_unit->target_layer;
|
||||
lv_draw_buf_t * draw_buf = layer->draw_buf;
|
||||
|
||||
/* Set target buffer */
|
||||
vglite_set_dest_buf(draw_buf->data, draw_buf->header.w, draw_buf->header.h, draw_buf->header.stride,
|
||||
draw_buf->header.cf);
|
||||
|
||||
lv_area_t clip_area;
|
||||
lv_area_copy(&clip_area, draw_unit->clip_area);
|
||||
lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1);
|
||||
|
||||
lv_area_t draw_area;
|
||||
lv_area_copy(&draw_area, &t->area);
|
||||
lv_area_move(&draw_area, -layer->buf_area.x1, -layer->buf_area.y1);
|
||||
|
||||
if(!lv_area_intersect(&draw_area, &draw_area, &clip_area))
|
||||
return; /*Fully clipped, nothing to do*/
|
||||
|
||||
if(_draw_info.unit_cnt > 1)
|
||||
lv_draw_buf_invalidate_cache(draw_buf, &draw_area);
|
||||
|
||||
/* Set scissor area, excluding the split blit case */
|
||||
#if LV_USE_VGLITE_BLIT_SPLIT
|
||||
if(t->type != LV_DRAW_TASK_TYPE_IMAGE || t->type != LV_DRAW_TASK_TYPE_LAYER)
|
||||
#endif
|
||||
vglite_set_scissor(&clip_area);
|
||||
|
||||
switch(t->type) {
|
||||
case LV_DRAW_TASK_TYPE_LABEL:
|
||||
lv_draw_vglite_label(draw_unit, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_FILL:
|
||||
lv_draw_vglite_fill(draw_unit, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_BORDER:
|
||||
lv_draw_vglite_border(draw_unit, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_IMAGE:
|
||||
lv_draw_vglite_img(draw_unit, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_ARC:
|
||||
lv_draw_vglite_arc(draw_unit, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_LINE:
|
||||
lv_draw_vglite_line(draw_unit, t->draw_dsc);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_LAYER:
|
||||
lv_draw_vglite_layer(draw_unit, t->draw_dsc, &t->area);
|
||||
break;
|
||||
case LV_DRAW_TASK_TYPE_TRIANGLE:
|
||||
lv_draw_vglite_triangle(draw_unit, t->draw_dsc);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Disable scissor */
|
||||
vglite_set_scissor(&layer->buf_area);
|
||||
|
||||
#if LV_USE_PARALLEL_DRAW_DEBUG
|
||||
/*Layers manage it for themselves*/
|
||||
if(t->type != LV_DRAW_TASK_TYPE_LAYER) {
|
||||
lv_area_t draw_area;
|
||||
if(!lv_area_intersect(&draw_area, &t->area, u->base_unit.clip_area))
|
||||
return;
|
||||
|
||||
int32_t idx = 0;
|
||||
lv_draw_unit_t * draw_unit_tmp = _draw_info.unit_head;
|
||||
while(draw_unit_tmp != (lv_draw_unit_t *)u) {
|
||||
draw_unit_tmp = draw_unit_tmp->next;
|
||||
idx++;
|
||||
}
|
||||
lv_draw_rect_dsc_t rect_dsc;
|
||||
lv_draw_rect_dsc_init(&rect_dsc);
|
||||
rect_dsc.bg_color = lv_palette_main(idx % LV_PALETTE_LAST);
|
||||
rect_dsc.border_color = rect_dsc.bg_color;
|
||||
rect_dsc.bg_opa = LV_OPA_10;
|
||||
rect_dsc.border_opa = LV_OPA_80;
|
||||
rect_dsc.border_width = 1;
|
||||
lv_draw_sw_fill((lv_draw_unit_t *)u, &rect_dsc, &draw_area);
|
||||
|
||||
lv_point_t txt_size;
|
||||
lv_text_get_size(&txt_size, "W", LV_FONT_DEFAULT, 0, 0, 100, LV_TEXT_FLAG_NONE);
|
||||
|
||||
lv_area_t txt_area;
|
||||
txt_area.x1 = draw_area.x1;
|
||||
txt_area.y1 = draw_area.y1;
|
||||
txt_area.x2 = draw_area.x1 + txt_size.x - 1;
|
||||
txt_area.y2 = draw_area.y1 + txt_size.y - 1;
|
||||
|
||||
lv_draw_rect_dsc_init(&rect_dsc);
|
||||
rect_dsc.bg_color = lv_color_white();
|
||||
lv_draw_sw_fill((lv_draw_unit_t *)u, &rect_dsc, &txt_area);
|
||||
|
||||
char buf[8];
|
||||
lv_snprintf(buf, sizeof(buf), "%d", idx);
|
||||
lv_draw_label_dsc_t label_dsc;
|
||||
lv_draw_label_dsc_init(&label_dsc);
|
||||
label_dsc.color = lv_color_black();
|
||||
label_dsc.text = buf;
|
||||
lv_draw_sw_label((lv_draw_unit_t *)u, &label_dsc, &txt_area);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if LV_USE_VGLITE_DRAW_ASYNC
|
||||
static inline void _vglite_queue_task(lv_draw_task_t * task)
|
||||
{
|
||||
VGLITE_ASSERT_MSG(((_tail + 1) % VGLITE_TASK_BUF_SIZE) != _head, "VGLite task buffer full.");
|
||||
|
||||
_draw_task_buf[_tail].task = task;
|
||||
_draw_task_buf[_tail].flushed = false;
|
||||
_tail = (_tail + 1) % VGLITE_TASK_BUF_SIZE;
|
||||
}
|
||||
|
||||
static inline void _vglite_signal_task_ready(lv_draw_task_t * task)
|
||||
{
|
||||
/* Signal the ready state to dispatcher. */
|
||||
task->state = LV_DRAW_TASK_STATE_READY;
|
||||
_head = (_head + 1) % VGLITE_TASK_BUF_SIZE;
|
||||
|
||||
/* No need to cleanup the tasks in buffer as we advance with the _head. */
|
||||
}
|
||||
|
||||
static inline void _vglite_signal_all_task_ready(void)
|
||||
{
|
||||
int end = (_head <= _tail) ? _tail : _tail + VGLITE_TASK_BUF_SIZE;
|
||||
|
||||
for(int i = _head; i < end; i++) {
|
||||
lv_draw_task_t * task = _draw_task_buf[i % VGLITE_TASK_BUF_SIZE].task;
|
||||
|
||||
_vglite_signal_task_ready(task);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void _vglite_signal_flushed_task_ready(void)
|
||||
{
|
||||
if(vglite_cmd_buf_is_flushed()) {
|
||||
int end = (_head <= _tail) ? _tail : _tail + VGLITE_TASK_BUF_SIZE;
|
||||
|
||||
for(int i = _head; i < end; i++) {
|
||||
if(_draw_task_buf[i % VGLITE_TASK_BUF_SIZE].flushed) {
|
||||
lv_draw_task_t * task = _draw_task_buf[i % VGLITE_TASK_BUF_SIZE].task;
|
||||
|
||||
_vglite_signal_task_ready(task);
|
||||
|
||||
}
|
||||
else {
|
||||
/* Those tasks have been flushed now. */
|
||||
_draw_task_buf[i % VGLITE_TASK_BUF_SIZE].flushed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LV_USE_VGLITE_DRAW_THREAD
|
||||
static void _vglite_render_thread_cb(void * ptr)
|
||||
{
|
||||
lv_draw_vglite_unit_t * u = ptr;
|
||||
|
||||
lv_thread_sync_init(&u->sync);
|
||||
u->inited = true;
|
||||
|
||||
while(1) {
|
||||
/* Wait for sync if there is no task set. */
|
||||
while(u->task_act == NULL
|
||||
#if LV_USE_VGLITE_DRAW_ASYNC
|
||||
/*
|
||||
* Wait for sync if _draw_task_buf is empty.
|
||||
* The thread will have to run to complete any pending tasks.
|
||||
*/
|
||||
&& !u->wait_for_finish
|
||||
#endif
|
||||
) {
|
||||
if(u->exit_status)
|
||||
break;
|
||||
|
||||
lv_thread_sync_wait(&u->sync);
|
||||
}
|
||||
|
||||
if(u->exit_status) {
|
||||
LV_LOG_INFO("Ready to exit VGLite draw thread.");
|
||||
break;
|
||||
}
|
||||
|
||||
if(u->task_act) {
|
||||
#if LV_USE_VGLITE_DRAW_ASYNC
|
||||
_vglite_queue_task((void *)u->task_act);
|
||||
#endif
|
||||
_vglite_execute_drawing(u);
|
||||
}
|
||||
#if LV_USE_VGLITE_DRAW_ASYNC
|
||||
if(u->wait_for_finish) {
|
||||
u->wait_for_finish = false;
|
||||
vglite_wait_for_finish();
|
||||
_vglite_signal_all_task_ready();
|
||||
}
|
||||
else { /* u->task_act */
|
||||
_vglite_signal_flushed_task_ready();
|
||||
}
|
||||
#else
|
||||
/* Signal the ready state to dispatcher. */
|
||||
u->task_act->state = LV_DRAW_TASK_STATE_READY;
|
||||
#endif
|
||||
/* Cleanup. */
|
||||
u->task_act = NULL;
|
||||
|
||||
/* The draw unit is free now. Request a new dispatching as it can get a new task. */
|
||||
lv_draw_dispatch_request();
|
||||
}
|
||||
|
||||
u->inited = false;
|
||||
lv_thread_sync_delete(&u->sync);
|
||||
LV_LOG_INFO("Exit VGLite draw thread.");
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*LV_USE_DRAW_VGLITE*/
|
||||
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* @file lv_draw_vglite.h
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2023-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef LV_DRAW_VGLITE_H
|
||||
#define LV_DRAW_VGLITE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_DRAW_VGLITE
|
||||
#include "../../lv_draw_private.h"
|
||||
#include "../../sw/lv_draw_sw_private.h"
|
||||
#include "../../../misc/lv_area_private.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct lv_draw_vglite_unit {
|
||||
lv_draw_sw_unit_t;
|
||||
#if LV_USE_VGLITE_DRAW_ASYNC
|
||||
volatile bool wait_for_finish;
|
||||
#endif
|
||||
} lv_draw_vglite_unit_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
void lv_draw_buf_vglite_init_handlers(void);
|
||||
|
||||
void lv_draw_vglite_init(void);
|
||||
|
||||
void lv_draw_vglite_deinit(void);
|
||||
|
||||
void lv_draw_vglite_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc,
|
||||
const lv_area_t * coords);
|
||||
|
||||
void lv_draw_vglite_border(lv_draw_unit_t * draw_unit, const lv_draw_border_dsc_t * dsc,
|
||||
const lv_area_t * coords);
|
||||
|
||||
void lv_draw_vglite_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc,
|
||||
const lv_area_t * coords);
|
||||
|
||||
void lv_draw_vglite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dsc,
|
||||
const lv_area_t * coords);
|
||||
|
||||
void lv_draw_vglite_label(lv_draw_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc,
|
||||
const lv_area_t * coords);
|
||||
|
||||
void lv_draw_vglite_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc,
|
||||
const lv_area_t * coords);
|
||||
|
||||
void lv_draw_vglite_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc);
|
||||
|
||||
void lv_draw_vglite_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle_dsc_t * dsc);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
#endif /*LV_USE_DRAW_VGLITE*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_DRAW_VGLITE_H*/
|
||||
@@ -0,0 +1,686 @@
|
||||
/**
|
||||
* @file lv_draw_vglite_arc.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2021-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_vglite.h"
|
||||
|
||||
#if LV_USE_DRAW_VGLITE
|
||||
#include "lv_vglite_buf.h"
|
||||
#include "lv_vglite_path.h"
|
||||
#include "lv_vglite_utils.h"
|
||||
|
||||
#include "../../../stdlib/lv_string.h"
|
||||
#include <math.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define T_FRACTION 16384.0f
|
||||
|
||||
#define DICHOTO_ITER 5
|
||||
|
||||
static const uint16_t TperDegree[90] = {
|
||||
0, 174, 348, 522, 697, 873, 1049, 1226, 1403, 1581,
|
||||
1759, 1938, 2117, 2297, 2477, 2658, 2839, 3020, 3202, 3384,
|
||||
3567, 3749, 3933, 4116, 4300, 4484, 4668, 4852, 5037, 5222,
|
||||
5407, 5592, 5777, 5962, 6148, 6334, 6519, 6705, 6891, 7077,
|
||||
7264, 7450, 7636, 7822, 8008, 8193, 8378, 8564, 8750, 8936,
|
||||
9122, 9309, 9495, 9681, 9867, 10052, 10238, 10424, 10609, 10794,
|
||||
10979, 11164, 11349, 11534, 11718, 11902, 12086, 12270, 12453, 12637,
|
||||
12819, 13002, 13184, 13366, 13547, 13728, 13909, 14089, 14269, 14448,
|
||||
14627, 14805, 14983, 15160, 15337, 15513, 15689, 15864, 16038, 16212
|
||||
};
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/* intermediate arc params */
|
||||
typedef struct _vg_arc {
|
||||
int32_t angle; /* angle <90deg */
|
||||
int32_t quarter; /* 0-3 counter-clockwise */
|
||||
int32_t rad; /* radius */
|
||||
int32_t p0x; /* point P0 */
|
||||
int32_t p0y;
|
||||
int32_t p1x; /* point P1 */
|
||||
int32_t p1y;
|
||||
int32_t p2x; /* point P2 */
|
||||
int32_t p2y;
|
||||
int32_t p3x; /* point P3 */
|
||||
int32_t p3y;
|
||||
} vg_arc;
|
||||
|
||||
typedef struct _cubic_cont_pt {
|
||||
float p0;
|
||||
float p1;
|
||||
float p2;
|
||||
float p3;
|
||||
} cubic_cont_pt;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Draw arc shape with effects
|
||||
*
|
||||
* @param[in] center Arc center with relative coordinates
|
||||
* @param[in] clip_area Clip area with relative coordinates to dest buff
|
||||
* @param[in] dsc Arc description structure (width, rounded ending, opacity)
|
||||
*
|
||||
*/
|
||||
static void _vglite_draw_arc(const lv_point_t * center, const lv_area_t * clip_area,
|
||||
const lv_draw_arc_dsc_t * dsc);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_vglite_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc,
|
||||
const lv_area_t * coords)
|
||||
{
|
||||
LV_UNUSED(coords);
|
||||
|
||||
if(dsc->opa <= (lv_opa_t)LV_OPA_MIN)
|
||||
return;
|
||||
if(dsc->width == 0)
|
||||
return;
|
||||
if(dsc->start_angle == dsc->end_angle)
|
||||
return;
|
||||
|
||||
lv_layer_t * layer = draw_unit->target_layer;
|
||||
lv_point_t center = {dsc->center.x - layer->buf_area.x1, dsc->center.y - layer->buf_area.y1};
|
||||
|
||||
lv_area_t clip_area;
|
||||
lv_area_copy(&clip_area, draw_unit->clip_area);
|
||||
lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1);
|
||||
|
||||
_vglite_draw_arc(¢er, &clip_area, dsc);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void _copy_arc(vg_arc * dst, vg_arc * src)
|
||||
{
|
||||
dst->quarter = src->quarter;
|
||||
dst->rad = src->rad;
|
||||
dst->angle = src->angle;
|
||||
dst->p0x = src->p0x;
|
||||
dst->p1x = src->p1x;
|
||||
dst->p2x = src->p2x;
|
||||
dst->p3x = src->p3x;
|
||||
dst->p0y = src->p0y;
|
||||
dst->p1y = src->p1y;
|
||||
dst->p2y = src->p2y;
|
||||
dst->p3y = src->p3y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate the point according given rotation angle rotation center is 0,0
|
||||
*/
|
||||
static void _rotate_point(int32_t angle, int32_t * x, int32_t * y)
|
||||
{
|
||||
int32_t ori_x = *x;
|
||||
int32_t ori_y = *y;
|
||||
int16_t alpha = (int16_t)angle;
|
||||
*x = ((lv_trigo_cos(alpha) * ori_x) / LV_TRIGO_SIN_MAX) - ((lv_trigo_sin(alpha) * ori_y) / LV_TRIGO_SIN_MAX);
|
||||
*y = ((lv_trigo_sin(alpha) * ori_x) / LV_TRIGO_SIN_MAX) + ((lv_trigo_cos(alpha) * ori_y) / LV_TRIGO_SIN_MAX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set full arc control points depending on quarter.
|
||||
* Control points match the best approximation of a circle.
|
||||
* Arc Quarter position is:
|
||||
* Q2 | Q3
|
||||
* ---+---
|
||||
* Q1 | Q0
|
||||
*/
|
||||
static void _set_full_arc(vg_arc * fullarc)
|
||||
{
|
||||
/* the tangent length for the bezier circle approx */
|
||||
float tang = ((float)fullarc->rad) * BEZIER_OPTIM_CIRCLE;
|
||||
switch(fullarc->quarter) {
|
||||
case 0:
|
||||
/* first quarter */
|
||||
fullarc->p0x = fullarc->rad;
|
||||
fullarc->p0y = 0;
|
||||
fullarc->p1x = fullarc->rad;
|
||||
fullarc->p1y = (int32_t)tang;
|
||||
fullarc->p2x = (int32_t)tang;
|
||||
fullarc->p2y = fullarc->rad;
|
||||
fullarc->p3x = 0;
|
||||
fullarc->p3y = fullarc->rad;
|
||||
break;
|
||||
case 1:
|
||||
/* second quarter */
|
||||
fullarc->p0x = 0;
|
||||
fullarc->p0y = fullarc->rad;
|
||||
fullarc->p1x = 0 - (int32_t)tang;
|
||||
fullarc->p1y = fullarc->rad;
|
||||
fullarc->p2x = 0 - fullarc->rad;
|
||||
fullarc->p2y = (int32_t)tang;
|
||||
fullarc->p3x = 0 - fullarc->rad;
|
||||
fullarc->p3y = 0;
|
||||
break;
|
||||
case 2:
|
||||
/* third quarter */
|
||||
fullarc->p0x = 0 - fullarc->rad;
|
||||
fullarc->p0y = 0;
|
||||
fullarc->p1x = 0 - fullarc->rad;
|
||||
fullarc->p1y = 0 - (int32_t)tang;
|
||||
fullarc->p2x = 0 - (int32_t)tang;
|
||||
fullarc->p2y = 0 - fullarc->rad;
|
||||
fullarc->p3x = 0;
|
||||
fullarc->p3y = 0 - fullarc->rad;
|
||||
break;
|
||||
case 3:
|
||||
/* fourth quarter */
|
||||
fullarc->p0x = 0;
|
||||
fullarc->p0y = 0 - fullarc->rad;
|
||||
fullarc->p1x = (int32_t)tang;
|
||||
fullarc->p1y = 0 - fullarc->rad;
|
||||
fullarc->p2x = fullarc->rad;
|
||||
fullarc->p2y = 0 - (int32_t)tang;
|
||||
fullarc->p3x = fullarc->rad;
|
||||
fullarc->p3y = 0;
|
||||
break;
|
||||
default:
|
||||
VGLITE_ASSERT_MSG(false, "Invalid arc quarter.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Linear interpolation between two points 'a' and 'b'
|
||||
* 't' parameter is the proportion ratio expressed in range [0 ; T_FRACTION ]
|
||||
*/
|
||||
static inline float _lerp(float coord_a, float coord_b, uint16_t t)
|
||||
{
|
||||
float tf = (float)t;
|
||||
return ((T_FRACTION - tf) * coord_a + tf * coord_b) / T_FRACTION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a point of bezier curve given 't' param
|
||||
*/
|
||||
static inline float _comp_bezier_point(float t, cubic_cont_pt cp)
|
||||
{
|
||||
float t_sq = t * t;
|
||||
float inv_t_sq = (1.0f - t) * (1.0f - t);
|
||||
float apt = (1.0f - t) * inv_t_sq * cp.p0 + 3.0f * inv_t_sq * t * cp.p1 + 3.0f * (1.0f - t) * t_sq * cp.p2 + t * t_sq *
|
||||
cp.p3;
|
||||
return apt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find parameter 't' in curve at point 'pt'
|
||||
* proceed by dichotomy on only 1 dimension,
|
||||
* works only if the curve is monotonic
|
||||
* bezier curve is defined by control points [p0 p1 p2 p3]
|
||||
* 'dec' tells if curve is decreasing (true) or increasing (false)
|
||||
*/
|
||||
static uint16_t _get_bez_t_from_pos(float pt, cubic_cont_pt cp, bool dec)
|
||||
{
|
||||
/* initialize dichotomy with boundary 't' values */
|
||||
float t_low = 0.0f;
|
||||
float t_mid = 0.5f;
|
||||
float t_hig = 1.0f;
|
||||
float a_pt;
|
||||
/* dichotomy loop */
|
||||
for(int i = 0; i < DICHOTO_ITER; i++) {
|
||||
a_pt = _comp_bezier_point(t_mid, cp);
|
||||
/* check mid-point position on bezier curve versus targeted point */
|
||||
if((a_pt > pt) != dec) {
|
||||
t_hig = t_mid;
|
||||
}
|
||||
else {
|
||||
t_low = t_mid;
|
||||
}
|
||||
/* define new 't' param for mid-point */
|
||||
t_mid = (t_low + t_hig) / 2.0f;
|
||||
}
|
||||
/* return parameter 't' in integer range [0 ; T_FRACTION] */
|
||||
return (uint16_t)floorf(t_mid * T_FRACTION + 0.5f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives relative coords of the control points
|
||||
* for the sub-arc starting at angle with given angle span
|
||||
*/
|
||||
static void _get_subarc_control_points(vg_arc * arc, int32_t span)
|
||||
{
|
||||
vg_arc fullarc = {0};
|
||||
fullarc.angle = arc->angle;
|
||||
fullarc.quarter = arc->quarter;
|
||||
fullarc.rad = arc->rad;
|
||||
_set_full_arc(&fullarc);
|
||||
|
||||
/* special case of full arc */
|
||||
if(arc->angle == 90) {
|
||||
_copy_arc(arc, &fullarc);
|
||||
return;
|
||||
}
|
||||
|
||||
/* compute 1st arc using the geometric construction of curve */
|
||||
uint16_t t2 = TperDegree[arc->angle + span];
|
||||
|
||||
/* lerp for A */
|
||||
float a2x = _lerp((float)fullarc.p0x, (float)fullarc.p1x, t2);
|
||||
float a2y = _lerp((float)fullarc.p0y, (float)fullarc.p1y, t2);
|
||||
/* lerp for B */
|
||||
float b2x = _lerp((float)fullarc.p1x, (float)fullarc.p2x, t2);
|
||||
float b2y = _lerp((float)fullarc.p1y, (float)fullarc.p2y, t2);
|
||||
/* lerp for C */
|
||||
float c2x = _lerp((float)fullarc.p2x, (float)fullarc.p3x, t2);
|
||||
float c2y = _lerp((float)fullarc.p2y, (float)fullarc.p3y, t2);
|
||||
|
||||
/* lerp for D */
|
||||
float d2x = _lerp(a2x, b2x, t2);
|
||||
float d2y = _lerp(a2y, b2y, t2);
|
||||
/* lerp for E */
|
||||
float e2x = _lerp(b2x, c2x, t2);
|
||||
float e2y = _lerp(b2y, c2y, t2);
|
||||
|
||||
float pt2x = _lerp(d2x, e2x, t2);
|
||||
float pt2y = _lerp(d2y, e2y, t2);
|
||||
|
||||
/* compute sub-arc using the geometric construction of curve */
|
||||
uint16_t t1 = TperDegree[arc->angle];
|
||||
|
||||
/* lerp for A */
|
||||
float a1x = _lerp((float)fullarc.p0x, (float)fullarc.p1x, t1);
|
||||
float a1y = _lerp((float)fullarc.p0y, (float)fullarc.p1y, t1);
|
||||
/* lerp for B */
|
||||
float b1x = _lerp((float)fullarc.p1x, (float)fullarc.p2x, t1);
|
||||
float b1y = _lerp((float)fullarc.p1y, (float)fullarc.p2y, t1);
|
||||
/* lerp for C */
|
||||
float c1x = _lerp((float)fullarc.p2x, (float)fullarc.p3x, t1);
|
||||
float c1y = _lerp((float)fullarc.p2y, (float)fullarc.p3y, t1);
|
||||
|
||||
/* lerp for D */
|
||||
float d1x = _lerp(a1x, b1x, t1);
|
||||
float d1y = _lerp(a1y, b1y, t1);
|
||||
/* lerp for E */
|
||||
float e1x = _lerp(b1x, c1x, t1);
|
||||
float e1y = _lerp(b1y, c1y, t1);
|
||||
|
||||
float pt1x = _lerp(d1x, e1x, t1);
|
||||
float pt1y = _lerp(d1y, e1y, t1);
|
||||
|
||||
/* find the 't3' parameter for point P(t1) on the sub-arc [P0 A2 D2 P(t2)] using dichotomy
|
||||
* use position of x axis only */
|
||||
uint16_t t3;
|
||||
t3 = _get_bez_t_from_pos(pt1x,
|
||||
(cubic_cont_pt) {
|
||||
.p0 = ((float)fullarc.p0x), .p1 = a2x, .p2 = d2x, .p3 = pt2x
|
||||
},
|
||||
(bool)(pt2x < (float)fullarc.p0x));
|
||||
|
||||
/* lerp for B */
|
||||
float b3x = _lerp(a2x, d2x, t3);
|
||||
float b3y = _lerp(a2y, d2y, t3);
|
||||
/* lerp for C */
|
||||
float c3x = _lerp(d2x, pt2x, t3);
|
||||
float c3y = _lerp(d2y, pt2y, t3);
|
||||
|
||||
/* lerp for E */
|
||||
float e3x = _lerp(b3x, c3x, t3);
|
||||
float e3y = _lerp(b3y, c3y, t3);
|
||||
|
||||
arc->p0x = (int32_t)floorf(0.5f + pt1x);
|
||||
arc->p0y = (int32_t)floorf(0.5f + pt1y);
|
||||
arc->p1x = (int32_t)floorf(0.5f + e3x);
|
||||
arc->p1y = (int32_t)floorf(0.5f + e3y);
|
||||
arc->p2x = (int32_t)floorf(0.5f + c3x);
|
||||
arc->p2y = (int32_t)floorf(0.5f + c3y);
|
||||
arc->p3x = (int32_t)floorf(0.5f + pt2x);
|
||||
arc->p3y = (int32_t)floorf(0.5f + pt2y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives relative coords of the control points
|
||||
*/
|
||||
static void _get_arc_control_points(vg_arc * arc, bool start)
|
||||
{
|
||||
vg_arc fullarc = {0};
|
||||
fullarc.angle = arc->angle;
|
||||
fullarc.quarter = arc->quarter;
|
||||
fullarc.rad = arc->rad;
|
||||
_set_full_arc(&fullarc);
|
||||
|
||||
/* special case of full arc */
|
||||
if(arc->angle == 90) {
|
||||
_copy_arc(arc, &fullarc);
|
||||
return;
|
||||
}
|
||||
|
||||
/* compute sub-arc using the geometric construction of curve */
|
||||
uint16_t t = TperDegree[arc->angle];
|
||||
/* lerp for A */
|
||||
float ax = _lerp((float)fullarc.p0x, (float)fullarc.p1x, t);
|
||||
float ay = _lerp((float)fullarc.p0y, (float)fullarc.p1y, t);
|
||||
/* lerp for B */
|
||||
float bx = _lerp((float)fullarc.p1x, (float)fullarc.p2x, t);
|
||||
float by = _lerp((float)fullarc.p1y, (float)fullarc.p2y, t);
|
||||
/* lerp for C */
|
||||
float cx = _lerp((float)fullarc.p2x, (float)fullarc.p3x, t);
|
||||
float cy = _lerp((float)fullarc.p2y, (float)fullarc.p3y, t);
|
||||
|
||||
/* lerp for D */
|
||||
float dx = _lerp(ax, bx, t);
|
||||
float dy = _lerp(ay, by, t);
|
||||
/* lerp for E */
|
||||
float ex = _lerp(bx, cx, t);
|
||||
float ey = _lerp(by, cy, t);
|
||||
|
||||
/* sub-arc's control points are tangents of DeCasteljau's algorithm */
|
||||
if(start) {
|
||||
arc->p0x = (int32_t)floorf(0.5f + _lerp(dx, ex, t));
|
||||
arc->p0y = (int32_t)floorf(0.5f + _lerp(dy, ey, t));
|
||||
arc->p1x = (int32_t)floorf(0.5f + ex);
|
||||
arc->p1y = (int32_t)floorf(0.5f + ey);
|
||||
arc->p2x = (int32_t)floorf(0.5f + cx);
|
||||
arc->p2y = (int32_t)floorf(0.5f + cy);
|
||||
arc->p3x = fullarc.p3x;
|
||||
arc->p3y = fullarc.p3y;
|
||||
}
|
||||
else {
|
||||
arc->p0x = fullarc.p0x;
|
||||
arc->p0y = fullarc.p0y;
|
||||
arc->p1x = (int32_t)floorf(0.5f + ax);
|
||||
arc->p1y = (int32_t)floorf(0.5f + ay);
|
||||
arc->p2x = (int32_t)floorf(0.5f + dx);
|
||||
arc->p2y = (int32_t)floorf(0.5f + dy);
|
||||
arc->p3x = (int32_t)floorf(0.5f + _lerp(dx, ex, t));
|
||||
arc->p3y = (int32_t)floorf(0.5f + _lerp(dy, ey, t));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the arc control points into the path data for vglite,
|
||||
* taking into account the real center of the arc (translation).
|
||||
* arc_path: (in/out) the path data array for vglite
|
||||
* pidx: (in/out) index of last element added in arc_path
|
||||
* q_arc: (in) the arc data containing control points
|
||||
* center: (in) the center of the circle in draw coordinates
|
||||
* cw: (in) true if arc is clockwise
|
||||
*/
|
||||
static void _add_split_arc_path(int32_t * arc_path, int * pidx, vg_arc * q_arc, const lv_point_t * center, bool cw)
|
||||
{
|
||||
/* assumes first control point already in array arc_path[] */
|
||||
int idx = *pidx;
|
||||
if(cw) {
|
||||
#if BEZIER_DBG_CONTROL_POINTS
|
||||
arc_path[idx++] = VLC_OP_LINE;
|
||||
arc_path[idx++] = q_arc->p1x + center->x;
|
||||
arc_path[idx++] = q_arc->p1y + center->y;
|
||||
arc_path[idx++] = VLC_OP_LINE;
|
||||
arc_path[idx++] = q_arc->p2x + center->x;
|
||||
arc_path[idx++] = q_arc->p2y + center->y;
|
||||
arc_path[idx++] = VLC_OP_LINE;
|
||||
arc_path[idx++] = q_arc->p3x + center->x;
|
||||
arc_path[idx++] = q_arc->p3y + center->y;
|
||||
#else
|
||||
arc_path[idx++] = VLC_OP_CUBIC;
|
||||
arc_path[idx++] = q_arc->p1x + center->x;
|
||||
arc_path[idx++] = q_arc->p1y + center->y;
|
||||
arc_path[idx++] = q_arc->p2x + center->x;
|
||||
arc_path[idx++] = q_arc->p2y + center->y;
|
||||
arc_path[idx++] = q_arc->p3x + center->x;
|
||||
arc_path[idx++] = q_arc->p3y + center->y;
|
||||
#endif
|
||||
}
|
||||
else { /* reverse points order when counter-clockwise */
|
||||
#if BEZIER_DBG_CONTROL_POINTS
|
||||
arc_path[idx++] = VLC_OP_LINE;
|
||||
arc_path[idx++] = q_arc->p2x + center->x;
|
||||
arc_path[idx++] = q_arc->p2y + center->y;
|
||||
arc_path[idx++] = VLC_OP_LINE;
|
||||
arc_path[idx++] = q_arc->p1x + center->x;
|
||||
arc_path[idx++] = q_arc->p1y + center->y;
|
||||
arc_path[idx++] = VLC_OP_LINE;
|
||||
arc_path[idx++] = q_arc->p0x + center->x;
|
||||
arc_path[idx++] = q_arc->p0y + center->y;
|
||||
#else
|
||||
arc_path[idx++] = VLC_OP_CUBIC;
|
||||
arc_path[idx++] = q_arc->p2x + center->x;
|
||||
arc_path[idx++] = q_arc->p2y + center->y;
|
||||
arc_path[idx++] = q_arc->p1x + center->x;
|
||||
arc_path[idx++] = q_arc->p1y + center->y;
|
||||
arc_path[idx++] = q_arc->p0x + center->x;
|
||||
arc_path[idx++] = q_arc->p0y + center->y;
|
||||
#endif
|
||||
}
|
||||
/* update index i n path array*/
|
||||
*pidx = idx;
|
||||
}
|
||||
|
||||
static void _add_arc_path(int32_t * arc_path, int * pidx, int32_t radius,
|
||||
int32_t start_angle, int32_t end_angle, const lv_point_t * center, bool cw)
|
||||
{
|
||||
/* set number of arcs to draw */
|
||||
vg_arc q_arc;
|
||||
int32_t start_arc_angle = start_angle % 90;
|
||||
int32_t end_arc_angle = end_angle % 90;
|
||||
int32_t inv_start_arc_angle = (start_arc_angle > 0) ? (90 - start_arc_angle) : 0;
|
||||
int32_t nbarc = (end_angle - start_angle - inv_start_arc_angle - end_arc_angle) / 90;
|
||||
q_arc.rad = radius;
|
||||
|
||||
/* handle special case of start & end point in the same quarter */
|
||||
if(((start_angle / 90) == (end_angle / 90)) && (nbarc <= 0)) {
|
||||
q_arc.quarter = (start_angle / 90) % 4;
|
||||
q_arc.angle = start_arc_angle;
|
||||
_get_subarc_control_points(&q_arc, end_arc_angle - start_arc_angle);
|
||||
_add_split_arc_path(arc_path, pidx, &q_arc, center, cw);
|
||||
return;
|
||||
}
|
||||
|
||||
if(cw) {
|
||||
/* partial starting arc */
|
||||
if(start_arc_angle > 0) {
|
||||
q_arc.quarter = (start_angle / 90) % 4;
|
||||
q_arc.angle = start_arc_angle;
|
||||
/* get cubic points relative to center */
|
||||
_get_arc_control_points(&q_arc, true);
|
||||
/* put cubic points in arc_path */
|
||||
_add_split_arc_path(arc_path, pidx, &q_arc, center, cw);
|
||||
}
|
||||
/* full arcs */
|
||||
for(int32_t q = 0; q < nbarc ; q++) {
|
||||
q_arc.quarter = (q + ((start_angle + 89) / 90)) % 4;
|
||||
q_arc.angle = 90;
|
||||
/* get cubic points relative to center */
|
||||
_get_arc_control_points(&q_arc, true); /* 2nd parameter 'start' ignored */
|
||||
/* put cubic points in arc_path */
|
||||
_add_split_arc_path(arc_path, pidx, &q_arc, center, cw);
|
||||
}
|
||||
/* partial ending arc */
|
||||
if(end_arc_angle > 0) {
|
||||
q_arc.quarter = (end_angle / 90) % 4;
|
||||
q_arc.angle = end_arc_angle;
|
||||
/* get cubic points relative to center */
|
||||
_get_arc_control_points(&q_arc, false);
|
||||
/* put cubic points in arc_path */
|
||||
_add_split_arc_path(arc_path, pidx, &q_arc, center, cw);
|
||||
}
|
||||
|
||||
}
|
||||
else { /* counter clockwise */
|
||||
|
||||
/* partial ending arc */
|
||||
if(end_arc_angle > 0) {
|
||||
q_arc.quarter = (end_angle / 90) % 4;
|
||||
q_arc.angle = end_arc_angle;
|
||||
/* get cubic points relative to center */
|
||||
_get_arc_control_points(&q_arc, false);
|
||||
/* put cubic points in arc_path */
|
||||
_add_split_arc_path(arc_path, pidx, &q_arc, center, cw);
|
||||
}
|
||||
/* full arcs */
|
||||
for(int32_t q = nbarc - 1; q >= 0; q--) {
|
||||
q_arc.quarter = (q + ((start_angle + 89) / 90)) % 4;
|
||||
q_arc.angle = 90;
|
||||
/* get cubic points relative to center */
|
||||
_get_arc_control_points(&q_arc, true); /* 2nd parameter 'start' ignored */
|
||||
/* put cubic points in arc_path */
|
||||
_add_split_arc_path(arc_path, pidx, &q_arc, center, cw);
|
||||
}
|
||||
/* partial starting arc */
|
||||
if(start_arc_angle > 0) {
|
||||
q_arc.quarter = (start_angle / 90) % 4;
|
||||
q_arc.angle = start_arc_angle;
|
||||
/* get cubic points relative to center */
|
||||
_get_arc_control_points(&q_arc, true);
|
||||
/* put cubic points in arc_path */
|
||||
_add_split_arc_path(arc_path, pidx, &q_arc, center, cw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void _vglite_draw_arc(const lv_point_t * center, const lv_area_t * clip_area,
|
||||
const lv_draw_arc_dsc_t * dsc)
|
||||
{
|
||||
vg_lite_path_t path;
|
||||
uint16_t start_angle = dsc->start_angle;
|
||||
uint16_t end_angle = dsc->end_angle;
|
||||
|
||||
/* be sure end_angle > start_angle */
|
||||
if(end_angle < start_angle)
|
||||
end_angle += 360;
|
||||
|
||||
bool donut = ((end_angle - start_angle) % 360 == 0) ? true : false;
|
||||
vg_lite_buffer_t * vgbuf = vglite_get_dest_buf();
|
||||
|
||||
int32_t arc_path[ARC_PATH_DATA_MAX_SIZE];
|
||||
lv_memzero(arc_path, sizeof(arc_path));
|
||||
|
||||
/*** Init path ***/
|
||||
int32_t width = dsc->width; /* inner arc radius = outer arc radius - width */
|
||||
uint16_t radius = dsc->radius;
|
||||
|
||||
if(width > radius)
|
||||
width = radius;
|
||||
|
||||
int pidx = 0;
|
||||
int32_t cp_x, cp_y; /* control point coords */
|
||||
|
||||
/* first control point of curve */
|
||||
cp_x = radius;
|
||||
cp_y = 0;
|
||||
_rotate_point(start_angle, &cp_x, &cp_y);
|
||||
arc_path[pidx++] = VLC_OP_MOVE;
|
||||
arc_path[pidx++] = center->x + cp_x;
|
||||
arc_path[pidx++] = center->y + cp_y;
|
||||
|
||||
/* draw 1-5 outer quarters */
|
||||
_add_arc_path(arc_path, &pidx, radius, start_angle, end_angle, center, true);
|
||||
|
||||
if(donut) {
|
||||
/* close outer circle */
|
||||
cp_x = radius;
|
||||
cp_y = 0;
|
||||
_rotate_point(start_angle, &cp_x, &cp_y);
|
||||
arc_path[pidx++] = VLC_OP_LINE;
|
||||
arc_path[pidx++] = center->x + cp_x;
|
||||
arc_path[pidx++] = center->y + cp_y;
|
||||
/* start inner circle */
|
||||
cp_x = radius - width;
|
||||
cp_y = 0;
|
||||
_rotate_point(start_angle, &cp_x, &cp_y);
|
||||
arc_path[pidx++] = VLC_OP_MOVE;
|
||||
arc_path[pidx++] = center->x + cp_x;
|
||||
arc_path[pidx++] = center->y + cp_y;
|
||||
|
||||
}
|
||||
else if(dsc->rounded != 0U) { /* 1st rounded arc ending */
|
||||
cp_x = radius - width / 2;
|
||||
cp_y = 0;
|
||||
_rotate_point(end_angle, &cp_x, &cp_y);
|
||||
lv_point_t round_center = {center->x + cp_x, center->y + cp_y};
|
||||
_add_arc_path(arc_path, &pidx, width / 2, end_angle, (end_angle + 180),
|
||||
&round_center, true);
|
||||
|
||||
}
|
||||
else { /* 1st flat ending */
|
||||
cp_x = radius - width;
|
||||
cp_y = 0;
|
||||
_rotate_point(end_angle, &cp_x, &cp_y);
|
||||
arc_path[pidx++] = VLC_OP_LINE;
|
||||
arc_path[pidx++] = center->x + cp_x;
|
||||
arc_path[pidx++] = center->y + cp_y;
|
||||
}
|
||||
|
||||
/* draw 1-5 inner quarters */
|
||||
_add_arc_path(arc_path, &pidx, radius - width, start_angle, end_angle, center, false);
|
||||
|
||||
/* last control point of curve */
|
||||
if(donut) { /* close the loop */
|
||||
cp_x = radius - width;
|
||||
cp_y = 0;
|
||||
_rotate_point(start_angle, &cp_x, &cp_y);
|
||||
arc_path[pidx++] = VLC_OP_LINE;
|
||||
arc_path[pidx++] = center->x + cp_x;
|
||||
arc_path[pidx++] = center->y + cp_y;
|
||||
|
||||
}
|
||||
else if(dsc->rounded != 0U) { /* 2nd rounded arc ending */
|
||||
cp_x = radius - width / 2;
|
||||
cp_y = 0;
|
||||
_rotate_point(start_angle, &cp_x, &cp_y);
|
||||
lv_point_t round_center = {center->x + cp_x, center->y + cp_y};
|
||||
_add_arc_path(arc_path, &pidx, width / 2, (start_angle + 180), (start_angle + 360),
|
||||
&round_center, true);
|
||||
|
||||
}
|
||||
else { /* 2nd flat ending */
|
||||
cp_x = radius;
|
||||
cp_y = 0;
|
||||
_rotate_point(start_angle, &cp_x, &cp_y);
|
||||
arc_path[pidx++] = VLC_OP_LINE;
|
||||
arc_path[pidx++] = center->x + cp_x;
|
||||
arc_path[pidx++] = center->y + cp_y;
|
||||
}
|
||||
|
||||
arc_path[pidx++] = VLC_OP_END;
|
||||
|
||||
VGLITE_CHECK_ERROR(vg_lite_init_path(&path, VG_LITE_S32, VG_LITE_HIGH, (uint32_t)pidx * sizeof(int32_t), arc_path,
|
||||
(vg_lite_float_t)clip_area->x1, (vg_lite_float_t)clip_area->y1,
|
||||
((vg_lite_float_t)clip_area->x2) + 1.0f, ((vg_lite_float_t)clip_area->y2) + 1.0f));
|
||||
|
||||
lv_color32_t col32 = lv_color_to_32(dsc->color, dsc->opa);
|
||||
vg_lite_color_t vgcol = vglite_get_color(col32, false);
|
||||
|
||||
vg_lite_matrix_t matrix;
|
||||
vg_lite_identity(&matrix);
|
||||
|
||||
/*** Draw arc ***/
|
||||
VGLITE_CHECK_ERROR(vg_lite_draw(vgbuf, &path, VG_LITE_FILL_NON_ZERO, &matrix, VG_LITE_BLEND_SRC_OVER, vgcol));
|
||||
|
||||
vglite_run();
|
||||
|
||||
VGLITE_CHECK_ERROR(vg_lite_clear_path(&path));
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DRAW_VGLITE*/
|
||||
@@ -0,0 +1,203 @@
|
||||
/**
|
||||
* @file lv_draw_vglite_border.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2022-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_vglite.h"
|
||||
|
||||
#if LV_USE_DRAW_VGLITE
|
||||
#include "lv_vglite_buf.h"
|
||||
#include "lv_vglite_path.h"
|
||||
#include "lv_vglite_utils.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/*** Define maximum numbers of rectangles needed to clip partial borders ***/
|
||||
#define MAX_NUM_RECTANGLES 4
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Draw rectangle border/outline shape with effects (rounded corners, opacity)
|
||||
*
|
||||
* @param[in] coords Coordinates of the rectangle border/outline (relative to dest buff)
|
||||
* @param[in] clip_area Clip area with relative coordinates to dest buff
|
||||
* @param[in] dsc Description of the rectangle border/outline
|
||||
*
|
||||
*/
|
||||
static void _vglite_draw_border(const lv_area_t * coords, const lv_area_t * clip_area,
|
||||
const lv_draw_border_dsc_t * dsc);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_vglite_border(lv_draw_unit_t * draw_unit, const lv_draw_border_dsc_t * dsc,
|
||||
const lv_area_t * coords)
|
||||
{
|
||||
if(dsc->opa <= (lv_opa_t)LV_OPA_MIN)
|
||||
return;
|
||||
if(dsc->width == 0)
|
||||
return;
|
||||
if(dsc->side == (lv_border_side_t)LV_BORDER_SIDE_NONE)
|
||||
return;
|
||||
|
||||
lv_layer_t * layer = draw_unit->target_layer;
|
||||
lv_area_t inward_coords;
|
||||
int32_t width = dsc->width;
|
||||
|
||||
/* Move border inwards to align with software rendered border */
|
||||
inward_coords.x1 = coords->x1 + ceil(width / 2.0f);
|
||||
inward_coords.x2 = coords->x2 - floor(width / 2.0f);
|
||||
inward_coords.y1 = coords->y1 + ceil(width / 2.0f);
|
||||
inward_coords.y2 = coords->y2 - floor(width / 2.0f);
|
||||
|
||||
lv_area_move(&inward_coords, -layer->buf_area.x1, -layer->buf_area.y1);
|
||||
|
||||
lv_area_t clip_area;
|
||||
lv_area_copy(&clip_area, draw_unit->clip_area);
|
||||
lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1);
|
||||
|
||||
lv_area_t clipped_coords;
|
||||
if(!lv_area_intersect(&clipped_coords, &inward_coords, &clip_area))
|
||||
return; /*Fully clipped, nothing to do*/
|
||||
|
||||
_vglite_draw_border(&inward_coords, &clip_area, dsc);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void _vglite_draw_border(const lv_area_t * coords, const lv_area_t * clip_area,
|
||||
const lv_draw_border_dsc_t * dsc)
|
||||
{
|
||||
int32_t radius = dsc->radius;
|
||||
vg_lite_buffer_t * vgbuf = vglite_get_dest_buf();
|
||||
|
||||
if(radius < 0)
|
||||
return;
|
||||
|
||||
int32_t border_half = (int32_t)floor(dsc->width / 2.0f);
|
||||
if(radius > border_half)
|
||||
radius = radius - border_half;
|
||||
|
||||
vg_lite_cap_style_t cap_style = (radius) ? VG_LITE_CAP_ROUND : VG_LITE_CAP_BUTT;
|
||||
vg_lite_join_style_t join_style = (radius) ? VG_LITE_JOIN_ROUND : VG_LITE_JOIN_MITER;
|
||||
|
||||
/*** Init path ***/
|
||||
int32_t path_data[RECT_PATH_DATA_MAX_SIZE];
|
||||
uint32_t path_data_size;
|
||||
vglite_create_rect_path_data(path_data, &path_data_size, radius, coords);
|
||||
vg_lite_quality_t path_quality = radius > 0 ? VG_LITE_HIGH : VG_LITE_MEDIUM;
|
||||
|
||||
vg_lite_path_t path;
|
||||
VGLITE_CHECK_ERROR(vg_lite_init_path(&path, VG_LITE_S32, path_quality, path_data_size, path_data,
|
||||
(vg_lite_float_t)clip_area->x1, (vg_lite_float_t)clip_area->y1,
|
||||
((vg_lite_float_t)clip_area->x2) + 1.0f, ((vg_lite_float_t)clip_area->y2) + 1.0f));
|
||||
|
||||
lv_color32_t col32 = lv_color_to_32(dsc->color, dsc->opa);
|
||||
vg_lite_color_t vgcol = vglite_get_color(col32, false);
|
||||
|
||||
vg_lite_matrix_t matrix;
|
||||
vg_lite_identity(&matrix);
|
||||
|
||||
int32_t line_width = dsc->width;
|
||||
lv_border_side_t border_side = dsc->side;
|
||||
|
||||
if(border_side == LV_BORDER_SIDE_FULL)
|
||||
border_side = LV_BORDER_SIDE_TOP | LV_BORDER_SIDE_BOTTOM | LV_BORDER_SIDE_LEFT | LV_BORDER_SIDE_RIGHT;
|
||||
|
||||
uint32_t num_rect = 0;
|
||||
vg_lite_rectangle_t rect[MAX_NUM_RECTANGLES];
|
||||
int32_t rect_width = coords->x2 - coords->x1;
|
||||
int32_t rect_height = coords->y2 - coords->y1;
|
||||
int32_t shortest_side = LV_MIN(rect_width, rect_height);
|
||||
int32_t final_radius = LV_MIN(radius, shortest_side / 2);
|
||||
|
||||
if(border_side & LV_BORDER_SIDE_TOP) {
|
||||
rect[num_rect].x = coords->x1 - ceil(line_width / 2.0f);
|
||||
rect[num_rect].y = coords->y1 - ceil(line_width / 2.0f);
|
||||
rect[num_rect].width = coords->x2 - coords->x1 + line_width;
|
||||
rect[num_rect].height = final_radius + ceil(line_width / 2.0f);
|
||||
num_rect++;
|
||||
}
|
||||
|
||||
if(border_side & LV_BORDER_SIDE_LEFT) {
|
||||
rect[num_rect].x = coords->x1 - ceil(line_width / 2.0f);
|
||||
rect[num_rect].y = coords->y1 - ceil(line_width / 2.0f);
|
||||
rect[num_rect].width = final_radius + ceil(line_width / 2.0f);
|
||||
rect[num_rect].height = coords->y2 - coords->y1 + line_width + 1;
|
||||
num_rect++;
|
||||
}
|
||||
|
||||
if(border_side & LV_BORDER_SIDE_RIGHT) {
|
||||
rect[num_rect].x = coords->x2 - final_radius + 1;
|
||||
rect[num_rect].y = coords->y1 - ceil(line_width / 2.0f);
|
||||
rect[num_rect].width = final_radius + ceil(line_width / 2.0f);
|
||||
rect[num_rect].height = coords->y2 - coords->y1 + line_width + 1;
|
||||
num_rect++;
|
||||
}
|
||||
|
||||
if(border_side & LV_BORDER_SIDE_BOTTOM) {
|
||||
rect[num_rect].x = coords->x1 - ceil(line_width / 2.0f);
|
||||
rect[num_rect].y = coords->y2 - final_radius + 1;
|
||||
rect[num_rect].width = coords->x2 - coords->x1 + line_width;
|
||||
rect[num_rect].height = final_radius + ceil(line_width / 2.0f);
|
||||
num_rect++;
|
||||
}
|
||||
|
||||
/*** Enable scissor and apply scissor rects ***/
|
||||
VGLITE_CHECK_ERROR(vg_lite_enable_scissor());
|
||||
VGLITE_CHECK_ERROR(vg_lite_scissor_rects(vgbuf, num_rect, rect));
|
||||
|
||||
/*** Draw border ***/
|
||||
VGLITE_CHECK_ERROR(vg_lite_set_draw_path_type(&path, VG_LITE_DRAW_STROKE_PATH));
|
||||
|
||||
VGLITE_CHECK_ERROR(vg_lite_set_stroke(&path, cap_style, join_style, line_width, 8, NULL, 0, 0, vgcol));
|
||||
|
||||
VGLITE_CHECK_ERROR(vg_lite_update_stroke(&path));
|
||||
|
||||
VGLITE_CHECK_ERROR(vg_lite_draw(vgbuf, &path, VG_LITE_FILL_NON_ZERO, &matrix, VG_LITE_BLEND_SRC_OVER, vgcol));
|
||||
|
||||
vglite_run();
|
||||
|
||||
VGLITE_CHECK_ERROR(vg_lite_clear_path(&path));
|
||||
|
||||
/*** Disable scissor ***/
|
||||
VGLITE_CHECK_ERROR(vg_lite_disable_scissor());
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DRAW_VGLITE*/
|
||||
@@ -0,0 +1,237 @@
|
||||
/**
|
||||
* @file lv_draw_vglite_fill.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2020-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_vglite.h"
|
||||
|
||||
#if LV_USE_DRAW_VGLITE
|
||||
#include "lv_vglite_buf.h"
|
||||
#include "lv_vglite_path.h"
|
||||
#include "lv_vglite_utils.h"
|
||||
|
||||
#include "../../../stdlib/lv_string.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Fill area, with optional opacity.
|
||||
*
|
||||
* @param[in] dest_area Area with relative coordinates of destination buffer
|
||||
* @param[in] dsc Description of the area to fill (color, opa)
|
||||
*
|
||||
*/
|
||||
static void _vglite_fill(const lv_area_t * dest_area, const lv_draw_fill_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* Draw rectangle background with effects (rounded corners, gradient)
|
||||
*
|
||||
* @param[in] coords Coordinates of the rectangle background (relative to dest buff)
|
||||
* @param[in] clip_area Clip area with relative coordinates to dest buff
|
||||
* @param[in] dsc Description of the rectangle background
|
||||
*
|
||||
*/
|
||||
static void _vglite_draw_rect(const lv_area_t * coords, const lv_area_t * clip_area,
|
||||
const lv_draw_fill_dsc_t * dsc);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_vglite_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc,
|
||||
const lv_area_t * coords)
|
||||
{
|
||||
if(dsc->opa <= (lv_opa_t)LV_OPA_MIN)
|
||||
return;
|
||||
|
||||
lv_layer_t * layer = draw_unit->target_layer;
|
||||
lv_area_t relative_coords;
|
||||
lv_area_copy(&relative_coords, coords);
|
||||
lv_area_move(&relative_coords, -layer->buf_area.x1, -layer->buf_area.y1);
|
||||
|
||||
lv_area_t clip_area;
|
||||
lv_area_copy(&clip_area, draw_unit->clip_area);
|
||||
lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1);
|
||||
|
||||
lv_area_t clipped_coords;
|
||||
if(!lv_area_intersect(&clipped_coords, &relative_coords, &clip_area))
|
||||
return; /*Fully clipped, nothing to do*/
|
||||
|
||||
/*
|
||||
* Most simple case: just a plain rectangle (no radius, no gradient)
|
||||
*/
|
||||
if((dsc->radius == 0) && (dsc->grad.dir == (lv_grad_dir_t)LV_GRAD_DIR_NONE))
|
||||
_vglite_fill(&clipped_coords, dsc);
|
||||
else
|
||||
_vglite_draw_rect(&relative_coords, &clip_area, dsc);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void _vglite_fill(const lv_area_t * dest_area, const lv_draw_fill_dsc_t * dsc)
|
||||
{
|
||||
vg_lite_buffer_t * vgbuf = vglite_get_dest_buf();
|
||||
|
||||
lv_color32_t col32 = lv_color_to_32(dsc->color, dsc->opa);
|
||||
vg_lite_color_t vgcol = vglite_get_color(col32, false);
|
||||
|
||||
if(dsc->opa >= (lv_opa_t)LV_OPA_MAX) { /*Opaque fill*/
|
||||
vg_lite_rectangle_t rect = {
|
||||
.x = dest_area->x1,
|
||||
.y = dest_area->y1,
|
||||
.width = lv_area_get_width(dest_area),
|
||||
.height = lv_area_get_height(dest_area)
|
||||
};
|
||||
|
||||
VGLITE_CHECK_ERROR(vg_lite_clear(vgbuf, &rect, vgcol));
|
||||
|
||||
vglite_run();
|
||||
}
|
||||
else { /*fill with transparency*/
|
||||
|
||||
vg_lite_path_t path;
|
||||
int32_t path_data[] = { /*VG rectangular path*/
|
||||
VLC_OP_MOVE, dest_area->x1, dest_area->y1,
|
||||
VLC_OP_LINE, dest_area->x2 + 1, dest_area->y1,
|
||||
VLC_OP_LINE, dest_area->x2 + 1, dest_area->y2 + 1,
|
||||
VLC_OP_LINE, dest_area->x1, dest_area->y2 + 1,
|
||||
VLC_OP_LINE, dest_area->x1, dest_area->y1,
|
||||
VLC_OP_END
|
||||
};
|
||||
|
||||
VGLITE_CHECK_ERROR(vg_lite_init_path(&path, VG_LITE_S32, VG_LITE_MEDIUM, sizeof(path_data), path_data,
|
||||
(vg_lite_float_t) dest_area->x1, (vg_lite_float_t) dest_area->y1,
|
||||
((vg_lite_float_t) dest_area->x2) + 1.0f, ((vg_lite_float_t) dest_area->y2) + 1.0f));
|
||||
|
||||
vg_lite_matrix_t matrix;
|
||||
vg_lite_identity(&matrix);
|
||||
|
||||
/*Draw rectangle*/
|
||||
VGLITE_CHECK_ERROR(vg_lite_draw(vgbuf, &path, VG_LITE_FILL_EVEN_ODD, &matrix, VG_LITE_BLEND_SRC_OVER, vgcol));
|
||||
|
||||
vglite_run();
|
||||
|
||||
VGLITE_CHECK_ERROR(vg_lite_clear_path(&path));
|
||||
}
|
||||
}
|
||||
|
||||
static void _vglite_draw_rect(const lv_area_t * coords, const lv_area_t * clip_area,
|
||||
const lv_draw_fill_dsc_t * dsc)
|
||||
{
|
||||
int32_t width = lv_area_get_width(coords);
|
||||
int32_t height = lv_area_get_height(coords);
|
||||
int32_t radius = dsc->radius;
|
||||
lv_opa_t opa = dsc->opa;
|
||||
vg_lite_buffer_t * vgbuf = vglite_get_dest_buf();
|
||||
|
||||
if(dsc->radius < 0)
|
||||
return;
|
||||
|
||||
/*** Init path ***/
|
||||
int32_t path_data[RECT_PATH_DATA_MAX_SIZE];
|
||||
uint32_t path_data_size;
|
||||
vglite_create_rect_path_data(path_data, &path_data_size, radius, coords);
|
||||
vg_lite_quality_t path_quality = dsc->radius > 0 ? VG_LITE_HIGH : VG_LITE_MEDIUM;
|
||||
|
||||
vg_lite_path_t path;
|
||||
VGLITE_CHECK_ERROR(vg_lite_init_path(&path, VG_LITE_S32, path_quality, path_data_size, path_data,
|
||||
(vg_lite_float_t)clip_area->x1, (vg_lite_float_t)clip_area->y1,
|
||||
((vg_lite_float_t)clip_area->x2) + 1.0f, ((vg_lite_float_t)clip_area->y2) + 1.0f));
|
||||
|
||||
vg_lite_matrix_t matrix;
|
||||
vg_lite_identity(&matrix);
|
||||
|
||||
/*** Init Color ***/
|
||||
lv_color32_t col32 = lv_color_to_32(dsc->color, opa);
|
||||
vg_lite_color_t vgcol = vglite_get_color(col32, false);
|
||||
|
||||
vg_lite_linear_gradient_t gradient;
|
||||
bool has_gradient = (dsc->grad.dir != (lv_grad_dir_t)LV_GRAD_DIR_NONE);
|
||||
|
||||
/*** Init Gradient ***/
|
||||
if(has_gradient) {
|
||||
vg_lite_matrix_t * grad_matrix;
|
||||
|
||||
vg_lite_uint32_t colors[LV_GRADIENT_MAX_STOPS];
|
||||
vg_lite_uint32_t stops[LV_GRADIENT_MAX_STOPS];
|
||||
lv_color32_t col32[LV_GRADIENT_MAX_STOPS];
|
||||
|
||||
/* Gradient setup */
|
||||
vg_lite_uint32_t cnt = LV_MAX(dsc->grad.stops_count, LV_GRADIENT_MAX_STOPS);
|
||||
lv_opa_t opa;
|
||||
|
||||
for(uint8_t i = 0; i < cnt; i++) {
|
||||
stops[i] = dsc->grad.stops[i].frac;
|
||||
|
||||
opa = LV_OPA_MIX2(dsc->grad.stops[i].opa, dsc->opa);
|
||||
|
||||
col32[i] = lv_color_to_32(dsc->grad.stops[i].color, opa);
|
||||
colors[i] = vglite_get_color(col32[i], true);
|
||||
}
|
||||
|
||||
lv_memzero(&gradient, sizeof(vg_lite_linear_gradient_t));
|
||||
|
||||
VGLITE_CHECK_ERROR(vg_lite_init_grad(&gradient));
|
||||
|
||||
VGLITE_CHECK_ERROR(vg_lite_set_grad(&gradient, cnt, colors, stops));
|
||||
|
||||
VGLITE_CHECK_ERROR(vg_lite_update_grad(&gradient));
|
||||
|
||||
grad_matrix = vg_lite_get_grad_matrix(&gradient);
|
||||
vg_lite_identity(grad_matrix);
|
||||
vg_lite_translate((float)coords->x1, (float)coords->y1, grad_matrix);
|
||||
|
||||
if(dsc->grad.dir == (lv_grad_dir_t)LV_GRAD_DIR_VER) {
|
||||
vg_lite_scale(1.0f, (float)height / 256.0f, grad_matrix);
|
||||
vg_lite_rotate(90.0f, grad_matrix);
|
||||
}
|
||||
else { /*LV_GRAD_DIR_HOR*/
|
||||
vg_lite_scale((float)width / 256.0f, 1.0f, grad_matrix);
|
||||
}
|
||||
|
||||
VGLITE_CHECK_ERROR(vg_lite_draw_gradient(vgbuf, &path, VG_LITE_FILL_EVEN_ODD, &matrix, &gradient,
|
||||
VG_LITE_BLEND_SRC_OVER));
|
||||
}
|
||||
else {
|
||||
VGLITE_CHECK_ERROR(vg_lite_draw(vgbuf, &path, VG_LITE_FILL_EVEN_ODD, &matrix, VG_LITE_BLEND_SRC_OVER, vgcol));
|
||||
}
|
||||
|
||||
vglite_run();
|
||||
|
||||
VGLITE_CHECK_ERROR(vg_lite_clear_path(&path));
|
||||
|
||||
if(has_gradient)
|
||||
VGLITE_CHECK_ERROR(vg_lite_clear_grad(&gradient));
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DRAW_VGLITE*/
|
||||
@@ -0,0 +1,443 @@
|
||||
/**
|
||||
* @file lv_draw_vglite_blend.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2020-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_vglite.h"
|
||||
|
||||
#if LV_USE_DRAW_VGLITE
|
||||
#include "lv_vglite_buf.h"
|
||||
#include "lv_vglite_matrix.h"
|
||||
#include "lv_vglite_utils.h"
|
||||
#include "lv_vglite_path.h"
|
||||
|
||||
#include "../../../misc/lv_log.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#if LV_USE_VGLITE_BLIT_SPLIT
|
||||
/**
|
||||
* BLIT split threshold - BLITs with width or height higher than this value will
|
||||
* be done in multiple steps. Value must be multiple of stride alignment in px.
|
||||
* For most color formats the alignment is 16px (except the index formats).
|
||||
*/
|
||||
#define VGLITE_BLIT_SPLIT_THR 352
|
||||
|
||||
/* Enable for logging debug traces. */
|
||||
#define VGLITE_LOG_TRACE 0
|
||||
|
||||
#if VGLITE_LOG_TRACE
|
||||
#define VGLITE_TRACE(fmt, ...) \
|
||||
do { \
|
||||
LV_LOG(fmt, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
#else
|
||||
#define VGLITE_TRACE(fmt, ...) \
|
||||
do { \
|
||||
} while (0)
|
||||
#endif
|
||||
#endif /*LV_USE_VGLITE_BLIT_SPLIT*/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
#if LV_USE_VGLITE_BLIT_SPLIT
|
||||
/**
|
||||
* Move buffer pointer as close as possible to area, but with respect to alignment requirements.
|
||||
*
|
||||
* @param[in] buf Buffer address pointer
|
||||
* @param[in] area Area with relative coordinates to the buffer
|
||||
* @param[in] stride Stride of buffer in bytes
|
||||
* @param[in] cf Color format of buffer
|
||||
*/
|
||||
static void _move_buf_close_to_area(void ** buf, lv_area_t * area, uint32_t stride, lv_color_format_t cf);
|
||||
|
||||
/**
|
||||
* BLock Image Transfer - copy rectangular image from src_buf to dst_buf with effects.
|
||||
* By default, image is copied directly, with optional opacity.
|
||||
*
|
||||
* @param dest_buf Destination buffer
|
||||
* @param[in] dest_area Destination area with relative coordinates to dest buffer
|
||||
* @param[in] dest_stride Stride of destination buffer in bytes
|
||||
* @param[in] dest_cf Color format of destination buffer
|
||||
* @param[in] src_buf Source buffer
|
||||
* @param[in] src_area Source area with relative coordinates to src buffer
|
||||
* @param[in] src_stride Stride of source buffer in bytes
|
||||
* @param[in] src_cf Color format of source buffer
|
||||
* @param[in] dsc Image descriptor
|
||||
*
|
||||
*/
|
||||
static void _vglite_blit_split(void * dest_buf, lv_area_t * dest_area, uint32_t dest_stride, lv_color_format_t dest_cf,
|
||||
const void * src_buf, lv_area_t * src_area, uint32_t src_stride, lv_color_format_t src_cf,
|
||||
const lv_draw_image_dsc_t * dsc);
|
||||
#endif /*LV_USE_VGLITE_BLIT_SPLIT*/
|
||||
|
||||
/**
|
||||
* VGlite blit - fill a path with an image pattern
|
||||
*
|
||||
*
|
||||
* @param[in] dest_area Destination area with relative coordinates to dest buffer
|
||||
* @param[in] clip_area Clip area with relative coordinates to dest buff
|
||||
* @param[in] coords Coordinates of the image (relative to dest buff)
|
||||
* @param[in] dsc Image descriptor
|
||||
*
|
||||
*/
|
||||
static void _vglite_draw_pattern(const lv_area_t * clip_area, const lv_area_t * coords,
|
||||
const lv_draw_image_dsc_t * dsc);
|
||||
|
||||
/**
|
||||
* BLock Image Transfer - copy rectangular image from src_buf to dst_buf with or without effects.
|
||||
*
|
||||
* @param[in] src_area Source area with relative coordinates to src buffer
|
||||
* @param[in] dsc Image descriptor
|
||||
*
|
||||
*/
|
||||
static void _vglite_blit(const lv_area_t * src_area, const lv_draw_image_dsc_t * dsc);
|
||||
|
||||
static vg_lite_color_t _vglite_recolor(const lv_draw_image_dsc_t * dsc);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_vglite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * dsc,
|
||||
const lv_area_t * coords)
|
||||
{
|
||||
if(dsc->opa <= (lv_opa_t)LV_OPA_MIN)
|
||||
return;
|
||||
|
||||
lv_layer_t * layer = draw_unit->target_layer;
|
||||
const lv_image_dsc_t * img_dsc = dsc->src;
|
||||
|
||||
lv_area_t relative_coords;
|
||||
lv_area_copy(&relative_coords, coords);
|
||||
lv_area_move(&relative_coords, -layer->buf_area.x1, -layer->buf_area.y1);
|
||||
|
||||
lv_area_t clip_area;
|
||||
lv_area_copy(&clip_area, draw_unit->clip_area);
|
||||
lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1);
|
||||
|
||||
lv_area_t blend_area;
|
||||
bool has_transform = (dsc->rotation != 0 || dsc->scale_x != LV_SCALE_NONE || dsc->scale_y != LV_SCALE_NONE);
|
||||
if(has_transform)
|
||||
lv_area_copy(&blend_area, &relative_coords);
|
||||
else if(!lv_area_intersect(&blend_area, &relative_coords, &clip_area))
|
||||
return; /*Fully clipped, nothing to do*/
|
||||
|
||||
const void * src_buf = img_dsc->data;
|
||||
|
||||
lv_area_t src_area;
|
||||
src_area.x1 = blend_area.x1 - (coords->x1 - layer->buf_area.x1);
|
||||
src_area.y1 = blend_area.y1 - (coords->y1 - layer->buf_area.y1);
|
||||
src_area.x2 = img_dsc->header.w - 1;
|
||||
src_area.y2 = img_dsc->header.h - 1;
|
||||
|
||||
lv_color_format_t src_cf = img_dsc->header.cf;
|
||||
uint32_t src_stride = img_dsc->header.stride;
|
||||
|
||||
/* Set src_vgbuf structure. */
|
||||
vglite_set_src_buf(src_buf, img_dsc->header.w, img_dsc->header.h, src_stride, src_cf);
|
||||
|
||||
#if LV_USE_VGLITE_BLIT_SPLIT
|
||||
void * dest_buf = layer->draw_buf->data;
|
||||
uint32_t dest_stride = layer->draw_buf->header.stride;
|
||||
lv_color_format_t dest_cf = layer->draw_buf->header.cf;
|
||||
|
||||
if(!has_transform)
|
||||
_vglite_blit_split(dest_buf, &blend_area, dest_stride, dest_cf,
|
||||
src_buf, &src_area, src_stride, src_cf, dsc);
|
||||
#else
|
||||
vglite_set_transformation_matrix(&blend_area, dsc);
|
||||
bool is_tiled = dsc->tile;
|
||||
if(is_tiled)
|
||||
_vglite_draw_pattern(&clip_area, &relative_coords, dsc);
|
||||
else
|
||||
_vglite_blit(&src_area, dsc);
|
||||
#endif /*LV_USE_VGLITE_BLIT_SPLIT*/
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
static void _vglite_blit(const lv_area_t * src_area, const lv_draw_image_dsc_t * dsc)
|
||||
{
|
||||
vg_lite_buffer_t * dst_vgbuf = vglite_get_dest_buf();
|
||||
vg_lite_buffer_t * src_vgbuf = vglite_get_src_buf();
|
||||
|
||||
vg_lite_rectangle_t rect = {
|
||||
.x = (vg_lite_int32_t)src_area->x1,
|
||||
.y = (vg_lite_int32_t)src_area->y1,
|
||||
.width = (vg_lite_int32_t)lv_area_get_width(src_area),
|
||||
.height = (vg_lite_int32_t)lv_area_get_height(src_area)
|
||||
};
|
||||
|
||||
src_vgbuf->image_mode = VG_LITE_MULTIPLY_IMAGE_MODE;
|
||||
src_vgbuf->transparency_mode = VG_LITE_IMAGE_TRANSPARENT;
|
||||
|
||||
vg_lite_color_t vgcol = _vglite_recolor(dsc);
|
||||
|
||||
vg_lite_matrix_t * vgmatrix = vglite_get_matrix();
|
||||
vg_lite_blend_t vgblend = vglite_get_blend_mode(dsc->blend_mode);
|
||||
|
||||
VGLITE_CHECK_ERROR(vg_lite_blit_rect(dst_vgbuf, src_vgbuf, &rect, vgmatrix, vgblend, vgcol, VG_LITE_FILTER_POINT));
|
||||
|
||||
vglite_run();
|
||||
}
|
||||
|
||||
#if LV_USE_VGLITE_BLIT_SPLIT
|
||||
static void _move_buf_close_to_area(void ** buf, lv_area_t * area, uint32_t stride, lv_color_format_t cf)
|
||||
{
|
||||
uint8_t ** buf_u8 = (uint8_t **)buf;
|
||||
uint8_t align_bytes = vglite_get_stride_alignment(cf);
|
||||
uint8_t bits_per_pixel = lv_color_format_get_bpp(cf);
|
||||
|
||||
uint16_t align_pixels = align_bytes * 8 / bits_per_pixel;
|
||||
|
||||
if(area->x1 >= (int32_t)(area->x1 % align_pixels)) {
|
||||
uint16_t shift_x = area->x1 - (area->x1 % align_pixels);
|
||||
|
||||
area->x1 -= shift_x;
|
||||
area->x2 -= shift_x;
|
||||
*buf_u8 += (shift_x * bits_per_pixel) / 8;
|
||||
}
|
||||
|
||||
if(area->y1) {
|
||||
uint16_t shift_y = area->y1;
|
||||
|
||||
area->y1 -= shift_y;
|
||||
area->y2 -= shift_y;
|
||||
*buf_u8 += shift_y * stride;
|
||||
}
|
||||
}
|
||||
|
||||
static void _vglite_blit_split(void * dest_buf, lv_area_t * dest_area, uint32_t dest_stride, lv_color_format_t dest_cf,
|
||||
const void * src_buf, lv_area_t * src_area, uint32_t src_stride, lv_color_format_t src_cf,
|
||||
const lv_draw_image_dsc_t * dsc)
|
||||
{
|
||||
VGLITE_TRACE("Blit "
|
||||
"Area: ([%d,%d], [%d,%d]) -> ([%d,%d], [%d,%d]) | "
|
||||
"Size: ([%dx%d] -> [%dx%d]) | "
|
||||
"Addr: (0x%x -> 0x%x)",
|
||||
src_area->x1, src_area->y1, src_area->x2, src_area->y2,
|
||||
dest_area->x1, dest_area->y1, dest_area->x2, dest_area->y2,
|
||||
lv_area_get_width(src_area), lv_area_get_height(src_area),
|
||||
lv_area_get_width(dest_area), lv_area_get_height(dest_area),
|
||||
(uintptr_t)src_buf, (uintptr_t)dest_buf);
|
||||
|
||||
/* Move starting pointers as close as possible to [x1, y1], so coordinates are as small as possible */
|
||||
_move_buf_close_to_area((void **)&src_buf, src_area, src_stride, src_cf);
|
||||
_move_buf_close_to_area(&dest_buf, dest_area, dest_stride, dest_cf);
|
||||
|
||||
/* Set clip area */
|
||||
vglite_set_scissor(dest_area);
|
||||
|
||||
/* If we're in limit, do a single BLIT */
|
||||
if((src_area->x2 < VGLITE_BLIT_SPLIT_THR) &&
|
||||
(src_area->y2 < VGLITE_BLIT_SPLIT_THR)) {
|
||||
|
||||
/* Set new dest_vgbuf and src_vgbuf memory addresses */
|
||||
vglite_set_dest_buf_ptr(dest_buf);
|
||||
vglite_set_src_buf_ptr(src_buf);
|
||||
|
||||
vglite_set_transformation_matrix(dest_area, dsc);
|
||||
_vglite_blit(src_area, dsc);
|
||||
|
||||
VGLITE_TRACE("Single "
|
||||
"Area: ([%d,%d], [%d,%d]) -> ([%d,%d], [%d,%d]) | "
|
||||
"Size: ([%dx%d] -> [%dx%d]) | "
|
||||
"Addr: (0x%x -> 0x%x)",
|
||||
src_area->x1, src_area->y1, src_area->x2, src_area->y2,
|
||||
dest_area->x1, dest_area->y1, dest_area->x2, dest_area->y2,
|
||||
lv_area_get_width(src_area), lv_area_get_height(src_area),
|
||||
lv_area_get_width(dest_area), lv_area_get_height(dest_area),
|
||||
(uintptr_t)src_buf, (uintptr_t)dest_buf);
|
||||
|
||||
return;
|
||||
};
|
||||
|
||||
/* Split the BLIT into multiple tiles */
|
||||
VGLITE_TRACE("Split "
|
||||
"Area: ([%d,%d], [%d,%d]) -> ([%d,%d], [%d,%d]) | "
|
||||
"Size: ([%dx%d] -> [%dx%d]) | "
|
||||
"Addr: (0x%x -> 0x%x)",
|
||||
src_area->x1, src_area->y1, src_area->x2, src_area->y2,
|
||||
dest_area->x1, dest_area->y1, dest_area->x2, dest_area->y2,
|
||||
lv_area_get_width(src_area), lv_area_get_height(src_area),
|
||||
lv_area_get_width(dest_area), lv_area_get_height(dest_area),
|
||||
(uintptr_t)src_buf, (uintptr_t)dest_buf);
|
||||
|
||||
int32_t width = LV_MIN(lv_area_get_width(src_area), lv_area_get_width(dest_area));
|
||||
int32_t height = LV_MIN(lv_area_get_height(src_area), lv_area_get_height(dest_area));
|
||||
|
||||
/* Number of tiles needed */
|
||||
uint8_t total_tiles_x = (src_area->x1 + width + VGLITE_BLIT_SPLIT_THR - 1) /
|
||||
VGLITE_BLIT_SPLIT_THR;
|
||||
uint8_t total_tiles_y = (src_area->y1 + height + VGLITE_BLIT_SPLIT_THR - 1) /
|
||||
VGLITE_BLIT_SPLIT_THR;
|
||||
|
||||
uint16_t shift_src_x = src_area->x1;
|
||||
uint16_t shift_dest_x = dest_area->x1;
|
||||
|
||||
VGLITE_TRACE("X shift: src: %d, dst: %d", shift_src_x, shift_dest_x);
|
||||
|
||||
uint8_t * tile_dest_buf;
|
||||
lv_area_t tile_dest_area;
|
||||
const uint8_t * tile_src_buf;
|
||||
lv_area_t tile_src_area;
|
||||
|
||||
for(uint8_t y = 0; y < total_tiles_y; y++) {
|
||||
/* y1 always start from 0 */
|
||||
tile_src_area.y1 = 0;
|
||||
|
||||
/* Calculate y2 coordinates */
|
||||
if(y < total_tiles_y - 1)
|
||||
tile_src_area.y2 = VGLITE_BLIT_SPLIT_THR - 1;
|
||||
else
|
||||
tile_src_area.y2 = height - y * VGLITE_BLIT_SPLIT_THR - 1;
|
||||
|
||||
/* No vertical shift, dest y is always in sync with src y */
|
||||
tile_dest_area.y1 = tile_src_area.y1;
|
||||
tile_dest_area.y2 = tile_src_area.y2;
|
||||
|
||||
/* Advance start pointer for every tile, except the first column (y = 0) */
|
||||
tile_src_buf = (uint8_t *)src_buf + y * VGLITE_BLIT_SPLIT_THR * src_stride;
|
||||
tile_dest_buf = (uint8_t *)dest_buf + y * VGLITE_BLIT_SPLIT_THR * dest_stride;
|
||||
|
||||
for(uint8_t x = 0; x < total_tiles_x; x++) {
|
||||
/* x1 always start from the same shift */
|
||||
tile_src_area.x1 = shift_src_x;
|
||||
tile_dest_area.x1 = shift_dest_x;
|
||||
if(x > 0) {
|
||||
/* Advance start pointer for every tile, except the first raw (x = 0) */
|
||||
tile_src_buf += VGLITE_BLIT_SPLIT_THR * lv_color_format_get_bpp(src_cf) / 8;
|
||||
tile_dest_buf += VGLITE_BLIT_SPLIT_THR * lv_color_format_get_bpp(dest_cf) / 8;
|
||||
}
|
||||
|
||||
/* Calculate x2 coordinates */
|
||||
if(x < total_tiles_x - 1)
|
||||
tile_src_area.x2 = VGLITE_BLIT_SPLIT_THR - 1;
|
||||
else
|
||||
tile_src_area.x2 = width - x * VGLITE_BLIT_SPLIT_THR - 1;
|
||||
|
||||
tile_dest_area.x2 = tile_src_area.x2;
|
||||
|
||||
/* Shift x2 coordinates */
|
||||
tile_src_area.x2 += shift_src_x;
|
||||
tile_dest_area.x2 += shift_dest_x;
|
||||
|
||||
/* Set new dest_vgbuf and src_vgbuf memory addresses */
|
||||
vglite_set_dest_buf_ptr(tile_dest_buf);
|
||||
vglite_set_src_buf_ptr(tile_src_buf);
|
||||
|
||||
vglite_set_transformation_matrix(&tile_dest_area, dsc);
|
||||
_vglite_blit(&tile_src_area, dsc);
|
||||
|
||||
VGLITE_TRACE("Tile [%d, %d] "
|
||||
"Area: ([%d,%d], [%d,%d]) -> ([%d,%d], [%d,%d]) | "
|
||||
"Size: ([%dx%d] -> [%dx%d]) | "
|
||||
"Addr: (0x%x -> 0x%x)",
|
||||
x, y,
|
||||
tile_src_area.x1, tile_src_area.y1, tile_src_area.x2, tile_src_area.y2,
|
||||
tile_dest_area.x1, tile_dest_area.y1, tile_dest_area.x2, tile_dest_area.y2,
|
||||
lv_area_get_width(&tile_src_area), lv_area_get_height(&tile_src_area),
|
||||
lv_area_get_width(&tile_dest_area), lv_area_get_height(&tile_dest_area),
|
||||
(uintptr_t)tile_src_buf, (uintptr_t)tile_dest_buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /*LV_USE_VGLITE_BLIT_SPLIT*/
|
||||
|
||||
static void _vglite_draw_pattern(const lv_area_t * clip_area, const lv_area_t * coords,
|
||||
const lv_draw_image_dsc_t * dsc)
|
||||
{
|
||||
/* Target buffer */
|
||||
vg_lite_buffer_t * dst_vgbuf = vglite_get_dest_buf();
|
||||
|
||||
/* Path to draw */
|
||||
int32_t path_data[RECT_PATH_DATA_MAX_SIZE];
|
||||
uint32_t path_data_size;
|
||||
vglite_create_rect_path_data(path_data, &path_data_size, dsc->clip_radius, coords);
|
||||
vg_lite_quality_t path_quality = VG_LITE_MEDIUM;
|
||||
|
||||
vg_lite_path_t path;
|
||||
VGLITE_CHECK_ERROR(vg_lite_init_path(&path, VG_LITE_S32, path_quality, path_data_size, path_data,
|
||||
(vg_lite_float_t)clip_area->x1, (vg_lite_float_t)clip_area->y1,
|
||||
((vg_lite_float_t)clip_area->x2) + 1.0f, ((vg_lite_float_t)clip_area->y2) + 1.0f));
|
||||
|
||||
/* Path Matrix */
|
||||
vg_lite_matrix_t path_matrix;
|
||||
vg_lite_identity(&path_matrix);
|
||||
|
||||
/* Pattern Image */
|
||||
vg_lite_buffer_t * src_vgbuf = vglite_get_src_buf();
|
||||
src_vgbuf->image_mode = VG_LITE_MULTIPLY_IMAGE_MODE;
|
||||
src_vgbuf->transparency_mode = VG_LITE_IMAGE_TRANSPARENT;
|
||||
|
||||
/* Pattern matrix */
|
||||
vg_lite_matrix_t vgmatrix;
|
||||
vg_lite_identity(&vgmatrix);
|
||||
vg_lite_translate((vg_lite_float_t)dsc->image_area.x1, (vg_lite_float_t)dsc->image_area.y1, &vgmatrix);
|
||||
|
||||
/* Blend mode */
|
||||
vg_lite_blend_t vgblend = vglite_get_blend_mode(dsc->blend_mode);
|
||||
|
||||
vg_lite_color_t vgcol = _vglite_recolor(dsc);
|
||||
|
||||
/* Filter */
|
||||
bool has_transform = (dsc->rotation != 0 || dsc->scale_x != LV_SCALE_NONE || dsc->scale_y != LV_SCALE_NONE);
|
||||
vg_lite_filter_t filter = has_transform ? VG_LITE_FILTER_BI_LINEAR : VG_LITE_FILTER_POINT;
|
||||
|
||||
/* Draw Pattern */
|
||||
VGLITE_CHECK_ERROR(vg_lite_draw_pattern(dst_vgbuf, &path, VG_LITE_FILL_NON_ZERO, &path_matrix,
|
||||
src_vgbuf, &vgmatrix, vgblend, VG_LITE_PATTERN_REPEAT,
|
||||
0, vgcol, filter));
|
||||
}
|
||||
|
||||
static vg_lite_color_t _vglite_recolor(const lv_draw_image_dsc_t * dsc)
|
||||
{
|
||||
lv_color_t color;
|
||||
lv_opa_t opa;
|
||||
|
||||
bool has_recolor = (dsc->recolor_opa > LV_OPA_MIN);
|
||||
if(has_recolor) {
|
||||
color = dsc->recolor;
|
||||
opa = LV_OPA_MIX2(dsc->recolor_opa, dsc->opa);
|
||||
}
|
||||
else {
|
||||
color.red = 0xFF;
|
||||
color.green = 0xFF;
|
||||
color.blue = 0xFF;
|
||||
opa = dsc->opa;
|
||||
}
|
||||
|
||||
lv_color32_t col32 = lv_color_to_32(color, opa);
|
||||
|
||||
return vglite_get_color(col32, false);
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DRAW_VGLITE*/
|
||||
@@ -0,0 +1,180 @@
|
||||
/**
|
||||
* @file lv_draw_vglite_label.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2023-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_vglite.h"
|
||||
|
||||
#if LV_USE_DRAW_VGLITE
|
||||
#include "lv_vglite_buf.h"
|
||||
#include "lv_vglite_matrix.h"
|
||||
#include "lv_vglite_utils.h"
|
||||
|
||||
#include "../../lv_draw_label_private.h"
|
||||
#include "../../../stdlib/lv_string.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void _draw_vglite_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * glyph_draw_dsc,
|
||||
lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area);
|
||||
|
||||
/**
|
||||
* Draw letter (character bitmap blend) with optional color and opacity
|
||||
*
|
||||
* @param[in] mask_area Mask area with relative coordinates of source buffer
|
||||
* @param[in] color Color
|
||||
* @param[in] opa Opacity
|
||||
*
|
||||
*/
|
||||
static void _vglite_draw_letter(const lv_area_t * mask_area, lv_color_t color, lv_opa_t opa);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_vglite_label(lv_draw_unit_t * draw_unit, const lv_draw_label_dsc_t * dsc,
|
||||
const lv_area_t * coords)
|
||||
{
|
||||
if(dsc->opa <= LV_OPA_MIN) return;
|
||||
|
||||
lv_draw_label_iterate_characters(draw_unit, dsc, coords, _draw_vglite_letter);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void _draw_vglite_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * glyph_draw_dsc,
|
||||
lv_draw_fill_dsc_t * fill_draw_dsc, const lv_area_t * fill_area)
|
||||
{
|
||||
if(glyph_draw_dsc) {
|
||||
switch(glyph_draw_dsc->format) {
|
||||
|
||||
case LV_FONT_GLYPH_FORMAT_NONE: {
|
||||
#if LV_USE_FONT_PLACEHOLDER
|
||||
/* Draw a placeholder rectangle*/
|
||||
lv_draw_border_dsc_t border_draw_dsc;
|
||||
lv_draw_border_dsc_init(&border_draw_dsc);
|
||||
border_draw_dsc.opa = glyph_draw_dsc->opa;
|
||||
border_draw_dsc.color = glyph_draw_dsc->color;
|
||||
border_draw_dsc.width = 1;
|
||||
lv_draw_vglite_border(draw_unit, &border_draw_dsc, glyph_draw_dsc->bg_coords);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case LV_FONT_GLYPH_FORMAT_A1 ... LV_FONT_GLYPH_FORMAT_A8: {
|
||||
/*Do not draw transparent things*/
|
||||
if(glyph_draw_dsc->opa <= LV_OPA_MIN)
|
||||
return;
|
||||
|
||||
lv_layer_t * layer = draw_unit->target_layer;
|
||||
|
||||
lv_area_t blend_area;
|
||||
if(!lv_area_intersect(&blend_area, glyph_draw_dsc->letter_coords, draw_unit->clip_area))
|
||||
return;
|
||||
lv_area_move(&blend_area, -layer->buf_area.x1, -layer->buf_area.y1);
|
||||
|
||||
const lv_draw_buf_t * draw_buf = glyph_draw_dsc->glyph_data;
|
||||
const void * mask_buf = draw_buf->data;
|
||||
|
||||
uint32_t mask_width = lv_area_get_width(glyph_draw_dsc->letter_coords);
|
||||
uint32_t mask_height = lv_area_get_height(glyph_draw_dsc->letter_coords);
|
||||
uint32_t mask_stride = draw_buf->header.stride;
|
||||
|
||||
lv_area_t mask_area;
|
||||
mask_area.x1 = blend_area.x1 - (glyph_draw_dsc->letter_coords->x1 - layer->buf_area.x1);
|
||||
mask_area.y1 = blend_area.y1 - (glyph_draw_dsc->letter_coords->y1 - layer->buf_area.y1);
|
||||
mask_area.x2 = mask_width - 1;
|
||||
mask_area.y2 = mask_height - 1;
|
||||
|
||||
/* Set src_vgbuf structure. */
|
||||
vglite_set_src_buf(mask_buf, mask_width, mask_height, mask_stride, LV_COLOR_FORMAT_A8);
|
||||
|
||||
/* Set vgmatrix. */
|
||||
vglite_set_translation_matrix(&blend_area);
|
||||
|
||||
lv_draw_buf_invalidate_cache(draw_buf, &mask_area);
|
||||
|
||||
_vglite_draw_letter(&mask_area, glyph_draw_dsc->color, glyph_draw_dsc->opa);
|
||||
}
|
||||
break;
|
||||
case LV_FONT_GLYPH_FORMAT_IMAGE: {
|
||||
#if LV_USE_IMGFONT
|
||||
lv_draw_image_dsc_t img_dsc;
|
||||
lv_draw_image_dsc_init(&img_dsc);
|
||||
img_dsc.opa = glyph_draw_dsc->opa;
|
||||
img_dsc.src = glyph_draw_dsc->glyph_data;
|
||||
lv_draw_vglite_img(draw_unit, &img_dsc, glyph_draw_dsc->letter_coords);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(fill_draw_dsc && fill_area) {
|
||||
lv_draw_vglite_fill(draw_unit, fill_draw_dsc, fill_area);
|
||||
}
|
||||
}
|
||||
|
||||
static void _vglite_draw_letter(const lv_area_t * mask_area, lv_color_t color, lv_opa_t opa)
|
||||
{
|
||||
vg_lite_buffer_t * dst_vgbuf = vglite_get_dest_buf();
|
||||
vg_lite_buffer_t * mask_vgbuf = vglite_get_src_buf();
|
||||
|
||||
mask_vgbuf->image_mode = VG_LITE_MULTIPLY_IMAGE_MODE;
|
||||
mask_vgbuf->transparency_mode = VG_LITE_IMAGE_TRANSPARENT;
|
||||
|
||||
vg_lite_rectangle_t rect = {
|
||||
.x = (vg_lite_int32_t)mask_area->x1,
|
||||
.y = (vg_lite_int32_t)mask_area->y1,
|
||||
.width = (vg_lite_int32_t)lv_area_get_width(mask_area),
|
||||
.height = (vg_lite_int32_t)lv_area_get_height(mask_area)
|
||||
};
|
||||
|
||||
lv_color32_t col32 = lv_color_to_32(color, opa);
|
||||
vg_lite_color_t vgcol = vglite_get_color(col32, false);
|
||||
|
||||
vg_lite_matrix_t * vgmatrix = vglite_get_matrix();
|
||||
|
||||
/*Blit with font color as paint color*/
|
||||
VGLITE_CHECK_ERROR(vg_lite_blit_rect(dst_vgbuf, mask_vgbuf, &rect, vgmatrix, VG_LITE_BLEND_SRC_OVER, vgcol,
|
||||
VG_LITE_FILTER_POINT));
|
||||
|
||||
vglite_run();
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DRAW_VGLITE*/
|
||||
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* @file lv_draw_vglite_layer.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2023-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_vglite.h"
|
||||
|
||||
#if LV_USE_DRAW_VGLITE
|
||||
|
||||
#include "../../../stdlib/lv_string.h"
|
||||
#include "../../../core/lv_global.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
#define _draw_info LV_GLOBAL_DEFAULT()->draw_info
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_vglite_layer(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * draw_dsc,
|
||||
const lv_area_t * coords)
|
||||
{
|
||||
lv_layer_t * layer_to_draw = (lv_layer_t *)draw_dsc->src;
|
||||
const lv_draw_buf_t * draw_buf = layer_to_draw->draw_buf;
|
||||
|
||||
/* It can happen that nothing was draw on a layer and therefore its buffer is not allocated.
|
||||
* In this case just return.
|
||||
*/
|
||||
if(draw_buf == NULL)
|
||||
return;
|
||||
|
||||
if(_draw_info.unit_cnt > 1) {
|
||||
const lv_area_t area_to_draw = {
|
||||
.x1 = 0,
|
||||
.y1 = 0,
|
||||
.x2 = draw_buf->header.w - 1,
|
||||
.y2 = draw_buf->header.h - 1
|
||||
};
|
||||
lv_draw_buf_invalidate_cache(draw_buf, &area_to_draw);
|
||||
}
|
||||
|
||||
lv_draw_image_dsc_t new_draw_dsc = *draw_dsc;
|
||||
new_draw_dsc.src = draw_buf;
|
||||
lv_draw_vglite_img(draw_unit, &new_draw_dsc, coords);
|
||||
|
||||
#if LV_USE_LAYER_DEBUG || LV_USE_PARALLEL_DRAW_DEBUG
|
||||
lv_area_t area_rot;
|
||||
lv_area_copy(&area_rot, coords);
|
||||
bool has_transform = (draw_dsc->rotation != 0 || draw_dsc->scale_x != LV_SCALE_NONE ||
|
||||
draw_dsc->scale_y != LV_SCALE_NONE);
|
||||
|
||||
if(has_transform) {
|
||||
int32_t w = lv_area_get_width(coords);
|
||||
int32_t h = lv_area_get_height(coords);
|
||||
|
||||
lv_image_buf_get_transformed_area(&area_rot, w, h, draw_dsc->rotation, draw_dsc->scale_x, draw_dsc->scale_y,
|
||||
&draw_dsc->pivot);
|
||||
|
||||
area_rot.x1 += coords->x1;
|
||||
area_rot.y1 += coords->y1;
|
||||
area_rot.x2 += coords->x1;
|
||||
area_rot.y2 += coords->y1;
|
||||
}
|
||||
lv_area_t draw_area;
|
||||
if(!lv_area_intersect(&draw_area, &area_rot, draw_unit->clip_area)) return;
|
||||
#endif
|
||||
|
||||
#if LV_USE_LAYER_DEBUG
|
||||
lv_draw_fill_dsc_t fill_dsc;
|
||||
lv_draw_fill_dsc_init(&fill_dsc);
|
||||
fill_dsc.color = lv_color_hex(layer_to_draw->color_format == LV_COLOR_FORMAT_ARGB8888 ? 0xff0000 : 0x00ff00);
|
||||
fill_dsc.opa = LV_OPA_20;
|
||||
lv_draw_sw_fill(draw_unit, &fill_dsc, &area_rot);
|
||||
|
||||
lv_draw_border_dsc_t border_dsc;
|
||||
lv_draw_border_dsc_init(&border_dsc);
|
||||
border_dsc.color = fill_dsc.color;
|
||||
border_dsc.opa = LV_OPA_60;
|
||||
border_dsc.width = 2;
|
||||
lv_draw_sw_border(draw_unit, &border_dsc, &area_rot);
|
||||
|
||||
#endif
|
||||
|
||||
#if LV_USE_PARALLEL_DRAW_DEBUG
|
||||
uint32_t idx = 0;
|
||||
lv_draw_unit_t * draw_unit_tmp = _draw_info.unit_head;
|
||||
while(draw_unit_tmp != draw_unit) {
|
||||
draw_unit_tmp = draw_unit_tmp->next;
|
||||
idx++;
|
||||
}
|
||||
|
||||
lv_draw_fill_dsc_t fill_dsc;
|
||||
lv_draw_rect_dsc_init(&fill_dsc);
|
||||
fill_dsc.color = lv_palette_main(idx % LV_PALETTE_LAST);
|
||||
fill_dsc.opa = LV_OPA_10;
|
||||
lv_draw_sw_fill(draw_unit, &fill_dsc, &area_rot);
|
||||
|
||||
lv_draw_border_dsc_t border_dsc;
|
||||
lv_draw_border_dsc_init(&border_dsc);
|
||||
border_dsc.color = lv_palette_main(idx % LV_PALETTE_LAST);
|
||||
border_dsc.opa = LV_OPA_100;
|
||||
border_dsc.width = 2;
|
||||
lv_draw_sw_border(draw_unit, &border_dsc, &area_rot);
|
||||
|
||||
lv_point_t txt_size;
|
||||
lv_text_get_size(&txt_size, "W", LV_FONT_DEFAULT, 0, 0, 100, LV_TEXT_FLAG_NONE);
|
||||
|
||||
lv_area_t txt_area;
|
||||
txt_area.x1 = draw_area.x1;
|
||||
txt_area.x2 = draw_area.x1 + txt_size.x - 1;
|
||||
txt_area.y2 = draw_area.y2;
|
||||
txt_area.y1 = draw_area.y2 - txt_size.y + 1;
|
||||
|
||||
lv_draw_fill_dsc_init(&fill_dsc);
|
||||
fill_dsc.color = lv_color_black();
|
||||
lv_draw_sw_fill(draw_unit, &fill_dsc, &txt_area);
|
||||
|
||||
char buf[8];
|
||||
lv_snprintf(buf, sizeof(buf), "%d", idx);
|
||||
lv_draw_label_dsc_t label_dsc;
|
||||
lv_draw_label_dsc_init(&label_dsc);
|
||||
label_dsc.color = lv_color_white();
|
||||
label_dsc.text = buf;
|
||||
lv_draw_sw_label(draw_unit, &label_dsc, &txt_area);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DRAW_VGLITE*/
|
||||
@@ -0,0 +1,145 @@
|
||||
/**
|
||||
* @file lv_draw_vglite_line.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2022-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_vglite.h"
|
||||
|
||||
#if LV_USE_DRAW_VGLITE
|
||||
#include "lv_vglite_buf.h"
|
||||
#include "lv_vglite_utils.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Draw line shape with effects
|
||||
*
|
||||
* @param[in] point1 Starting point with relative coordinates
|
||||
* @param[in] point2 Ending point with relative coordinates
|
||||
* @param[in] clip_area Clip area with relative coordinates to dest buff
|
||||
* @param[in] dsc Line description structure (width, rounded ending, opacity, ...)
|
||||
*
|
||||
*/
|
||||
static void _vglite_draw_line(const lv_point_t * point1, const lv_point_t * point2,
|
||||
const lv_area_t * clip_area, const lv_draw_line_dsc_t * dsc);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_vglite_line(lv_draw_unit_t * draw_unit, const lv_draw_line_dsc_t * dsc)
|
||||
{
|
||||
if(dsc->width == 0)
|
||||
return;
|
||||
if(dsc->opa <= (lv_opa_t)LV_OPA_MIN)
|
||||
return;
|
||||
if(dsc->p1.x == dsc->p2.x && dsc->p1.y == dsc->p2.y)
|
||||
return;
|
||||
|
||||
lv_layer_t * layer = draw_unit->target_layer;
|
||||
lv_area_t clip_area;
|
||||
clip_area.x1 = LV_MIN(dsc->p1.x, dsc->p2.x) - dsc->width / 2;
|
||||
clip_area.x2 = LV_MAX(dsc->p1.x, dsc->p2.x) + dsc->width / 2;
|
||||
clip_area.y1 = LV_MIN(dsc->p1.y, dsc->p2.y) - dsc->width / 2;
|
||||
clip_area.y2 = LV_MAX(dsc->p1.y, dsc->p2.y) + dsc->width / 2;
|
||||
|
||||
if(!lv_area_intersect(&clip_area, &clip_area, draw_unit->clip_area))
|
||||
return; /*Fully clipped, nothing to do*/
|
||||
|
||||
lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1);
|
||||
|
||||
lv_point_t point1 = {dsc->p1.x - layer->buf_area.x1, dsc->p1.y - layer->buf_area.y1};
|
||||
lv_point_t point2 = {dsc->p2.x - layer->buf_area.x1, dsc->p2.y - layer->buf_area.y1};
|
||||
|
||||
_vglite_draw_line(&point1, &point2, &clip_area, dsc);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void _vglite_draw_line(const lv_point_t * point1, const lv_point_t * point2,
|
||||
const lv_area_t * clip_area, const lv_draw_line_dsc_t * dsc)
|
||||
{
|
||||
vg_lite_path_t path;
|
||||
vg_lite_buffer_t * vgbuf = vglite_get_dest_buf();
|
||||
vg_lite_cap_style_t cap_style = (dsc->round_start || dsc->round_end) ? VG_LITE_CAP_ROUND : VG_LITE_CAP_BUTT;
|
||||
vg_lite_join_style_t join_style = (dsc->round_start || dsc->round_end) ? VG_LITE_JOIN_ROUND : VG_LITE_JOIN_MITER;
|
||||
|
||||
bool is_dashed = (dsc->dash_width && dsc->dash_gap);
|
||||
|
||||
vg_lite_float_t stroke_dash_pattern[2] = {0, 0};
|
||||
uint32_t stroke_dash_count = 0;
|
||||
vg_lite_float_t stroke_dash_phase = 0;
|
||||
if(is_dashed) {
|
||||
stroke_dash_pattern[0] = (vg_lite_float_t)dsc->dash_width;
|
||||
stroke_dash_pattern[1] = (vg_lite_float_t)dsc->dash_gap;
|
||||
stroke_dash_count = sizeof(stroke_dash_pattern) / sizeof(vg_lite_float_t);
|
||||
stroke_dash_phase = (vg_lite_float_t)dsc->dash_width / 2;
|
||||
}
|
||||
|
||||
vg_lite_blend_t vgblend = vglite_get_blend_mode(dsc->blend_mode);
|
||||
|
||||
/*** Init path ***/
|
||||
int32_t width = dsc->width;
|
||||
|
||||
int32_t line_path[] = { /*VG line path*/
|
||||
VLC_OP_MOVE, point1->x, point1->y,
|
||||
VLC_OP_LINE, point2->x, point2->y,
|
||||
VLC_OP_END
|
||||
};
|
||||
|
||||
VGLITE_CHECK_ERROR(vg_lite_init_path(&path, VG_LITE_S32, VG_LITE_HIGH, sizeof(line_path), line_path,
|
||||
(vg_lite_float_t)clip_area->x1, (vg_lite_float_t)clip_area->y1,
|
||||
((vg_lite_float_t)clip_area->x2) + 1.0f, ((vg_lite_float_t)clip_area->y2) + 1.0f));
|
||||
|
||||
lv_color32_t col32 = lv_color_to_32(dsc->color, dsc->opa);
|
||||
vg_lite_color_t vgcol = vglite_get_color(col32, false);
|
||||
|
||||
vg_lite_matrix_t matrix;
|
||||
vg_lite_identity(&matrix);
|
||||
|
||||
/*** Draw line ***/
|
||||
VGLITE_CHECK_ERROR(vg_lite_set_draw_path_type(&path, VG_LITE_DRAW_STROKE_PATH));
|
||||
|
||||
VGLITE_CHECK_ERROR(vg_lite_set_stroke(&path, cap_style, join_style, width, 8, stroke_dash_pattern, stroke_dash_count,
|
||||
stroke_dash_phase, vgcol));
|
||||
|
||||
VGLITE_CHECK_ERROR(vg_lite_update_stroke(&path));
|
||||
|
||||
VGLITE_CHECK_ERROR(vg_lite_draw(vgbuf, &path, VG_LITE_FILL_NON_ZERO, &matrix, vgblend, vgcol));
|
||||
|
||||
vglite_run();
|
||||
|
||||
VGLITE_CHECK_ERROR(vg_lite_clear_path(&path));
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DRAW_VGLITE*/
|
||||
@@ -0,0 +1,182 @@
|
||||
/**
|
||||
* @file lv_draw_vglite_triangle.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2023-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_draw_vglite.h"
|
||||
|
||||
#if LV_USE_DRAW_VGLITE
|
||||
#include "lv_vglite_buf.h"
|
||||
#include "lv_vglite_path.h"
|
||||
#include "lv_vglite_utils.h"
|
||||
|
||||
#include "../../../stdlib/lv_string.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Draw triangle shape with effects (opacity, gradient)
|
||||
*
|
||||
* @param[in] coords Coordinates of the triangle (relative to dest buff)
|
||||
* @param[in] clip_area Clipping area with relative coordinates to dest buff
|
||||
* @param[in] dsc Description of the triangle
|
||||
*
|
||||
*/
|
||||
static void _vglite_draw_triangle(const lv_area_t * coords, const lv_area_t * clip_area,
|
||||
const lv_draw_triangle_dsc_t * dsc);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_draw_vglite_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle_dsc_t * dsc)
|
||||
{
|
||||
if(dsc->bg_opa <= (lv_opa_t)LV_OPA_MIN)
|
||||
return;
|
||||
|
||||
lv_layer_t * layer = draw_unit->target_layer;
|
||||
lv_area_t clip_area;
|
||||
lv_area_copy(&clip_area, draw_unit->clip_area);
|
||||
lv_area_move(&clip_area, -layer->buf_area.x1, -layer->buf_area.y1);
|
||||
|
||||
lv_area_t coords;
|
||||
coords.x1 = (int32_t)LV_MIN3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x);
|
||||
coords.y1 = (int32_t)LV_MIN3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y);
|
||||
coords.x2 = (int32_t)LV_MAX3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x);
|
||||
coords.y2 = (int32_t)LV_MAX3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y);
|
||||
|
||||
lv_area_move(&coords, -layer->buf_area.x1, -layer->buf_area.y1);
|
||||
|
||||
lv_area_t clipped_coords;
|
||||
if(!lv_area_intersect(&clipped_coords, &coords, &clip_area))
|
||||
return; /* Fully clipped, nothing to do */
|
||||
|
||||
_vglite_draw_triangle(&coords, &clip_area, dsc);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void _vglite_draw_triangle(const lv_area_t * coords, const lv_area_t * clip_area,
|
||||
const lv_draw_triangle_dsc_t * dsc)
|
||||
{
|
||||
vg_lite_buffer_t * vgbuf = vglite_get_dest_buf();
|
||||
|
||||
lv_area_t tri_area;
|
||||
tri_area.x1 = (int32_t)LV_MIN3(dsc->p[0].x, dsc->p[1].x, dsc->p[2].x);
|
||||
tri_area.y1 = (int32_t)LV_MIN3(dsc->p[0].y, dsc->p[1].y, dsc->p[2].y);
|
||||
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 = lv_area_get_width(&tri_area);
|
||||
uint32_t height = lv_area_get_height(&tri_area);
|
||||
|
||||
/* Init path */
|
||||
int32_t triangle_path[] = { /*VG line path*/
|
||||
VLC_OP_MOVE, dsc->p[0].x, dsc->p[0].y,
|
||||
VLC_OP_LINE, dsc->p[1].x, dsc->p[1].y,
|
||||
VLC_OP_LINE, dsc->p[2].x, dsc->p[2].y,
|
||||
VLC_OP_LINE, dsc->p[0].x, dsc->p[0].y,
|
||||
VLC_OP_END
|
||||
};
|
||||
|
||||
vg_lite_path_t path;
|
||||
VGLITE_CHECK_ERROR(vg_lite_init_path(&path, VG_LITE_S32, VG_LITE_HIGH, sizeof(triangle_path), triangle_path,
|
||||
(vg_lite_float_t)clip_area->x1, (vg_lite_float_t)clip_area->y1,
|
||||
((vg_lite_float_t)clip_area->x2) + 1.0f, ((vg_lite_float_t)clip_area->y2) + 1.0f));
|
||||
|
||||
vg_lite_matrix_t matrix;
|
||||
vg_lite_identity(&matrix);
|
||||
|
||||
/* Init Color */
|
||||
lv_color32_t col32 = lv_color_to_32(dsc->bg_color, dsc->bg_opa);
|
||||
vg_lite_color_t vgcol = vglite_get_color(col32, false);
|
||||
|
||||
vg_lite_linear_gradient_t gradient;
|
||||
bool has_gradient = (dsc->bg_grad.dir != (lv_grad_dir_t)LV_GRAD_DIR_NONE);
|
||||
|
||||
/* Init Gradient*/
|
||||
if(has_gradient) {
|
||||
vg_lite_matrix_t * grad_matrix;
|
||||
|
||||
vg_lite_uint32_t colors[LV_GRADIENT_MAX_STOPS];
|
||||
vg_lite_uint32_t stops[LV_GRADIENT_MAX_STOPS];
|
||||
lv_color32_t col32[LV_GRADIENT_MAX_STOPS];
|
||||
|
||||
/* Gradient Setup */
|
||||
vg_lite_uint32_t cnt = LV_MAX(dsc->bg_grad.stops_count, LV_GRADIENT_MAX_STOPS);
|
||||
lv_opa_t bg_opa;
|
||||
|
||||
for(uint8_t i = 0; i < cnt; i++) {
|
||||
stops[i] = dsc->bg_grad.stops[i].frac;
|
||||
bg_opa = LV_OPA_MIX2(dsc->bg_grad.stops[i].opa, dsc->bg_opa);
|
||||
|
||||
col32[i] = lv_color_to_32(dsc->bg_grad.stops[i].color, bg_opa);
|
||||
colors[i] = vglite_get_color(col32[i], true);
|
||||
}
|
||||
|
||||
lv_memzero(&gradient, sizeof(vg_lite_linear_gradient_t));
|
||||
|
||||
VGLITE_CHECK_ERROR(vg_lite_init_grad(&gradient));
|
||||
|
||||
VGLITE_CHECK_ERROR(vg_lite_set_grad(&gradient, cnt, colors, stops));
|
||||
|
||||
VGLITE_CHECK_ERROR(vg_lite_update_grad(&gradient));
|
||||
|
||||
grad_matrix = vg_lite_get_grad_matrix(&gradient);
|
||||
vg_lite_identity(grad_matrix);
|
||||
vg_lite_translate((float)coords->x1, (float)coords->y1, grad_matrix);
|
||||
|
||||
if(dsc->bg_grad.dir == (lv_grad_dir_t)LV_GRAD_DIR_VER) {
|
||||
vg_lite_scale(1.0f, (float)height / 256.0f, grad_matrix);
|
||||
vg_lite_rotate(90.0f, grad_matrix);
|
||||
}
|
||||
else { /*LV_GRAD_DIR_HOR*/
|
||||
vg_lite_scale((float)width / 256.0f, 1.0f, grad_matrix);
|
||||
}
|
||||
|
||||
VGLITE_CHECK_ERROR(vg_lite_draw_gradient(vgbuf, &path, VG_LITE_FILL_EVEN_ODD, &matrix, &gradient,
|
||||
VG_LITE_BLEND_SRC_OVER));
|
||||
}
|
||||
else {
|
||||
VGLITE_CHECK_ERROR(vg_lite_draw(vgbuf, &path, VG_LITE_FILL_EVEN_ODD, &matrix, VG_LITE_BLEND_SRC_OVER, vgcol));
|
||||
}
|
||||
|
||||
vglite_run();
|
||||
|
||||
VGLITE_CHECK_ERROR(vg_lite_clear_path(&path));
|
||||
|
||||
if(has_gradient)
|
||||
VGLITE_CHECK_ERROR(vg_lite_clear_grad(&gradient));
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DRAW_VGLITE*/
|
||||
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* @file lv_vglite_buf.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2023 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_vglite_buf.h"
|
||||
|
||||
#if LV_USE_DRAW_VGLITE
|
||||
#include "lv_vglite_utils.h"
|
||||
|
||||
#include "../../../stdlib/lv_string.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static inline void _set_vgbuf_ptr(vg_lite_buffer_t * vgbuf, void * buf);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
static vg_lite_buffer_t _dest_vgbuf;
|
||||
static vg_lite_buffer_t _src_vgbuf;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
vg_lite_buffer_t * vglite_get_dest_buf(void)
|
||||
{
|
||||
return &_dest_vgbuf;
|
||||
}
|
||||
|
||||
vg_lite_buffer_t * vglite_get_src_buf(void)
|
||||
{
|
||||
return &_src_vgbuf;
|
||||
}
|
||||
|
||||
void vglite_set_dest_buf_ptr(void * buf)
|
||||
{
|
||||
_set_vgbuf_ptr(&_dest_vgbuf, buf);
|
||||
}
|
||||
|
||||
void vglite_set_src_buf_ptr(const void * buf)
|
||||
{
|
||||
_set_vgbuf_ptr(&_src_vgbuf, (void *)buf);
|
||||
}
|
||||
|
||||
void vglite_set_dest_buf(const void * buf, uint32_t width, uint32_t height, uint32_t stride,
|
||||
lv_color_format_t cf)
|
||||
{
|
||||
vglite_set_buf(&_dest_vgbuf, (void *)buf, width, height, stride, cf);
|
||||
}
|
||||
|
||||
void vglite_set_src_buf(const void * buf, uint32_t width, uint32_t height, uint32_t stride,
|
||||
lv_color_format_t cf)
|
||||
{
|
||||
vglite_set_buf(&_src_vgbuf, (void *)buf, width, height, stride, cf);
|
||||
}
|
||||
|
||||
void vglite_set_buf(vg_lite_buffer_t * vgbuf, void * buf,
|
||||
uint32_t width, uint32_t height, uint32_t stride,
|
||||
lv_color_format_t cf)
|
||||
{
|
||||
vg_lite_buffer_format_t vgformat = vglite_get_buf_format(cf);
|
||||
|
||||
vgbuf->format = vgformat;
|
||||
vgbuf->tiled = VG_LITE_LINEAR;
|
||||
vgbuf->image_mode = VG_LITE_NORMAL_IMAGE_MODE;
|
||||
vgbuf->transparency_mode = VG_LITE_IMAGE_OPAQUE;
|
||||
|
||||
vgbuf->width = (int32_t)width;
|
||||
vgbuf->height = (int32_t)height;
|
||||
vgbuf->stride = (int32_t)stride;
|
||||
|
||||
lv_memzero(&vgbuf->yuv, sizeof(vgbuf->yuv));
|
||||
|
||||
vgbuf->memory = buf;
|
||||
vgbuf->address = (uint32_t)vgbuf->memory;
|
||||
vgbuf->handle = NULL;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static inline void _set_vgbuf_ptr(vg_lite_buffer_t * vgbuf, void * buf)
|
||||
{
|
||||
vgbuf->memory = buf;
|
||||
vgbuf->address = (uint32_t)vgbuf->memory;
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DRAW_VGLITE*/
|
||||
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* @file lv_vglite_buf.h
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2023 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef LV_VGLITE_BUF_H
|
||||
#define LV_VGLITE_BUF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_DRAW_VGLITE
|
||||
#include "../../sw/lv_draw_sw.h"
|
||||
|
||||
#include "vg_lite.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Get vglite destination buffer pointer.
|
||||
*
|
||||
* @retval The vglite destination buffer
|
||||
*
|
||||
*/
|
||||
vg_lite_buffer_t * vglite_get_dest_buf(void);
|
||||
|
||||
/**
|
||||
* Get vglite source buffer pointer.
|
||||
*
|
||||
* @retval The vglite source buffer
|
||||
*
|
||||
*/
|
||||
vg_lite_buffer_t * vglite_get_src_buf(void);
|
||||
|
||||
/**
|
||||
* Set vglite destination buffer address only.
|
||||
*
|
||||
* @param[in] buf Destination buffer address (does not require alignment for VG_LITE_LINEAR mode)
|
||||
*
|
||||
*/
|
||||
void vglite_set_dest_buf_ptr(void * buf);
|
||||
|
||||
/**
|
||||
* Set vglite source buffer address only.
|
||||
*
|
||||
* @param[in] buf Source buffer address
|
||||
*
|
||||
*/
|
||||
void vglite_set_src_buf_ptr(const void * buf);
|
||||
|
||||
/**
|
||||
* Set vglite destination buffer.
|
||||
*
|
||||
* @param[in] buf Destination buffer address
|
||||
* @param[in] width Destination buffer width
|
||||
* @param[in] height Destination buffer height
|
||||
* @param[in] stride Destination buffer stride in bytes
|
||||
* @param[in] cf Destination buffer color format
|
||||
*
|
||||
*/
|
||||
void vglite_set_dest_buf(const void * buf, uint32_t width, uint32_t height, uint32_t stride,
|
||||
lv_color_format_t cf);
|
||||
|
||||
/**
|
||||
* Set vglite source buffer.
|
||||
*
|
||||
* @param[in] buf Source buffer address
|
||||
* @param[in] width Source buffer width
|
||||
* @param[in] height Source buffer height
|
||||
* @param[in] stride Source buffer stride in bytes
|
||||
* @param[in] cf Source buffer color format
|
||||
*
|
||||
*/
|
||||
void vglite_set_src_buf(const void * buf, uint32_t width, uint32_t height, uint32_t stride,
|
||||
lv_color_format_t cf);
|
||||
|
||||
/**
|
||||
* Set vglite buffer.
|
||||
*
|
||||
* @param[in] vgbuf Address of the VGLite buffer object
|
||||
* @param[in] buf Address of the memory for the VGLite buffer
|
||||
* @param[in] width Buffer width
|
||||
* @param[in] height Buffer height
|
||||
* @param[in] stride Buffer stride in bytes
|
||||
* @param[in] cf Buffer color format
|
||||
*
|
||||
*/
|
||||
void vglite_set_buf(vg_lite_buffer_t * vgbuf, void * buf,
|
||||
uint32_t width, uint32_t height, uint32_t stride,
|
||||
lv_color_format_t cf);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_VGLITE*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_VGLITE_BUF_H*/
|
||||
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* @file lv_vglite_matrix.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2023 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_vglite_matrix.h"
|
||||
|
||||
#if LV_USE_DRAW_VGLITE
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
static vg_lite_matrix_t _vgmatrix;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
vg_lite_matrix_t * vglite_get_matrix(void)
|
||||
{
|
||||
return &_vgmatrix;
|
||||
}
|
||||
|
||||
void vglite_set_translation_matrix(const lv_area_t * dest_area)
|
||||
{
|
||||
vg_lite_identity(&_vgmatrix);
|
||||
vg_lite_translate((vg_lite_float_t)dest_area->x1, (vg_lite_float_t)dest_area->y1, &_vgmatrix);
|
||||
}
|
||||
|
||||
void vglite_set_transformation_matrix(const lv_area_t * dest_area, const lv_draw_image_dsc_t * dsc)
|
||||
{
|
||||
vglite_set_translation_matrix(dest_area);
|
||||
|
||||
bool has_scale = (dsc->scale_x != LV_SCALE_NONE || dsc->scale_y != LV_SCALE_NONE);
|
||||
bool has_rotation = (dsc->rotation != 0);
|
||||
|
||||
if(has_scale || has_rotation) {
|
||||
vg_lite_translate(dsc->pivot.x, dsc->pivot.y, &_vgmatrix);
|
||||
if(has_rotation)
|
||||
vg_lite_rotate(dsc->rotation / 10.0f, &_vgmatrix); /* angle is 1/10 degree */
|
||||
if(has_scale) {
|
||||
vg_lite_float_t scale_x = 1.0f * dsc->scale_x / LV_SCALE_NONE;
|
||||
vg_lite_float_t scale_y = 1.0f * dsc->scale_y / LV_SCALE_NONE;
|
||||
vg_lite_scale(scale_x, scale_y, &_vgmatrix);
|
||||
}
|
||||
vg_lite_translate(0.0f - dsc->pivot.x, 0.0f - dsc->pivot.y, &_vgmatrix);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_VGLITE*/
|
||||
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* @file lv_vglite_matrix.h
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2023 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef LV_VGLITE_MATRIX_H
|
||||
#define LV_VGLITE_MATRIX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_DRAW_VGLITE
|
||||
#include "../../sw/lv_draw_sw.h"
|
||||
|
||||
#include "vg_lite.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
vg_lite_matrix_t * vglite_get_matrix(void);
|
||||
|
||||
/**
|
||||
* Creates matrix that translates to origin of given destination area.
|
||||
*
|
||||
* @param[in] dest_area Area with relative coordinates of destination buffer
|
||||
*
|
||||
*/
|
||||
void vglite_set_translation_matrix(const lv_area_t * dest_area);
|
||||
|
||||
/**
|
||||
* Creates matrix that translates to origin of given destination area with transformation (scale or rotate).
|
||||
*
|
||||
* @param[in] dest_area Area with relative coordinates of destination buffer
|
||||
* @param[in] dsc Image descriptor
|
||||
*
|
||||
*/
|
||||
void vglite_set_transformation_matrix(const lv_area_t * dest_area, const lv_draw_image_dsc_t * dsc);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_VGLITE*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_VGLITE_MATRIX_H*/
|
||||
@@ -0,0 +1,217 @@
|
||||
/**
|
||||
* @file lv_vglite_path.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2023 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_vglite_path.h"
|
||||
|
||||
#if LV_USE_DRAW_VGLITE
|
||||
#include "vg_lite.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void vglite_create_rect_path_data(int32_t * path_data, uint32_t * path_data_size,
|
||||
int32_t radius,
|
||||
const lv_area_t * coords)
|
||||
{
|
||||
int32_t rect_width = lv_area_get_width(coords);
|
||||
int32_t rect_height = lv_area_get_height(coords);
|
||||
|
||||
/* Get the final radius. Can't be larger than the half of the shortest side */
|
||||
int32_t shortest_side = LV_MIN(rect_width, rect_height);
|
||||
int32_t final_radius = LV_MIN(radius, shortest_side / 2);
|
||||
|
||||
/* Path data element index */
|
||||
uint8_t pidx = 0;
|
||||
|
||||
if((radius == (int32_t)LV_RADIUS_CIRCLE) && (rect_width == rect_height)) {
|
||||
|
||||
/* Get the control point offset for rounded cases */
|
||||
int32_t cpoff = (int32_t)((float)final_radius * BEZIER_OPTIM_CIRCLE);
|
||||
|
||||
/* Circle case */
|
||||
/* Starting point */
|
||||
path_data[pidx++] = VLC_OP_MOVE;
|
||||
path_data[pidx++] = coords->x1 + final_radius;
|
||||
path_data[pidx++] = coords->y1;
|
||||
|
||||
/* Top-right arc */
|
||||
path_data[pidx++] = VLC_OP_CUBIC_REL;
|
||||
path_data[pidx++] = cpoff;
|
||||
path_data[pidx++] = 0;
|
||||
path_data[pidx++] = final_radius;
|
||||
path_data[pidx++] = final_radius - cpoff;
|
||||
path_data[pidx++] = final_radius;
|
||||
path_data[pidx++] = final_radius;
|
||||
|
||||
/* Bottom-right arc*/
|
||||
path_data[pidx++] = VLC_OP_CUBIC_REL;
|
||||
path_data[pidx++] = 0;
|
||||
path_data[pidx++] = cpoff;
|
||||
path_data[pidx++] = cpoff - final_radius;
|
||||
path_data[pidx++] = final_radius;
|
||||
path_data[pidx++] = 0 - final_radius;
|
||||
path_data[pidx++] = final_radius;
|
||||
|
||||
/* Bottom-left arc */
|
||||
path_data[pidx++] = VLC_OP_CUBIC_REL;
|
||||
path_data[pidx++] = 0 - cpoff;
|
||||
path_data[pidx++] = 0;
|
||||
path_data[pidx++] = 0 - final_radius;
|
||||
path_data[pidx++] = cpoff - final_radius;
|
||||
path_data[pidx++] = 0 - final_radius;
|
||||
path_data[pidx++] = 0 - final_radius;
|
||||
|
||||
/* Top-left arc*/
|
||||
path_data[pidx++] = VLC_OP_CUBIC_REL;
|
||||
path_data[pidx++] = 0;
|
||||
path_data[pidx++] = 0 - cpoff;
|
||||
path_data[pidx++] = final_radius - cpoff;
|
||||
path_data[pidx++] = 0 - final_radius;
|
||||
path_data[pidx++] = final_radius;
|
||||
path_data[pidx++] = 0 - final_radius;
|
||||
|
||||
/* Ending point */
|
||||
path_data[pidx++] = VLC_OP_END;
|
||||
}
|
||||
else if(radius > 0) {
|
||||
/* Get the control point offset for rounded cases */
|
||||
int32_t cpoff = (int32_t)((float)final_radius * BEZIER_OPTIM_CIRCLE);
|
||||
|
||||
/* Rounded rectangle case */
|
||||
/* Starting point */
|
||||
path_data[pidx++] = VLC_OP_MOVE;
|
||||
path_data[pidx++] = coords->x1 + final_radius;
|
||||
path_data[pidx++] = coords->y1;
|
||||
|
||||
/* Top side */
|
||||
path_data[pidx++] = VLC_OP_LINE;
|
||||
path_data[pidx++] = coords->x2 - final_radius + 1; /*Extended for VGLite*/
|
||||
path_data[pidx++] = coords->y1;
|
||||
|
||||
/* Top-right corner */
|
||||
path_data[pidx++] = VLC_OP_CUBIC_REL;
|
||||
path_data[pidx++] = cpoff;
|
||||
path_data[pidx++] = 0;
|
||||
path_data[pidx++] = final_radius;
|
||||
path_data[pidx++] = final_radius - cpoff;
|
||||
path_data[pidx++] = final_radius;
|
||||
path_data[pidx++] = final_radius;
|
||||
|
||||
/* Right side */
|
||||
path_data[pidx++] = VLC_OP_LINE;
|
||||
path_data[pidx++] = coords->x2 + 1; /*Extended for VGLite*/
|
||||
path_data[pidx++] = coords->y2 - final_radius + 1; /*Extended for VGLite*/
|
||||
|
||||
/* Bottom-right corner*/
|
||||
path_data[pidx++] = VLC_OP_CUBIC_REL;
|
||||
path_data[pidx++] = 0;
|
||||
path_data[pidx++] = cpoff;
|
||||
path_data[pidx++] = cpoff - final_radius;
|
||||
path_data[pidx++] = final_radius;
|
||||
path_data[pidx++] = 0 - final_radius;
|
||||
path_data[pidx++] = final_radius;
|
||||
|
||||
/* Bottom side */
|
||||
path_data[pidx++] = VLC_OP_LINE;
|
||||
path_data[pidx++] = coords->x1 + final_radius;
|
||||
path_data[pidx++] = coords->y2 + 1; /*Extended for VGLite*/
|
||||
|
||||
/* Bottom-left corner */
|
||||
path_data[pidx++] = VLC_OP_CUBIC_REL;
|
||||
path_data[pidx++] = 0 - cpoff;
|
||||
path_data[pidx++] = 0;
|
||||
path_data[pidx++] = 0 - final_radius;
|
||||
path_data[pidx++] = cpoff - final_radius;
|
||||
path_data[pidx++] = 0 - final_radius;
|
||||
path_data[pidx++] = 0 - final_radius;
|
||||
|
||||
/* Left side*/
|
||||
path_data[pidx++] = VLC_OP_LINE;
|
||||
path_data[pidx++] = coords->x1;
|
||||
path_data[pidx++] = coords->y1 + final_radius;
|
||||
|
||||
/* Top-left corner */
|
||||
path_data[pidx++] = VLC_OP_CUBIC_REL;
|
||||
path_data[pidx++] = 0;
|
||||
path_data[pidx++] = 0 - cpoff;
|
||||
path_data[pidx++] = final_radius - cpoff;
|
||||
path_data[pidx++] = 0 - final_radius;
|
||||
path_data[pidx++] = final_radius;
|
||||
path_data[pidx++] = 0 - final_radius;
|
||||
|
||||
/* Ending point */
|
||||
path_data[pidx++] = VLC_OP_END;
|
||||
}
|
||||
else {
|
||||
/* Non-rounded rectangle case */
|
||||
/* Starting point */
|
||||
path_data[pidx++] = VLC_OP_MOVE;
|
||||
path_data[pidx++] = coords->x1;
|
||||
path_data[pidx++] = coords->y1;
|
||||
|
||||
/* Top side */
|
||||
path_data[pidx++] = VLC_OP_LINE;
|
||||
path_data[pidx++] = coords->x2 + 1; /*Extended for VGLite*/
|
||||
path_data[pidx++] = coords->y1;
|
||||
|
||||
/* Right side */
|
||||
path_data[pidx++] = VLC_OP_LINE;
|
||||
path_data[pidx++] = coords->x2 + 1; /*Extended for VGLite*/
|
||||
path_data[pidx++] = coords->y2 + 1; /*Extended for VGLite*/
|
||||
|
||||
/* Bottom side */
|
||||
path_data[pidx++] = VLC_OP_LINE;
|
||||
path_data[pidx++] = coords->x1;
|
||||
path_data[pidx++] = coords->y2 + 1; /*Extended for VGLite*/
|
||||
|
||||
/* Left side*/
|
||||
path_data[pidx++] = VLC_OP_LINE;
|
||||
path_data[pidx++] = coords->x1;
|
||||
path_data[pidx++] = coords->y1;
|
||||
|
||||
/* Ending point */
|
||||
path_data[pidx++] = VLC_OP_END;
|
||||
}
|
||||
|
||||
/* Resulting path size */
|
||||
*path_data_size = pidx * sizeof(int32_t);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_VGLITE*/
|
||||
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* @file lv_vglite_path.h
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2023 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef LV_VGLITE_PATH_H
|
||||
#define LV_VGLITE_PATH_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_DRAW_VGLITE
|
||||
#include "../../sw/lv_draw_sw.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/* The optimal Bezier control point offset for radial unit
|
||||
* see: https://spencermortensen.com/articles/bezier-circle/
|
||||
**/
|
||||
#define BEZIER_OPTIM_CIRCLE 0.551915024494f
|
||||
|
||||
/* Draw lines for control points of Bezier curves */
|
||||
#define BEZIER_DBG_CONTROL_POINTS 0
|
||||
|
||||
/* Path data sizes for different elements */
|
||||
#define CUBIC_PATH_DATA_SIZE 7 /* 1 opcode, 6 arguments */
|
||||
#define LINE_PATH_DATA_SIZE 3 /* 1 opcode, 2 arguments */
|
||||
#define MOVE_PATH_DATA_SIZE 3 /* 1 opcode, 2 arguments */
|
||||
#define END_PATH_DATA_SIZE 1 /* 1 opcode, 0 arguments */
|
||||
/* Maximum possible rectangle path size
|
||||
* is in the rounded rectangle case:
|
||||
* - 1 move for the path start
|
||||
* - 4 cubics for the corners
|
||||
* - 4 lines for the sides
|
||||
* - 1 end for the path end */
|
||||
#define RECT_PATH_DATA_MAX_SIZE (1 * MOVE_PATH_DATA_SIZE + 4 * CUBIC_PATH_DATA_SIZE + 4 * LINE_PATH_DATA_SIZE + 1 * END_PATH_DATA_SIZE)
|
||||
|
||||
/* Maximum possible arc path size
|
||||
* is in the rounded arc case:
|
||||
* - 1 move for the path start
|
||||
* - 16 cubics for the arc (5 inner, 5 outer) and corners (3 per corner)
|
||||
* - 1 end for the path end */
|
||||
#define ARC_PATH_DATA_MAX_SIZE (1 * MOVE_PATH_DATA_SIZE + 16 * CUBIC_PATH_DATA_SIZE + 1 * END_PATH_DATA_SIZE)
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Generates path data for rectangle drawing.
|
||||
*
|
||||
* @param[in/out] path The path data to initialize
|
||||
* @param[in/out] path_size The resulting size of the created path data
|
||||
* @param[in] dsc The style descriptor for the rectangle to be drawn
|
||||
* @param[in] coords The coordinates of the rectangle to be drawn
|
||||
*
|
||||
*/
|
||||
void vglite_create_rect_path_data(int32_t * path_data, uint32_t * path_data_size,
|
||||
int32_t radius,
|
||||
const lv_area_t * coords);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_VGLITE*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_VGLITE_PATH_H*/
|
||||
@@ -0,0 +1,282 @@
|
||||
/**
|
||||
* @file lv_vglite_utils.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2022-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_vglite_utils.h"
|
||||
|
||||
#if LV_USE_DRAW_VGLITE
|
||||
#include "lv_vglite_buf.h"
|
||||
|
||||
#include "../../../core/lv_refr.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
#if LV_USE_VGLITE_DRAW_ASYNC
|
||||
static volatile bool _cmd_buf_flushed = false;
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
const char * vglite_error_to_string(vg_lite_error_t error)
|
||||
{
|
||||
switch(error) {
|
||||
ENUM_TO_STRING(VG_LITE_SUCCESS);
|
||||
ENUM_TO_STRING(VG_LITE_INVALID_ARGUMENT);
|
||||
ENUM_TO_STRING(VG_LITE_OUT_OF_MEMORY);
|
||||
ENUM_TO_STRING(VG_LITE_NO_CONTEXT);
|
||||
ENUM_TO_STRING(VG_LITE_TIMEOUT);
|
||||
ENUM_TO_STRING(VG_LITE_OUT_OF_RESOURCES);
|
||||
ENUM_TO_STRING(VG_LITE_GENERIC_IO);
|
||||
ENUM_TO_STRING(VG_LITE_NOT_SUPPORT);
|
||||
ENUM_TO_STRING(VG_LITE_ALREADY_EXISTS);
|
||||
ENUM_TO_STRING(VG_LITE_NOT_ALIGNED);
|
||||
ENUM_TO_STRING(VG_LITE_FLEXA_TIME_OUT);
|
||||
ENUM_TO_STRING(VG_LITE_FLEXA_HANDSHAKE_FAIL);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return "VG_LITE_UKNOWN_ERROR";
|
||||
}
|
||||
|
||||
#if LV_USE_VGLITE_DRAW_ASYNC
|
||||
bool vglite_cmd_buf_is_flushed(void)
|
||||
{
|
||||
return _cmd_buf_flushed;
|
||||
}
|
||||
#endif
|
||||
|
||||
void vglite_run(void)
|
||||
{
|
||||
#if LV_USE_VGLITE_DRAW_ASYNC
|
||||
vg_lite_uint32_t gpu_idle = 0;
|
||||
|
||||
VGLITE_CHECK_ERROR(vg_lite_get_parameter(VG_LITE_GPU_IDLE_STATE, 1, (vg_lite_pointer)&gpu_idle));
|
||||
|
||||
if(!gpu_idle) {
|
||||
_cmd_buf_flushed = false;
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If LV_USE_VGLITE_DRAW_ASYNC is enabled, simply flush the command buffer and the
|
||||
* vglite draw thread will signal asynchronous the dispatcher for completed tasks.
|
||||
* Without draw async, process the tasks and signal them as complete one by one.
|
||||
*/
|
||||
#if LV_USE_VGLITE_DRAW_ASYNC
|
||||
VGLITE_CHECK_ERROR(vg_lite_flush());
|
||||
_cmd_buf_flushed = true;
|
||||
#else
|
||||
VGLITE_CHECK_ERROR(vg_lite_finish());
|
||||
#endif
|
||||
}
|
||||
|
||||
#if LV_USE_VGLITE_DRAW_ASYNC
|
||||
void vglite_wait_for_finish(void)
|
||||
{
|
||||
VGLITE_CHECK_ERROR(vg_lite_finish());
|
||||
}
|
||||
#endif
|
||||
|
||||
vg_lite_color_t vglite_get_color(lv_color32_t lv_col32, bool gradient)
|
||||
{
|
||||
vg_lite_color_t vg_col32;
|
||||
|
||||
/* Pre-multiply alpha */
|
||||
lv_col32.red = LV_UDIV255(lv_col32.red * lv_col32.alpha);
|
||||
lv_col32.green = LV_UDIV255(lv_col32.green * lv_col32.alpha);
|
||||
lv_col32.blue = LV_UDIV255(lv_col32.blue * lv_col32.alpha);
|
||||
|
||||
if(!gradient)
|
||||
/* The color is in ABGR8888 format with red channel in the lower 8 bits. */
|
||||
vg_col32 = ((vg_lite_color_t)lv_col32.alpha << 24) | ((vg_lite_color_t)lv_col32.blue << 16) |
|
||||
((vg_lite_color_t)lv_col32.green << 8) | (vg_lite_color_t)lv_col32.red;
|
||||
else
|
||||
/* The gradient color is in ARGB8888 format with blue channel in the lower 8 bits. */
|
||||
vg_col32 = ((vg_lite_color_t)lv_col32.alpha << 24) | ((vg_lite_color_t)lv_col32.red << 16) |
|
||||
((vg_lite_color_t)lv_col32.green << 8) | (vg_lite_color_t)lv_col32.blue;
|
||||
|
||||
return vg_col32;
|
||||
}
|
||||
|
||||
vg_lite_blend_t vglite_get_blend_mode(lv_blend_mode_t lv_blend_mode)
|
||||
{
|
||||
vg_lite_blend_t vg_blend_mode = VG_LITE_BLEND_NONE;
|
||||
|
||||
if(vg_lite_query_feature(gcFEATURE_BIT_VG_LVGL_SUPPORT)) {
|
||||
switch(lv_blend_mode) {
|
||||
case LV_BLEND_MODE_NORMAL:
|
||||
vg_blend_mode = VG_LITE_BLEND_NORMAL_LVGL;
|
||||
break;
|
||||
case LV_BLEND_MODE_ADDITIVE:
|
||||
vg_blend_mode = VG_LITE_BLEND_ADDITIVE_LVGL;
|
||||
break;
|
||||
case LV_BLEND_MODE_SUBTRACTIVE:
|
||||
vg_blend_mode = VG_LITE_BLEND_SUBTRACT_LVGL;
|
||||
break;
|
||||
case LV_BLEND_MODE_MULTIPLY:
|
||||
vg_blend_mode = VG_LITE_BLEND_MULTIPLY_LVGL;
|
||||
break;
|
||||
default:
|
||||
VGLITE_ASSERT_MSG(false, "Unsupported blend mode.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch(lv_blend_mode) {
|
||||
case LV_BLEND_MODE_NORMAL:
|
||||
vg_blend_mode = VG_LITE_BLEND_SRC_OVER;
|
||||
break;
|
||||
case LV_BLEND_MODE_ADDITIVE:
|
||||
vg_blend_mode = VG_LITE_BLEND_ADDITIVE;
|
||||
break;
|
||||
case LV_BLEND_MODE_SUBTRACTIVE:
|
||||
vg_blend_mode = VG_LITE_BLEND_SUBTRACT;
|
||||
break;
|
||||
case LV_BLEND_MODE_MULTIPLY:
|
||||
vg_blend_mode = VG_LITE_BLEND_MULTIPLY;
|
||||
break;
|
||||
default:
|
||||
VGLITE_ASSERT_MSG(false, "Unsupported blend mode.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return vg_blend_mode;
|
||||
}
|
||||
|
||||
vg_lite_buffer_format_t vglite_get_buf_format(lv_color_format_t cf)
|
||||
{
|
||||
vg_lite_buffer_format_t vg_buffer_format = VG_LITE_BGR565;
|
||||
|
||||
switch(cf) {
|
||||
case LV_COLOR_FORMAT_L8:
|
||||
vg_buffer_format = VG_LITE_L8;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_A8:
|
||||
vg_buffer_format = VG_LITE_A8;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_I1:
|
||||
vg_buffer_format = VG_LITE_INDEX_1;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_I2:
|
||||
vg_buffer_format = VG_LITE_INDEX_2;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_I4:
|
||||
vg_buffer_format = VG_LITE_INDEX_4;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_I8:
|
||||
vg_buffer_format = VG_LITE_INDEX_8;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_RGB565:
|
||||
vg_buffer_format = VG_LITE_BGR565;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_RGB565A8:
|
||||
vg_buffer_format = VG_LITE_ABGR8565;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_RGB888:
|
||||
vg_buffer_format = VG_LITE_BGR888;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_ARGB8888:
|
||||
vg_buffer_format = VG_LITE_BGRA8888;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_XRGB8888:
|
||||
vg_buffer_format = VG_LITE_BGRX8888;
|
||||
break;
|
||||
|
||||
default:
|
||||
VGLITE_ASSERT_MSG(false, "Unsupported color format.");
|
||||
break;
|
||||
}
|
||||
|
||||
return vg_buffer_format;
|
||||
}
|
||||
|
||||
uint8_t vglite_get_stride_alignment(lv_color_format_t cf)
|
||||
{
|
||||
uint8_t align_bytes = LV_COLOR_DEPTH / 8 * 16; /*16 pixels*/
|
||||
|
||||
switch(cf) {
|
||||
case LV_COLOR_FORMAT_I1:
|
||||
case LV_COLOR_FORMAT_I2:
|
||||
case LV_COLOR_FORMAT_I4:
|
||||
align_bytes = 8;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_I8:
|
||||
case LV_COLOR_FORMAT_A8:
|
||||
case LV_COLOR_FORMAT_L8:
|
||||
align_bytes = 16;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_RGB565:
|
||||
align_bytes = 32;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_RGB565A8:
|
||||
case LV_COLOR_FORMAT_RGB888:
|
||||
align_bytes = 48;
|
||||
break;
|
||||
case LV_COLOR_FORMAT_ARGB8888:
|
||||
case LV_COLOR_FORMAT_XRGB8888:
|
||||
align_bytes = 64;
|
||||
break;
|
||||
|
||||
default:
|
||||
VGLITE_ASSERT_MSG(false, "Unsupported buffer format.");
|
||||
break;
|
||||
}
|
||||
|
||||
return align_bytes;
|
||||
}
|
||||
|
||||
bool vglite_src_buf_aligned(const void * buf, uint32_t stride, lv_color_format_t cf)
|
||||
{
|
||||
/* No alignment requirement for destination buffer when using mode VG_LITE_LINEAR */
|
||||
|
||||
/* Test for pointer alignment */
|
||||
if((uintptr_t)buf % LV_ATTRIBUTE_MEM_ALIGN_SIZE)
|
||||
return false;
|
||||
|
||||
/* Test for stride alignment */
|
||||
if(stride == 0 || stride % vglite_get_stride_alignment(cf))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_VGLITE*/
|
||||
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
* @file lv_vglite_utils.h
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copyright 2022-2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef LV_VGLITE_UTILS_H
|
||||
#define LV_VGLITE_UTILS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../../lv_conf_internal.h"
|
||||
|
||||
#if LV_USE_DRAW_VGLITE
|
||||
#include "../../sw/lv_draw_sw.h"
|
||||
|
||||
#include "vg_lite.h"
|
||||
#include "vg_lite_options.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define ENUM_TO_STRING(e) \
|
||||
case (e): \
|
||||
return #e
|
||||
|
||||
#if LV_USE_VGLITE_ASSERT
|
||||
#define VGLITE_ASSERT(expr) LV_ASSERT(expr)
|
||||
#else
|
||||
#define VGLITE_ASSERT(expr)
|
||||
#endif
|
||||
|
||||
#define VGLITE_ASSERT_MSG(expr, msg) \
|
||||
do { \
|
||||
if(!(expr)) { \
|
||||
LV_LOG_ERROR(msg); \
|
||||
VGLITE_ASSERT(false); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define VGLITE_CHECK_ERROR(function) \
|
||||
do { \
|
||||
vg_lite_error_t error = function; \
|
||||
if(error != VG_LITE_SUCCESS) { \
|
||||
LV_LOG_ERROR("Execute '" #function "' error(%d): %s", \
|
||||
(int)error, vglite_error_to_string(error)); \
|
||||
VGLITE_ASSERT(false); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Set the clipping box.
|
||||
*
|
||||
* @param[in] clip_area Clip area with relative coordinates of destination buffer
|
||||
*
|
||||
*/
|
||||
static inline void vglite_set_scissor(const lv_area_t * clip_area);
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
const char * vglite_error_to_string(vg_lite_error_t error);
|
||||
|
||||
#if LV_USE_VGLITE_DRAW_ASYNC
|
||||
/**
|
||||
* Get VG-Lite command buffer flushed status.
|
||||
*
|
||||
*/
|
||||
bool vglite_cmd_buf_is_flushed(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Flush command to VG-Lite.
|
||||
*
|
||||
*/
|
||||
void vglite_run(void);
|
||||
|
||||
/**
|
||||
* Wait for VG-Lite finish.
|
||||
*
|
||||
*/
|
||||
#if LV_USE_VGLITE_DRAW_ASYNC
|
||||
void vglite_wait_for_finish(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get vglite color. Premultiplies (if not hw already) and swizzles the given
|
||||
* LVGL 32bit color to obtain vglite color.
|
||||
*
|
||||
* @param[in] lv_col32 The initial LVGL 32bit color
|
||||
* @param[in] gradient True for gradient color
|
||||
*
|
||||
* @retval The vglite 32-bit color value:
|
||||
*
|
||||
*/
|
||||
vg_lite_color_t vglite_get_color(lv_color32_t lv_col32, bool gradient);
|
||||
|
||||
/**
|
||||
* Get vglite blend mode.
|
||||
*
|
||||
* @param[in] lv_blend_mode The LVGL blend mode
|
||||
*
|
||||
* @retval The vglite blend mode
|
||||
*
|
||||
*/
|
||||
vg_lite_blend_t vglite_get_blend_mode(lv_blend_mode_t lv_blend_mode);
|
||||
|
||||
/**
|
||||
* Get vglite buffer format.
|
||||
*
|
||||
* @param[in] cf Color format
|
||||
*
|
||||
* @retval The vglite buffer format
|
||||
*
|
||||
*/
|
||||
vg_lite_buffer_format_t vglite_get_buf_format(lv_color_format_t cf);
|
||||
|
||||
/**
|
||||
* Get vglite stride alignment.
|
||||
*
|
||||
* @param[in] cf Color format
|
||||
*
|
||||
* @retval Alignment requirement in bytes
|
||||
*
|
||||
*/
|
||||
uint8_t vglite_get_stride_alignment(lv_color_format_t cf);
|
||||
|
||||
/**
|
||||
* Check source start address and stride alignment.
|
||||
*
|
||||
* @param[in] buf Buffer address
|
||||
* @param[in] stride Stride of buffer in bytes
|
||||
* @param[in] cf Color format - to calculate the expected alignment
|
||||
*
|
||||
* @retval true Alignment OK
|
||||
*
|
||||
*/
|
||||
bool vglite_src_buf_aligned(const void * buf, uint32_t stride, lv_color_format_t cf);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static inline void vglite_set_scissor(const lv_area_t * clip_area)
|
||||
{
|
||||
vg_lite_set_scissor(clip_area->x1, clip_area->y1, clip_area->x2 + 1, clip_area->y2 + 1);
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DRAW_VGLITE*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_VGLITE_UTILS_H*/
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user