From 1a41f13fd633d522cc4e4f1e96f72a5ff30771bd Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Thu, 18 Jun 2020 17:06:24 -0700 Subject: [PATCH 001/173] Initial lv_rotary work extending lv_arc with stubbed signal handler. --- lv_conf_template.h | 3 + src/lv_conf_internal.h | 3 + src/lv_misc/lv_math.h | 2 + src/lv_themes/lv_theme_material.c | 57 ++++ src/lv_widgets/lv_rotary.c | 458 ++++++++++++++++++++++++++++++ src/lv_widgets/lv_rotary.h | 281 ++++++++++++++++++ 6 files changed, 804 insertions(+) create mode 100644 src/lv_widgets/lv_rotary.c create mode 100644 src/lv_widgets/lv_rotary.h diff --git a/lv_conf_template.h b/lv_conf_template.h index de2287cf4..629e0bf62 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -654,6 +654,9 @@ typedef void * lv_obj_user_data_t; # define LV_ROLLER_INF_PAGES 7 #endif +/*Rotary (dependencies: lv_arc, lv_btn)*/ +#define LV_USE_ROTARY 1 + /*Slider (dependencies: lv_bar)*/ #define LV_USE_SLIDER 1 diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h index da8f7d8d1..9ea1abbd7 100644 --- a/src/lv_conf_internal.h +++ b/src/lv_conf_internal.h @@ -991,6 +991,9 @@ #endif #endif +/*Rotary (dependencies: lv_arc, lv_btn)*/ +#define LV_USE_ROTARY 1 + /*Slider (dependencies: lv_bar)*/ #ifndef LV_USE_SLIDER #define LV_USE_SLIDER 1 diff --git a/src/lv_misc/lv_math.h b/src/lv_misc/lv_math.h index 499176244..dc45ad630 100644 --- a/src/lv_misc/lv_math.h +++ b/src/lv_misc/lv_math.h @@ -31,6 +31,8 @@ extern "C" { #define LV_MATH_UDIV255(x) ((uint32_t)((uint32_t) (x) * 0x8081) >> 0x17) +#define LV_MATH_MAP(a, min_in, max_in, min, max) (min - (((max - min) / (max_in - min_in)) * min_in) + (((max - min) / (max_in - min_in)) * a)) + #define LV_IS_SIGNED(t) (((t)(-1)) < ((t) 0)) #define LV_UMAX_OF(t) (((0x1ULL << ((sizeof(t) * 8ULL) - 1ULL)) - 1ULL) | (0xFULL << ((sizeof(t) * 8ULL) - 4ULL))) #define LV_SMAX_OF(t) (((0x1ULL << ((sizeof(t) * 8ULL) - 1ULL)) - 1ULL) | (0x7ULL << ((sizeof(t) * 8ULL) - 4ULL))) diff --git a/src/lv_themes/lv_theme_material.c b/src/lv_themes/lv_theme_material.c index 33d6f4985..e0b0e9762 100644 --- a/src/lv_themes/lv_theme_material.c +++ b/src/lv_themes/lv_theme_material.c @@ -147,6 +147,10 @@ typedef struct { lv_style_t roller_bg, roller_sel; #endif +#if LV_USE_ROTARY + lv_style_t rotary_bg, rotary_indic, rotary_knob; +#endif + #if LV_USE_SLIDER lv_style_t slider_knob, slider_bg; #endif @@ -789,6 +793,38 @@ static void roller_init(void) #endif } +static void rotary_init(void) +{ +#if LV_USE_ROTARY != 0 + style_init_reset(&styles->rotary_bg); + lv_style_set_clip_corner(&styles->rotary_bg, LV_STATE_DEFAULT, true); + lv_style_set_pad_left(&styles->rotary_bg, LV_STATE_DEFAULT, 0); + lv_style_set_pad_right(&styles->rotary_bg, LV_STATE_DEFAULT, 0); + lv_style_set_pad_top(&styles->rotary_bg, LV_STATE_DEFAULT, 0); + lv_style_set_pad_bottom(&styles->rotary_bg, LV_STATE_DEFAULT, 0); + lv_style_set_pad_inner(&styles->rotary_bg, LV_STATE_DEFAULT, 0); + lv_style_set_border_width(&styles->rotary_bg, LV_STATE_DEFAULT, 0); + lv_style_set_line_color(&styles->rotary_bg, LV_STATE_DEFAULT, COLOR_BG_SEC); + lv_style_set_line_width(&styles->rotary_bg, LV_STATE_DEFAULT, LV_DPX(8)); + lv_style_set_line_rounded(&styles->rotary_bg, LV_STATE_DEFAULT, true); + + style_init_reset(&styles->rotary_indic); + lv_style_set_line_color(&styles->rotary_indic, LV_STATE_DEFAULT, theme.color_primary); + lv_style_set_line_width(&styles->rotary_indic, LV_STATE_DEFAULT, LV_DPX(8)); + lv_style_set_line_rounded(&styles->rotary_indic, LV_STATE_DEFAULT, true); + + style_init_reset(&styles->rotary_knob); + lv_style_set_bg_opa(&styles->rotary_knob, LV_STATE_DEFAULT, LV_OPA_COVER); + lv_style_set_bg_color(&styles->rotary_knob, LV_STATE_DEFAULT, LV_COLOR_WHITE); + lv_style_set_radius(&styles->rotary_knob, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE); + lv_style_set_pad_top(&styles->rotary_knob, LV_STATE_DEFAULT, - LV_DPX(4)); + lv_style_set_pad_bottom(&styles->rotary_knob, LV_STATE_DEFAULT, - LV_DPX(4)); + lv_style_set_pad_left(&styles->rotary_knob, LV_STATE_DEFAULT, - LV_DPX(4)); + lv_style_set_pad_right(&styles->rotary_knob, LV_STATE_DEFAULT, - LV_DPX(4)); + lv_style_set_pad_inner(&styles->rotary_knob, LV_STATE_DEFAULT, LV_DPX(6)); +#endif +} + static void tabview_init(void) { #if LV_USE_TABVIEW != 0 @@ -923,6 +959,7 @@ lv_theme_t * lv_theme_material_init(lv_color_t color_primary, lv_color_t color_s list_init(); ddlist_init(); roller_init(); + rotary_init(); tabview_init(); tileview_init(); table_init(); @@ -1223,6 +1260,26 @@ static void theme_apply(lv_obj_t * obj, lv_theme_style_t name) break; #endif +#if LV_USE_ROTARY + case LV_THEME_ROTARY: + lv_obj_clean_style_list(obj, LV_ROTARY_PART_BG); + list = lv_obj_get_style_list(obj, LV_ROTARY_PART_BG); + _lv_style_list_add_style(list, &styles->bg); + _lv_style_list_add_style(list, &styles->arc_bg); + _lv_style_list_add_style(list, &styles->rotary_bg); + + lv_obj_clean_style_list(obj, LV_ROTARY_PART_INDIC); + list = lv_obj_get_style_list(obj, LV_ROTARY_PART_INDIC); + _lv_style_list_add_style(list, &styles->arc_indic); + _lv_style_list_add_style(list, &styles->rotary_indic); + + lv_obj_clean_style_list(obj, LV_ROTARY_PART_KNOB); + list = lv_obj_get_style_list(obj, LV_ROTARY_PART_KNOB); + _lv_style_list_add_style(list, &styles->btn); + _lv_style_list_add_style(list, &styles->rotary_knob); + + break; +#endif #if LV_USE_OBJMASK case LV_THEME_OBJMASK: diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c new file mode 100644 index 000000000..c3ef76683 --- /dev/null +++ b/src/lv_widgets/lv_rotary.c @@ -0,0 +1,458 @@ + +/** + * @file lv_rotary.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_rotary.h" +#if LV_USE_ROTARY != 0 + +#include "../lv_core/lv_debug.h" +#include "../lv_core/lv_group.h" +#include "../lv_core/lv_indev.h" +#include "../lv_draw/lv_draw.h" +#include "../lv_themes/lv_theme.h" +#include "../lv_misc/lv_math.h" +#include "lv_img.h" + +/********************* + * DEFINES + *********************/ +#define LV_OBJX_NAME "lv_rotary" + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static lv_design_res_t lv_rotary_design(lv_obj_t * rotary, const lv_area_t * clip_area, lv_design_mode_t mode); +static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * param); +static lv_style_list_t * lv_rotary_get_style(lv_obj_t * rotary, uint8_t part); +// static void draw_bg(lv_obj_t * rotary, const lv_area_t * clip_area); +// static void draw_indic(lv_obj_t * rotary, const lv_area_t * clip_area); +static void draw_knob(lv_obj_t * rotary, const lv_area_t * clip_area); + +/********************** + * STATIC VARIABLES + **********************/ +static lv_design_cb_t ancestor_design; +static lv_signal_cb_t ancestor_signal; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * Create a rotary objects + * @param par pointer to an object, it will be the parent of the new rotary + * @param copy pointer to a rotary object, if not NULL then the new object will be copied from it + * @return pointer to the created rotary + */ +lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) +{ + LV_LOG_TRACE("rotary create started"); + + /*Create the ancestor rotary*/ + lv_obj_t * rotary = lv_arc_create(par, copy); + LV_ASSERT_MEM(rotary); + if(rotary == NULL) return NULL; + + if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(rotary); + if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(rotary); + + /*Allocate the rotary type specific extended data*/ + lv_rotary_ext_t * ext = lv_obj_allocate_ext_attr(rotary, sizeof(lv_rotary_ext_t)); + LV_ASSERT_MEM(ext); + if(ext == NULL) { + lv_obj_del(rotary); + return NULL; + } + + /*Initialize the allocated 'ext' */ + ext->arc.rotation_angle = 0; + ext->arc.bg_angle_start = 135; + ext->arc.bg_angle_end = 45; + ext->arc.arc_angle_start = 135; + ext->arc.arc_angle_end = 270; + ext->cur_value = 0; + ext->min_value = 0; + ext->max_value = 0; + ext->start_value = 0; + ext->dragging = false; + lv_style_list_init(&ext->style_bg); + lv_style_list_init(&ext->style_indic); + lv_style_list_init(&ext->style_knob); + + /*The signal and design functions are not copied so set them here*/ + lv_obj_set_signal_cb(rotary, lv_rotary_signal); + lv_obj_set_design_cb(rotary, lv_rotary_design); + + /*Init the new rotary rotary*/ + if(copy == NULL) { + lv_obj_set_click(rotary, true); + lv_obj_add_protect(rotary, LV_PROTECT_PRESS_LOST); + lv_obj_set_ext_click_area(rotary, 0, 0, LV_DPI / 10, LV_DPI / 10); + + lv_theme_apply(rotary, LV_THEME_ROTARY); + lv_obj_set_height(rotary, LV_DPI / 15); + } + /*Copy an existing rotary*/ + else { + lv_rotary_ext_t * copy_ext = lv_obj_get_ext_attr(copy); + ext->cur_value = copy_ext->cur_value; + ext->min_value = copy_ext->min_value; + ext->max_value = copy_ext->max_value; + ext->start_value = copy_ext->start_value; + ext->dragging = copy_ext->dragging; + lv_style_list_copy(&ext->style_bg, ©_ext->style_bg); + lv_style_list_copy(&ext->style_indic, ©_ext->style_indic); + lv_style_list_copy(&ext->style_knob, ©_ext->style_knob); + + lv_obj_refresh_style(rotary, LV_OBJ_PART_ALL); + } + + LV_LOG_INFO("rotary created"); + + return rotary; +} + +/*===================== + * Setter functions + *====================*/ + +/** + * Set a new value on the rotary + * @param rotary pointer to a rotary object + * @param value new value + * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately + */ +void lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim) +{ + LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); + + lv_rotary_ext_t * ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); + if(ext->cur_value == value) return; + + int16_t new_value; + new_value = value > ext->max_value ? ext->max_value : value; + new_value = new_value < ext->min_value ? ext->min_value : new_value; + + if(ext->cur_value == new_value) return; + + ext->cur_value = new_value; + + lv_arc_set_end_angle( + rotary, + LV_MATH_MAP( + ext->cur_value, + ext->min_value, + ext->max_value, + ext->arc.arc_angle_start, + ext->arc.arc_angle_start + 360 + ) + ); +} + +/** + * Set a new value for the left knob of a rotary + * @param rotary pointer to a rotary object + * @param left_value new value + * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately + */ +void lv_rotary_set_start_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim) +{ + LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); + + lv_rotary_ext_t * ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); + ext->start_value = value; +} + +/** + * Set minimum and the maximum values of a rotary + * @param rotary pointer to the rotary object + * @param min minimum value + * @param max maximum value + */ +void lv_rotary_set_range(lv_obj_t * rotary, int16_t min, int16_t max) +{ + LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); + + lv_rotary_ext_t * ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); + if(ext->min_value == min && ext->max_value == max) return; + + ext->min_value = min; + ext->max_value = max; + + if(ext->cur_value < min) { + ext->cur_value = min; + } + if(ext->cur_value > max) { + ext->cur_value = max; + } + + lv_rotary_set_value(rotary, ext->cur_value, false); +} + +/** + * Make the rotary symmetric to zero. The indicator will grow from zero instead of the minimum + * position. + * @param rotary pointer to a rotary object + * @param en true: enable disable symmetric behavior; false: disable + */ +void lv_rotary_set_type(lv_obj_t * rotary, lv_rotary_type_t type) +{ + LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); + + lv_rotary_ext_t *ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); + ext->type = type; + + lv_obj_invalidate(rotary); +} + +/*===================== + * Getter functions + *====================*/ + +/** + * Get the value of a rotary + * @param rotary pointer to a rotary object + * @return the value of the rotary + */ +int16_t lv_rotary_get_value(const lv_obj_t * rotary) +{ + LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); + + lv_rotary_ext_t * ext = lv_obj_get_ext_attr(rotary); + return ext->cur_value; +} + +/** + * Get the value of the left knob of a rotary + * @param rotary pointer to a rotary object + * @return the start value of the rotary + */ +int16_t lv_rotary_get_start_value(const lv_obj_t * rotary) +{ + LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); + + lv_rotary_ext_t *ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); + return ext->start_value; +} + +/** + * Get the minimum value of a rotary + * @param rotary pointer to a rotary object + * @return the minimum value of the rotary + */ +int16_t lv_rotary_get_min_value(const lv_obj_t * rotary) +{ + LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); + + lv_rotary_ext_t *ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); + return ext->min_value; +} + +/** + * Get the maximum value of a rotary + * @param rotary pointer to a rotary object + * @return the maximum value of the rotary + */ +int16_t lv_rotary_get_max_value(const lv_obj_t * rotary) +{ + LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); + + lv_rotary_ext_t *ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); + return ext->max_value; +} + +/** + * Give the rotary is being dragged or not + * @param rotary pointer to a rotary object + * @return true: drag in progress false: not dragged + */ +bool lv_rotary_is_dragged(const lv_obj_t * rotary) +{ + LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); + + lv_rotary_ext_t * ext = lv_obj_get_ext_attr(rotary); + return ext->dragging; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +/** + * Handle the drawing related tasks of the rotarys + * @param rotary pointer to an object + * @param clip_area the object will be drawn only in this area + * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area + * (return 'true' if yes) + * LV_DESIGN_DRAW: draw the object (always return 'true') + * LV_DESIGN_DRAW_POST: drawing after every children are drawn + * @param return an element of `lv_design_res_t` + */ +static lv_design_res_t lv_rotary_design(lv_obj_t * rotary, const lv_area_t * clip_area, lv_design_mode_t mode) +{ + /*Return false if the object is not covers the mask_p area*/ + if(mode == LV_DESIGN_COVER_CHK) { + return LV_DESIGN_RES_NOT_COVER; + } + /*Draw the object*/ + else if(mode == LV_DESIGN_DRAW_MAIN) { + /*The ancestor design function will draw the background and the indicator.*/ + ancestor_design(rotary, clip_area, mode); + draw_knob(rotary, clip_area); + } + /*Post draw when the children are drawn*/ + else if(mode == LV_DESIGN_DRAW_POST) { + return ancestor_design(rotary, clip_area, mode); + } + + return LV_DESIGN_RES_OK; +} + +/** + * Signal function of the rotary + * @param rotary pointer to a rotary object + * @param sign a signal type from lv_signal_t enum + * @param param pointer to a signal specific variable + * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted + */ +static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * param) +{ + lv_res_t res; + + if(sign == LV_SIGNAL_GET_STYLE) { + lv_get_style_info_t * info = param; + info->result = lv_rotary_get_style(rotary, info->part); + if(info->result != NULL) return LV_RES_OK; + else return ancestor_signal(rotary, sign, param); + } + + /* Include the ancient signal function */ + res = ancestor_signal(rotary, sign, param); + if(res != LV_RES_OK) return res; + if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME); + + lv_rotary_ext_t * ext = lv_obj_get_ext_attr(rotary); + lv_point_t p; + + if(sign == LV_SIGNAL_PRESSED) { + ext->dragging = true; + if(lv_rotary_get_type(rotary) == LV_ROTARY_TYPE_NORMAL) { + ext->value_to_set = &ext->cur_value; + } + } + else if(sign == LV_SIGNAL_PRESSING && ext->value_to_set != NULL) { + lv_indev_get_point(param, &p); + + // TODO: get new_value and set + } + else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) { + ext->dragging = false; + ext->value_to_set = NULL; + +#if LV_USE_GROUP + /*Leave edit mode if released. (No need to wait for LONG_PRESS) */ + lv_group_t * g = lv_obj_get_group(rotary); + bool editing = lv_group_get_editing(g); + lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act()); + if(indev_type == LV_INDEV_TYPE_ENCODER) { + if(editing) lv_group_set_editing(g, false); + } +#endif + + } + else if(sign == LV_SIGNAL_CONTROL) { + char c = *((char *)param); + + if(c == LV_KEY_RIGHT || c == LV_KEY_UP) { + lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + 1, LV_ANIM_ON); + res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) { + lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) - 1, LV_ANIM_ON); + res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + } + else if(sign == LV_SIGNAL_CLEANUP) { + lv_obj_clean_style_list(rotary, LV_ROTARY_PART_KNOB); + } + else if(sign == LV_SIGNAL_GET_EDITABLE) { + bool * editable = (bool *)param; + *editable = true; + } + + return res; +} + + +static lv_style_list_t * lv_rotary_get_style(lv_obj_t * rotary, uint8_t part) +{ + LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); + + lv_rotary_ext_t * ext = lv_obj_get_ext_attr(rotary); + lv_style_list_t * style_dsc_p; + + switch(part) { + case LV_ROTARY_PART_BG: + style_dsc_p = &ext->style_bg; + break; + case LV_ROTARY_PART_INDIC: + style_dsc_p = &ext->style_indic; + break; + case LV_ROTARY_PART_KNOB: + style_dsc_p = &ext->style_knob; + break; + default: + style_dsc_p = NULL; + } + + return style_dsc_p; +} + +static void draw_knob(lv_obj_t * rotary, const lv_area_t * clip_area) +{ + lv_bidi_dir_t base_dir = lv_obj_get_base_dir(rotary); + + lv_rotary_ext_t *ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); + + lv_coord_t left_bg = lv_obj_get_style_pad_left(rotary, LV_ROTARY_PART_BG); + lv_coord_t right_bg = lv_obj_get_style_pad_right(rotary, LV_ROTARY_PART_BG); + lv_coord_t top_bg = lv_obj_get_style_pad_top(rotary, LV_ROTARY_PART_BG); + lv_coord_t bottom_bg = lv_obj_get_style_pad_bottom(rotary, LV_ROTARY_PART_BG); + lv_coord_t r = (LV_MATH_MIN(lv_obj_get_width(rotary) - left_bg - right_bg, + lv_obj_get_height(rotary) - top_bg - bottom_bg)) / 2; + lv_coord_t indic_width = lv_obj_get_style_line_width(rotary, LV_ROTARY_PART_INDIC); + lv_area_t knob_area; + lv_draw_rect_dsc_t knob_rect_dsc; + lv_coord_t center_x = rotary->coords.x1 + r + left_bg; + lv_coord_t center_y = rotary->coords.y1 + r + top_bg; + + + if(r > 0) { + knob_area.x1 = center_x - r + indic_width + lv_obj_get_style_pad_inner(rotary, LV_ROTARY_PART_KNOB); + knob_area.x2 = center_x + r - indic_width - lv_obj_get_style_pad_inner(rotary, LV_ROTARY_PART_KNOB); + knob_area.y1 = center_y - r + indic_width + lv_obj_get_style_pad_inner(rotary, LV_ROTARY_PART_KNOB); + knob_area.y2 = center_y + r - indic_width - lv_obj_get_style_pad_inner(rotary, LV_ROTARY_PART_KNOB); + + lv_draw_rect_dsc_init(&knob_rect_dsc); + lv_obj_init_draw_rect_dsc(rotary, LV_ROTARY_PART_KNOB, &knob_rect_dsc); + + lv_draw_rect(&knob_area, clip_area, &knob_rect_dsc); + } +} + +#endif diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h new file mode 100644 index 000000000..14e5b1de7 --- /dev/null +++ b/src/lv_widgets/lv_rotary.h @@ -0,0 +1,281 @@ +/** + * @file lv_rotary.h + * + */ + +#ifndef LV_ROTARY_H +#define LV_ROTARY_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#include "../lv_conf_internal.h" + +#if LV_USE_ROTARY != 0 + +/*Testing of dependencies*/ +#if LV_USE_ARC == 0 +#error "lv_rotary: lv_arc is required. Enable it in lv_conf.h (LV_USE_ARC 1) " +#endif + +#if LV_USE_BTN == 0 +#error "lv_rotary: lv_btn is required. Enable it in lv_conf.h (LV_USE_BTN 1) " +#endif + +#define LV_ROTARY_KNOB_SIZE_MIN 4 /* cannot make the knob smaller then this [px] */ + +#include "../lv_core/lv_obj.h" +#include "lv_arc.h" +#include "lv_btn.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +enum { + LV_ROTARY_TYPE_NORMAL +}; +typedef uint8_t lv_rotary_type_t; + +/*Data of rotary*/ +typedef struct { + /*Ext. of ancestor*/ + lv_arc_ext_t arc; + /*New data for this type*/ + lv_btn_ext_t btn; + lv_rotary_type_t type; + lv_style_list_t style_bg; /* Style of the background */ + lv_style_list_t style_indic; /* Style of the indicator */ + lv_style_list_t style_knob; /* Style of the knob */ + int16_t cur_value; /*Current value of the rotary*/ + int16_t min_value; /*Minimum value of the rotary*/ + int16_t max_value; /*Maximum value of the rotary*/ + int16_t start_value; /*Start value of the rotary*/ + int16_t value_to_set; /*Start value of the rotary*/ + bool dragging; +} lv_rotary_ext_t; + +/** Built-in styles of rotary*/ +enum { + LV_ROTARY_PART_BG, /** Rotary background style. */ + LV_ROTARY_PART_INDIC, /** Rotary indicator (filled area) style. */ + LV_ROTARY_PART_KNOB, /** Rotary knob style. */ +}; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a rotary objects + * @param par pointer to an object, it will be the parent of the new rotary + * @param copy pointer to a rotary object, if not NULL then the new object will be copied from it + * @return pointer to the created rotary + */ +lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy); + +/*===================== + * Setter functions + *====================*/ + +/** + * Set a new value on the rotary + * @param rotary pointer to a rotary object + * @param value new value + * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately + */ +void lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim); + +/** + * Set a new value for the left knob of a rotary + * @param rotary pointer to a rotary object + * @param left_value new value + * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately + */ +void lv_rotary_set_start_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim); + +/** + * Set minimum and the maximum values of a rotary + * @param rotary pointer to the rotary object + * @param min minimum value + * @param max maximum value + */ +void lv_rotary_set_range(lv_obj_t * rotary, int16_t min, int16_t max); + +/** + * Make the rotary symmetric to zero. The indicator will grow from zero instead of the minimum + * position. + * @param rotary pointer to a rotary object + * @param en true: enable disable symmetric behavior; false: disable + */ +void lv_rotary_set_type(lv_obj_t * rotary, lv_rotary_type_t type); + +/** + * Set the start angle of rotary indicator. 0 deg: right, 90 bottom, etc. + * @param arc pointer to an arc object + * @param start the start angle + */ +static inline void lv_rotary_set_start_angle(lv_obj_t * rotary, uint16_t start) { + lv_arc_set_start_angle(rotary, start); +} + +/** + * Set the start angle of rotary indicator. 0 deg: right, 90 bottom, etc. + * @param rotary pointer to an rotary object + * @param end the end angle + */ +static inline void lv_rotary_set_end_angle(lv_obj_t * rotary, uint16_t end) { + lv_arc_set_end_angle(rotary, end); +} + +/** + * Set the start and end angles + * @param rotary pointer to an rotary object + * @param start the start angle + * @param end the end angle + */ +static inline void lv_rotary_set_angles(lv_obj_t * rotary, uint16_t start, uint16_t end) { + lv_arc_set_angles(rotary, start, end); +} + +/** + * Set the start angle of ar otary indicator background. 0 deg: right, 90 bottom, etc. + * @param rotary pointer to an rotary object + * @param start the start angle + */ +static inline void lv_rotary_set_bg_start_angle(lv_obj_t * rotary, uint16_t start) { + lv_arc_set_bg_start_angle(rotary, start); +} + +/** + * Set the start angle of rotary indicator background. 0 deg: right, 90 bottom etc. + * @param rotary pointer to an rotary object + * @param end the end angle + */ +static inline void lv_rotary_set_bg_end_angle(lv_obj_t * rotary, uint16_t end) { + lv_arc_set_bg_end_angle(rotary, end); +} + +/** + * Set the start and end angles of the rotary indicator background + * @param rotary pointer to an rotary object + * @param start the start angle + * @param end the end angle + */ +static inline void lv_rotary_set_bg_angles(lv_obj_t * rotary, uint16_t start, uint16_t end) { + lv_arc_set_bg_angles(rotary, start, end); +} + +/** + * Set the rotation for the whole rotary indicator + * @param rotary pointer to an rotary object + * @param rotation_angle rotation angle + */ +static inline void lv_rotary_set_rotation(lv_obj_t * rotary, uint16_t rotation_angle) { + lv_arc_set_rotation(rotary, rotation_angle); +} + +/*===================== + * Getter functions + *====================*/ + +/** + * Get the start angle of a rotary indicator. + * @param rotary pointer to an rotary object + * @return the start angle [0..360] + */ +static inline uint16_t lv_rotary_get_angle_start(lv_obj_t * rotary) { + return lv_rotary_get_angle_start(rotary); +} + +/** + * Get the end angle of a rotary indicator. + * @param rotary pointer to an rotary object + * @return the end angle [0..360] + */ +static inline uint16_t lv_rotary_get_angle_end(lv_obj_t * rotary) { + return lv_arc_get_angle_end(rotary); +} + +/** + * Get the start angle of a rotary indicator background. + * @param rotary pointer to an rotary object + * @return the start angle [0..360] + */ +static inline uint16_t lv_rotary_get_bg_angle_start(lv_obj_t * rotary) { + return lv_arc_get_bg_angle_start(rotary); +} + +/** + * Get the end angle of a rotary indicator background. + * @param rotary pointer to an rotary object + * @return the end angle [0..360] + */ +static inline uint16_t lv_rotary_get_bg_angle_end(lv_obj_t * rotary) { + return lv_arc_get_bg_angle_end(rotary); +} + +/** + * Get the value of the of a rotary + * @param rotary pointer to a rotary object + * @return the value of the of the rotary + */ +int16_t lv_rotary_get_value(const lv_obj_t * rotary); + +/** + * Get the value of the left knob of a rotary + * @param rotary pointer to a rotary object + * @return the start value of the rotary + */ +int16_t lv_rotary_get_start_value(const lv_obj_t * rotary); + +/** + * Get the minimum value of a rotary + * @param rotary pointer to a rotary object + * @return the minimum value of the rotary + */ +int16_t lv_rotary_get_min_value(const lv_obj_t * rotary); + +/** + * Get the maximum value of a rotary + * @param rotary pointer to a rotary object + * @return the maximum value of the rotary + */ +int16_t lv_rotary_get_max_value(const lv_obj_t * rotary); + +/** + * Give the rotary is being dragged or not + * @param rotary pointer to a rotary object + * @return true: drag in progress false: not dragged + */ +bool lv_rotary_is_dragged(const lv_obj_t * rotary); + +/** + * Get whether the rotary is symmetric or not. + * @param rotary pointer to a rotary object + * @return true: symmetric is enabled; false: disable + */ +static inline lv_rotary_type_t lv_rotary_get_type(lv_obj_t * rotary) +{ + return LV_ROTARY_TYPE_NORMAL; +} + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_rotary*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_ROTARY_H*/ From 2908a74b42cd73c0fc8efe1bba92847e43ab2e89 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Thu, 18 Jun 2020 17:11:15 -0700 Subject: [PATCH 002/173] Reduce knob pad get logic --- src/lv_widgets/lv_rotary.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index c3ef76683..3f3f6eb70 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -440,13 +440,13 @@ static void draw_knob(lv_obj_t * rotary, const lv_area_t * clip_area) lv_draw_rect_dsc_t knob_rect_dsc; lv_coord_t center_x = rotary->coords.x1 + r + left_bg; lv_coord_t center_y = rotary->coords.y1 + r + top_bg; - + lv_coord_t knob_inner = lv_obj_get_style_pad_inner(rotary, LV_ROTARY_PART_KNOB) if(r > 0) { - knob_area.x1 = center_x - r + indic_width + lv_obj_get_style_pad_inner(rotary, LV_ROTARY_PART_KNOB); - knob_area.x2 = center_x + r - indic_width - lv_obj_get_style_pad_inner(rotary, LV_ROTARY_PART_KNOB); - knob_area.y1 = center_y - r + indic_width + lv_obj_get_style_pad_inner(rotary, LV_ROTARY_PART_KNOB); - knob_area.y2 = center_y + r - indic_width - lv_obj_get_style_pad_inner(rotary, LV_ROTARY_PART_KNOB); + knob_area.x1 = center_x - r + indic_width + knob_inner; + knob_area.x2 = center_x + r - indic_width - knob_inner; + knob_area.y1 = center_y - r + indic_width + knob_inner; + knob_area.y2 = center_y + r - indic_width - knob_inner; lv_draw_rect_dsc_init(&knob_rect_dsc); lv_obj_init_draw_rect_dsc(rotary, LV_ROTARY_PART_KNOB, &knob_rect_dsc); From 2dc14fc7e57d11a78e4a0bc21d1473c1065fb96f Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Thu, 18 Jun 2020 22:22:22 -0700 Subject: [PATCH 003/173] Add missing rotary widget import --- lvgl.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lvgl.h b/lvgl.h index 5165a598b..eabad3f7a 100644 --- a/lvgl.h +++ b/lvgl.h @@ -53,6 +53,7 @@ extern "C" { #include "src/lv_widgets/lv_keyboard.h" #include "src/lv_widgets/lv_dropdown.h" #include "src/lv_widgets/lv_roller.h" +#include "src/lv_widgets/lv_rotary.h" #include "src/lv_widgets/lv_textarea.h" #include "src/lv_widgets/lv_canvas.h" #include "src/lv_widgets/lv_win.h" From b9d92236e3e0b87cde0354847d4f728daca8c4b1 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Thu, 18 Jun 2020 22:25:41 -0700 Subject: [PATCH 004/173] Add rotary to build.py defines --- tests/build.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/build.py b/tests/build.py index 73a06148f..f014027c7 100755 --- a/tests/build.py +++ b/tests/build.py @@ -120,6 +120,7 @@ minimal_monochrome = { "LV_USE_PAGE":0, "LV_USE_SPINNER":0, "LV_USE_ROLLER":0, + "LV_USE_ROTARY":0, "LV_USE_SLIDER":0, "LV_USE_SPINBOX":0, "LV_USE_SWITCH":0, @@ -196,6 +197,7 @@ all_obj_minimal_features = { "LV_USE_PAGE":1, "LV_USE_SPINNER":0, #Disabled beacsue needs anim "LV_USE_ROLLER":1, + "LV_USE_ROTARY":1, "LV_USE_SLIDER":1, "LV_USE_SPINBOX":1, "LV_USE_SWITCH":1, @@ -274,6 +276,7 @@ all_obj_all_features = { "LV_USE_PAGE":1, "LV_USE_SPINNER":1, "LV_USE_ROLLER":1, + "LV_USE_ROTARY":1, "LV_USE_SLIDER":1, "LV_USE_SPINBOX":1, "LV_USE_SWITCH":1, @@ -365,6 +368,7 @@ advanced_features = { "LV_USE_PAGE":1, "LV_USE_SPINNER":1, "LV_USE_ROLLER":1, + "LV_USE_ROTARY":1, "LV_USE_SLIDER":1, "LV_USE_SPINBOX":1, "LV_USE_SWITCH":1, From 6dddbde38757f1905a2e28b1d6584b205aec1fc1 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Thu, 18 Jun 2020 22:27:51 -0700 Subject: [PATCH 005/173] Add ifndef to internal conf --- src/lv_conf_internal.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h index 9ea1abbd7..30325b5ed 100644 --- a/src/lv_conf_internal.h +++ b/src/lv_conf_internal.h @@ -992,8 +992,9 @@ #endif /*Rotary (dependencies: lv_arc, lv_btn)*/ -#define LV_USE_ROTARY 1 - +#ifndef LV_USE_ROTARY +#define LV_USE_ROTARY 1 +#endif /*Slider (dependencies: lv_bar)*/ #ifndef LV_USE_SLIDER #define LV_USE_SLIDER 1 From a696aef9593bdb727a9b19208144746e5f6ff44c Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Thu, 18 Jun 2020 22:43:38 -0700 Subject: [PATCH 006/173] Use rotary param in type getter --- src/lv_widgets/lv_rotary.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index 14e5b1de7..a62983b13 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -265,7 +265,9 @@ bool lv_rotary_is_dragged(const lv_obj_t * rotary); */ static inline lv_rotary_type_t lv_rotary_get_type(lv_obj_t * rotary) { - return LV_ROTARY_TYPE_NORMAL; + lv_bar_type_t type = lv_bar_get_type(rotary); + if(type == LV_ROTARY_TYPE_NORMAL) + return LV_ROTARY_TYPE_NORMAL; } /********************** From 168a7c4c456b96c2977e0640aac1ad63cb6feec8 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Thu, 18 Jun 2020 22:46:30 -0700 Subject: [PATCH 007/173] Add theme define --- src/lv_themes/lv_theme.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lv_themes/lv_theme.h b/src/lv_themes/lv_theme.h index 7b4f65b3d..13d5a1ccd 100644 --- a/src/lv_themes/lv_theme.h +++ b/src/lv_themes/lv_theme.h @@ -109,6 +109,9 @@ typedef enum { #if LV_USE_ROLLER LV_THEME_ROLLER, #endif +#if LV_USE_ROTARY + LV_THEME_ROTARY, +#endif #if LV_USE_SLIDER LV_THEME_SLIDER, #endif From 884be64d1745223af3e40b7065ee4b7734aa32cb Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Fri, 19 Jun 2020 11:38:22 -0700 Subject: [PATCH 008/173] Fix rotary type getter. --- src/lv_widgets/lv_rotary.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index a62983b13..0a0aef5cd 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -265,7 +265,7 @@ bool lv_rotary_is_dragged(const lv_obj_t * rotary); */ static inline lv_rotary_type_t lv_rotary_get_type(lv_obj_t * rotary) { - lv_bar_type_t type = lv_bar_get_type(rotary); + lv_rotary_type_t type = lv_rotary_get_type(rotary); if(type == LV_ROTARY_TYPE_NORMAL) return LV_ROTARY_TYPE_NORMAL; } From 1396fce9615302c6028a01b1f7718ac76e55155c Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Fri, 19 Jun 2020 11:42:55 -0700 Subject: [PATCH 009/173] Fix debug import --- src/lv_widgets/lv_rotary.c | 2 +- src/lv_widgets/lv_rotary.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 3f3f6eb70..ad4cb85c8 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -10,7 +10,7 @@ #include "lv_rotary.h" #if LV_USE_ROTARY != 0 -#include "../lv_core/lv_debug.h" +#include "../lv_misc/lv_debug.h" #include "../lv_core/lv_group.h" #include "../lv_core/lv_indev.h" #include "../lv_draw/lv_draw.h" diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index 0a0aef5cd..ddac0ccb0 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -26,8 +26,6 @@ extern "C" { #error "lv_rotary: lv_btn is required. Enable it in lv_conf.h (LV_USE_BTN 1) " #endif -#define LV_ROTARY_KNOB_SIZE_MIN 4 /* cannot make the knob smaller then this [px] */ - #include "../lv_core/lv_obj.h" #include "lv_arc.h" #include "lv_btn.h" @@ -36,6 +34,8 @@ extern "C" { * DEFINES *********************/ +#define LV_ROTARY_KNOB_SIZE_MIN 4 /* cannot make the knob smaller then this [px] */ + /********************** * TYPEDEFS **********************/ From b9dc9e81de2b4f6ca89e5cd56fcb8d5cfd6bf4de Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Fri, 19 Jun 2020 11:44:29 -0700 Subject: [PATCH 010/173] Missing ; --- src/lv_widgets/lv_rotary.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index ad4cb85c8..ba182ba2c 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -440,7 +440,7 @@ static void draw_knob(lv_obj_t * rotary, const lv_area_t * clip_area) lv_draw_rect_dsc_t knob_rect_dsc; lv_coord_t center_x = rotary->coords.x1 + r + left_bg; lv_coord_t center_y = rotary->coords.y1 + r + top_bg; - lv_coord_t knob_inner = lv_obj_get_style_pad_inner(rotary, LV_ROTARY_PART_KNOB) + lv_coord_t knob_inner = lv_obj_get_style_pad_inner(rotary, LV_ROTARY_PART_KNOB); if(r > 0) { knob_area.x1 = center_x - r + indic_width + knob_inner; From 95b07a2d234662f290f67c31f9398aeb6d4a07b5 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Fri, 19 Jun 2020 23:25:17 +0200 Subject: [PATCH 011/173] rotary: clean up --- src/lv_widgets/lv_rotary.c | 48 ++++---------------------------------- src/lv_widgets/lv_rotary.h | 41 +++++++++----------------------- 2 files changed, 15 insertions(+), 74 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index ba182ba2c..b3f20785a 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -86,10 +86,7 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) ext->cur_value = 0; ext->min_value = 0; ext->max_value = 0; - ext->start_value = 0; ext->dragging = false; - lv_style_list_init(&ext->style_bg); - lv_style_list_init(&ext->style_indic); lv_style_list_init(&ext->style_knob); /*The signal and design functions are not copied so set them here*/ @@ -111,10 +108,7 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) ext->cur_value = copy_ext->cur_value; ext->min_value = copy_ext->min_value; ext->max_value = copy_ext->max_value; - ext->start_value = copy_ext->start_value; ext->dragging = copy_ext->dragging; - lv_style_list_copy(&ext->style_bg, ©_ext->style_bg); - lv_style_list_copy(&ext->style_indic, ©_ext->style_indic); lv_style_list_copy(&ext->style_knob, ©_ext->style_knob); lv_obj_refresh_style(rotary, LV_OBJ_PART_ALL); @@ -162,20 +156,6 @@ void lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim ); } -/** - * Set a new value for the left knob of a rotary - * @param rotary pointer to a rotary object - * @param left_value new value - * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately - */ -void lv_rotary_set_start_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim) -{ - LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); - - lv_rotary_ext_t * ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); - ext->start_value = value; -} - /** * Set minimum and the maximum values of a rotary * @param rotary pointer to the rotary object @@ -208,12 +188,12 @@ void lv_rotary_set_range(lv_obj_t * rotary, int16_t min, int16_t max) * @param rotary pointer to a rotary object * @param en true: enable disable symmetric behavior; false: disable */ -void lv_rotary_set_type(lv_obj_t * rotary, lv_rotary_type_t type) +void lv_rotary_set_symmetric(lv_obj_t * rotary, bool en) { LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); lv_rotary_ext_t *ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); - ext->type = type; + ext->sym = en; lv_obj_invalidate(rotary); } @@ -235,19 +215,6 @@ int16_t lv_rotary_get_value(const lv_obj_t * rotary) return ext->cur_value; } -/** - * Get the value of the left knob of a rotary - * @param rotary pointer to a rotary object - * @return the start value of the rotary - */ -int16_t lv_rotary_get_start_value(const lv_obj_t * rotary) -{ - LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); - - lv_rotary_ext_t *ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); - return ext->start_value; -} - /** * Get the minimum value of a rotary * @param rotary pointer to a rotary object @@ -349,9 +316,6 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par if(sign == LV_SIGNAL_PRESSED) { ext->dragging = true; - if(lv_rotary_get_type(rotary) == LV_ROTARY_TYPE_NORMAL) { - ext->value_to_set = &ext->cur_value; - } } else if(sign == LV_SIGNAL_PRESSING && ext->value_to_set != NULL) { lv_indev_get_point(param, &p); @@ -408,10 +372,10 @@ static lv_style_list_t * lv_rotary_get_style(lv_obj_t * rotary, uint8_t part) switch(part) { case LV_ROTARY_PART_BG: - style_dsc_p = &ext->style_bg; + style_dsc_p = lv_obj_get_style_list(rotary, LV_ARC_PART_BG); break; case LV_ROTARY_PART_INDIC: - style_dsc_p = &ext->style_indic; + style_dsc_p = lv_obj_get_style_list(rotary, LV_ARC_PART_INDIC); break; case LV_ROTARY_PART_KNOB: style_dsc_p = &ext->style_knob; @@ -425,10 +389,6 @@ static lv_style_list_t * lv_rotary_get_style(lv_obj_t * rotary, uint8_t part) static void draw_knob(lv_obj_t * rotary, const lv_area_t * clip_area) { - lv_bidi_dir_t base_dir = lv_obj_get_base_dir(rotary); - - lv_rotary_ext_t *ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); - lv_coord_t left_bg = lv_obj_get_style_pad_left(rotary, LV_ROTARY_PART_BG); lv_coord_t right_bg = lv_obj_get_style_pad_right(rotary, LV_ROTARY_PART_BG); lv_coord_t top_bg = lv_obj_get_style_pad_top(rotary, LV_ROTARY_PART_BG); diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index ddac0ccb0..7d614d499 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -50,24 +50,21 @@ typedef struct { /*Ext. of ancestor*/ lv_arc_ext_t arc; /*New data for this type*/ - lv_btn_ext_t btn; - lv_rotary_type_t type; - lv_style_list_t style_bg; /* Style of the background */ - lv_style_list_t style_indic; /* Style of the indicator */ lv_style_list_t style_knob; /* Style of the knob */ int16_t cur_value; /*Current value of the rotary*/ int16_t min_value; /*Minimum value of the rotary*/ int16_t max_value; /*Maximum value of the rotary*/ - int16_t start_value; /*Start value of the rotary*/ - int16_t value_to_set; /*Start value of the rotary*/ - bool dragging; + int16_t * value_to_set; /*Start value of the rotary*/ + uint16_t dragging :1; + uint16_t sym :1; } lv_rotary_ext_t; /** Built-in styles of rotary*/ enum { - LV_ROTARY_PART_BG, /** Rotary background style. */ - LV_ROTARY_PART_INDIC, /** Rotary indicator (filled area) style. */ - LV_ROTARY_PART_KNOB, /** Rotary knob style. */ + LV_ROTARY_PART_BG = LV_ARC_PART_BG, /** Rotary background style. */ + LV_ROTARY_PART_INDIC = LV_ARC_PART_INDIC, /** Rotary indicator (filled area) style. */ + LV_ROTARY_PART_KNOB = _LV_ARC_PART_VIRTUAL_LAST, /** Rotary knob style. */ + _LV_ROTARY_PART_VIRTUAL_LAST }; /********************** @@ -94,14 +91,6 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy); */ void lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim); -/** - * Set a new value for the left knob of a rotary - * @param rotary pointer to a rotary object - * @param left_value new value - * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately - */ -void lv_rotary_set_start_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim); - /** * Set minimum and the maximum values of a rotary * @param rotary pointer to the rotary object @@ -116,7 +105,7 @@ void lv_rotary_set_range(lv_obj_t * rotary, int16_t min, int16_t max); * @param rotary pointer to a rotary object * @param en true: enable disable symmetric behavior; false: disable */ -void lv_rotary_set_type(lv_obj_t * rotary, lv_rotary_type_t type); +void lv_rotary_set_symmetric(lv_obj_t * rotary, bool en); /** * Set the start angle of rotary indicator. 0 deg: right, 90 bottom, etc. @@ -230,13 +219,6 @@ static inline uint16_t lv_rotary_get_bg_angle_end(lv_obj_t * rotary) { */ int16_t lv_rotary_get_value(const lv_obj_t * rotary); -/** - * Get the value of the left knob of a rotary - * @param rotary pointer to a rotary object - * @return the start value of the rotary - */ -int16_t lv_rotary_get_start_value(const lv_obj_t * rotary); - /** * Get the minimum value of a rotary * @param rotary pointer to a rotary object @@ -263,11 +245,10 @@ bool lv_rotary_is_dragged(const lv_obj_t * rotary); * @param rotary pointer to a rotary object * @return true: symmetric is enabled; false: disable */ -static inline lv_rotary_type_t lv_rotary_get_type(lv_obj_t * rotary) +static inline bool lv_rotary_get_symmetric(lv_obj_t * rotary) { - lv_rotary_type_t type = lv_rotary_get_type(rotary); - if(type == LV_ROTARY_TYPE_NORMAL) - return LV_ROTARY_TYPE_NORMAL; + lv_rotary_ext_t * ext = lv_obj_get_ext_attr(rotary); + return ext->sym; } /********************** From 75a27e4cc778531180c091d31470f2568ccb23b0 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Fri, 19 Jun 2020 23:41:29 +0200 Subject: [PATCH 012/173] rotary: leave the default size from arc + fix style get --- src/lv_widgets/lv_rotary.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index b3f20785a..eb91dbebe 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -100,7 +100,6 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) lv_obj_set_ext_click_area(rotary, 0, 0, LV_DPI / 10, LV_DPI / 10); lv_theme_apply(rotary, LV_THEME_ROTARY); - lv_obj_set_height(rotary, LV_DPI / 15); } /*Copy an existing rotary*/ else { @@ -371,12 +370,6 @@ static lv_style_list_t * lv_rotary_get_style(lv_obj_t * rotary, uint8_t part) lv_style_list_t * style_dsc_p; switch(part) { - case LV_ROTARY_PART_BG: - style_dsc_p = lv_obj_get_style_list(rotary, LV_ARC_PART_BG); - break; - case LV_ROTARY_PART_INDIC: - style_dsc_p = lv_obj_get_style_list(rotary, LV_ARC_PART_INDIC); - break; case LV_ROTARY_PART_KNOB: style_dsc_p = &ext->style_knob; break; From 4e13d6ae4d5f616b06e23d9790c7374aa80ae633 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Fri, 19 Jun 2020 15:59:04 -0700 Subject: [PATCH 013/173] Cast ext --- src/lv_widgets/lv_rotary.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index 7d614d499..f7f137407 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -247,7 +247,7 @@ bool lv_rotary_is_dragged(const lv_obj_t * rotary); */ static inline bool lv_rotary_get_symmetric(lv_obj_t * rotary) { - lv_rotary_ext_t * ext = lv_obj_get_ext_attr(rotary); + lv_rotary_ext_t * ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); return ext->sym; } From 7a7e1668fafdbccfd9f011e6af343ff7d92bdfce Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Fri, 19 Jun 2020 17:15:15 -0700 Subject: [PATCH 014/173] Make value setter indic mapping from arc start to bg end. --- src/lv_widgets/lv_rotary.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index eb91dbebe..04f2d939e 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -150,7 +150,7 @@ void lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim ext->min_value, ext->max_value, ext->arc.arc_angle_start, - ext->arc.arc_angle_start + 360 + ext->arc.bg_angle_end ) ); } From f5d9e4bff4464c592821fe2edf768f1351a95a90 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Fri, 19 Jun 2020 17:39:50 -0700 Subject: [PATCH 015/173] Fix range mapping for value setter assuming left to right indic --- src/lv_widgets/lv_rotary.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 04f2d939e..7ea1cfa22 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -150,7 +150,7 @@ void lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim ext->min_value, ext->max_value, ext->arc.arc_angle_start, - ext->arc.bg_angle_end + 360 + ext->arc.bg_angle_end ) ); } From e100565c673044947194a72a29c10b5fd36b3305 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Fri, 19 Jun 2020 17:49:02 -0700 Subject: [PATCH 016/173] Move map function to proper func to avoid recalc of slope --- src/lv_misc/lv_math.c | 17 ++++++++++++++++- src/lv_misc/lv_math.h | 12 ++++++++++-- src/lv_widgets/lv_rotary.c | 9 ++------- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/lv_misc/lv_math.c b/src/lv_misc/lv_math.c index 230d79990..1b338ebd4 100644 --- a/src/lv_misc/lv_math.c +++ b/src/lv_misc/lv_math.c @@ -128,7 +128,6 @@ LV_ATTRIBUTE_FAST_MEM void _lv_sqrt(uint32_t x, lv_sqrt_res_t * q, uint32_t mask q->f = (uint32_t)(root & 0xf) << 4; } - /** * Calculate the atan2 of a vector. * @param x @@ -232,6 +231,22 @@ int64_t _lv_pow(int64_t base, int8_t exp) return result; } +/** + * Get the mapped of a number given an imput and output range + * @param x integer which mapped value should be calculated + * @param min_in min input range + * @param max_in max input range + * @param in min output range + * @param out max output range + */ +LV_ATTRIBUTE_FAST_MEM int16_t _lv_map(int16_t x, int16_t min_in, int16_t max_in, int16_t min, int16_t max) +{ + int16_t slope = (max - min) / (max_in - min_in); + int16_t bias = min - slope * min_in; + + return bias + slope * x; +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/lv_misc/lv_math.h b/src/lv_misc/lv_math.h index dc45ad630..0d72fb5af 100644 --- a/src/lv_misc/lv_math.h +++ b/src/lv_misc/lv_math.h @@ -31,8 +31,6 @@ extern "C" { #define LV_MATH_UDIV255(x) ((uint32_t)((uint32_t) (x) * 0x8081) >> 0x17) -#define LV_MATH_MAP(a, min_in, max_in, min, max) (min - (((max - min) / (max_in - min_in)) * min_in) + (((max - min) / (max_in - min_in)) * a)) - #define LV_IS_SIGNED(t) (((t)(-1)) < ((t) 0)) #define LV_UMAX_OF(t) (((0x1ULL << ((sizeof(t) * 8ULL) - 1ULL)) - 1ULL) | (0xFULL << ((sizeof(t) * 8ULL) - 4ULL))) #define LV_SMAX_OF(t) (((0x1ULL << ((sizeof(t) * 8ULL) - 1ULL)) - 1ULL) | (0x7ULL << ((sizeof(t) * 8ULL) - 4ULL))) @@ -114,6 +112,16 @@ LV_ATTRIBUTE_FAST_MEM void _lv_sqrt(uint32_t x, lv_sqrt_res_t * q, uint32_t mask */ int64_t _lv_pow(int64_t base, int8_t exp); +/** + * Get the mapped of a number given an imput and output range + * @param x integer which mapped value should be calculated + * @param min_in min input range + * @param max_in max input range + * @param in min output range + * @param out max output range + */ +LV_ATTRIBUTE_FAST_MEM int16_t _lv_map(int16_t x, int16_t min_in, int16_t max_in, int16_t min, int16_t max); + /********************** * MACROS **********************/ diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 7ea1cfa22..309b263dc 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -145,13 +145,8 @@ void lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim lv_arc_set_end_angle( rotary, - LV_MATH_MAP( - ext->cur_value, - ext->min_value, - ext->max_value, - ext->arc.arc_angle_start, - 360 + ext->arc.bg_angle_end - ) + _lv_map(ext->cur_value, ext->min_value, ext->max_value, + ext->arc.arc_angle_start, 360 + ext->arc.bg_angle_end) ); } From c8546700625f29e1c125c627715224a176a1db80 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Fri, 19 Jun 2020 18:00:28 -0700 Subject: [PATCH 017/173] Test float for mapping --- src/lv_misc/lv_math.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_misc/lv_math.c b/src/lv_misc/lv_math.c index 1b338ebd4..c0ea6ec78 100644 --- a/src/lv_misc/lv_math.c +++ b/src/lv_misc/lv_math.c @@ -239,7 +239,7 @@ int64_t _lv_pow(int64_t base, int8_t exp) * @param in min output range * @param out max output range */ -LV_ATTRIBUTE_FAST_MEM int16_t _lv_map(int16_t x, int16_t min_in, int16_t max_in, int16_t min, int16_t max) +LV_ATTRIBUTE_FAST_MEM int16_t _lv_map(int16_t x, float min_in, float max_in, float min, float max) { int16_t slope = (max - min) / (max_in - min_in); int16_t bias = min - slope * min_in; From cf4db992063c7f51b2688e5f085561f2e5fa29a5 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Fri, 19 Jun 2020 18:01:15 -0700 Subject: [PATCH 018/173] Test float for mapping --- src/lv_misc/lv_math.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_misc/lv_math.h b/src/lv_misc/lv_math.h index 0d72fb5af..aeb9e4d7a 100644 --- a/src/lv_misc/lv_math.h +++ b/src/lv_misc/lv_math.h @@ -120,7 +120,7 @@ int64_t _lv_pow(int64_t base, int8_t exp); * @param in min output range * @param out max output range */ -LV_ATTRIBUTE_FAST_MEM int16_t _lv_map(int16_t x, int16_t min_in, int16_t max_in, int16_t min, int16_t max); +LV_ATTRIBUTE_FAST_MEM int16_t _lv_map(int16_t x, float min_in, float max_in, float min, float max); /********************** * MACROS From 446b0b6429d2c619cc0f3e0ef42dfdc35c658c7a Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Fri, 19 Jun 2020 18:05:55 -0700 Subject: [PATCH 019/173] Floats working fro value mapping --- src/lv_misc/lv_math.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lv_misc/lv_math.c b/src/lv_misc/lv_math.c index c0ea6ec78..7c467b5f1 100644 --- a/src/lv_misc/lv_math.c +++ b/src/lv_misc/lv_math.c @@ -241,8 +241,8 @@ int64_t _lv_pow(int64_t base, int8_t exp) */ LV_ATTRIBUTE_FAST_MEM int16_t _lv_map(int16_t x, float min_in, float max_in, float min, float max) { - int16_t slope = (max - min) / (max_in - min_in); - int16_t bias = min - slope * min_in; + float slope = (max - min) / (max_in - min_in); + float bias = min - slope * min_in; return bias + slope * x; } From 1dfdabd638d7624455f8e8b0e97c6d507b3cdc1b Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sat, 20 Jun 2020 11:06:06 -0700 Subject: [PATCH 020/173] Test btn extension --- src/lv_themes/lv_theme_material.c | 14 +++++++------- src/lv_widgets/lv_rotary.h | 22 ++++++++++++++++++++++ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/lv_themes/lv_theme_material.c b/src/lv_themes/lv_theme_material.c index e0b0e9762..54399c540 100644 --- a/src/lv_themes/lv_theme_material.c +++ b/src/lv_themes/lv_theme_material.c @@ -798,14 +798,14 @@ static void rotary_init(void) #if LV_USE_ROTARY != 0 style_init_reset(&styles->rotary_bg); lv_style_set_clip_corner(&styles->rotary_bg, LV_STATE_DEFAULT, true); - lv_style_set_pad_left(&styles->rotary_bg, LV_STATE_DEFAULT, 0); - lv_style_set_pad_right(&styles->rotary_bg, LV_STATE_DEFAULT, 0); - lv_style_set_pad_top(&styles->rotary_bg, LV_STATE_DEFAULT, 0); - lv_style_set_pad_bottom(&styles->rotary_bg, LV_STATE_DEFAULT, 0); - lv_style_set_pad_inner(&styles->rotary_bg, LV_STATE_DEFAULT, 0); - lv_style_set_border_width(&styles->rotary_bg, LV_STATE_DEFAULT, 0); + lv_style_set_pad_left(&styles->rotary_bg, LV_STATE_DEFAULT, LV_DPX(6)); + lv_style_set_pad_right(&styles->rotary_bg, LV_STATE_DEFAULT, LV_DPX(6)); + lv_style_set_pad_top(&styles->rotary_bg, LV_STATE_DEFAULT, LV_DPX(6)); + lv_style_set_pad_bottom(&styles->rotary_bg, LV_STATE_DEFAULT, LV_DPX(6)); + lv_style_set_pad_inner(&styles->rotary_bg, LV_STATE_DEFAULT, LV_DPX(6)); + lv_style_set_border_width(&styles->rotary_bg, LV_STATE_DEFAULT, LV_DPX(2)); lv_style_set_line_color(&styles->rotary_bg, LV_STATE_DEFAULT, COLOR_BG_SEC); - lv_style_set_line_width(&styles->rotary_bg, LV_STATE_DEFAULT, LV_DPX(8)); + lv_style_set_line_width(&styles->rotary_bg, LV_STATE_DEFAULT, LV_DPX(2)); lv_style_set_line_rounded(&styles->rotary_bg, LV_STATE_DEFAULT, true); style_init_reset(&styles->rotary_indic); diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index f7f137407..49b5856e0 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -45,6 +45,18 @@ enum { }; typedef uint8_t lv_rotary_type_t; +/** Possible states of a rotary.*/ +enum { + LV_ROTARY_STATE_RELEASED = LV_BTN_STATE_RELEASED, + LV_ROTARY_STATE_PRESSED = LV_BTN_STATE_PRESSED, + LV_ROTARY_STATE_DISABLED = LV_BTN_STATE_DISABLED, + LV_ROTARY_STATE_CHECKED_RELEASED = LV_BTN_STATE_CHECKED_RELEASED, + LV_ROTARY_STATE_CHECKED_PRESSED = LV_BTN_STATE_CHECKED_PRESSED, + LV_ROTARY_STATE_CHECKED_DISABLED = LV_BTN_STATE_CHECKED_DISABLED, + _LV_ROTARY_STATE_LAST = _LV_BTN_STATE_LAST, /* Number of states*/ +}; +typedef uint8_t lv_btn_state_t; + /*Data of rotary*/ typedef struct { /*Ext. of ancestor*/ @@ -172,6 +184,16 @@ static inline void lv_rotary_set_rotation(lv_obj_t * rotary, uint16_t rotation_a lv_arc_set_rotation(rotary, rotation_angle); } +/** + * Set the state of the rotary + * @param rotary pointer to a rotary object + * @param state the new state of the rotary (from lv_rotary_state_t enum) + */ +void lv_rotary_set_state(lv_obj_t * rotary, lv_rotary_state_t state) +{ + lv_btn_set_state(rotary, state); +} + /*===================== * Getter functions *====================*/ From b1afc3f34d101b3ec5ec45dbf6fc14e3e3893d4d Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sat, 20 Jun 2020 11:11:26 -0700 Subject: [PATCH 021/173] Add rotary state --- src/lv_widgets/lv_rotary.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index 49b5856e0..fa584e0fd 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -55,7 +55,7 @@ enum { LV_ROTARY_STATE_CHECKED_DISABLED = LV_BTN_STATE_CHECKED_DISABLED, _LV_ROTARY_STATE_LAST = _LV_BTN_STATE_LAST, /* Number of states*/ }; -typedef uint8_t lv_btn_state_t; +typedef uint8_t lv_rotary_state_t; /*Data of rotary*/ typedef struct { From 9b38b3542032ebed46cf6b8fdf3c352dcbf7d324 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sat, 20 Jun 2020 11:13:37 -0700 Subject: [PATCH 022/173] Static state setter --- src/lv_widgets/lv_rotary.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index fa584e0fd..5ddd1a485 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -189,7 +189,7 @@ static inline void lv_rotary_set_rotation(lv_obj_t * rotary, uint16_t rotation_a * @param rotary pointer to a rotary object * @param state the new state of the rotary (from lv_rotary_state_t enum) */ -void lv_rotary_set_state(lv_obj_t * rotary, lv_rotary_state_t state) +static inline void lv_rotary_set_state(lv_obj_t * rotary, lv_rotary_state_t state) { lv_btn_set_state(rotary, state); } From f6d75e759c63136b8a9f5023642ddc5a8bb732ae Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sat, 20 Jun 2020 12:12:42 -0700 Subject: [PATCH 023/173] Add btn like signal handling for knob part. Add custom event to distuinguish from VALUE_CHANGED --- src/lv_core/lv_obj.h | 1 + src/lv_widgets/lv_rotary.c | 49 ++++++++++++++++++++++++++++++++++++++ src/lv_widgets/lv_rotary.h | 43 +++++++++++++++++++++++++++++++-- 3 files changed, 91 insertions(+), 2 deletions(-) diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index 88b71cb99..9d5edffb5 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -102,6 +102,7 @@ enum { LV_EVENT_APPLY, /**< "Ok", "Apply" or similar specific button has clicked*/ LV_EVENT_CANCEL, /**< "Close", "Cancel" or similar specific button has clicked*/ LV_EVENT_DELETE, /**< Object is being deleted */ + _LV_EVENT_LAST /** Number of events*/ }; typedef uint8_t lv_event_t; /**< Type of event being sent to the object. */ diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 309b263dc..0fd4b5cc3 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -87,6 +87,7 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) ext->min_value = 0; ext->max_value = 0; ext->dragging = false; + ext->checkable = 0; lv_style_list_init(&ext->style_knob); /*The signal and design functions are not copied so set them here*/ @@ -108,6 +109,8 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) ext->min_value = copy_ext->min_value; ext->max_value = copy_ext->max_value; ext->dragging = copy_ext->dragging; + ext->sym = copy_ext->sym; + ext->checkable = copy_ext->checkable; lv_style_list_copy(&ext->style_knob, ©_ext->style_knob); lv_obj_refresh_style(rotary, LV_OBJ_PART_ALL); @@ -192,6 +195,20 @@ void lv_rotary_set_symmetric(lv_obj_t * rotary, bool en) lv_obj_invalidate(rotary); } +/** + * Enable the toggled states + * @param rotary pointer to a button object + * @param tgl true: enable toggled states, false: disable + */ +void lv_rotary_set_checkable(lv_obj_t * rotary, bool tgl) +{ + LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); + + lv_rotary_ext_t * ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); + + ext->checkable = tgl != false ? 1 : 0; +} + /*===================== * Getter functions *====================*/ @@ -248,6 +265,20 @@ bool lv_rotary_is_dragged(const lv_obj_t * rotary) return ext->dragging; } +/** + * Get the toggle enable attribute of the rotary + * @param rotary pointer to a rotary object + * @return true: toggle enabled, false: disabled + */ +bool lv_rotary_get_checkable(const lv_obj_t * rotary) +{ + LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); + + lv_rotary_ext_t * ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); + + return ext->checkable != 0 ? true : false; +} + /********************** * STATIC FUNCTIONS **********************/ @@ -305,6 +336,7 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par if(res != LV_RES_OK) return res; if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME); + bool tgl = lv_rotary_get_checkable(rotary); lv_rotary_ext_t * ext = lv_obj_get_ext_attr(rotary); lv_point_t p; @@ -320,6 +352,23 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par ext->dragging = false; ext->value_to_set = NULL; + /*If not dragged and it was not long press action then + *change state and run the action*/ + if(lv_indev_is_dragging(param) == false && tgl) { + uint32_t toggled = 0; + if(lv_obj_get_state(rotary, LV_ROTARY_PART_KNOB) & LV_STATE_CHECKED) { + lv_btn_set_state(rotary, LV_ROTARY_STATE_RELEASED); + toggled = 0; + } + else { + lv_btn_set_state(rotary, LV_ROTARY_STATE_CHECKED_RELEASED); + toggled = 1; + } + + res = lv_event_send(rotary, LV_EVENT_ROTARY_TOGGLED, &toggled); + if(res != LV_RES_OK) return res; + } + #if LV_USE_GROUP /*Leave edit mode if released. (No need to wait for LONG_PRESS) */ lv_group_t * g = lv_obj_get_group(rotary); diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index 5ddd1a485..f833902c8 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -69,6 +69,7 @@ typedef struct { int16_t * value_to_set; /*Start value of the rotary*/ uint16_t dragging :1; uint16_t sym :1; + uint8_t checkable :1; /* 1: Toggle enabled*/ } lv_rotary_ext_t; /** Built-in styles of rotary*/ @@ -79,6 +80,13 @@ enum { _LV_ROTARY_PART_VIRTUAL_LAST }; +/** Custom events of rotary*/ +enum { + LV_EVENT_ROTARY_TOGGLED = _LV_EVENT_LAST +}; +typedef uint8_t lv_rotary_event_t; + + /********************** * GLOBAL PROTOTYPES **********************/ @@ -184,16 +192,30 @@ static inline void lv_rotary_set_rotation(lv_obj_t * rotary, uint16_t rotation_a lv_arc_set_rotation(rotary, rotation_angle); } +/** + * Enable the toggled states + * @param rotary pointer to a rotary object + * @param tgl true: enable toggled states, false: disable + */ +void lv_rotary_set_checkable(lv_obj_t * rotary, bool tgl) + /** * Set the state of the rotary * @param rotary pointer to a rotary object * @param state the new state of the rotary (from lv_rotary_state_t enum) */ -static inline void lv_rotary_set_state(lv_obj_t * rotary, lv_rotary_state_t state) -{ +static inline void lv_rotary_set_state(lv_obj_t * rotary, lv_rotary_state_t state) { lv_btn_set_state(rotary, state); } +/** + * Toggle the state of the rotary (ON->OFF, OFF->ON) + * @param rotary pointer to a rotary object + */ +static inline void lv_rotary_toggle(lv_obj_t * rotary) { + lv_btn_toggle(rotary); +} + /*===================== * Getter functions *====================*/ @@ -273,6 +295,23 @@ static inline bool lv_rotary_get_symmetric(lv_obj_t * rotary) return ext->sym; } +/** + * Get the current state of the rotary + * @param rotary pointer to a rotary object + * @return the state of the rotary (from lv_rotary_state_t enum). + * If the rotary is in disabled state `LV_ROTARY_STATE_DISABLED` will be ORed to the other rotary states. + */ +static inline lv_btn_state_t lv_rotary_get_state(const lv_obj_t * rotary) { + return lv_btn_get_state(rotary); +} + +/** + * Get the toggle enable attribute of the rotary + * @param rotary pointer to a rotary object + * @return true: toggle enabled, false: disabled + */ +bool lv_rotary_get_checkable(const lv_obj_t * rotary) + /********************** * MACROS **********************/ From 1860742c1349aa618e83cb5e217e7b11b644ed49 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sat, 20 Jun 2020 12:14:17 -0700 Subject: [PATCH 024/173] Fix missing ;. Add custom event last --- src/lv_widgets/lv_rotary.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index f833902c8..51be3ea04 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -82,7 +82,8 @@ enum { /** Custom events of rotary*/ enum { - LV_EVENT_ROTARY_TOGGLED = _LV_EVENT_LAST + LV_EVENT_ROTARY_TOGGLED = _LV_EVENT_LAST, + _LV_EVENT_ROTARY_LAST }; typedef uint8_t lv_rotary_event_t; @@ -197,7 +198,7 @@ static inline void lv_rotary_set_rotation(lv_obj_t * rotary, uint16_t rotation_a * @param rotary pointer to a rotary object * @param tgl true: enable toggled states, false: disable */ -void lv_rotary_set_checkable(lv_obj_t * rotary, bool tgl) +void lv_rotary_set_checkable(lv_obj_t * rotary, bool tgl); /** * Set the state of the rotary From f3773694bcfeb74d705c88dfd1229c2b8115b59a Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sat, 20 Jun 2020 12:17:15 -0700 Subject: [PATCH 025/173] Remove custom event in favor or NULL diff --- src/lv_widgets/lv_rotary.c | 2 +- src/lv_widgets/lv_rotary.h | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 0fd4b5cc3..37bcb70fe 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -365,7 +365,7 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par toggled = 1; } - res = lv_event_send(rotary, LV_EVENT_ROTARY_TOGGLED, &toggled); + res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, &toggled); /** non-NULL indicates toggle event*/ if(res != LV_RES_OK) return res; } diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index 51be3ea04..b0217d80e 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -80,13 +80,6 @@ enum { _LV_ROTARY_PART_VIRTUAL_LAST }; -/** Custom events of rotary*/ -enum { - LV_EVENT_ROTARY_TOGGLED = _LV_EVENT_LAST, - _LV_EVENT_ROTARY_LAST -}; -typedef uint8_t lv_rotary_event_t; - /********************** * GLOBAL PROTOTYPES From fa8deb524d34b3985eb98220fc0b6f17e47070e4 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sat, 20 Jun 2020 12:18:53 -0700 Subject: [PATCH 026/173] Mising ; --- src/lv_widgets/lv_rotary.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index b0217d80e..7ca0beb88 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -304,7 +304,7 @@ static inline lv_btn_state_t lv_rotary_get_state(const lv_obj_t * rotary) { * @param rotary pointer to a rotary object * @return true: toggle enabled, false: disabled */ -bool lv_rotary_get_checkable(const lv_obj_t * rotary) +bool lv_rotary_get_checkable(const lv_obj_t * rotary); /********************** * MACROS From 35c0cfcfea30b0c8ed92ba88fef7f691bf87981d Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sat, 20 Jun 2020 12:23:24 -0700 Subject: [PATCH 027/173] Use custom event as data is not transfered to CB --- src/lv_widgets/lv_rotary.c | 2 +- src/lv_widgets/lv_rotary.h | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 37bcb70fe..0fd4b5cc3 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -365,7 +365,7 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par toggled = 1; } - res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, &toggled); /** non-NULL indicates toggle event*/ + res = lv_event_send(rotary, LV_EVENT_ROTARY_TOGGLED, &toggled); if(res != LV_RES_OK) return res; } diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index 7ca0beb88..70f48ad84 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -80,6 +80,12 @@ enum { _LV_ROTARY_PART_VIRTUAL_LAST }; +/** Custom events of rotary*/ +enum { + LV_EVENT_ROTARY_TOGGLED = _LV_EVENT_LAST, + _LV_EVENT_ROTARY_LAST +}; +typedef uint8_t lv_rotary_event_t; /********************** * GLOBAL PROTOTYPES From 3e079a47aedd379184a4fa7e819c269207724ca9 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sat, 20 Jun 2020 16:40:47 -0700 Subject: [PATCH 028/173] Pull btn functionality out for now, make checked state make DEAFULT. Add dragging value setters. --- src/lv_themes/lv_theme_material.c | 4 ++++ src/lv_widgets/lv_rotary.c | 32 +++++++++++-------------------- src/lv_widgets/lv_rotary.h | 13 +++---------- 3 files changed, 18 insertions(+), 31 deletions(-) diff --git a/src/lv_themes/lv_theme_material.c b/src/lv_themes/lv_theme_material.c index 54399c540..f02e122c7 100644 --- a/src/lv_themes/lv_theme_material.c +++ b/src/lv_themes/lv_theme_material.c @@ -814,6 +814,10 @@ static void rotary_init(void) lv_style_set_line_rounded(&styles->rotary_indic, LV_STATE_DEFAULT, true); style_init_reset(&styles->rotary_knob); + lv_style_set_bg_color(&styles->rotary_knob, LV_STATE_CHECKED, COLOR_BTN); + lv_style_set_border_opa(&styles->rotary_knob, LV_STATE_CHECKED, COLOR_BTN_BORDER); + lv_style_set_text_color(&styles->rotary_knob, LV_STATE_CHECKED, IS_LIGHT ? lv_color_hex(0x31404f) : lv_color_hex(0xffffff)); + lv_style_set_value_color(&styles->rotary_knob, LV_STATE_CHECKED, IS_LIGHT ? lv_color_hex(0x31404f) : lv_color_hex(0xffffff)); lv_style_set_bg_opa(&styles->rotary_knob, LV_STATE_DEFAULT, LV_OPA_COVER); lv_style_set_bg_color(&styles->rotary_knob, LV_STATE_DEFAULT, LV_COLOR_WHITE); lv_style_set_radius(&styles->rotary_knob, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE); diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 0fd4b5cc3..f948ce7d5 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -33,8 +33,6 @@ static lv_design_res_t lv_rotary_design(lv_obj_t * rotary, const lv_area_t * clip_area, lv_design_mode_t mode); static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * param); static lv_style_list_t * lv_rotary_get_style(lv_obj_t * rotary, uint8_t part); -// static void draw_bg(lv_obj_t * rotary, const lv_area_t * clip_area); -// static void draw_indic(lv_obj_t * rotary, const lv_area_t * clip_area); static void draw_knob(lv_obj_t * rotary, const lv_area_t * clip_area); /********************** @@ -343,32 +341,24 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par if(sign == LV_SIGNAL_PRESSED) { ext->dragging = true; } - else if(sign == LV_SIGNAL_PRESSING && ext->value_to_set != NULL) { + else if(sign == LV_SIGNAL_PRESSING && ext->last_drag_x != NULL) { lv_indev_get_point(param, &p); - // TODO: get new_value and set + if (ext->right_knob_area.y1 < p.y && p.y < ext->right_knob_area.y2) { + if (p.x > ext->last_drag_x && p.x < ext->right_knob_area.x2) { + lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + 1, LV_ANIM_ON); + } + else if (p.x < ext->last_drag_x && p.x > ext->right_knob_area.x1) { + lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) - 1, LV_ANIM_ON); + } + } + + ext->last_drag_x = p.x; } else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) { ext->dragging = false; ext->value_to_set = NULL; - /*If not dragged and it was not long press action then - *change state and run the action*/ - if(lv_indev_is_dragging(param) == false && tgl) { - uint32_t toggled = 0; - if(lv_obj_get_state(rotary, LV_ROTARY_PART_KNOB) & LV_STATE_CHECKED) { - lv_btn_set_state(rotary, LV_ROTARY_STATE_RELEASED); - toggled = 0; - } - else { - lv_btn_set_state(rotary, LV_ROTARY_STATE_CHECKED_RELEASED); - toggled = 1; - } - - res = lv_event_send(rotary, LV_EVENT_ROTARY_TOGGLED, &toggled); - if(res != LV_RES_OK) return res; - } - #if LV_USE_GROUP /*Leave edit mode if released. (No need to wait for LONG_PRESS) */ lv_group_t * g = lv_obj_get_group(rotary); diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index 70f48ad84..f0fcdecb7 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -66,10 +66,9 @@ typedef struct { int16_t cur_value; /*Current value of the rotary*/ int16_t min_value; /*Minimum value of the rotary*/ int16_t max_value; /*Maximum value of the rotary*/ - int16_t * value_to_set; /*Start value of the rotary*/ uint16_t dragging :1; + lv_coord_t last_drag_x; /*Last drag x coordintate of the rotary*/ uint16_t sym :1; - uint8_t checkable :1; /* 1: Toggle enabled*/ } lv_rotary_ext_t; /** Built-in styles of rotary*/ @@ -77,16 +76,10 @@ enum { LV_ROTARY_PART_BG = LV_ARC_PART_BG, /** Rotary background style. */ LV_ROTARY_PART_INDIC = LV_ARC_PART_INDIC, /** Rotary indicator (filled area) style. */ LV_ROTARY_PART_KNOB = _LV_ARC_PART_VIRTUAL_LAST, /** Rotary knob style. */ - _LV_ROTARY_PART_VIRTUAL_LAST + _LV_ROTARY_PART_VIRTUAL_LAST, + _LV_ROTARY_PART_REAL_LAST = _LV_ARC_PART_REAL_LAST }; -/** Custom events of rotary*/ -enum { - LV_EVENT_ROTARY_TOGGLED = _LV_EVENT_LAST, - _LV_EVENT_ROTARY_LAST -}; -typedef uint8_t lv_rotary_event_t; - /********************** * GLOBAL PROTOTYPES **********************/ From 5a0c0e2e97ac560ca1eaa559da9e41e3193b7e6b Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sat, 20 Jun 2020 16:43:53 -0700 Subject: [PATCH 029/173] Add value change event calls for dragging --- src/lv_widgets/lv_rotary.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index f948ce7d5..69c41812e 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -346,14 +346,19 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par if (ext->right_knob_area.y1 < p.y && p.y < ext->right_knob_area.y2) { if (p.x > ext->last_drag_x && p.x < ext->right_knob_area.x2) { + ext->last_drag_x = p.x; lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + 1, LV_ANIM_ON); + res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; } else if (p.x < ext->last_drag_x && p.x > ext->right_knob_area.x1) { + ext->last_drag_x = p.x; lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) - 1, LV_ANIM_ON); + res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; } } - ext->last_drag_x = p.x; } else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) { ext->dragging = false; From 71f8497ee6632970fb4620113538de36f8d09027 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sat, 20 Jun 2020 16:47:23 -0700 Subject: [PATCH 030/173] Add knob_area ext --- src/lv_widgets/lv_rotary.c | 8 +++++--- src/lv_widgets/lv_rotary.h | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 69c41812e..76cc24d2d 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -344,14 +344,14 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par else if(sign == LV_SIGNAL_PRESSING && ext->last_drag_x != NULL) { lv_indev_get_point(param, &p); - if (ext->right_knob_area.y1 < p.y && p.y < ext->right_knob_area.y2) { - if (p.x > ext->last_drag_x && p.x < ext->right_knob_area.x2) { + if (ext->knob_area.y1 < p.y && p.y < ext->knob_area.y2) { + if (p.x > ext->last_drag_x && p.x < ext->knob_area.x2) { ext->last_drag_x = p.x; lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + 1, LV_ANIM_ON); res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; } - else if (p.x < ext->last_drag_x && p.x > ext->right_knob_area.x1) { + else if (p.x < ext->last_drag_x && p.x > ext->knob_area.x1) { ext->last_drag_x = p.x; lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) - 1, LV_ANIM_ON); res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); @@ -445,6 +445,8 @@ static void draw_knob(lv_obj_t * rotary, const lv_area_t * clip_area) lv_draw_rect(&knob_area, clip_area, &knob_rect_dsc); } + + lv_area_copy(&ext->knob_area, &knob_area); } #endif diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index f0fcdecb7..7870e3eb6 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -63,6 +63,7 @@ typedef struct { lv_arc_ext_t arc; /*New data for this type*/ lv_style_list_t style_knob; /* Style of the knob */ + lv_area_t knob_area; /* Area of the knob */ int16_t cur_value; /*Current value of the rotary*/ int16_t min_value; /*Minimum value of the rotary*/ int16_t max_value; /*Maximum value of the rotary*/ From fc14c2c01c4d5c90c22ff3dfcc75e5dd28b9e06f Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sat, 20 Jun 2020 17:11:12 -0700 Subject: [PATCH 031/173] Remove chechable and toggle --- src/lv_widgets/lv_rotary.c | 31 ------------------------------- src/lv_widgets/lv_rotary.h | 22 ---------------------- 2 files changed, 53 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 76cc24d2d..626fef2af 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -85,7 +85,6 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) ext->min_value = 0; ext->max_value = 0; ext->dragging = false; - ext->checkable = 0; lv_style_list_init(&ext->style_knob); /*The signal and design functions are not copied so set them here*/ @@ -108,7 +107,6 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) ext->max_value = copy_ext->max_value; ext->dragging = copy_ext->dragging; ext->sym = copy_ext->sym; - ext->checkable = copy_ext->checkable; lv_style_list_copy(&ext->style_knob, ©_ext->style_knob); lv_obj_refresh_style(rotary, LV_OBJ_PART_ALL); @@ -193,20 +191,6 @@ void lv_rotary_set_symmetric(lv_obj_t * rotary, bool en) lv_obj_invalidate(rotary); } -/** - * Enable the toggled states - * @param rotary pointer to a button object - * @param tgl true: enable toggled states, false: disable - */ -void lv_rotary_set_checkable(lv_obj_t * rotary, bool tgl) -{ - LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); - - lv_rotary_ext_t * ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); - - ext->checkable = tgl != false ? 1 : 0; -} - /*===================== * Getter functions *====================*/ @@ -263,20 +247,6 @@ bool lv_rotary_is_dragged(const lv_obj_t * rotary) return ext->dragging; } -/** - * Get the toggle enable attribute of the rotary - * @param rotary pointer to a rotary object - * @return true: toggle enabled, false: disabled - */ -bool lv_rotary_get_checkable(const lv_obj_t * rotary) -{ - LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); - - lv_rotary_ext_t * ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); - - return ext->checkable != 0 ? true : false; -} - /********************** * STATIC FUNCTIONS **********************/ @@ -334,7 +304,6 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par if(res != LV_RES_OK) return res; if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME); - bool tgl = lv_rotary_get_checkable(rotary); lv_rotary_ext_t * ext = lv_obj_get_ext_attr(rotary); lv_point_t p; diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index 7870e3eb6..9b4b73985 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -186,13 +186,6 @@ static inline void lv_rotary_set_rotation(lv_obj_t * rotary, uint16_t rotation_a lv_arc_set_rotation(rotary, rotation_angle); } -/** - * Enable the toggled states - * @param rotary pointer to a rotary object - * @param tgl true: enable toggled states, false: disable - */ -void lv_rotary_set_checkable(lv_obj_t * rotary, bool tgl); - /** * Set the state of the rotary * @param rotary pointer to a rotary object @@ -202,14 +195,6 @@ static inline void lv_rotary_set_state(lv_obj_t * rotary, lv_rotary_state_t stat lv_btn_set_state(rotary, state); } -/** - * Toggle the state of the rotary (ON->OFF, OFF->ON) - * @param rotary pointer to a rotary object - */ -static inline void lv_rotary_toggle(lv_obj_t * rotary) { - lv_btn_toggle(rotary); -} - /*===================== * Getter functions *====================*/ @@ -299,13 +284,6 @@ static inline lv_btn_state_t lv_rotary_get_state(const lv_obj_t * rotary) { return lv_btn_get_state(rotary); } -/** - * Get the toggle enable attribute of the rotary - * @param rotary pointer to a rotary object - * @return true: toggle enabled, false: disabled - */ -bool lv_rotary_get_checkable(const lv_obj_t * rotary); - /********************** * MACROS **********************/ From 15ec0f8e2fd070510eee2a2a7d58cd731c9b78cd Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sat, 20 Jun 2020 17:15:09 -0700 Subject: [PATCH 032/173] Remove value_to_set remnant. Do not override checked opacity --- src/lv_themes/lv_theme_material.c | 1 - src/lv_widgets/lv_rotary.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lv_themes/lv_theme_material.c b/src/lv_themes/lv_theme_material.c index f02e122c7..edb106c6f 100644 --- a/src/lv_themes/lv_theme_material.c +++ b/src/lv_themes/lv_theme_material.c @@ -815,7 +815,6 @@ static void rotary_init(void) style_init_reset(&styles->rotary_knob); lv_style_set_bg_color(&styles->rotary_knob, LV_STATE_CHECKED, COLOR_BTN); - lv_style_set_border_opa(&styles->rotary_knob, LV_STATE_CHECKED, COLOR_BTN_BORDER); lv_style_set_text_color(&styles->rotary_knob, LV_STATE_CHECKED, IS_LIGHT ? lv_color_hex(0x31404f) : lv_color_hex(0xffffff)); lv_style_set_value_color(&styles->rotary_knob, LV_STATE_CHECKED, IS_LIGHT ? lv_color_hex(0x31404f) : lv_color_hex(0xffffff)); lv_style_set_bg_opa(&styles->rotary_knob, LV_STATE_DEFAULT, LV_OPA_COVER); diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 626fef2af..bcd85721a 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -331,7 +331,7 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par } else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) { ext->dragging = false; - ext->value_to_set = NULL; + ext->last_drag_x = NULL; #if LV_USE_GROUP /*Leave edit mode if released. (No need to wait for LONG_PRESS) */ From 866e088f988f8c19acd0f99c35fc8ab14f7b03bc Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sat, 20 Jun 2020 17:16:57 -0700 Subject: [PATCH 033/173] Copy knob_area to ext --- src/lv_widgets/lv_rotary.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index bcd85721a..d725756be 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -402,6 +402,8 @@ static void draw_knob(lv_obj_t * rotary, const lv_area_t * clip_area) lv_coord_t center_x = rotary->coords.x1 + r + left_bg; lv_coord_t center_y = rotary->coords.y1 + r + top_bg; lv_coord_t knob_inner = lv_obj_get_style_pad_inner(rotary, LV_ROTARY_PART_KNOB); + + lv_rotary_ext_t * ext = lv_obj_get_ext_attr(rotary); if(r > 0) { knob_area.x1 = center_x - r + indic_width + knob_inner; @@ -414,7 +416,7 @@ static void draw_knob(lv_obj_t * rotary, const lv_area_t * clip_area) lv_draw_rect(&knob_area, clip_area, &knob_rect_dsc); } - + lv_area_copy(&ext->knob_area, &knob_area); } From c93ef97ab9796f341a6ab9a942c8ac218a8eb202 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sat, 20 Jun 2020 17:18:53 -0700 Subject: [PATCH 034/173] Remove NULL comp --- src/lv_widgets/lv_rotary.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index d725756be..a1f127894 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -308,9 +308,13 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par lv_point_t p; if(sign == LV_SIGNAL_PRESSED) { + lv_indev_get_point(param, &p); + + ext->last_drag_x = p.x; ext->dragging = true; + } - else if(sign == LV_SIGNAL_PRESSING && ext->last_drag_x != NULL) { + else if(sign == LV_SIGNAL_PRESSING) { lv_indev_get_point(param, &p); if (ext->knob_area.y1 < p.y && p.y < ext->knob_area.y2) { @@ -331,7 +335,6 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par } else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) { ext->dragging = false; - ext->last_drag_x = NULL; #if LV_USE_GROUP /*Leave edit mode if released. (No need to wait for LONG_PRESS) */ From a7350282f08ff00c6e11b4654fbc074e6dc6f0c3 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sat, 20 Jun 2020 17:24:34 -0700 Subject: [PATCH 035/173] Use drag diff for value setting --- src/lv_widgets/lv_rotary.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index a1f127894..fc04ef80c 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -316,17 +316,18 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par } else if(sign == LV_SIGNAL_PRESSING) { lv_indev_get_point(param, &p); - + lv_coord_t drag_x_diff = ext->last_drag - p.x; + + ext->last_drag_x = p.x; if (ext->knob_area.y1 < p.y && p.y < ext->knob_area.y2) { - if (p.x > ext->last_drag_x && p.x < ext->knob_area.x2) { - ext->last_drag_x = p.x; - lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + 1, LV_ANIM_ON); + if (drag_x_diff > 0 && p.x < ext->knob_area.x2) { + lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff, LV_ANIM_ON); res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; } - else if (p.x < ext->last_drag_x && p.x > ext->knob_area.x1) { + else if (drag_x_diff < 0 && p.x > ext->knob_area.x1) { ext->last_drag_x = p.x; - lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) - 1, LV_ANIM_ON); + lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff, LV_ANIM_ON); res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; } From 3721fc52a8ab7ea2bede18a0a2a852bd0d4febb3 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sat, 20 Jun 2020 17:25:14 -0700 Subject: [PATCH 036/173] Typo --- src/lv_widgets/lv_rotary.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index fc04ef80c..b4e5142b8 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -316,7 +316,7 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par } else if(sign == LV_SIGNAL_PRESSING) { lv_indev_get_point(param, &p); - lv_coord_t drag_x_diff = ext->last_drag - p.x; + lv_coord_t drag_x_diff = ext->last_drag_x - p.x; ext->last_drag_x = p.x; if (ext->knob_area.y1 < p.y && p.y < ext->knob_area.y2) { From 3a315775927826ccea5e05c867db109d11aa4243 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sat, 20 Jun 2020 23:20:12 -0700 Subject: [PATCH 037/173] Add sesitivty setter --- src/lv_widgets/lv_rotary.c | 23 +++++++++++++++++++---- src/lv_widgets/lv_rotary.h | 14 ++++++++++++-- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index b4e5142b8..0d596e000 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -107,6 +107,7 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) ext->max_value = copy_ext->max_value; ext->dragging = copy_ext->dragging; ext->sym = copy_ext->sym; + ext->sensitivity = copy_ext->sensitivity; lv_style_list_copy(&ext->style_knob, ©_ext->style_knob); lv_obj_refresh_style(rotary, LV_OBJ_PART_ALL); @@ -191,6 +192,20 @@ void lv_rotary_set_symmetric(lv_obj_t * rotary, bool en) lv_obj_invalidate(rotary); } +/** + * Set the sesitivity of rotary knob increments + * position. + * @param rotary pointer to a rotary object + * @param sensitivity increment multiplier + */ +void lv_rotary_set_sensitivity(lv_obj_t * rotary, uint16_t sensitivity) +{ + LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); + + lv_rotary_ext_t *ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); + ext->sensitivity = sensitivity; +} + /*===================== * Getter functions *====================*/ @@ -321,13 +336,13 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par ext->last_drag_x = p.x; if (ext->knob_area.y1 < p.y && p.y < ext->knob_area.y2) { if (drag_x_diff > 0 && p.x < ext->knob_area.x2) { - lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff, LV_ANIM_ON); + lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON); res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; } else if (drag_x_diff < 0 && p.x > ext->knob_area.x1) { ext->last_drag_x = p.x; - lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff, LV_ANIM_ON); + lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON); res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; } @@ -352,12 +367,12 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par char c = *((char *)param); if(c == LV_KEY_RIGHT || c == LV_KEY_UP) { - lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + 1, LV_ANIM_ON); + lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + ext->sensitivity, LV_ANIM_ON); res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; } else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) { - lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) - 1, LV_ANIM_ON); + lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) - ext->sensitivity, LV_ANIM_ON); res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; } diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index 9b4b73985..3b7f718fc 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -67,9 +67,11 @@ typedef struct { int16_t cur_value; /*Current value of the rotary*/ int16_t min_value; /*Minimum value of the rotary*/ int16_t max_value; /*Maximum value of the rotary*/ - uint16_t dragging :1; lv_coord_t last_drag_x; /*Last drag x coordintate of the rotary*/ - uint16_t sym :1; + uint16_t dragging :1; + uint16_t sym :1; + uint16_t sensitivity :1; + } lv_rotary_ext_t; /** Built-in styles of rotary*/ @@ -121,6 +123,14 @@ void lv_rotary_set_range(lv_obj_t * rotary, int16_t min, int16_t max); */ void lv_rotary_set_symmetric(lv_obj_t * rotary, bool en); +/** + * Set the sesitivity of rotary knob increments + * position. + * @param rotary pointer to a rotary object + * @param sensitivity increment multiplier + */ +void lv_rotary_set_sensitivity(lv_obj_t * rotary, uint16_t sensitivity); + /** * Set the start angle of rotary indicator. 0 deg: right, 90 bottom, etc. * @param arc pointer to an arc object From fe483e8e21f821ff9d897b1f4516c56ee4582202 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sat, 20 Jun 2020 23:26:22 -0700 Subject: [PATCH 038/173] Add sensitivity default explicit --- src/lv_widgets/lv_rotary.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 0d596e000..be3ea0b86 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -85,6 +85,7 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) ext->min_value = 0; ext->max_value = 0; ext->dragging = false; + ext->sensitivity = 1; lv_style_list_init(&ext->style_knob); /*The signal and design functions are not copied so set them here*/ From dc873966e97dc6c9ecb9560476d3681244801b74 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sat, 20 Jun 2020 23:33:18 -0700 Subject: [PATCH 039/173] Make sensitivity an int --- src/lv_widgets/lv_rotary.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index 3b7f718fc..32e3d4c0e 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -67,10 +67,10 @@ typedef struct { int16_t cur_value; /*Current value of the rotary*/ int16_t min_value; /*Minimum value of the rotary*/ int16_t max_value; /*Maximum value of the rotary*/ + nt16_t sensitivity; /*Increment multiplier of the rotary*/ lv_coord_t last_drag_x; /*Last drag x coordintate of the rotary*/ uint16_t dragging :1; uint16_t sym :1; - uint16_t sensitivity :1; } lv_rotary_ext_t; From 6836947e672d7c9d74b6c5054d16db3efa8d8ef4 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sat, 20 Jun 2020 23:33:50 -0700 Subject: [PATCH 040/173] typo --- src/lv_widgets/lv_rotary.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index 32e3d4c0e..65766812e 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -67,7 +67,7 @@ typedef struct { int16_t cur_value; /*Current value of the rotary*/ int16_t min_value; /*Minimum value of the rotary*/ int16_t max_value; /*Maximum value of the rotary*/ - nt16_t sensitivity; /*Increment multiplier of the rotary*/ + int16_t sensitivity; /*Increment multiplier of the rotary*/ lv_coord_t last_drag_x; /*Last drag x coordintate of the rotary*/ uint16_t dragging :1; uint16_t sym :1; From 247b5b6f0c05637dcc38f95427f2023f98e9b044 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sat, 20 Jun 2020 23:43:40 -0700 Subject: [PATCH 041/173] Fix drag diff calc --- src/lv_widgets/lv_rotary.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index be3ea0b86..7ac680304 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -332,7 +332,7 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par } else if(sign == LV_SIGNAL_PRESSING) { lv_indev_get_point(param, &p); - lv_coord_t drag_x_diff = ext->last_drag_x - p.x; + lv_coord_t drag_x_diff = p.x - ext->last_drag_x; ext->last_drag_x = p.x; if (ext->knob_area.y1 < p.y && p.y < ext->knob_area.y2) { From ad990994d08615f5835a791128682ba780026c89 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sat, 20 Jun 2020 23:54:25 -0700 Subject: [PATCH 042/173] Fix release drag hoping better checking for -1 last drag x --- src/lv_widgets/lv_rotary.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 7ac680304..668a6a40e 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -332,26 +332,31 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par } else if(sign == LV_SIGNAL_PRESSING) { lv_indev_get_point(param, &p); - lv_coord_t drag_x_diff = p.x - ext->last_drag_x; - ext->last_drag_x = p.x; - if (ext->knob_area.y1 < p.y && p.y < ext->knob_area.y2) { - if (drag_x_diff > 0 && p.x < ext->knob_area.x2) { - lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON); - res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - else if (drag_x_diff < 0 && p.x > ext->knob_area.x1) { - ext->last_drag_x = p.x; - lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON); - res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; + if (ext->last_drag_x == -1) { + ext->last_drag_x = p.x; + } else { + lv_coord_t drag_x_diff = p.x - ext->last_drag_x; + ext->last_drag_x = p.x; + + if (ext->knob_area.y1 < p.y && p.y < ext->knob_area.y2) { + if (drag_x_diff > 0 && p.x < ext->knob_area.x2) { + lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON); + res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + else if (drag_x_diff < 0 && p.x > ext->knob_area.x1) { + ext->last_drag_x = p.x; + lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON); + res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } } } - } else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) { ext->dragging = false; + ext->last_drag_x = -1; /** Reset drag diff calc */ #if LV_USE_GROUP /*Leave edit mode if released. (No need to wait for LONG_PRESS) */ From 856368284e937c5302ce23410af76584f3d30684 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sat, 20 Jun 2020 23:58:03 -0700 Subject: [PATCH 043/173] Test sensitivity threshold for value jumping --- src/lv_widgets/lv_rotary.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 668a6a40e..7dc88d4cc 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -332,31 +332,31 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par } else if(sign == LV_SIGNAL_PRESSING) { lv_indev_get_point(param, &p); + lv_coord_t drag_x_diff = p.x -ext->last_drag_x; + + if (abs(drag_x_diff) > abs(ext->sensitivity)) { + if (drag_x_diff > 0) drag_x_diff = ext->sensitivity; + else drag_x_diff = -ext->sensitivity; + } + ext->last_drag_x = p.x; - if (ext->last_drag_x == -1) { - ext->last_drag_x = p.x; - } else { - lv_coord_t drag_x_diff = p.x - ext->last_drag_x; - ext->last_drag_x = p.x; - - if (ext->knob_area.y1 < p.y && p.y < ext->knob_area.y2) { - if (drag_x_diff > 0 && p.x < ext->knob_area.x2) { - lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON); - res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - else if (drag_x_diff < 0 && p.x > ext->knob_area.x1) { - ext->last_drag_x = p.x; - lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON); - res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } + if (ext->knob_area.y1 < p.y && p.y < ext->knob_area.y2) { + if (drag_x_diff > 0 && p.x < ext->knob_area.x2) { + lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON); + res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + else if (drag_x_diff < 0 && p.x > ext->knob_area.x1) { + ext->last_drag_x = p.x; + lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON); + res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; } } + } else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) { ext->dragging = false; - ext->last_drag_x = -1; /** Reset drag diff calc */ #if LV_USE_GROUP /*Leave edit mode if released. (No need to wait for LONG_PRESS) */ From e1761d50a1a3ad066ce3d03644a082d9a25bd5cc Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sun, 21 Jun 2020 00:05:09 -0700 Subject: [PATCH 044/173] Test threshold for value jupming --- src/lv_widgets/lv_rotary.c | 11 +++++++---- src/lv_widgets/lv_rotary.h | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 7dc88d4cc..d6a3253ec 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -109,6 +109,7 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) ext->dragging = copy_ext->dragging; ext->sym = copy_ext->sym; ext->sensitivity = copy_ext->sensitivity; + ext->threshold = copy_ext->threshold; lv_style_list_copy(&ext->style_knob, ©_ext->style_knob); lv_obj_refresh_style(rotary, LV_OBJ_PART_ALL); @@ -173,6 +174,8 @@ void lv_rotary_set_range(lv_obj_t * rotary, int16_t min, int16_t max) if(ext->cur_value > max) { ext->cur_value = max; } + + ext->threshold = (abs(ext->min_value) + abs(ext->max_value)) / 10; lv_rotary_set_value(rotary, ext->cur_value, false); } @@ -334,12 +337,12 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par lv_indev_get_point(param, &p); lv_coord_t drag_x_diff = p.x -ext->last_drag_x; - if (abs(drag_x_diff) > abs(ext->sensitivity)) { - if (drag_x_diff > 0) drag_x_diff = ext->sensitivity; - else drag_x_diff = -ext->sensitivity; + if (abs(drag_x_diff) > ext->threshold) { + if (drag_x_diff > 0) drag_x_diff = ext->threshold; + else drag_x_diff = -ext->threshold; } ext->last_drag_x = p.x; - + if (ext->knob_area.y1 < p.y && p.y < ext->knob_area.y2) { if (drag_x_diff > 0 && p.x < ext->knob_area.x2) { lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON); diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index 65766812e..07dc308cd 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -68,6 +68,7 @@ typedef struct { int16_t min_value; /*Minimum value of the rotary*/ int16_t max_value; /*Maximum value of the rotary*/ int16_t sensitivity; /*Increment multiplier of the rotary*/ + int16_t threshold; /*Increment threshold of the rotary*/ lv_coord_t last_drag_x; /*Last drag x coordintate of the rotary*/ uint16_t dragging :1; uint16_t sym :1; From 4bedc57b7d7237a86c6e768b78bedab0a3c5eb88 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sun, 21 Jun 2020 00:08:49 -0700 Subject: [PATCH 045/173] Add setter for threshold --- src/lv_widgets/lv_rotary.c | 17 +++++++++++++++-- src/lv_widgets/lv_rotary.h | 8 ++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index d6a3253ec..8b07a09bd 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -86,6 +86,7 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) ext->max_value = 0; ext->dragging = false; ext->sensitivity = 1; + ext->threshold = 1; lv_style_list_init(&ext->style_knob); /*The signal and design functions are not copied so set them here*/ @@ -175,8 +176,6 @@ void lv_rotary_set_range(lv_obj_t * rotary, int16_t min, int16_t max) ext->cur_value = max; } - ext->threshold = (abs(ext->min_value) + abs(ext->max_value)) / 10; - lv_rotary_set_value(rotary, ext->cur_value, false); } @@ -210,6 +209,20 @@ void lv_rotary_set_sensitivity(lv_obj_t * rotary, uint16_t sensitivity) ext->sensitivity = sensitivity; } +/** + * Set the threshold of rotary knob increments + * position. + * @param rotary pointer to a rotary object + * @param threshold increment threshold + */ +void lv_rotary_set_threshold(lv_obj_t * rotary, uint16_t threshold) +{ + LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); + + lv_rotary_ext_t *ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); + ext->threshold = threshold; +} + /*===================== * Getter functions *====================*/ diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index 07dc308cd..8f5e2e45f 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -132,6 +132,14 @@ void lv_rotary_set_symmetric(lv_obj_t * rotary, bool en); */ void lv_rotary_set_sensitivity(lv_obj_t * rotary, uint16_t sensitivity); +/** + * Set the threshold of rotary knob increments + * position. + * @param rotary pointer to a rotary object + * @param threshold increment threshold + */ +void lv_rotary_set_threshold(lv_obj_t * rotary, uint16_t threshold); + /** * Set the start angle of rotary indicator. 0 deg: right, 90 bottom, etc. * @param arc pointer to an arc object From d60a6cbc7614a5052d9e6b88c9f23bda9bdce0bc Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sun, 21 Jun 2020 00:26:20 -0700 Subject: [PATCH 046/173] Add reverse value mapping and arc tracking --- src/lv_widgets/lv_rotary.c | 46 +++++++++++++++++++++++++++++++------- src/lv_widgets/lv_rotary.h | 9 ++++++++ 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 8b07a09bd..599406d3a 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -84,9 +84,9 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) ext->cur_value = 0; ext->min_value = 0; ext->max_value = 0; - ext->dragging = false; ext->sensitivity = 1; ext->threshold = 1; + ext->dragging = false; lv_style_list_init(&ext->style_knob); /*The signal and design functions are not copied so set them here*/ @@ -107,10 +107,11 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) ext->cur_value = copy_ext->cur_value; ext->min_value = copy_ext->min_value; ext->max_value = copy_ext->max_value; - ext->dragging = copy_ext->dragging; - ext->sym = copy_ext->sym; ext->sensitivity = copy_ext->sensitivity; ext->threshold = copy_ext->threshold; + ext->dragging = copy_ext->dragging; + ext->sym = copy_ext->sym; + ext->reverse = copy_ext->reverse; lv_style_list_copy(&ext->style_knob, ©_ext->style_knob); lv_obj_refresh_style(rotary, LV_OBJ_PART_ALL); @@ -146,11 +147,19 @@ void lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim ext->cur_value = new_value; - lv_arc_set_end_angle( - rotary, - _lv_map(ext->cur_value, ext->min_value, ext->max_value, - ext->arc.arc_angle_start, 360 + ext->arc.bg_angle_end) - ); + if (ext->reverse) { + lv_arc_set_start_angle( + rotary, + _lv_map(ext->cur_value, ext->min_value, ext->max_value, + ext->arc.arc_angle_start, ext->arc.bg_angle_start) + ); + } else { + lv_arc_set_end_angle( + rotary, + _lv_map(ext->cur_value, ext->min_value, ext->max_value, + ext->arc.arc_angle_start, 360 + ext->arc.bg_angle_end) + ); + } } /** @@ -195,6 +204,27 @@ void lv_rotary_set_symmetric(lv_obj_t * rotary, bool en) lv_obj_invalidate(rotary); } +/** + * Reverse rotary behavior. The indicator will grow from arc end instead of arc start. + * position. + * @param rotary pointer to a rotary object + * @param reverse true: enable disable reverse behavior; false: disable + */ +void lv_rotary_set_reverse(lv_obj_t * rotary, bool reverse) +{ + LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); + + lv_rotary_ext_t *ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); + ext->reverse = reverse; + + uint16_t end = ext->arc.arc_angle_end; + + ext->arc.arc_angle_end = ext->arc.bg_angle_end; + ext->arc.arc_angle_start= end; + + lv_obj_invalidate(rotary); +} + /** * Set the sesitivity of rotary knob increments * position. diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index 8f5e2e45f..bf96820fc 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -72,6 +72,7 @@ typedef struct { lv_coord_t last_drag_x; /*Last drag x coordintate of the rotary*/ uint16_t dragging :1; uint16_t sym :1; + uint16_t reverse :1; } lv_rotary_ext_t; @@ -124,6 +125,14 @@ void lv_rotary_set_range(lv_obj_t * rotary, int16_t min, int16_t max); */ void lv_rotary_set_symmetric(lv_obj_t * rotary, bool en); +/** + * Reverse rotary behavior. The indicator will grow from arc end instead of arc start. + * position. + * @param rotary pointer to a rotary object + * @param reverse true: enable disable reverse behavior; false: disable + */ +void lv_rotary_set_reverse(lv_obj_t * rotary, bool reverse); + /** * Set the sesitivity of rotary knob increments * position. From 4ab8520bfbb3ca7c90fd38c32a5485ac18e4891a Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sun, 21 Jun 2020 00:29:03 -0700 Subject: [PATCH 047/173] Use lv math abs --- src/lv_widgets/lv_rotary.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 599406d3a..f18694f2b 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -380,7 +380,7 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par lv_indev_get_point(param, &p); lv_coord_t drag_x_diff = p.x -ext->last_drag_x; - if (abs(drag_x_diff) > ext->threshold) { + if (LV_MATH_ABS(drag_x_diff) > ext->threshold) { if (drag_x_diff > 0) drag_x_diff = ext->threshold; else drag_x_diff = -ext->threshold; } From 6c014903721464ead6b21fa5bafd41a2275ffc01 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sun, 21 Jun 2020 00:34:08 -0700 Subject: [PATCH 048/173] Use value setter for reverse start angle setting --- src/lv_widgets/lv_rotary.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index f18694f2b..afcffe3d2 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -151,7 +151,7 @@ void lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim lv_arc_set_start_angle( rotary, _lv_map(ext->cur_value, ext->min_value, ext->max_value, - ext->arc.arc_angle_start, ext->arc.bg_angle_start) + ext->arc.arc_angle_end, ext->arc.bg_angle_start) ); } else { lv_arc_set_end_angle( @@ -220,9 +220,8 @@ void lv_rotary_set_reverse(lv_obj_t * rotary, bool reverse) uint16_t end = ext->arc.arc_angle_end; ext->arc.arc_angle_end = ext->arc.bg_angle_end; - ext->arc.arc_angle_start= end; - - lv_obj_invalidate(rotary); + + lv_rotary_set_value(rotary, ext->cur_value, false); } /** From 0d6b8a86d483a5a46fbcc31c1e9f2e205023c9a5 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sun, 21 Jun 2020 00:36:39 -0700 Subject: [PATCH 049/173] Try reverse mapping --- src/lv_widgets/lv_rotary.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index afcffe3d2..f8cc7641e 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -151,7 +151,7 @@ void lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim lv_arc_set_start_angle( rotary, _lv_map(ext->cur_value, ext->min_value, ext->max_value, - ext->arc.arc_angle_end, ext->arc.bg_angle_start) + 360 + ext->arc.bg_angle_end, ext->arc.bg_angle_start) ); } else { lv_arc_set_end_angle( @@ -215,10 +215,8 @@ void lv_rotary_set_reverse(lv_obj_t * rotary, bool reverse) LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); lv_rotary_ext_t *ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); + ext->reverse = reverse; - - uint16_t end = ext->arc.arc_angle_end; - ext->arc.arc_angle_end = ext->arc.bg_angle_end; lv_rotary_set_value(rotary, ext->cur_value, false); From 5359a762b8a47a66791b130e670c63abf98abd1f Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sun, 21 Jun 2020 10:59:41 -0700 Subject: [PATCH 050/173] Reverse min and max in mapping reverse --- src/lv_widgets/lv_rotary.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index f8cc7641e..629ade3aa 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -150,8 +150,8 @@ void lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim if (ext->reverse) { lv_arc_set_start_angle( rotary, - _lv_map(ext->cur_value, ext->min_value, ext->max_value, - 360 + ext->arc.bg_angle_end, ext->arc.bg_angle_start) + _lv_map(ext->cur_value, ext->max_value, ext->min_value, + ext->arc.arc_angle_start, 360 + ext->arc.bg_angle_end) ); } else { lv_arc_set_end_angle( From 19a1afbd89e258f8b4f38e2220466241cbe8c737 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sun, 21 Jun 2020 11:05:24 -0700 Subject: [PATCH 051/173] Fix reverse mapping --- src/lv_widgets/lv_rotary.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 629ade3aa..fe459587f 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -151,7 +151,7 @@ void lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim lv_arc_set_start_angle( rotary, _lv_map(ext->cur_value, ext->max_value, ext->min_value, - ext->arc.arc_angle_start, 360 + ext->arc.bg_angle_end) + 360 + ext->arc.bg_angle_end, ext->arc.bg_angle_start) ); } else { lv_arc_set_end_angle( From af7134269e3186f1fc32ce7d55caea706f8a7803 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sun, 21 Jun 2020 11:15:48 -0700 Subject: [PATCH 052/173] Force set_value handling in reverse --- src/lv_widgets/lv_rotary.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index fe459587f..e57461669 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -215,11 +215,13 @@ void lv_rotary_set_reverse(lv_obj_t * rotary, bool reverse) LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); lv_rotary_ext_t *ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); - - ext->reverse = reverse; - ext->arc.arc_angle_end = ext->arc.bg_angle_end; + int16_t val = ext->cur_value; - lv_rotary_set_value(rotary, ext->cur_value, false); + ext->cur_value = -1; /** Force set_value handling*/ + ext->reverse = reverse; + + lv_rotary_set_end_angle(rotary, ext->arc.bg_angle_end); + lv_rotary_set_value(rotary, val, false); } /** From ba10671b2b553f6330b136d84779aefd939976d2 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Mon, 22 Jun 2020 21:50:21 -0700 Subject: [PATCH 053/173] Rotary types. Add symmetric value setter --- src/lv_widgets/lv_rotary.c | 134 ++++++++++++++++++++++++------------- src/lv_widgets/lv_rotary.h | 34 +++++----- 2 files changed, 101 insertions(+), 67 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index e57461669..b67c5f954 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -147,18 +147,43 @@ void lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim ext->cur_value = new_value; - if (ext->reverse) { - lv_arc_set_start_angle( - rotary, - _lv_map(ext->cur_value, ext->max_value, ext->min_value, - 360 + ext->arc.bg_angle_end, ext->arc.bg_angle_start) - ); - } else { - lv_arc_set_end_angle( - rotary, - _lv_map(ext->cur_value, ext->min_value, ext->max_value, - ext->arc.arc_angle_start, 360 + ext->arc.bg_angle_end) - ); + switch(ext->type) { + case LV_ROTARY_TYPE_SYMMETRIC: + unint16_t bg_midpoint; + if (ext->arc.bg_angle_end < ext->arc.bg_angle_start) { + bg_midpoint = (ext->arc.bg_angle_start + ext->arc.bg_angle_end + 360) / 2; + } else { + bg_midpoint = (ext->arc.bg_angle_start + ext->arc.bg_angle_end) / 2; + } + + int16_t range_midpoint = (ext->min_value + ext->max_value) / 2; + if (ext->cur_value < range_midpoint) { + lv_arc_set_start_angle( + rotary, + _lv_map(ext->cur_value, ext->max_value, ext->min_value, + ext->arc.bg_angle_start, bg_midpoint) + ); + } else if (ext->cur_value > range_midpoint) { + lv_arc_set_start_angle( + rotary, + _lv_map(ext->cur_value, ext->max_value, ext->min_value, + ext->arc.bg_angle_start, bg_midpoint) + ); + } + break; + case LV_ROTARY_TYPE_REVERSE: + lv_arc_set_start_angle( + rotary, + _lv_map(ext->cur_value, ext->max_value, ext->min_value, + 360 + ext->arc.bg_angle_end, ext->arc.bg_angle_start) + ); + break; + default: /** LV_ROTARY_TYPE_NORMAL*/ + lv_arc_set_end_angle( + rotary, + _lv_map(ext->cur_value, ext->min_value, ext->max_value, + ext->arc.arc_angle_start, 360 + ext->arc.bg_angle_end) + ); } } @@ -188,42 +213,6 @@ void lv_rotary_set_range(lv_obj_t * rotary, int16_t min, int16_t max) lv_rotary_set_value(rotary, ext->cur_value, false); } -/** - * Make the rotary symmetric to zero. The indicator will grow from zero instead of the minimum - * position. - * @param rotary pointer to a rotary object - * @param en true: enable disable symmetric behavior; false: disable - */ -void lv_rotary_set_symmetric(lv_obj_t * rotary, bool en) -{ - LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); - - lv_rotary_ext_t *ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); - ext->sym = en; - - lv_obj_invalidate(rotary); -} - -/** - * Reverse rotary behavior. The indicator will grow from arc end instead of arc start. - * position. - * @param rotary pointer to a rotary object - * @param reverse true: enable disable reverse behavior; false: disable - */ -void lv_rotary_set_reverse(lv_obj_t * rotary, bool reverse) -{ - LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); - - lv_rotary_ext_t *ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); - int16_t val = ext->cur_value; - - ext->cur_value = -1; /** Force set_value handling*/ - ext->reverse = reverse; - - lv_rotary_set_end_angle(rotary, ext->arc.bg_angle_end); - lv_rotary_set_value(rotary, val, false); -} - /** * Set the sesitivity of rotary knob increments * position. @@ -252,6 +241,42 @@ void lv_rotary_set_threshold(lv_obj_t * rotary, uint16_t threshold) ext->threshold = threshold; } +/** + * Set the type of rotary. + * @param rotary pointer to rotary object + * @param type rotary type + */ +void lv_rotary_set_type(lv_obj_t * rotary, lv_rotary_type_t type) +{ + LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); + + lv_rotary_ext_t *ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); + int16_t val = ext->cur_value; + + ext->type = type; + ext->cur_value = -1; /** Force set_value handling*/ + + switch(ext->type) { + case LV_ROTARY_TYPE_SYMMETRIC: + unint16_t bg_midpoint; + if (ext->arc.bg_angle_end < ext->arc.bg_angle_start) { + bg_midpoint = (ext->arc.bg_angle_start + ext->arc.bg_angle_end + 360) / 2; + } else { + bg_midpoint = (ext->arc.bg_angle_start + ext->arc.bg_angle_end) / 2; + } + lv_rotary_set_start_angle(rotary, bg_midpoint); + lv_rotary_set_start_angle(rotary, bg_midpoint); + break; + case LV_ROTARY_TYPE_REVERSE: + lv_rotary_set_end_angle(rotary, ext->arc.bg_angle_end); + break; + default: /** LV_ROTARY_TYPE_NORMAL*/ + lv_rotary_set_start_angle(rotary, ext->arc.bg_angle_start); + } + + lv_rotary_set_value(rotary, val, false); +} + /*===================== * Getter functions *====================*/ @@ -308,6 +333,19 @@ bool lv_rotary_is_dragged(const lv_obj_t * rotary) return ext->dragging; } +/** + * Get whether the rotary is type or not. + * @param rotary pointer to a rotary object + * @return rotary type + */ +lv_rotary_type_t lv_rotary_get_type(const lv_obj_t * rotary) +{ + LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); + + lv_rotary_ext_t * ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); + return ext->type; +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index bf96820fc..a9b85d40a 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -41,7 +41,9 @@ extern "C" { **********************/ enum { - LV_ROTARY_TYPE_NORMAL + LV_ROTARY_TYPE_NORMAL, + LV_ROTARY_TYPE_SYMMETRIC, + LV_ROTARY_TYPE_REVERSE }; typedef uint8_t lv_rotary_type_t; @@ -71,8 +73,7 @@ typedef struct { int16_t threshold; /*Increment threshold of the rotary*/ lv_coord_t last_drag_x; /*Last drag x coordintate of the rotary*/ uint16_t dragging :1; - uint16_t sym :1; - uint16_t reverse :1; + uint16_t type :2; } lv_rotary_ext_t; @@ -117,14 +118,6 @@ void lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim */ void lv_rotary_set_range(lv_obj_t * rotary, int16_t min, int16_t max); -/** - * Make the rotary symmetric to zero. The indicator will grow from zero instead of the minimum - * position. - * @param rotary pointer to a rotary object - * @param en true: enable disable symmetric behavior; false: disable - */ -void lv_rotary_set_symmetric(lv_obj_t * rotary, bool en); - /** * Reverse rotary behavior. The indicator will grow from arc end instead of arc start. * position. @@ -149,6 +142,13 @@ void lv_rotary_set_sensitivity(lv_obj_t * rotary, uint16_t sensitivity); */ void lv_rotary_set_threshold(lv_obj_t * rotary, uint16_t threshold); +/** + * Set the type of rotary. + * @param rotary pointer to rotary object + * @param type rotary type + */ +void lv_rotary_set_type(lv_obj_t * rotary, lv_rotary_type_t type); + /** * Set the start angle of rotary indicator. 0 deg: right, 90 bottom, etc. * @param arc pointer to an arc object @@ -292,15 +292,11 @@ int16_t lv_rotary_get_max_value(const lv_obj_t * rotary); bool lv_rotary_is_dragged(const lv_obj_t * rotary); /** - * Get whether the rotary is symmetric or not. + * Get whether the rotary is type or not. * @param rotary pointer to a rotary object - * @return true: symmetric is enabled; false: disable + * @return rotary type */ -static inline bool lv_rotary_get_symmetric(lv_obj_t * rotary) -{ - lv_rotary_ext_t * ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); - return ext->sym; -} +lv_rotary_type_t lv_rotary_get_type(const lv_obj_t * rotary); /** * Get the current state of the rotary @@ -308,7 +304,7 @@ static inline bool lv_rotary_get_symmetric(lv_obj_t * rotary) * @return the state of the rotary (from lv_rotary_state_t enum). * If the rotary is in disabled state `LV_ROTARY_STATE_DISABLED` will be ORed to the other rotary states. */ -static inline lv_btn_state_t lv_rotary_get_state(const lv_obj_t * rotary) { +static inline lv_rotary_state_t lv_rotary_get_state(const lv_obj_t * rotary) { return lv_btn_get_state(rotary); } From 1c071530adc7f509a463fa558bfdd670d058c93a Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Mon, 22 Jun 2020 21:54:03 -0700 Subject: [PATCH 054/173] Remove sym references --- src/lv_widgets/lv_rotary.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index b67c5f954..b4d895d2b 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -87,6 +87,7 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) ext->sensitivity = 1; ext->threshold = 1; ext->dragging = false; + ext->type = LV_ROTARY_TYPE_NORMAL; lv_style_list_init(&ext->style_knob); /*The signal and design functions are not copied so set them here*/ @@ -110,8 +111,7 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) ext->sensitivity = copy_ext->sensitivity; ext->threshold = copy_ext->threshold; ext->dragging = copy_ext->dragging; - ext->sym = copy_ext->sym; - ext->reverse = copy_ext->reverse; + ext->type = copy_ext->type; lv_style_list_copy(&ext->style_knob, ©_ext->style_knob); lv_obj_refresh_style(rotary, LV_OBJ_PART_ALL); From 9ede4ba7079dc795703a2f7dde6e27e3ddf3f974 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Mon, 22 Jun 2020 21:54:47 -0700 Subject: [PATCH 055/173] typo --- src/lv_widgets/lv_rotary.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index b4d895d2b..09f1cdcce 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -149,7 +149,7 @@ void lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim switch(ext->type) { case LV_ROTARY_TYPE_SYMMETRIC: - unint16_t bg_midpoint; + uint16_t bg_midpoint; if (ext->arc.bg_angle_end < ext->arc.bg_angle_start) { bg_midpoint = (ext->arc.bg_angle_start + ext->arc.bg_angle_end + 360) / 2; } else { @@ -258,7 +258,7 @@ void lv_rotary_set_type(lv_obj_t * rotary, lv_rotary_type_t type) switch(ext->type) { case LV_ROTARY_TYPE_SYMMETRIC: - unint16_t bg_midpoint; + uint16_t bg_midpoint; if (ext->arc.bg_angle_end < ext->arc.bg_angle_start) { bg_midpoint = (ext->arc.bg_angle_start + ext->arc.bg_angle_end + 360) / 2; } else { From 46f7dff9e2faafb22dfb7f2282a9aa71cce8bd70 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Mon, 22 Jun 2020 21:56:31 -0700 Subject: [PATCH 056/173] Fix statement declaration --- src/lv_widgets/lv_rotary.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 09f1cdcce..4f5255cfb 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -147,16 +147,16 @@ void lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim ext->cur_value = new_value; + uint16_t bg_midpoint, range_midpoint; switch(ext->type) { case LV_ROTARY_TYPE_SYMMETRIC: - uint16_t bg_midpoint; if (ext->arc.bg_angle_end < ext->arc.bg_angle_start) { bg_midpoint = (ext->arc.bg_angle_start + ext->arc.bg_angle_end + 360) / 2; } else { bg_midpoint = (ext->arc.bg_angle_start + ext->arc.bg_angle_end) / 2; } - int16_t range_midpoint = (ext->min_value + ext->max_value) / 2; + range_midpoint = (ext->min_value + ext->max_value) / 2; if (ext->cur_value < range_midpoint) { lv_arc_set_start_angle( rotary, @@ -256,9 +256,9 @@ void lv_rotary_set_type(lv_obj_t * rotary, lv_rotary_type_t type) ext->type = type; ext->cur_value = -1; /** Force set_value handling*/ + uint16_t bg_midpoint; switch(ext->type) { case LV_ROTARY_TYPE_SYMMETRIC: - uint16_t bg_midpoint; if (ext->arc.bg_angle_end < ext->arc.bg_angle_start) { bg_midpoint = (ext->arc.bg_angle_start + ext->arc.bg_angle_end + 360) / 2; } else { From f0cae0057483bfb2672f4ac3553c57ea1f885d8a Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Mon, 22 Jun 2020 22:47:01 -0700 Subject: [PATCH 057/173] Rearrange type call for clarity. Fix symmetric arc setters --- src/lv_widgets/lv_rotary.c | 97 ++++++++++++++++++-------------------- src/lv_widgets/lv_rotary.h | 30 ++++++------ 2 files changed, 61 insertions(+), 66 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 4f5255cfb..e79ff94ac 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -126,6 +126,40 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) * Setter functions *====================*/ +/** + * Set the type of rotary. + * @param rotary pointer to rotary object + * @param type rotary type + */ +void lv_rotary_set_type(lv_obj_t * rotary, lv_rotary_type_t type) +{ + LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); + + lv_rotary_ext_t *ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); + int16_t val = ext->cur_value; + + ext->type = type; + ext->cur_value = -1; /** Force set_value handling*/ + + int16_t bg_end, bg_midpoint; + if (ext->arc.bg_angle_end < ext->arc.bg_angle_start) bg_end = ext->arc.bg_angle_end + 360; + + switch(ext->type) { + case LV_ROTARY_TYPE_SYMMETRIC: + bg_midpoint = (ext->arc.bg_angle_start + bg_end) / 2; + lv_rotary_set_start_angle(rotary, bg_midpoint); + lv_rotary_set_end_angle(rotary, bg_midpoint); + break; + case LV_ROTARY_TYPE_REVERSE: + lv_rotary_set_end_angle(rotary, ext->arc.bg_angle_end); + break; + default: /** LV_ROTARY_TYPE_NORMAL*/ + lv_rotary_set_start_angle(rotary, ext->arc.bg_angle_start); + } + + lv_rotary_set_value(rotary, val, false); +} + /** * Set a new value on the rotary * @param rotary pointer to a rotary object @@ -144,30 +178,27 @@ void lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim new_value = new_value < ext->min_value ? ext->min_value : new_value; if(ext->cur_value == new_value) return; - ext->cur_value = new_value; - uint16_t bg_midpoint, range_midpoint; + int16_t bg_end, bg_midpoint, range_midpoint; + if (ext->arc.bg_angle_end < ext->arc.bg_angle_start) bg_end = ext->arc.bg_angle_end + 360; + switch(ext->type) { case LV_ROTARY_TYPE_SYMMETRIC: - if (ext->arc.bg_angle_end < ext->arc.bg_angle_start) { - bg_midpoint = (ext->arc.bg_angle_start + ext->arc.bg_angle_end + 360) / 2; - } else { - bg_midpoint = (ext->arc.bg_angle_start + ext->arc.bg_angle_end) / 2; - } - - range_midpoint = (ext->min_value + ext->max_value) / 2; + bg_midpoint = (ext->arc.bg_angle_start + bg_end) / 2; + range_midpoint = (int32_t)(ext->min_value + ext->max_value) / 2; + if (ext->cur_value < range_midpoint) { lv_arc_set_start_angle( rotary, - _lv_map(ext->cur_value, ext->max_value, ext->min_value, + _lv_map(ext->cur_value, ext->min_value, range_midpoint, ext->arc.bg_angle_start, bg_midpoint) ); - } else if (ext->cur_value > range_midpoint) { + } else { lv_arc_set_start_angle( rotary, - _lv_map(ext->cur_value, ext->max_value, ext->min_value, - ext->arc.bg_angle_start, bg_midpoint) + _lv_map(ext->cur_value, range_midpoint, ext->max_value, + bg_midpoint, bg_end) ); } break; @@ -175,14 +206,14 @@ void lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim lv_arc_set_start_angle( rotary, _lv_map(ext->cur_value, ext->max_value, ext->min_value, - 360 + ext->arc.bg_angle_end, ext->arc.bg_angle_start) + bg_end, ext->arc.bg_angle_start) ); break; default: /** LV_ROTARY_TYPE_NORMAL*/ lv_arc_set_end_angle( rotary, _lv_map(ext->cur_value, ext->min_value, ext->max_value, - ext->arc.arc_angle_start, 360 + ext->arc.bg_angle_end) + ext->arc.bg_angle_start, bg_end) ); } } @@ -241,42 +272,6 @@ void lv_rotary_set_threshold(lv_obj_t * rotary, uint16_t threshold) ext->threshold = threshold; } -/** - * Set the type of rotary. - * @param rotary pointer to rotary object - * @param type rotary type - */ -void lv_rotary_set_type(lv_obj_t * rotary, lv_rotary_type_t type) -{ - LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); - - lv_rotary_ext_t *ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); - int16_t val = ext->cur_value; - - ext->type = type; - ext->cur_value = -1; /** Force set_value handling*/ - - uint16_t bg_midpoint; - switch(ext->type) { - case LV_ROTARY_TYPE_SYMMETRIC: - if (ext->arc.bg_angle_end < ext->arc.bg_angle_start) { - bg_midpoint = (ext->arc.bg_angle_start + ext->arc.bg_angle_end + 360) / 2; - } else { - bg_midpoint = (ext->arc.bg_angle_start + ext->arc.bg_angle_end) / 2; - } - lv_rotary_set_start_angle(rotary, bg_midpoint); - lv_rotary_set_start_angle(rotary, bg_midpoint); - break; - case LV_ROTARY_TYPE_REVERSE: - lv_rotary_set_end_angle(rotary, ext->arc.bg_angle_end); - break; - default: /** LV_ROTARY_TYPE_NORMAL*/ - lv_rotary_set_start_angle(rotary, ext->arc.bg_angle_start); - } - - lv_rotary_set_value(rotary, val, false); -} - /*===================== * Getter functions *====================*/ diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index a9b85d40a..6a45f04ab 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -66,6 +66,7 @@ typedef struct { /*New data for this type*/ lv_style_list_t style_knob; /* Style of the knob */ lv_area_t knob_area; /* Area of the knob */ + uint16_t type :2; int16_t cur_value; /*Current value of the rotary*/ int16_t min_value; /*Minimum value of the rotary*/ int16_t max_value; /*Maximum value of the rotary*/ @@ -73,7 +74,6 @@ typedef struct { int16_t threshold; /*Increment threshold of the rotary*/ lv_coord_t last_drag_x; /*Last drag x coordintate of the rotary*/ uint16_t dragging :1; - uint16_t type :2; } lv_rotary_ext_t; @@ -102,6 +102,13 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy); * Setter functions *====================*/ +/** + * Set the type of rotary. + * @param rotary pointer to rotary object + * @param type rotary type + */ +void lv_rotary_set_type(lv_obj_t * rotary, lv_rotary_type_t type); + /** * Set a new value on the rotary * @param rotary pointer to a rotary object @@ -142,13 +149,6 @@ void lv_rotary_set_sensitivity(lv_obj_t * rotary, uint16_t sensitivity); */ void lv_rotary_set_threshold(lv_obj_t * rotary, uint16_t threshold); -/** - * Set the type of rotary. - * @param rotary pointer to rotary object - * @param type rotary type - */ -void lv_rotary_set_type(lv_obj_t * rotary, lv_rotary_type_t type); - /** * Set the start angle of rotary indicator. 0 deg: right, 90 bottom, etc. * @param arc pointer to an arc object @@ -263,6 +263,13 @@ static inline uint16_t lv_rotary_get_bg_angle_end(lv_obj_t * rotary) { return lv_arc_get_bg_angle_end(rotary); } +/** + * Get whether the rotary is type or not. + * @param rotary pointer to a rotary object + * @return rotary type + */ +lv_rotary_type_t lv_rotary_get_type(const lv_obj_t * rotary); + /** * Get the value of the of a rotary * @param rotary pointer to a rotary object @@ -291,13 +298,6 @@ int16_t lv_rotary_get_max_value(const lv_obj_t * rotary); */ bool lv_rotary_is_dragged(const lv_obj_t * rotary); -/** - * Get whether the rotary is type or not. - * @param rotary pointer to a rotary object - * @return rotary type - */ -lv_rotary_type_t lv_rotary_get_type(const lv_obj_t * rotary); - /** * Get the current state of the rotary * @param rotary pointer to a rotary object From 83d05f945f71c92d43a91b7b2f62e2d1ca0aba4f Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Mon, 22 Jun 2020 22:49:23 -0700 Subject: [PATCH 058/173] Fix bg_end init --- src/lv_widgets/lv_rotary.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index e79ff94ac..5c1011e4a 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -141,7 +141,7 @@ void lv_rotary_set_type(lv_obj_t * rotary, lv_rotary_type_t type) ext->type = type; ext->cur_value = -1; /** Force set_value handling*/ - int16_t bg_end, bg_midpoint; + int16_t bg_midpoint, bg_end = ext->arc.bg_angle_end; if (ext->arc.bg_angle_end < ext->arc.bg_angle_start) bg_end = ext->arc.bg_angle_end + 360; switch(ext->type) { @@ -180,7 +180,7 @@ void lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim if(ext->cur_value == new_value) return; ext->cur_value = new_value; - int16_t bg_end, bg_midpoint, range_midpoint; + int16_t bg_midpoint, range_midpoint, bg_end = ext->arc.bg_angle_end; if (ext->arc.bg_angle_end < ext->arc.bg_angle_start) bg_end = ext->arc.bg_angle_end + 360; switch(ext->type) { From 0aeb49d28a1f3e8144df60b48060dc9de6d9df3b Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Mon, 22 Jun 2020 22:53:58 -0700 Subject: [PATCH 059/173] Fix Set sym end angle --- src/lv_widgets/lv_rotary.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 5c1011e4a..0dfd0ef73 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -195,7 +195,7 @@ void lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim ext->arc.bg_angle_start, bg_midpoint) ); } else { - lv_arc_set_start_angle( + lv_arc_set_end_angle( rotary, _lv_map(ext->cur_value, range_midpoint, ext->max_value, bg_midpoint, bg_end) From 663af3dfb32ef81bf7bc45d926721e8d48d31587 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Tue, 23 Jun 2020 12:54:06 -0700 Subject: [PATCH 060/173] Shift mapping math out of floating point --- src/lv_misc/lv_math.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lv_misc/lv_math.c b/src/lv_misc/lv_math.c index 7c467b5f1..9e8a91b80 100644 --- a/src/lv_misc/lv_math.c +++ b/src/lv_misc/lv_math.c @@ -239,12 +239,12 @@ int64_t _lv_pow(int64_t base, int8_t exp) * @param in min output range * @param out max output range */ -LV_ATTRIBUTE_FAST_MEM int16_t _lv_map(int16_t x, float min_in, float max_in, float min, float max) +LV_ATTRIBUTE_FAST_MEM int16_t _lv_map(int16_t x, int16_t min_in, int16_t max_in, int16_t min, int16_t max) { - float slope = (max - min) / (max_in - min_in); - float bias = min - slope * min_in; + uint32_t slope = ((uint32_t)(max - min) * 1000) / (uint32_t)(max_in - min_in); /** times 1000 to avoid rounding errors*/ + uint32_t bias = min - (slope * min_in) / 1000; - return bias + slope * x; + return bias + (slope * x) / 1000; } /********************** From 5961800fe0a12855281a9a677c00aaf1a5ddba0d Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Tue, 23 Jun 2020 12:56:07 -0700 Subject: [PATCH 061/173] Fix map contract --- src/lv_misc/lv_math.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_misc/lv_math.h b/src/lv_misc/lv_math.h index aeb9e4d7a..0d72fb5af 100644 --- a/src/lv_misc/lv_math.h +++ b/src/lv_misc/lv_math.h @@ -120,7 +120,7 @@ int64_t _lv_pow(int64_t base, int8_t exp); * @param in min output range * @param out max output range */ -LV_ATTRIBUTE_FAST_MEM int16_t _lv_map(int16_t x, float min_in, float max_in, float min, float max); +LV_ATTRIBUTE_FAST_MEM int16_t _lv_map(int16_t x, int16_t min_in, int16_t max_in, int16_t min, int16_t max); /********************** * MACROS From b414aa755d1e111407b343a962b9d4f0f9079aca Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Tue, 23 Jun 2020 13:33:25 -0700 Subject: [PATCH 062/173] int32 fix to mapping logic --- src/lv_misc/lv_math.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lv_misc/lv_math.c b/src/lv_misc/lv_math.c index 9e8a91b80..b2c914f2b 100644 --- a/src/lv_misc/lv_math.c +++ b/src/lv_misc/lv_math.c @@ -241,10 +241,10 @@ int64_t _lv_pow(int64_t base, int8_t exp) */ LV_ATTRIBUTE_FAST_MEM int16_t _lv_map(int16_t x, int16_t min_in, int16_t max_in, int16_t min, int16_t max) { - uint32_t slope = ((uint32_t)(max - min) * 1000) / (uint32_t)(max_in - min_in); /** times 1000 to avoid rounding errors*/ - uint32_t bias = min - (slope * min_in) / 1000; + int32_t slope = ((int32_t)(max - min) * 10000) / (int32_t)(max_in - min_in); /** times 10000 to avoid rounding errors*/ + int32_t bias = (int32_t)(min * 10000) - slope * min_in; - return bias + (slope * x) / 1000; + return (bias + slope * x) / 10000; } /********************** From f75428e52b5b4af13b21967a93331a53557262b2 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Tue, 23 Jun 2020 23:06:56 -0700 Subject: [PATCH 063/173] Match rotary_bg line width to indicator width --- src/lv_themes/lv_theme_material.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_themes/lv_theme_material.c b/src/lv_themes/lv_theme_material.c index edb106c6f..7ba501949 100644 --- a/src/lv_themes/lv_theme_material.c +++ b/src/lv_themes/lv_theme_material.c @@ -805,7 +805,7 @@ static void rotary_init(void) lv_style_set_pad_inner(&styles->rotary_bg, LV_STATE_DEFAULT, LV_DPX(6)); lv_style_set_border_width(&styles->rotary_bg, LV_STATE_DEFAULT, LV_DPX(2)); lv_style_set_line_color(&styles->rotary_bg, LV_STATE_DEFAULT, COLOR_BG_SEC); - lv_style_set_line_width(&styles->rotary_bg, LV_STATE_DEFAULT, LV_DPX(2)); + lv_style_set_line_width(&styles->rotary_bg, LV_STATE_DEFAULT, LV_DPX(8)); lv_style_set_line_rounded(&styles->rotary_bg, LV_STATE_DEFAULT, true); style_init_reset(&styles->rotary_indic); From 92ecff3fc0a41ea236c6168a39561085302b15b4 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Thu, 25 Jun 2020 21:18:42 -0700 Subject: [PATCH 064/173] WIP: dragging on ring only using lv_atan --- src/lv_widgets/lv_rotary.c | 70 +++++++++++++++++++++++++------------- src/lv_widgets/lv_rotary.h | 2 +- 2 files changed, 48 insertions(+), 24 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 0dfd0ef73..0b188bc59 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -404,38 +404,63 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par if(sign == LV_SIGNAL_PRESSED) { lv_indev_get_point(param, &p); - ext->last_drag_x = p.x; + lv_indev_get_point(lv_indev_get_act(), &ext->last_press_point); + res = double_click_reset(cpicker); + if(res != LV_RES_OK) return res; ext->dragging = true; - } else if(sign == LV_SIGNAL_PRESSING) { - lv_indev_get_point(param, &p); - lv_coord_t drag_x_diff = p.x -ext->last_drag_x; + lv_indev_t * indev = lv_indev_get_act(); + if(indev == NULL) return res; - if (LV_MATH_ABS(drag_x_diff) > ext->threshold) { - if (drag_x_diff > 0) drag_x_diff = ext->threshold; - else drag_x_diff = -ext->threshold; + lv_indev_type_t indev_type = lv_indev_get_type(indev); + lv_point_t p; + if(indev_type == LV_INDEV_TYPE_ENCODER || indev_type == LV_INDEV_TYPE_KEYPAD) { + p.x = rotary->coords.x1 + lv_obj_get_width(rotary) / 2; + p.y = rotary->coords.y1 + lv_obj_get_height(rotary) / 2; } - ext->last_drag_x = p.x; - - if (ext->knob_area.y1 < p.y && p.y < ext->knob_area.y2) { - if (drag_x_diff > 0 && p.x < ext->knob_area.x2) { - lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON); - res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - else if (drag_x_diff < 0 && p.x > ext->knob_area.x1) { - ext->last_drag_x = p.x; - lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON); - res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } + else { + lv_indev_get_point(indev, &p); } + if((LV_MATH_ABS(p.x - ext->last_press_point.x) > indev->driver.drag_limit / 2) || + (LV_MATH_ABS(p.y - ext->last_press_point.y) > indev->driver.drag_limit / 2)) { + ext->last_change_time = lv_tick_get(); + ext->last_press_point.x = p.x; + ext->last_press_point.y = p.y; + } + + /*Make point 0 relative to the rotary*/ + p.x -= rotary->coords.x1; + p.y -= rotary->coords.y1; + + /*Ignore pressing in the inner area*/ + uint16_t w = lv_obj_get_width(rotary); + int16_t angle; + lv_coord_t r_in = lv_area_get_width(ext->knob_area) / 2; + + p.x -= r_in; + p.y -= r_in; + bool on_ring = true; + if(p.x * p.x + p.y * p.y < r_in * r_in) { + return res; /*Set the angle only if pressed on the ring*/ + } + angle = _lv_atan2(p.x, p.y) % 360; + + int16_t bg_end = ext->arc.bg_angle_end; + if (ext->arc.bg_angle_end < ext->arc.bg_angle_start) { + bg_end = ext->arc.bg_angle_end + 360; + if (angle < ext->arc.bg_angle_start) angle += 360; + } + + lv_rotary_set_value( + rotary, + _lv_map(angle, ext->arc.bg_angle_start, bg_end, + ext->min_value, ext->max_value) + ); } else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) { ext->dragging = false; - #if LV_USE_GROUP /*Leave edit mode if released. (No need to wait for LONG_PRESS) */ lv_group_t * g = lv_obj_get_group(rotary); @@ -445,7 +470,6 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par if(editing) lv_group_set_editing(g, false); } #endif - } else if(sign == LV_SIGNAL_CONTROL) { char c = *((char *)param); diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index 6a45f04ab..1a8972a2b 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -72,7 +72,7 @@ typedef struct { int16_t max_value; /*Maximum value of the rotary*/ int16_t sensitivity; /*Increment multiplier of the rotary*/ int16_t threshold; /*Increment threshold of the rotary*/ - lv_coord_t last_drag_x; /*Last drag x coordintate of the rotary*/ + lv_point_t last_press_point; /*Last drag x coordintate of the rotary*/ uint16_t dragging :1; } lv_rotary_ext_t; From 2d4c709a88ddef3c825779dbc5c5a14e645f8dbb Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Thu, 25 Jun 2020 21:22:37 -0700 Subject: [PATCH 065/173] Get area width using pointer --- src/lv_widgets/lv_rotary.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 0b188bc59..9fc0fa1f0 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -435,9 +435,8 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par p.y -= rotary->coords.y1; /*Ignore pressing in the inner area*/ - uint16_t w = lv_obj_get_width(rotary); int16_t angle; - lv_coord_t r_in = lv_area_get_width(ext->knob_area) / 2; + lv_coord_t r_in = lv_area_get_width(&ext->knob_area) / 2; p.x -= r_in; p.y -= r_in; @@ -456,7 +455,8 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par lv_rotary_set_value( rotary, _lv_map(angle, ext->arc.bg_angle_start, bg_end, - ext->min_value, ext->max_value) + ext->min_value, ext->max_value), + LV_ANIM_OFF ); } else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) { From 9e3d8c90908146534cd9f5758561b7b5eb3afb43 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Thu, 25 Jun 2020 21:23:14 -0700 Subject: [PATCH 066/173] Remove undeclared --- src/lv_widgets/lv_rotary.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 9fc0fa1f0..f55151304 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -405,7 +405,7 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par lv_indev_get_point(param, &p); lv_indev_get_point(lv_indev_get_act(), &ext->last_press_point); - res = double_click_reset(cpicker); + res = double_click_reset(rotary); if(res != LV_RES_OK) return res; ext->dragging = true; } From 70a22875684bd13e3e19180e862ab09b6c6594db Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Thu, 25 Jun 2020 21:24:19 -0700 Subject: [PATCH 067/173] Remove undeclared --- src/lv_widgets/lv_rotary.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index f55151304..02d28729d 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -425,7 +425,6 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par if((LV_MATH_ABS(p.x - ext->last_press_point.x) > indev->driver.drag_limit / 2) || (LV_MATH_ABS(p.y - ext->last_press_point.y) > indev->driver.drag_limit / 2)) { - ext->last_change_time = lv_tick_get(); ext->last_press_point.x = p.x; ext->last_press_point.y = p.y; } From a73b3166813a9b967d151ec805956a2196d11b76 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Thu, 25 Jun 2020 21:27:18 -0700 Subject: [PATCH 068/173] Remove undeclared --- src/lv_widgets/lv_rotary.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 02d28729d..3fcffdada 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -403,10 +403,7 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par if(sign == LV_SIGNAL_PRESSED) { lv_indev_get_point(param, &p); - lv_indev_get_point(lv_indev_get_act(), &ext->last_press_point); - res = double_click_reset(rotary); - if(res != LV_RES_OK) return res; ext->dragging = true; } else if(sign == LV_SIGNAL_PRESSING) { From 6d07effbc32e846aadb96238922929e46f1f9672 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Thu, 25 Jun 2020 21:39:19 -0700 Subject: [PATCH 069/173] Revert arc tracking --- src/lv_widgets/lv_rotary.c | 68 ++++++++++++++------------------------ src/lv_widgets/lv_rotary.h | 2 +- 2 files changed, 25 insertions(+), 45 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 3fcffdada..0dfd0ef73 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -403,60 +403,39 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par if(sign == LV_SIGNAL_PRESSED) { lv_indev_get_point(param, &p); - lv_indev_get_point(lv_indev_get_act(), &ext->last_press_point); + + ext->last_drag_x = p.x; ext->dragging = true; + } else if(sign == LV_SIGNAL_PRESSING) { - lv_indev_t * indev = lv_indev_get_act(); - if(indev == NULL) return res; + lv_indev_get_point(param, &p); + lv_coord_t drag_x_diff = p.x -ext->last_drag_x; - lv_indev_type_t indev_type = lv_indev_get_type(indev); - lv_point_t p; - if(indev_type == LV_INDEV_TYPE_ENCODER || indev_type == LV_INDEV_TYPE_KEYPAD) { - p.x = rotary->coords.x1 + lv_obj_get_width(rotary) / 2; - p.y = rotary->coords.y1 + lv_obj_get_height(rotary) / 2; + if (LV_MATH_ABS(drag_x_diff) > ext->threshold) { + if (drag_x_diff > 0) drag_x_diff = ext->threshold; + else drag_x_diff = -ext->threshold; } - else { - lv_indev_get_point(indev, &p); + ext->last_drag_x = p.x; + + if (ext->knob_area.y1 < p.y && p.y < ext->knob_area.y2) { + if (drag_x_diff > 0 && p.x < ext->knob_area.x2) { + lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON); + res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + else if (drag_x_diff < 0 && p.x > ext->knob_area.x1) { + ext->last_drag_x = p.x; + lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON); + res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } } - if((LV_MATH_ABS(p.x - ext->last_press_point.x) > indev->driver.drag_limit / 2) || - (LV_MATH_ABS(p.y - ext->last_press_point.y) > indev->driver.drag_limit / 2)) { - ext->last_press_point.x = p.x; - ext->last_press_point.y = p.y; - } - - /*Make point 0 relative to the rotary*/ - p.x -= rotary->coords.x1; - p.y -= rotary->coords.y1; - - /*Ignore pressing in the inner area*/ - int16_t angle; - lv_coord_t r_in = lv_area_get_width(&ext->knob_area) / 2; - - p.x -= r_in; - p.y -= r_in; - bool on_ring = true; - if(p.x * p.x + p.y * p.y < r_in * r_in) { - return res; /*Set the angle only if pressed on the ring*/ - } - angle = _lv_atan2(p.x, p.y) % 360; - - int16_t bg_end = ext->arc.bg_angle_end; - if (ext->arc.bg_angle_end < ext->arc.bg_angle_start) { - bg_end = ext->arc.bg_angle_end + 360; - if (angle < ext->arc.bg_angle_start) angle += 360; - } - - lv_rotary_set_value( - rotary, - _lv_map(angle, ext->arc.bg_angle_start, bg_end, - ext->min_value, ext->max_value), - LV_ANIM_OFF - ); } else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) { ext->dragging = false; + #if LV_USE_GROUP /*Leave edit mode if released. (No need to wait for LONG_PRESS) */ lv_group_t * g = lv_obj_get_group(rotary); @@ -466,6 +445,7 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par if(editing) lv_group_set_editing(g, false); } #endif + } else if(sign == LV_SIGNAL_CONTROL) { char c = *((char *)param); diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index 1a8972a2b..6a45f04ab 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -72,7 +72,7 @@ typedef struct { int16_t max_value; /*Maximum value of the rotary*/ int16_t sensitivity; /*Increment multiplier of the rotary*/ int16_t threshold; /*Increment threshold of the rotary*/ - lv_point_t last_press_point; /*Last drag x coordintate of the rotary*/ + lv_coord_t last_drag_x; /*Last drag x coordintate of the rotary*/ uint16_t dragging :1; } lv_rotary_ext_t; From f836e908697b72c64c769ed4b8e32db3f062ced5 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Thu, 25 Jun 2020 22:40:03 -0700 Subject: [PATCH 070/173] Account for indev drag limit --- src/lv_widgets/lv_rotary.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 0dfd0ef73..5c37a38f3 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -409,6 +409,9 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par } else if(sign == LV_SIGNAL_PRESSING) { + lv_indev_t * indev = lv_indev_get_act(); + if(indev == NULL) return res; + lv_indev_get_point(param, &p); lv_coord_t drag_x_diff = p.x -ext->last_drag_x; @@ -416,22 +419,23 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par if (drag_x_diff > 0) drag_x_diff = ext->threshold; else drag_x_diff = -ext->threshold; } - ext->last_drag_x = p.x; + if (LV_MATH_ABS(drag_x_diff) > indev->driver.drag_limit) { + ext->last_drag_x = p.x; - if (ext->knob_area.y1 < p.y && p.y < ext->knob_area.y2) { - if (drag_x_diff > 0 && p.x < ext->knob_area.x2) { - lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON); - res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - else if (drag_x_diff < 0 && p.x > ext->knob_area.x1) { - ext->last_drag_x = p.x; - lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON); - res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; + if (ext->knob_area.y1 < p.y && p.y < ext->knob_area.y2) { + if (drag_x_diff > 0 && p.x < ext->knob_area.x2) { + lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON); + res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + else if (drag_x_diff < 0 && p.x > ext->knob_area.x1) { + ext->last_drag_x = p.x; + lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON); + res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } } } - } else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) { ext->dragging = false; From 7ce9a969c8fb8ea626a297099084584d4cfbeb23 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Thu, 25 Jun 2020 22:43:54 -0700 Subject: [PATCH 071/173] Rever drag limit integration as it makes rotary control too granular --- src/lv_widgets/lv_rotary.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 5c37a38f3..233f5d134 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -409,9 +409,6 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par } else if(sign == LV_SIGNAL_PRESSING) { - lv_indev_t * indev = lv_indev_get_act(); - if(indev == NULL) return res; - lv_indev_get_point(param, &p); lv_coord_t drag_x_diff = p.x -ext->last_drag_x; @@ -419,21 +416,19 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par if (drag_x_diff > 0) drag_x_diff = ext->threshold; else drag_x_diff = -ext->threshold; } - if (LV_MATH_ABS(drag_x_diff) > indev->driver.drag_limit) { - ext->last_drag_x = p.x; + ext->last_drag_x = p.x; - if (ext->knob_area.y1 < p.y && p.y < ext->knob_area.y2) { - if (drag_x_diff > 0 && p.x < ext->knob_area.x2) { - lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON); - res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - else if (drag_x_diff < 0 && p.x > ext->knob_area.x1) { - ext->last_drag_x = p.x; - lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON); - res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } + if (ext->knob_area.y1 < p.y && p.y < ext->knob_area.y2) { + if (drag_x_diff > 0 && p.x < ext->knob_area.x2) { + lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON); + res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + else if (drag_x_diff < 0 && p.x > ext->knob_area.x1) { + ext->last_drag_x = p.x; + lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON); + res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; } } } From 8bcbceef08b28bae3bcda032551e7180d3a49aa3 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Thu, 25 Jun 2020 23:05:48 -0700 Subject: [PATCH 072/173] Send event on if the value really does change --- src/lv_widgets/lv_rotary.c | 35 ++++++++++++++++++++--------------- src/lv_widgets/lv_rotary.h | 3 ++- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 233f5d134..613b34708 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -166,18 +166,18 @@ void lv_rotary_set_type(lv_obj_t * rotary, lv_rotary_type_t type) * @param value new value * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately */ -void lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim) +bool lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim) { LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); lv_rotary_ext_t * ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); - if(ext->cur_value == value) return; + if(ext->cur_value == value) return false; int16_t new_value; new_value = value > ext->max_value ? ext->max_value : value; new_value = new_value < ext->min_value ? ext->min_value : new_value; - if(ext->cur_value == new_value) return; + if(ext->cur_value == new_value) return false; ext->cur_value = new_value; int16_t bg_midpoint, range_midpoint, bg_end = ext->arc.bg_angle_end; @@ -216,6 +216,7 @@ void lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim ext->arc.bg_angle_start, bg_end) ); } + return true; } /** @@ -420,15 +421,17 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par if (ext->knob_area.y1 < p.y && p.y < ext->knob_area.y2) { if (drag_x_diff > 0 && p.x < ext->knob_area.x2) { - lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON); - res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; + if (lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON)) { + res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } } else if (drag_x_diff < 0 && p.x > ext->knob_area.x1) { ext->last_drag_x = p.x; - lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON); - res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; + if (lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON)) { + res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } } } } @@ -450,14 +453,16 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par char c = *((char *)param); if(c == LV_KEY_RIGHT || c == LV_KEY_UP) { - lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + ext->sensitivity, LV_ANIM_ON); - res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; + if (lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + ext->sensitivity, LV_ANIM_ON)) { + res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } } else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) { - lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) - ext->sensitivity, LV_ANIM_ON); - res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; + if (lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) - ext->sensitivity, LV_ANIM_ON)) { + res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } } } else if(sign == LV_SIGNAL_CLEANUP) { diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index 6a45f04ab..83576c4e7 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -114,8 +114,9 @@ void lv_rotary_set_type(lv_obj_t * rotary, lv_rotary_type_t type); * @param rotary pointer to a rotary object * @param value new value * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately + * @return true if value changed, otw false */ -void lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim); +bool lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim); /** * Set minimum and the maximum values of a rotary From 4011d546684f09096e96d4d5022d569131d8764f Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Fri, 26 Jun 2020 08:40:30 -0700 Subject: [PATCH 073/173] Use the max x and y drag diff to control drag --- src/lv_widgets/lv_rotary.c | 26 ++++++++++++++------------ src/lv_widgets/lv_rotary.h | 2 +- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 613b34708..2cc8ac7f2 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -403,32 +403,34 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par lv_point_t p; if(sign == LV_SIGNAL_PRESSED) { - lv_indev_get_point(param, &p); - - ext->last_drag_x = p.x; + lv_indev_get_point(lv_indev_get_act(), &ext->last_press_point); ext->dragging = true; - } else if(sign == LV_SIGNAL_PRESSING) { lv_indev_get_point(param, &p); - lv_coord_t drag_x_diff = p.x -ext->last_drag_x; + lv_coord_t drag_diff; + lv_coord_t drag_x_diff = p.x -ext->last_press_point.x; + lv_coord_t drag_y_diff = p.y -ext->last_press_point.y; - if (LV_MATH_ABS(drag_x_diff) > ext->threshold) { - if (drag_x_diff > 0) drag_x_diff = ext->threshold; - else drag_x_diff = -ext->threshold; + if (LV_MATH_ABS(drag_x_diff) > LV_MATH_ABS(drag_y_diff)) drag_diff = drag_x_diff; + else drag_diff = drag_y_diff; + + if (LV_MATH_ABS(drag_diff) > ext->threshold) { + if (drag_diff > 0) drag_diff = ext->threshold; + else drag_diff = -ext->threshold; } ext->last_drag_x = p.x; if (ext->knob_area.y1 < p.y && p.y < ext->knob_area.y2) { - if (drag_x_diff > 0 && p.x < ext->knob_area.x2) { - if (lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON)) { + if (drag_diff > 0 && p.x < ext->knob_area.x2) { + if (lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_diff * ext->sensitivity, LV_ANIM_ON)) { res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; } } - else if (drag_x_diff < 0 && p.x > ext->knob_area.x1) { + else if (drag_diff < 0 && p.x > ext->knob_area.x1) { ext->last_drag_x = p.x; - if (lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_x_diff * ext->sensitivity, LV_ANIM_ON)) { + if (lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_diff * ext->sensitivity, LV_ANIM_ON)) { res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; } diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index 83576c4e7..426af0307 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -72,7 +72,7 @@ typedef struct { int16_t max_value; /*Maximum value of the rotary*/ int16_t sensitivity; /*Increment multiplier of the rotary*/ int16_t threshold; /*Increment threshold of the rotary*/ - lv_coord_t last_drag_x; /*Last drag x coordintate of the rotary*/ + lv_point_t last_press_point; /*Last drag point of the rotary*/ uint16_t dragging :1; } lv_rotary_ext_t; From 7de60867ef25baff809fda1c5afc772045be53a4 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Fri, 26 Jun 2020 08:45:41 -0700 Subject: [PATCH 074/173] Set last drag point based on diffs --- src/lv_widgets/lv_rotary.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 2cc8ac7f2..a06749cd0 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -412,15 +412,20 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par lv_coord_t drag_x_diff = p.x -ext->last_press_point.x; lv_coord_t drag_y_diff = p.y -ext->last_press_point.y; + if (LV_MATH_ABS(drag_x_diff) > ext->threshold) { + if (drag_x_diff > 0) drag_x_diff = ext->threshold; + else drag_x_diff = -ext->threshold; + } + if (LV_MATH_ABS(drag_y_diff) > ext->threshold) { + if (drag_y_diff > 0) drag_x_diff = ext->threshold; + else drag_y_diff = -ext->threshold; + } + ext->last_press_point.x = ext->last_press_point.x + drag_x_diff; + ext->last_press_point.y = ext->last_press_point.y + drag_y_diff; + if (LV_MATH_ABS(drag_x_diff) > LV_MATH_ABS(drag_y_diff)) drag_diff = drag_x_diff; else drag_diff = drag_y_diff; - if (LV_MATH_ABS(drag_diff) > ext->threshold) { - if (drag_diff > 0) drag_diff = ext->threshold; - else drag_diff = -ext->threshold; - } - ext->last_drag_x = p.x; - if (ext->knob_area.y1 < p.y && p.y < ext->knob_area.y2) { if (drag_diff > 0 && p.x < ext->knob_area.x2) { if (lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_diff * ext->sensitivity, LV_ANIM_ON)) { From ec4cc14bf97dd9f67b13dd78a17bebe45a355963 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Fri, 26 Jun 2020 08:46:56 -0700 Subject: [PATCH 075/173] Remove unsec x setter --- src/lv_widgets/lv_rotary.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index a06749cd0..53480ac39 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -434,7 +434,6 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par } } else if (drag_diff < 0 && p.x > ext->knob_area.x1) { - ext->last_drag_x = p.x; if (lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_diff * ext->sensitivity, LV_ANIM_ON)) { res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; From 849d3d32555f5a4c21e08374589097e89ed89b47 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Fri, 26 Jun 2020 08:48:12 -0700 Subject: [PATCH 076/173] Use point as last point --- src/lv_widgets/lv_rotary.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 53480ac39..33a932377 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -420,8 +420,7 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par if (drag_y_diff > 0) drag_x_diff = ext->threshold; else drag_y_diff = -ext->threshold; } - ext->last_press_point.x = ext->last_press_point.x + drag_x_diff; - ext->last_press_point.y = ext->last_press_point.y + drag_y_diff; + ext->last_press_point = p; if (LV_MATH_ABS(drag_x_diff) > LV_MATH_ABS(drag_y_diff)) drag_diff = drag_x_diff; else drag_diff = drag_y_diff; From c36f73131638f091860b5015d7e273f327bb7e00 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Fri, 26 Jun 2020 08:50:24 -0700 Subject: [PATCH 077/173] Only drag in one dimension because its too jumpy --- src/lv_widgets/lv_rotary.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 33a932377..149a41064 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -410,21 +410,14 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par lv_indev_get_point(param, &p); lv_coord_t drag_diff; lv_coord_t drag_x_diff = p.x -ext->last_press_point.x; - lv_coord_t drag_y_diff = p.y -ext->last_press_point.y; if (LV_MATH_ABS(drag_x_diff) > ext->threshold) { if (drag_x_diff > 0) drag_x_diff = ext->threshold; else drag_x_diff = -ext->threshold; } - if (LV_MATH_ABS(drag_y_diff) > ext->threshold) { - if (drag_y_diff > 0) drag_x_diff = ext->threshold; - else drag_y_diff = -ext->threshold; - } + drag_diff = drag_x_diff; ext->last_press_point = p; - if (LV_MATH_ABS(drag_x_diff) > LV_MATH_ABS(drag_y_diff)) drag_diff = drag_x_diff; - else drag_diff = drag_y_diff; - if (ext->knob_area.y1 < p.y && p.y < ext->knob_area.y2) { if (drag_diff > 0 && p.x < ext->knob_area.x2) { if (lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_diff * ext->sensitivity, LV_ANIM_ON)) { From 7e4b8aa49b5acb9f620684e79941dd1314116951 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Fri, 26 Jun 2020 09:46:55 -0700 Subject: [PATCH 078/173] Second attempt arc drag --- src/lv_widgets/lv_rotary.c | 100 +++++++++++++++++++++++++++++-------- 1 file changed, 79 insertions(+), 21 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 149a41064..61b5996c6 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -98,7 +98,7 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) if(copy == NULL) { lv_obj_set_click(rotary, true); lv_obj_add_protect(rotary, LV_PROTECT_PRESS_LOST); - lv_obj_set_ext_click_area(rotary, 0, 0, LV_DPI / 10, LV_DPI / 10); + lv_theme_apply(rotary, LV_THEME_ROTARY); } @@ -407,31 +407,88 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par ext->dragging = true; } else if(sign == LV_SIGNAL_PRESSING) { - lv_indev_get_point(param, &p); - lv_coord_t drag_diff; - lv_coord_t drag_x_diff = p.x -ext->last_press_point.x; + // lv_indev_get_point(param, &p); + // lv_coord_t drag_diff; + // lv_coord_t drag_x_diff = p.x -ext->last_press_point.x; + + // if (LV_MATH_ABS(drag_x_diff) > ext->threshold) { + // if (drag_x_diff > 0) drag_x_diff = ext->threshold; + // else drag_x_diff = -ext->threshold; + // } + // drag_diff = drag_x_diff; + // ext->last_press_point = p; + + // if (ext->knob_area.y1 < p.y && p.y < ext->knob_area.y2) { + // if (drag_diff > 0 && p.x < ext->knob_area.x2) { + // if (lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_diff * ext->sensitivity, LV_ANIM_ON)) { + // res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); + // if(res != LV_RES_OK) return res; + // } + // } + // else if (drag_diff < 0 && p.x > ext->knob_area.x1) { + // if (lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_diff * ext->sensitivity, LV_ANIM_ON)) { + // res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); + // if(res != LV_RES_OK) return res; + // } + // } + // } + + lv_indev_t * indev = lv_indev_get_act(); + if(indev == NULL) return res; + + lv_indev_type_t indev_type = lv_indev_get_type(indev); + lv_point_t p; + if(indev_type == LV_INDEV_TYPE_ENCODER || indev_type == LV_INDEV_TYPE_KEYPAD) { + p.x = rotary->coords.x1 + lv_obj_get_width(rotary) / 2; + p.y = rotary->coords.y1 + lv_obj_get_height(rotary) / 2; + } + else { + lv_indev_get_point(indev, &p); + } + + lv_coord_t drag_x_diff = p.x - ext->last_press_point.x; + lv_coord_t drag_y_diff = p.y - ext->last_press_point.y; if (LV_MATH_ABS(drag_x_diff) > ext->threshold) { - if (drag_x_diff > 0) drag_x_diff = ext->threshold; - else drag_x_diff = -ext->threshold; + if (drag_x_diff > 0) p.x = ext->last_press_point.x + ext->threshold; + else p.x = ext->last_press_point.x - ext->threshold; + } + if (LV_MATH_ABS(drag_y_diff) > ext->threshold) { + if (drag_y_diff > 0) p.y = ext->last_press_point.y + ext->threshold; + else p.y = ext->last_press_point.y - ext->threshold; } - drag_diff = drag_x_diff; - ext->last_press_point = p; - if (ext->knob_area.y1 < p.y && p.y < ext->knob_area.y2) { - if (drag_diff > 0 && p.x < ext->knob_area.x2) { - if (lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_diff * ext->sensitivity, LV_ANIM_ON)) { - res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - } - else if (drag_diff < 0 && p.x > ext->knob_area.x1) { - if (lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_diff * ext->sensitivity, LV_ANIM_ON)) { - res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - } + ext->last_press_point.x = p.x; + ext->last_press_point.y = p.y; + + /*Make point 0 relative to the rotary*/ + p.x -= rotary->coords.x1; + p.y -= rotary->coords.y1; + + /*Ignore pressing in the inner area*/ + int16_t angle; + lv_coord_t r_in = lv_area_get_width(&ext->knob_area) / 2; + + p.x -= r_in; + p.y -= r_in; + bool on_ring = true; + if(p.x * p.x + p.y * p.y < r_in * r_in) { + return res; /*Set the angle only if pressed on the ring*/ } + angle = _lv_atan2(p.x, p.y) % 360; + + int16_t bg_end = ext->arc.bg_angle_end; + if (ext->arc.bg_angle_end < ext->arc.bg_angle_start) { + bg_end = ext->arc.bg_angle_end + 360; + if (angle < ext->arc.bg_angle_start) angle += 360; + } + + lv_rotary_set_value( + rotary, + _lv_map(angle, ext->arc.bg_angle_start, bg_end, + ext->min_value, ext->max_value), + LV_ANIM_OFF + ); } else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) { ext->dragging = false; @@ -522,6 +579,7 @@ static void draw_knob(lv_obj_t * rotary, const lv_area_t * clip_area) lv_draw_rect(&knob_area, clip_area, &knob_rect_dsc); } + lv_obj_set_ext_click_area(rotary, knob_area.x1, knob_area.x2, knob_area.y1, knob_area.y2); lv_area_copy(&ext->knob_area, &knob_area); } From d271fd6108196e517cd91bef6f2e8c6892b691c9 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Fri, 26 Jun 2020 12:35:41 -0700 Subject: [PATCH 079/173] Adjust click area extension --- src/lv_widgets/lv_rotary.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 61b5996c6..bce1754fa 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -98,7 +98,7 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) if(copy == NULL) { lv_obj_set_click(rotary, true); lv_obj_add_protect(rotary, LV_PROTECT_PRESS_LOST); - + lv_obj_set_ext_click_area(rotary, LV_DPI / 10, LV_DPI / 10, LV_DPI / 10, LV_DPI / 10); lv_theme_apply(rotary, LV_THEME_ROTARY); } @@ -579,7 +579,6 @@ static void draw_knob(lv_obj_t * rotary, const lv_area_t * clip_area) lv_draw_rect(&knob_area, clip_area, &knob_rect_dsc); } - lv_obj_set_ext_click_area(rotary, knob_area.x1, knob_area.x2, knob_area.y1, knob_area.y2); lv_area_copy(&ext->knob_area, &knob_area); } From 200c1e788fc3d35370b4b7343e3ab6196cd8e004 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Fri, 26 Jun 2020 16:54:36 -0700 Subject: [PATCH 080/173] Second pass at angle based drag. Working with proper threshold setting with knowledge of rotary range. --- src/lv_widgets/lv_rotary.c | 56 ++++++++++++-------------------------- src/lv_widgets/lv_rotary.h | 7 +++-- 2 files changed, 21 insertions(+), 42 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index bce1754fa..f64ab63e7 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -85,7 +85,7 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) ext->min_value = 0; ext->max_value = 0; ext->sensitivity = 1; - ext->threshold = 1; + ext->threshold = 10; ext->dragging = false; ext->type = LV_ROTARY_TYPE_NORMAL; lv_style_list_init(&ext->style_knob); @@ -194,7 +194,9 @@ bool lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim _lv_map(ext->cur_value, ext->min_value, range_midpoint, ext->arc.bg_angle_start, bg_midpoint) ); + lv_arc_set_end_angle(rotary, bg_midpoint); } else { + lv_arc_set_start_angle(rotary, bg_midpoint); lv_arc_set_end_angle( rotary, _lv_map(ext->cur_value, range_midpoint, ext->max_value, @@ -407,32 +409,6 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par ext->dragging = true; } else if(sign == LV_SIGNAL_PRESSING) { - // lv_indev_get_point(param, &p); - // lv_coord_t drag_diff; - // lv_coord_t drag_x_diff = p.x -ext->last_press_point.x; - - // if (LV_MATH_ABS(drag_x_diff) > ext->threshold) { - // if (drag_x_diff > 0) drag_x_diff = ext->threshold; - // else drag_x_diff = -ext->threshold; - // } - // drag_diff = drag_x_diff; - // ext->last_press_point = p; - - // if (ext->knob_area.y1 < p.y && p.y < ext->knob_area.y2) { - // if (drag_diff > 0 && p.x < ext->knob_area.x2) { - // if (lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_diff * ext->sensitivity, LV_ANIM_ON)) { - // res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); - // if(res != LV_RES_OK) return res; - // } - // } - // else if (drag_diff < 0 && p.x > ext->knob_area.x1) { - // if (lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + drag_diff * ext->sensitivity, LV_ANIM_ON)) { - // res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); - // if(res != LV_RES_OK) return res; - // } - // } - // } - lv_indev_t * indev = lv_indev_get_act(); if(indev == NULL) return res; @@ -471,24 +447,26 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par p.x -= r_in; p.y -= r_in; - bool on_ring = true; if(p.x * p.x + p.y * p.y < r_in * r_in) { return res; /*Set the angle only if pressed on the ring*/ } - angle = _lv_atan2(p.x, p.y) % 360; - - int16_t bg_end = ext->arc.bg_angle_end; + + int16_t bg_midpoint, bg_zero, bg_end = ext->arc.bg_angle_end; if (ext->arc.bg_angle_end < ext->arc.bg_angle_start) { bg_end = ext->arc.bg_angle_end + 360; - if (angle < ext->arc.bg_angle_start) angle += 360; - } + } + bg_zero = (((ext->arc.bg_angle_start + bg_end) / 2) + 180) % 360; - lv_rotary_set_value( - rotary, - _lv_map(angle, ext->arc.bg_angle_start, bg_end, - ext->min_value, ext->max_value), - LV_ANIM_OFF - ); + angle = (_lv_atan2(p.x, p.y) + bg_zero) % 360; + if (bg_end > 360 && angle < ext->arc.bg_angle_start) angle += 360; + + int16_t new_value = _lv_map(angle, ext->arc.bg_angle_start, bg_end, ext->max_value, ext->min_value); + if (LV_MATH_ABS(ext->cur_value - new_value) < ext->threshold) { + if (lv_rotary_set_value(rotary, new_value, LV_ANIM_OFF)) { + res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + } } else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) { ext->dragging = false; diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index 426af0307..32c0c87b9 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -70,9 +70,10 @@ typedef struct { int16_t cur_value; /*Current value of the rotary*/ int16_t min_value; /*Minimum value of the rotary*/ int16_t max_value; /*Maximum value of the rotary*/ - int16_t sensitivity; /*Increment multiplier of the rotary*/ - int16_t threshold; /*Increment threshold of the rotary*/ - lv_point_t last_press_point; /*Last drag point of the rotary*/ + int16_t sensitivity; /*Control signal increment multiplier of the rotary*/ + int16_t threshold; /*Drag increment threshold of the rotary*/ + lv_point_t last_press_point; /*Last press point of the rotary*/ + uint16_t last_press_angle; /*Last press angle of the rotary*/ uint16_t dragging :1; } lv_rotary_ext_t; From 3af55796d9936910fd04f288205ef73267fe73ba Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Fri, 26 Jun 2020 19:39:10 -0700 Subject: [PATCH 081/173] Remove uneeded point manupulaton --- src/lv_widgets/lv_rotary.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index f64ab63e7..3b2d2241b 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -402,7 +402,6 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME); lv_rotary_ext_t * ext = lv_obj_get_ext_attr(rotary); - lv_point_t p; if(sign == LV_SIGNAL_PRESSED) { lv_indev_get_point(lv_indev_get_act(), &ext->last_press_point); @@ -422,18 +421,6 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par lv_indev_get_point(indev, &p); } - lv_coord_t drag_x_diff = p.x - ext->last_press_point.x; - lv_coord_t drag_y_diff = p.y - ext->last_press_point.y; - - if (LV_MATH_ABS(drag_x_diff) > ext->threshold) { - if (drag_x_diff > 0) p.x = ext->last_press_point.x + ext->threshold; - else p.x = ext->last_press_point.x - ext->threshold; - } - if (LV_MATH_ABS(drag_y_diff) > ext->threshold) { - if (drag_y_diff > 0) p.y = ext->last_press_point.y + ext->threshold; - else p.y = ext->last_press_point.y - ext->threshold; - } - ext->last_press_point.x = p.x; ext->last_press_point.y = p.y; @@ -451,7 +438,7 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par return res; /*Set the angle only if pressed on the ring*/ } - int16_t bg_midpoint, bg_zero, bg_end = ext->arc.bg_angle_end; + int16_t bg_zero, bg_end = ext->arc.bg_angle_end; if (ext->arc.bg_angle_end < ext->arc.bg_angle_start) { bg_end = ext->arc.bg_angle_end + 360; } From 3aa35a77cbdcb89529a1cb2dc4f51f18c8e99274 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sun, 28 Jun 2020 22:03:20 +0200 Subject: [PATCH 082/173] rotary: minor fixes on dragging --- src/lv_misc/lv_math.c | 26 +++++++++++----- src/lv_misc/lv_math.h | 9 +++--- src/lv_widgets/lv_rotary.c | 63 ++++++++++++++++++-------------------- src/lv_widgets/lv_rotary.h | 3 -- 4 files changed, 53 insertions(+), 48 deletions(-) diff --git a/src/lv_misc/lv_math.c b/src/lv_misc/lv_math.c index b2c914f2b..b0ecfaad7 100644 --- a/src/lv_misc/lv_math.c +++ b/src/lv_misc/lv_math.c @@ -232,19 +232,29 @@ int64_t _lv_pow(int64_t base, int8_t exp) } /** - * Get the mapped of a number given an imput and output range + * Get the mapped of a number given an input and output range * @param x integer which mapped value should be calculated * @param min_in min input range * @param max_in max input range - * @param in min output range - * @param out max output range + * @param min_out max output range + * @param max_out max output range + * @return the mapped number */ -LV_ATTRIBUTE_FAST_MEM int16_t _lv_map(int16_t x, int16_t min_in, int16_t max_in, int16_t min, int16_t max) +int16_t _lv_map(int32_t x, int32_t min_in, int32_t max_in, int32_t min_out, int32_t max_out) { - int32_t slope = ((int32_t)(max - min) * 10000) / (int32_t)(max_in - min_in); /** times 10000 to avoid rounding errors*/ - int32_t bias = (int32_t)(min * 10000) - slope * min_in; - - return (bias + slope * x) / 10000; + if(x <= min_in) return min_out; + if(x >= max_in) return max_out; + + /* The equation should be: + * ((x - min_in) / delta in) * delta_out + min_out + * To avoid rounding error reorder the operations: + * (((x - min_in) * delta_out) / delta in) + min_out + */ + + int32_t delta_in = max_in - min_in; + int32_t delta_out = max_out - min_out; + + return ((x - min_in) * delta_out) / delta_in + min_out; } /********************** diff --git a/src/lv_misc/lv_math.h b/src/lv_misc/lv_math.h index 0d72fb5af..d4d626ef9 100644 --- a/src/lv_misc/lv_math.h +++ b/src/lv_misc/lv_math.h @@ -113,14 +113,15 @@ LV_ATTRIBUTE_FAST_MEM void _lv_sqrt(uint32_t x, lv_sqrt_res_t * q, uint32_t mask int64_t _lv_pow(int64_t base, int8_t exp); /** - * Get the mapped of a number given an imput and output range + * Get the mapped of a number given an input and output range * @param x integer which mapped value should be calculated * @param min_in min input range * @param max_in max input range - * @param in min output range - * @param out max output range + * @param min_out max output range + * @param max_out max output range + * @return the mapped number */ -LV_ATTRIBUTE_FAST_MEM int16_t _lv_map(int16_t x, int16_t min_in, int16_t max_in, int16_t min, int16_t max); +int16_t _lv_map(int32_t x, int32_t min_in, int32_t max_in, int32_t min, int32_t max); /********************** * MACROS diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 3b2d2241b..e4c0e5c62 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -207,8 +207,8 @@ bool lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim case LV_ROTARY_TYPE_REVERSE: lv_arc_set_start_angle( rotary, - _lv_map(ext->cur_value, ext->max_value, ext->min_value, - bg_end, ext->arc.bg_angle_start) + _lv_map(ext->cur_value, ext->min_value, ext->max_value, + ext->arc.bg_angle_start, bg_end) ); break; default: /** LV_ROTARY_TYPE_NORMAL*/ @@ -403,51 +403,48 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par lv_rotary_ext_t * ext = lv_obj_get_ext_attr(rotary); - if(sign == LV_SIGNAL_PRESSED) { - lv_indev_get_point(lv_indev_get_act(), &ext->last_press_point); - ext->dragging = true; - } - else if(sign == LV_SIGNAL_PRESSING) { + if(sign == LV_SIGNAL_PRESSING) { lv_indev_t * indev = lv_indev_get_act(); if(indev == NULL) return res; + /*Handle only pointers here*/ lv_indev_type_t indev_type = lv_indev_get_type(indev); + if(indev_type != LV_INDEV_TYPE_POINTER) return res; + lv_point_t p; - if(indev_type == LV_INDEV_TYPE_ENCODER || indev_type == LV_INDEV_TYPE_KEYPAD) { - p.x = rotary->coords.x1 + lv_obj_get_width(rotary) / 2; - p.y = rotary->coords.y1 + lv_obj_get_height(rotary) / 2; - } - else { - lv_indev_get_point(indev, &p); + lv_indev_get_point(indev, &p); + + /*Make point relative to the rotary's center*/ + lv_coord_t w_half = lv_obj_get_width(rotary) / 2; + p.x -= rotary->coords.x1 + w_half; + p.y -= rotary->coords.y1 + w_half; + + /*Enter dragging mode if pressed out of the knob*/ + if(ext->dragging == false) { + lv_coord_t r_in = lv_area_get_width(&ext->knob_area) / 2; + + if(p.x * p.x + p.y * p.y > r_in * r_in) { + ext->dragging = true; + } } - ext->last_press_point.x = p.x; - ext->last_press_point.y = p.y; + /*It must be in "dragging" mode to turn the arc*/ + if(ext->dragging == false) return res; - /*Make point 0 relative to the rotary*/ - p.x -= rotary->coords.x1; - p.y -= rotary->coords.y1; - - /*Ignore pressing in the inner area*/ + /*Calculate the angle of the pressed point*/ int16_t angle; - lv_coord_t r_in = lv_area_get_width(&ext->knob_area) / 2; - - p.x -= r_in; - p.y -= r_in; - if(p.x * p.x + p.y * p.y < r_in * r_in) { - return res; /*Set the angle only if pressed on the ring*/ - } - - int16_t bg_zero, bg_end = ext->arc.bg_angle_end; + int16_t bg_end = ext->arc.bg_angle_end; if (ext->arc.bg_angle_end < ext->arc.bg_angle_start) { bg_end = ext->arc.bg_angle_end + 360; } - bg_zero = (((ext->arc.bg_angle_start + bg_end) / 2) + 180) % 360; - angle = (_lv_atan2(p.x, p.y) + bg_zero) % 360; - if (bg_end > 360 && angle < ext->arc.bg_angle_start) angle += 360; + angle = 360 - _lv_atan2(p.x, p.y) + 90; /*Some transformation is required*/ + if(angle < ext->arc.bg_angle_start) angle = ext->arc.bg_angle_start; + if(angle > bg_end) angle = bg_end; - int16_t new_value = _lv_map(angle, ext->arc.bg_angle_start, bg_end, ext->max_value, ext->min_value); + int16_t new_value = _lv_map(angle, ext->arc.bg_angle_start, bg_end, ext->min_value, ext->max_value); + + /*Set the new value if it's larger than the threshold*/ if (LV_MATH_ABS(ext->cur_value - new_value) < ext->threshold) { if (lv_rotary_set_value(rotary, new_value, LV_ANIM_OFF)) { res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index 32c0c87b9..a74c6a925 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -72,10 +72,7 @@ typedef struct { int16_t max_value; /*Maximum value of the rotary*/ int16_t sensitivity; /*Control signal increment multiplier of the rotary*/ int16_t threshold; /*Drag increment threshold of the rotary*/ - lv_point_t last_press_point; /*Last press point of the rotary*/ - uint16_t last_press_angle; /*Last press angle of the rotary*/ uint16_t dragging :1; - } lv_rotary_ext_t; /** Built-in styles of rotary*/ From e256a27b5a07c71839a42e30a0e67c82d0700f15 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sun, 5 Jul 2020 12:25:44 -0700 Subject: [PATCH 083/173] Add slew rate limited angle delta based on threshold of degress/sec --- src/lv_widgets/lv_rotary.c | 14 ++++++++++++++ src/lv_widgets/lv_rotary.h | 4 +++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index e4c0e5c62..a4cc31c35 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -442,6 +442,20 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par if(angle < ext->arc.bg_angle_start) angle = ext->arc.bg_angle_start; if(angle > bg_end) angle = bg_end; + /*Calculate the slew rate limited angle delta the threshold (degrees/sec)*/ + int16_t delta_angle = angle - ext->last_angle; + uint16_t delta_ts_milli = lv_tick_get() - ext->last_timestamp; + int16_t delta_angle_threshold = (ext->threshold * 1000) / delta_ts_milli; + + if (delta_angle > delta_angle_threshold) { + delta_angle = delta_angle_threshold; + } else if (delta_angle < -delta_angle_threshold) { + delta_angle = -delta_angle_threshold; + } + + angle = ext->last_angle + delta_angle; /*Apply the limited angle change*/ + ext->last_angle = angle; /*Cache angle for the next iteration*/ + int16_t new_value = _lv_map(angle, ext->arc.bg_angle_start, bg_end, ext->min_value, ext->max_value); /*Set the new value if it's larger than the threshold*/ diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index a74c6a925..e59e81b92 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -71,8 +71,10 @@ typedef struct { int16_t min_value; /*Minimum value of the rotary*/ int16_t max_value; /*Maximum value of the rotary*/ int16_t sensitivity; /*Control signal increment multiplier of the rotary*/ - int16_t threshold; /*Drag increment threshold of the rotary*/ uint16_t dragging :1; + uint16_t threshold; /*Drag angle rate of change threshold of the rotary (degrees/sec)*/ + int16_t last_timestamp; /*Last dragging event timestamp of the rotary*/ + int16_t last_angle; /*Last dragging angle of the rotary*/ } lv_rotary_ext_t; /** Built-in styles of rotary*/ From e3f4c1150097f0f5e8eb5996376bb1c91b7dc439 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sun, 5 Jul 2020 12:49:27 -0700 Subject: [PATCH 084/173] Remove previous thresholding and add creation defaults. Move angle caching to set value to cache last angel for type changes and external value setters. --- src/lv_widgets/lv_rotary.c | 57 +++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 32 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index a4cc31c35..969011722 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -81,13 +81,15 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) ext->arc.bg_angle_end = 45; ext->arc.arc_angle_start = 135; ext->arc.arc_angle_end = 270; + ext->type = LV_ROTARY_TYPE_NORMAL; ext->cur_value = 0; ext->min_value = 0; ext->max_value = 0; ext->sensitivity = 1; - ext->threshold = 10; ext->dragging = false; - ext->type = LV_ROTARY_TYPE_NORMAL; + ext->threshold = 360; + ext->last_timestamp = lv_tick_get(); + ext->last_angle = ext->arc.arc_angle_end; lv_style_list_init(&ext->style_knob); /*The signal and design functions are not copied so set them here*/ @@ -105,13 +107,15 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) /*Copy an existing rotary*/ else { lv_rotary_ext_t * copy_ext = lv_obj_get_ext_attr(copy); + ext->type = copy_ext->type; ext->cur_value = copy_ext->cur_value; ext->min_value = copy_ext->min_value; ext->max_value = copy_ext->max_value; ext->sensitivity = copy_ext->sensitivity; - ext->threshold = copy_ext->threshold; ext->dragging = copy_ext->dragging; - ext->type = copy_ext->type; + ext->threshold = copy_ext->threshold; + ext->last_timestamp = copy_ext->last_timestamp; + ext->last_angle = copy_ext->last_angle; lv_style_list_copy(&ext->style_knob, ©_ext->style_knob); lv_obj_refresh_style(rotary, LV_OBJ_PART_ALL); @@ -183,41 +187,32 @@ bool lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim int16_t bg_midpoint, range_midpoint, bg_end = ext->arc.bg_angle_end; if (ext->arc.bg_angle_end < ext->arc.bg_angle_start) bg_end = ext->arc.bg_angle_end + 360; + int16_t angle; switch(ext->type) { case LV_ROTARY_TYPE_SYMMETRIC: bg_midpoint = (ext->arc.bg_angle_start + bg_end) / 2; range_midpoint = (int32_t)(ext->min_value + ext->max_value) / 2; if (ext->cur_value < range_midpoint) { - lv_arc_set_start_angle( - rotary, - _lv_map(ext->cur_value, ext->min_value, range_midpoint, - ext->arc.bg_angle_start, bg_midpoint) - ); + angle = _lv_map(ext->cur_value, ext->min_value, range_midpoint, ext->arc.bg_angle_start, bg_midpoint); + lv_arc_set_start_angle(rotary, angle); lv_arc_set_end_angle(rotary, bg_midpoint); } else { + angle = _lv_map(ext->cur_value, range_midpoint, ext->max_value, bg_midpoint, bg_end); lv_arc_set_start_angle(rotary, bg_midpoint); - lv_arc_set_end_angle( - rotary, - _lv_map(ext->cur_value, range_midpoint, ext->max_value, - bg_midpoint, bg_end) - ); + lv_arc_set_end_angle(rotary, angle); } break; case LV_ROTARY_TYPE_REVERSE: - lv_arc_set_start_angle( - rotary, - _lv_map(ext->cur_value, ext->min_value, ext->max_value, - ext->arc.bg_angle_start, bg_end) - ); + angle = _lv_map(ext->cur_value, ext->min_value, ext->max_value, ext->arc.bg_angle_start, bg_end); + lv_arc_set_start_angle(rotary, angle); break; default: /** LV_ROTARY_TYPE_NORMAL*/ - lv_arc_set_end_angle( - rotary, - _lv_map(ext->cur_value, ext->min_value, ext->max_value, - ext->arc.bg_angle_start, bg_end) - ); + angle = _lv_map(ext->cur_value, ext->min_value, ext->max_value, ext->arc.bg_angle_start, bg_end); + lv_arc_set_end_angle(rotary, angle); } + ext->last_angle = angle; /*Cache angle slew rate limiting*/ + return true; } @@ -442,7 +437,7 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par if(angle < ext->arc.bg_angle_start) angle = ext->arc.bg_angle_start; if(angle > bg_end) angle = bg_end; - /*Calculate the slew rate limited angle delta the threshold (degrees/sec)*/ + /*Calculate the slew rate limited angle based on threshold (degrees/sec)*/ int16_t delta_angle = angle - ext->last_angle; uint16_t delta_ts_milli = lv_tick_get() - ext->last_timestamp; int16_t delta_angle_threshold = (ext->threshold * 1000) / delta_ts_milli; @@ -454,16 +449,14 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par } angle = ext->last_angle + delta_angle; /*Apply the limited angle change*/ - ext->last_angle = angle; /*Cache angle for the next iteration*/ + // ext->last_angle = angle; /*Cache angle for the next iteration*/ int16_t new_value = _lv_map(angle, ext->arc.bg_angle_start, bg_end, ext->min_value, ext->max_value); - /*Set the new value if it's larger than the threshold*/ - if (LV_MATH_ABS(ext->cur_value - new_value) < ext->threshold) { - if (lv_rotary_set_value(rotary, new_value, LV_ANIM_OFF)) { - res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } + /*Set the new value*/ + if (lv_rotary_set_value(rotary, new_value, LV_ANIM_OFF)) { + res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; } } else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) { From aea84d8d79a3616ea7d761cc22b0bf2d54fb193e Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sun, 5 Jul 2020 13:18:08 -0700 Subject: [PATCH 085/173] Cache timestamp for slew rate limit interation --- src/lv_widgets/lv_rotary.c | 4 ++-- src/lv_widgets/lv_rotary.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 969011722..83340c363 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -439,7 +439,7 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par /*Calculate the slew rate limited angle based on threshold (degrees/sec)*/ int16_t delta_angle = angle - ext->last_angle; - uint16_t delta_ts_milli = lv_tick_get() - ext->last_timestamp; + uint32_t delta_ts_milli = lv_tick_elaps(ext->last_timestamp); int16_t delta_angle_threshold = (ext->threshold * 1000) / delta_ts_milli; if (delta_angle > delta_angle_threshold) { @@ -449,7 +449,7 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par } angle = ext->last_angle + delta_angle; /*Apply the limited angle change*/ - // ext->last_angle = angle; /*Cache angle for the next iteration*/ + ext->last_timestamp = lv_tick_get(); /*Cache timestamp for the next iteration*/ int16_t new_value = _lv_map(angle, ext->arc.bg_angle_start, bg_end, ext->min_value, ext->max_value); diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index e59e81b92..ad72a4a4c 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -73,7 +73,7 @@ typedef struct { int16_t sensitivity; /*Control signal increment multiplier of the rotary*/ uint16_t dragging :1; uint16_t threshold; /*Drag angle rate of change threshold of the rotary (degrees/sec)*/ - int16_t last_timestamp; /*Last dragging event timestamp of the rotary*/ + int32_t last_timestamp; /*Last dragging event timestamp of the rotary*/ int16_t last_angle; /*Last dragging angle of the rotary*/ } lv_rotary_ext_t; From 7a10b700e2acd8e597aa6ef3fed5de849938c942 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sun, 5 Jul 2020 13:21:54 -0700 Subject: [PATCH 086/173] Remove use of tick_elaspe --- src/lv_widgets/lv_rotary.c | 10 +++++----- src/lv_widgets/lv_rotary.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 83340c363..4fa4c8885 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -88,7 +88,7 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) ext->sensitivity = 1; ext->dragging = false; ext->threshold = 360; - ext->last_timestamp = lv_tick_get(); + ext->last_tick = lv_tick_get(); ext->last_angle = ext->arc.arc_angle_end; lv_style_list_init(&ext->style_knob); @@ -114,7 +114,7 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) ext->sensitivity = copy_ext->sensitivity; ext->dragging = copy_ext->dragging; ext->threshold = copy_ext->threshold; - ext->last_timestamp = copy_ext->last_timestamp; + ext->last_tick = copy_ext->last_tick; ext->last_angle = copy_ext->last_angle; lv_style_list_copy(&ext->style_knob, ©_ext->style_knob); @@ -439,8 +439,8 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par /*Calculate the slew rate limited angle based on threshold (degrees/sec)*/ int16_t delta_angle = angle - ext->last_angle; - uint32_t delta_ts_milli = lv_tick_elaps(ext->last_timestamp); - int16_t delta_angle_threshold = (ext->threshold * 1000) / delta_ts_milli; + uint32_t delta_tick = lv_get_tick() - ext->last_tick; + int16_t delta_angle_threshold = (ext->threshold * 1000) / delta_tick; if (delta_angle > delta_angle_threshold) { delta_angle = delta_angle_threshold; @@ -449,7 +449,7 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par } angle = ext->last_angle + delta_angle; /*Apply the limited angle change*/ - ext->last_timestamp = lv_tick_get(); /*Cache timestamp for the next iteration*/ + ext->last_tick = lv_tick_get(); /*Cache timestamp for the next iteration*/ int16_t new_value = _lv_map(angle, ext->arc.bg_angle_start, bg_end, ext->min_value, ext->max_value); diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index ad72a4a4c..104b4d77d 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -73,7 +73,7 @@ typedef struct { int16_t sensitivity; /*Control signal increment multiplier of the rotary*/ uint16_t dragging :1; uint16_t threshold; /*Drag angle rate of change threshold of the rotary (degrees/sec)*/ - int32_t last_timestamp; /*Last dragging event timestamp of the rotary*/ + int32_t last_tick; /*Last dragging event timestamp of the rotary*/ int16_t last_angle; /*Last dragging angle of the rotary*/ } lv_rotary_ext_t; From a0bf57f5295418184ce9531f07cd1e0365b1891c Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sun, 5 Jul 2020 13:22:37 -0700 Subject: [PATCH 087/173] tick type --- src/lv_widgets/lv_rotary.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 4fa4c8885..2550eef20 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -439,7 +439,7 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par /*Calculate the slew rate limited angle based on threshold (degrees/sec)*/ int16_t delta_angle = angle - ext->last_angle; - uint32_t delta_tick = lv_get_tick() - ext->last_tick; + uint32_t delta_tick = lv_tick_get() - ext->last_tick; int16_t delta_angle_threshold = (ext->threshold * 1000) / delta_tick; if (delta_angle > delta_angle_threshold) { From cf39677dfa223815200e575fd637294d0092c6b9 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sun, 5 Jul 2020 13:30:07 -0700 Subject: [PATCH 088/173] Use tick elps --- src/lv_widgets/lv_rotary.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 2550eef20..34e8c16c7 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -439,7 +439,7 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par /*Calculate the slew rate limited angle based on threshold (degrees/sec)*/ int16_t delta_angle = angle - ext->last_angle; - uint32_t delta_tick = lv_tick_get() - ext->last_tick; + uint32_t delta_tick = lv_tick_elaps(ext->last_tick); int16_t delta_angle_threshold = (ext->threshold * 1000) / delta_tick; if (delta_angle > delta_angle_threshold) { From b371bd3d05191bdd640833b8b91a990ab1e3f75f Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sun, 5 Jul 2020 13:50:05 -0700 Subject: [PATCH 089/173] Capture tick at drap start --- src/lv_widgets/lv_rotary.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 34e8c16c7..84e9bad34 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -420,6 +420,7 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par if(p.x * p.x + p.y * p.y > r_in * r_in) { ext->dragging = true; + ext->last_tick = lv_tick_get(); /*Capture timestamp at dragging start*/ } } @@ -451,9 +452,8 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par angle = ext->last_angle + delta_angle; /*Apply the limited angle change*/ ext->last_tick = lv_tick_get(); /*Cache timestamp for the next iteration*/ - int16_t new_value = _lv_map(angle, ext->arc.bg_angle_start, bg_end, ext->min_value, ext->max_value); - /*Set the new value*/ + int16_t new_value = _lv_map(angle, ext->arc.bg_angle_start, bg_end, ext->min_value, ext->max_value); if (lv_rotary_set_value(rotary, new_value, LV_ANIM_OFF)) { res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; From 085a6499a71955a3d89002ff14cae4893dcc254e Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sun, 5 Jul 2020 13:59:03 -0700 Subject: [PATCH 090/173] Comment updates for clarity --- src/lv_widgets/lv_rotary.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 84e9bad34..28001e53b 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -211,7 +211,7 @@ bool lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim angle = _lv_map(ext->cur_value, ext->min_value, ext->max_value, ext->arc.bg_angle_start, bg_end); lv_arc_set_end_angle(rotary, angle); } - ext->last_angle = angle; /*Cache angle slew rate limiting*/ + ext->last_angle = angle; /*Cache angle for slew rate limiting*/ return true; } @@ -454,7 +454,7 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par /*Set the new value*/ int16_t new_value = _lv_map(angle, ext->arc.bg_angle_start, bg_end, ext->min_value, ext->max_value); - if (lv_rotary_set_value(rotary, new_value, LV_ANIM_OFF)) { + if (lv_rotary_set_value(rotary, new_value, LV_ANIM_OFF)) { /*set_value caches the last_angle for the next interation*/ res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; } From 83bdb6c34777c680fbd9735d333e4578e2459d84 Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sun, 5 Jul 2020 14:44:11 -0700 Subject: [PATCH 091/173] Reverse angle delta logic --- src/lv_widgets/lv_rotary.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 28001e53b..f28e4efd8 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -441,7 +441,7 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par /*Calculate the slew rate limited angle based on threshold (degrees/sec)*/ int16_t delta_angle = angle - ext->last_angle; uint32_t delta_tick = lv_tick_elaps(ext->last_tick); - int16_t delta_angle_threshold = (ext->threshold * 1000) / delta_tick; + int16_t delta_angle_threshold = (ext->threshold * delta_tick) / 1000; if (delta_angle > delta_angle_threshold) { delta_angle = delta_angle_threshold; From 96728e7ed92ffe12fc8a22c5fdbf773213d9277a Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 6 Jul 2020 11:51:26 +0200 Subject: [PATCH 092/173] rotary: minor refactoring --- src/lv_widgets/lv_rotary.c | 26 +++++++++++++------------- src/lv_widgets/lv_rotary.h | 4 ++-- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index f28e4efd8..fdea7f606 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -82,12 +82,12 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) ext->arc.arc_angle_start = 135; ext->arc.arc_angle_end = 270; ext->type = LV_ROTARY_TYPE_NORMAL; - ext->cur_value = 0; + ext->cur_value = -1; ext->min_value = 0; - ext->max_value = 0; + ext->max_value = 100; ext->sensitivity = 1; ext->dragging = false; - ext->threshold = 360; + ext->chg_rate = 360; ext->last_tick = lv_tick_get(); ext->last_angle = ext->arc.arc_angle_end; lv_style_list_init(&ext->style_knob); @@ -101,7 +101,7 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) lv_obj_set_click(rotary, true); lv_obj_add_protect(rotary, LV_PROTECT_PRESS_LOST); lv_obj_set_ext_click_area(rotary, LV_DPI / 10, LV_DPI / 10, LV_DPI / 10, LV_DPI / 10); - + lv_rotary_set_value(rotary, ext->min_value, LV_ANIM_OFF); lv_theme_apply(rotary, LV_THEME_ROTARY); } /*Copy an existing rotary*/ @@ -113,7 +113,7 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) ext->max_value = copy_ext->max_value; ext->sensitivity = copy_ext->sensitivity; ext->dragging = copy_ext->dragging; - ext->threshold = copy_ext->threshold; + ext->chg_rate = copy_ext->chg_rate; ext->last_tick = copy_ext->last_tick; ext->last_angle = copy_ext->last_angle; lv_style_list_copy(&ext->style_knob, ©_ext->style_knob); @@ -262,12 +262,12 @@ void lv_rotary_set_sensitivity(lv_obj_t * rotary, uint16_t sensitivity) * @param rotary pointer to a rotary object * @param threshold increment threshold */ -void lv_rotary_set_threshold(lv_obj_t * rotary, uint16_t threshold) +void lv_rotary_set_chg_rate(lv_obj_t * rotary, uint16_t rate) { LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); lv_rotary_ext_t *ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); - ext->threshold = threshold; + ext->chg_rate = rate; } /*===================== @@ -438,15 +438,15 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par if(angle < ext->arc.bg_angle_start) angle = ext->arc.bg_angle_start; if(angle > bg_end) angle = bg_end; - /*Calculate the slew rate limited angle based on threshold (degrees/sec)*/ + /*Calculate the slew rate limited angle based on change rate (degrees/sec)*/ int16_t delta_angle = angle - ext->last_angle; uint32_t delta_tick = lv_tick_elaps(ext->last_tick); - int16_t delta_angle_threshold = (ext->threshold * delta_tick) / 1000; + int16_t delta_angle_max = (ext->chg_rate * delta_tick) / 1000; - if (delta_angle > delta_angle_threshold) { - delta_angle = delta_angle_threshold; - } else if (delta_angle < -delta_angle_threshold) { - delta_angle = -delta_angle_threshold; + if (delta_angle > delta_angle_max) { + delta_angle = delta_angle_max; + } else if (delta_angle < -delta_angle_max) { + delta_angle = -delta_angle_max; } angle = ext->last_angle + delta_angle; /*Apply the limited angle change*/ diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index 104b4d77d..81c9bc488 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -72,7 +72,7 @@ typedef struct { int16_t max_value; /*Maximum value of the rotary*/ int16_t sensitivity; /*Control signal increment multiplier of the rotary*/ uint16_t dragging :1; - uint16_t threshold; /*Drag angle rate of change threshold of the rotary (degrees/sec)*/ + uint16_t chg_rate; /*Drag angle rate of change of the rotary (degrees/sec)*/ int32_t last_tick; /*Last dragging event timestamp of the rotary*/ int16_t last_angle; /*Last dragging angle of the rotary*/ } lv_rotary_ext_t; @@ -148,7 +148,7 @@ void lv_rotary_set_sensitivity(lv_obj_t * rotary, uint16_t sensitivity); * @param rotary pointer to a rotary object * @param threshold increment threshold */ -void lv_rotary_set_threshold(lv_obj_t * rotary, uint16_t threshold); +void lv_rotary_set_chg_rate(lv_obj_t * rotary, uint16_t threshold); /** * Set the start angle of rotary indicator. 0 deg: right, 90 bottom, etc. From cae5132038d68e7407ade195cb90dbbc0e91cb6c Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 7 Jul 2020 12:35:23 +0200 Subject: [PATCH 093/173] rotary: fix with low chg_rate --- src/lv_widgets/lv_rotary.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index fdea7f606..92ac3172b 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -87,7 +87,7 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) ext->max_value = 100; ext->sensitivity = 1; ext->dragging = false; - ext->chg_rate = 360; + ext->chg_rate = 540; ext->last_tick = lv_tick_get(); ext->last_angle = ext->arc.arc_angle_end; lv_style_list_init(&ext->style_knob); @@ -101,7 +101,7 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) lv_obj_set_click(rotary, true); lv_obj_add_protect(rotary, LV_PROTECT_PRESS_LOST); lv_obj_set_ext_click_area(rotary, LV_DPI / 10, LV_DPI / 10, LV_DPI / 10, LV_DPI / 10); - lv_rotary_set_value(rotary, ext->min_value, LV_ANIM_OFF); + lv_rotary_set_value(rotary, 50, LV_ANIM_OFF); lv_theme_apply(rotary, LV_THEME_ROTARY); } /*Copy an existing rotary*/ @@ -450,13 +450,25 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par } angle = ext->last_angle + delta_angle; /*Apply the limited angle change*/ - ext->last_tick = lv_tick_get(); /*Cache timestamp for the next iteration*/ + + /*Rounding for symmetry*/ + int32_t round = ((bg_end - ext->arc.bg_angle_start) * 8) / (ext->max_value - ext->min_value); + round = (round + 4) >> 4; + angle += round; /*Set the new value*/ int16_t new_value = _lv_map(angle, ext->arc.bg_angle_start, bg_end, ext->min_value, ext->max_value); - if (lv_rotary_set_value(rotary, new_value, LV_ANIM_OFF)) { /*set_value caches the last_angle for the next interation*/ - res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; + if(new_value != lv_rotary_get_value(rotary)) { + ext->last_tick = lv_tick_get(); /*Cache timestamp for the next iteration*/ + if (lv_rotary_set_value(rotary, new_value, LV_ANIM_OFF)) { /*set_value caches the last_angle for the next interation*/ + res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + } + + /*Don1't let the elapsed time to big while sitting on an end point*/ + if(new_value == ext->min_value || new_value == ext->max_value) { + ext->last_tick = lv_tick_get(); /*Cache timestamp for the next iteration*/ } } else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) { From b0e3f11da13ffb3e705fbc8c911cc3c4e00ddc62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sven=20Krau=C3=9F?= Date: Tue, 28 Jul 2020 17:08:21 +0200 Subject: [PATCH 094/173] Make lv_draw_line_dsc_t parameters constant --- src/lv_draw/lv_draw_line.c | 14 +++++++------- src/lv_draw/lv_draw_line.h | 2 +- src/lv_widgets/lv_canvas.c | 2 +- src/lv_widgets/lv_canvas.h | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/lv_draw/lv_draw_line.c b/src/lv_draw/lv_draw_line.c index 2a22ec509..0c84b2c49 100644 --- a/src/lv_draw/lv_draw_line.c +++ b/src/lv_draw/lv_draw_line.c @@ -26,13 +26,13 @@ **********************/ LV_ATTRIBUTE_FAST_MEM static void draw_line_skew(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, - lv_draw_line_dsc_t * dsc); + const lv_draw_line_dsc_t * dsc); LV_ATTRIBUTE_FAST_MEM static void draw_line_hor(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, - lv_draw_line_dsc_t * dsc); + const lv_draw_line_dsc_t * dsc); LV_ATTRIBUTE_FAST_MEM static void draw_line_ver(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, - lv_draw_line_dsc_t * dsc); + const lv_draw_line_dsc_t * dsc); /********************** * STATIC VARIABLES @@ -63,7 +63,7 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_line_dsc_init(lv_draw_line_dsc_t * dsc) * @param opa_scale scale down all opacities by the factor */ LV_ATTRIBUTE_FAST_MEM void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, - lv_draw_line_dsc_t * dsc) + const lv_draw_line_dsc_t * dsc) { if(dsc->width == 0) return; if(dsc->opa <= LV_OPA_MIN) return; @@ -120,7 +120,7 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_line(const lv_point_t * point1, const lv_poin LV_ATTRIBUTE_FAST_MEM static void draw_line_hor(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, - lv_draw_line_dsc_t * dsc) + const lv_draw_line_dsc_t * dsc) { lv_opa_t opa = dsc->opa; @@ -221,7 +221,7 @@ LV_ATTRIBUTE_FAST_MEM static void draw_line_hor(const lv_point_t * point1, const LV_ATTRIBUTE_FAST_MEM static void draw_line_ver(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, - lv_draw_line_dsc_t * dsc) + const lv_draw_line_dsc_t * dsc) { lv_opa_t opa = dsc->opa; @@ -316,7 +316,7 @@ LV_ATTRIBUTE_FAST_MEM static void draw_line_ver(const lv_point_t * point1, const LV_ATTRIBUTE_FAST_MEM static void draw_line_skew(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, - lv_draw_line_dsc_t * dsc) + const lv_draw_line_dsc_t * dsc) { /*Keep the great y in p1*/ lv_point_t p1; diff --git a/src/lv_draw/lv_draw_line.h b/src/lv_draw/lv_draw_line.h index abc2e9819..83abe6818 100644 --- a/src/lv_draw/lv_draw_line.h +++ b/src/lv_draw/lv_draw_line.h @@ -48,7 +48,7 @@ typedef struct { * @param opa_scale scale down all opacities by the factor */ LV_ATTRIBUTE_FAST_MEM void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * mask, - lv_draw_line_dsc_t * dsc); + const lv_draw_line_dsc_t * dsc); LV_ATTRIBUTE_FAST_MEM void lv_draw_line_dsc_init(lv_draw_line_dsc_t * dsc); diff --git a/src/lv_widgets/lv_canvas.c b/src/lv_widgets/lv_canvas.c index 70571b903..d16d40a22 100644 --- a/src/lv_widgets/lv_canvas.c +++ b/src/lv_widgets/lv_canvas.c @@ -909,7 +909,7 @@ void lv_canvas_draw_img(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, const voi * @param style style of the line (`line` properties are used) */ void lv_canvas_draw_line(lv_obj_t * canvas, const lv_point_t points[], uint32_t point_cnt, - lv_draw_line_dsc_t * line_draw_dsc) + const lv_draw_line_dsc_t * line_draw_dsc) { LV_ASSERT_OBJ(canvas, LV_OBJX_NAME); diff --git a/src/lv_widgets/lv_canvas.h b/src/lv_widgets/lv_canvas.h index ce4cca2f7..14958c1d8 100644 --- a/src/lv_widgets/lv_canvas.h +++ b/src/lv_widgets/lv_canvas.h @@ -215,7 +215,7 @@ void lv_canvas_draw_img(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, const voi * @param style style of the line (`line` properties are used) */ void lv_canvas_draw_line(lv_obj_t * canvas, const lv_point_t points[], uint32_t point_cnt, - lv_draw_line_dsc_t * line_draw_dsc); + const lv_draw_line_dsc_t * line_draw_dsc); /** * Draw a polygon on the canvas From 41fd83e1d326da37210fc8bdbdc851e79c1683eb Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sun, 2 Aug 2020 10:14:29 +0200 Subject: [PATCH 095/173] implement caching on style lists --- src/lv_core/lv_obj.c | 168 +++++++++++++++++++++++++++++++++++++---- src/lv_core/lv_obj.h | 14 ++++ src/lv_core/lv_style.c | 3 + src/lv_core/lv_style.h | 31 ++++++-- 4 files changed, 197 insertions(+), 19 deletions(-) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 8eedc3da0..ec443efd3 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -1300,6 +1300,8 @@ void lv_obj_refresh_style(lv_obj_t * obj, lv_style_property_t prop) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + _lv_obj_invalidate_style_cache(obj); + /*If a real style refresh is required*/ bool real_refr = false; switch(prop) { @@ -1387,6 +1389,64 @@ void lv_obj_report_style_mod(lv_style_t * style) } } + +/** + * Update the cache of style list + * @param obj pointer to an obejct + * @param part the part of the object + */ +void _lv_obj_update_style_cache(lv_obj_t * obj, uint8_t part) +{ + lv_style_list_t * list = lv_obj_get_style_list(obj, part); + if(list->valid_cache) return; + + bool ignore_cache_ori = list->ignore_cache; + list->ignore_cache = 1; + list->bg_grad_dir_none = lv_obj_get_style_bg_grad_dir(obj, part) == LV_GRAD_DIR_NONE ? 1 : 0; + list->bg_opa_transp = lv_obj_get_style_bg_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; + list->border_width_zero = lv_obj_get_style_border_width(obj, part) == LV_OPA_TRANSP ? 1 : 0; + list->clip_corner_off = lv_obj_get_style_clip_corner(obj, part) == false ? 1 : 0; + list->img_recolor_opa_transp = lv_obj_get_style_image_recolor_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; + list->line_width_zerop = lv_obj_get_style_line_width(obj, part) == 0 ? 1 : 0; + list->opa_scale_transp = lv_obj_get_style_opa_scale(obj, part) == LV_OPA_TRANSP ? 1 : 0; + list->outline_width_zero = lv_obj_get_style_outline_width(obj, part) == 0 ? 1 : 0; + list->pattern_img_null = lv_obj_get_style_pattern_image(obj, part) == NULL ? 1 : 0; + list->shadow_width_zero = lv_obj_get_style_shadow_width(obj, part) == 0 ? 1 : 0; + list->text_decor_none = lv_obj_get_style_text_decor(obj, part) == LV_TEXT_DECOR_NONE ? 1 : 0; + list->text_letter_space_zero = lv_obj_get_style_text_letter_space(obj, part) == 0 ? 1 : 0; + list->text_line_space_zero = lv_obj_get_style_text_line_space(obj, part) == 0 ? 1 : 0; + list->transform_angle_zero = lv_obj_get_style_transform_angle(obj, part) == 0 ? 1 : 0; + list->transform_height_zero = lv_obj_get_style_transform_width(obj, part) == 0 ? 1 : 0; + list->transform_width_zero = lv_obj_get_style_transform_height(obj, part) == 0 ? 1 : 0; + list->transform_zoom_zero = lv_obj_get_style_transform_zoom(obj, part) == LV_IMG_ZOOM_NONE ? 1 : 0; + list->value_txt_str = lv_obj_get_style_value_str(obj, part) == NULL ? 1 : 0; + + list->ignore_cache = ignore_cache_ori; + list->valid_cache = 1; +} + +/** + * Mark the object and all of it's children's style lists as invalid. + * The cache will be updated when a cached property asked nest time + * @param obj pointer to an object + */ +void _lv_obj_invalidate_style_cache(lv_obj_t * obj) +{ + uint8_t part; + for(part = 0; part != _LV_OBJ_PART_REAL_LAST; part++) { + lv_style_list_t * list = lv_obj_get_style_list(obj, part); + if(list == NULL) break; + list->valid_cache = 0; + + } + + lv_obj_t * child = lv_obj_get_child(obj, NULL); + while(child) { + _lv_obj_invalidate_style_cache(child); + child = lv_obj_get_child(obj, child); + } +} + /*----------------- * Attribute set *----------------*/ @@ -2448,12 +2508,58 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl lv_res_t res = LV_RES_INV; const lv_obj_t * parent = obj; while(parent) { - lv_style_list_t * dsc = lv_obj_get_style_list(parent, part); + lv_style_list_t * list = lv_obj_get_style_list(parent, part); + + if(!list->ignore_cache) { + _lv_obj_update_style_cache((lv_obj_t*)parent, part); + bool def = false; + switch(prop & (~LV_STYLE_STATE_MASK)) { + case LV_STYLE_BG_GRAD_DIR: + if(list->bg_grad_dir_none) def = true; + break; + case LV_STYLE_CLIP_CORNER: + if(list->clip_corner_off) def = true; + break; + case LV_STYLE_TEXT_LETTER_SPACE: + if(list->text_letter_space_zero) def = true; + break; + case LV_STYLE_TEXT_LINE_SPACE: + if(list->text_line_space_zero) def = true; + break; + case LV_STYLE_TRANSFORM_ANGLE: + if(list->transform_angle_zero) def = true; + break; + case LV_STYLE_TRANSFORM_WIDTH: + if(list->transform_width_zero) def = true; + break; + case LV_STYLE_TRANSFORM_HEIGHT: + if(list->transform_height_zero) def = true; + break; + case LV_STYLE_TRANSFORM_ZOOM: + if(list->transform_zoom_zero) def = true; + break; + case LV_STYLE_BORDER_WIDTH: + if(list->border_width_zero) def = true; + break; + case LV_STYLE_LINE_WIDTH: + if(list->line_width_zerop) def = true; + break; + case LV_STYLE_OUTLINE_WIDTH: + if(list->outline_width_zero) def = true; + break; + case LV_STYLE_SHADOW_WIDTH: + if(list->shadow_width_zero) def = true; + break; + } + + if(def) break; + } + lv_state_t state = lv_obj_get_state(parent, part); prop = (uint16_t)prop_ori + ((uint16_t)state << LV_STYLE_STATE_POS); - res = _lv_style_list_get_int(dsc, prop, &value_act); + res = _lv_style_list_get_int(list, prop, &value_act); if(res == LV_RES_OK) return value_act; if(LV_STYLE_ATTR_GET_INHERIT(attr) == 0) break; @@ -2511,12 +2617,12 @@ lv_color_t _lv_obj_get_style_color(const lv_obj_t * obj, uint8_t part, lv_style_ lv_res_t res = LV_RES_INV; const lv_obj_t * parent = obj; while(parent) { - lv_style_list_t * dsc = lv_obj_get_style_list(parent, part); + lv_style_list_t * list = lv_obj_get_style_list(parent, part); lv_state_t state = lv_obj_get_state(parent, part); prop = (uint16_t)prop_ori + ((uint16_t)state << LV_STYLE_STATE_POS); - res = _lv_style_list_get_color(dsc, prop, &value_act); + res = _lv_style_list_get_color(list, prop, &value_act); if(res == LV_RES_OK) return value_act; if(LV_STYLE_ATTR_GET_INHERIT(attr) == 0) break; @@ -2567,12 +2673,31 @@ lv_opa_t _lv_obj_get_style_opa(const lv_obj_t * obj, uint8_t part, lv_style_prop lv_res_t res = LV_RES_INV; const lv_obj_t * parent = obj; while(parent) { - lv_style_list_t * dsc = lv_obj_get_style_list(parent, part); + lv_style_list_t * list = lv_obj_get_style_list(parent, part); + + + if(!list->ignore_cache) { + _lv_obj_update_style_cache((lv_obj_t*)parent, part); + bool def = false; + switch(prop & (~LV_STYLE_STATE_MASK)) { + case LV_STYLE_OPA_SCALE: + if(list->opa_scale_transp) def = true; + break; + case LV_STYLE_BG_OPA: + if(list->bg_opa_transp) def = true; + break; + case LV_STYLE_IMAGE_RECOLOR_OPA: + if(list->img_recolor_opa_transp) def = true; + break; + } + if(def) break; + } + lv_state_t state = lv_obj_get_state(parent, part); prop = (uint16_t)prop_ori + ((uint16_t)state << LV_STYLE_STATE_POS); - res = _lv_style_list_get_opa(dsc, prop, &value_act); + res = _lv_style_list_get_opa(list, prop, &value_act); if(res == LV_RES_OK) return value_act; if(LV_STYLE_ATTR_GET_INHERIT(attr) == 0) break; @@ -2624,12 +2749,27 @@ const void * _lv_obj_get_style_ptr(const lv_obj_t * obj, uint8_t part, lv_style_ lv_res_t res = LV_RES_INV; const lv_obj_t * parent = obj; while(parent) { - lv_style_list_t * dsc = lv_obj_get_style_list(parent, part); + lv_style_list_t * list = lv_obj_get_style_list(parent, part); + + if(!list->ignore_cache) { + bool def = false; + _lv_obj_update_style_cache((lv_obj_t*)parent, part); + switch(prop & (~LV_STYLE_STATE_MASK)) { + case LV_STYLE_VALUE_STR: + if(list->opa_scale_transp) def = true; + break; + case LV_STYLE_PATTERN_IMAGE: + if(list->pattern_img_null) def = true; + break; + } + + if(def) break; + } lv_state_t state = lv_obj_get_state(parent, part); prop = (uint16_t)prop_ori + ((uint16_t)state << LV_STYLE_STATE_POS); - res = _lv_style_list_get_ptr(dsc, prop, &value_act); + res = _lv_style_list_get_ptr(list, prop, &value_act); if(res == LV_RES_OK) return value_act; if(LV_STYLE_ATTR_GET_INHERIT(attr) == 0) break; @@ -3809,14 +3949,14 @@ static void refresh_children_position(lv_obj_t * obj, lv_coord_t x_diff, lv_coor */ static void report_style_mod_core(void * style, lv_obj_t * obj) { - uint8_t part_sub; - for(part_sub = 0; part_sub != _LV_OBJ_PART_REAL_LAST; part_sub++) { - lv_style_list_t * dsc = lv_obj_get_style_list(obj, part_sub); - if(dsc == NULL) break; + uint8_t part; + for(part = 0; part != _LV_OBJ_PART_REAL_LAST; part++) { + lv_style_list_t * list = lv_obj_get_style_list(obj, part); + if(list == NULL) break; uint8_t ci; - for(ci = 0; ci < dsc->style_cnt; ci++) { - lv_style_t * class = lv_style_list_get_style(dsc, ci); + for(ci = 0; ci < list->style_cnt; ci++) { + lv_style_t * class = lv_style_list_get_style(list, ci); if(class == style || style == NULL) { lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL); break; diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index 9815d3b9b..06d2bc070 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -595,6 +595,20 @@ void lv_obj_refresh_style(lv_obj_t * obj, lv_style_property_t prop); */ void lv_obj_report_style_mod(lv_style_t * style); +/** + * Update the cache of style list + * @param obj pointer to an obejct + * @param part the part of the object + */ +void _lv_obj_update_style_cache(lv_obj_t * obj, uint8_t part); + +/** + * Mark the object and all of it's children's style lists as invalid. + * The cache will be updated when a cached property asked nest time + * @param obj pointer to an object + */ +void _lv_obj_invalidate_style_cache(lv_obj_t * obj); + /** * Set a local style property of a part of an object in a given state. * @param obj pointer to an object diff --git a/src/lv_core/lv_style.c b/src/lv_core/lv_style.c index ce3665e0d..7428ac731 100644 --- a/src/lv_core/lv_style.c +++ b/src/lv_core/lv_style.c @@ -1052,6 +1052,9 @@ bool lv_debug_check_style_list(const lv_style_list_t * list) */ LV_ATTRIBUTE_FAST_MEM static inline int32_t get_property_index(const lv_style_t * style, lv_style_property_t prop) { + static uint32_t c = 0; + c++; + if(c % 100 == 0) printf("%d\n", c); LV_ASSERT_STYLE(style); if(style->map == NULL) return -1; diff --git a/src/lv_core/lv_style.h b/src/lv_core/lv_style.h index 5909299b6..391c17459 100644 --- a/src/lv_core/lv_style.h +++ b/src/lv_core/lv_style.h @@ -221,11 +221,32 @@ typedef struct { #if LV_USE_ASSERT_STYLE uint32_t sentinel; #endif - uint8_t style_cnt; - uint8_t has_local : 1; - uint8_t has_trans : 1; - uint8_t skip_trans : 1; /*1: Temporally skip the transition style if any*/ - uint8_t ignore_trans : 1; /*1: Mark that this style list shouldn't receive transitions at all*/ + uint32_t style_cnt :7; + uint32_t has_local :1; + uint32_t has_trans :1; + uint32_t skip_trans :1; /*1: Temporally skip the transition style if any*/ + uint32_t ignore_trans :1; /*1: Mark that this style list shouldn't receive transitions at all*/ + uint32_t ignore_cache :1; /*1: Ignore cache while getting value of properties*/ + uint32_t valid_cache :1; /*1: The cache is invalid and needs to be updated*/ + + uint32_t opa_scale_transp :1; + uint32_t clip_corner_off :1; + uint32_t transform_width_zero :1; + uint32_t transform_height_zero :1; + uint32_t transform_angle_zero :1; + uint32_t transform_zoom_zero :1; + uint32_t bg_opa_transp :1; + uint32_t bg_grad_dir_none :1; + uint32_t border_width_zero :1; + uint32_t outline_width_zero :1; + uint32_t pattern_img_null :1; + uint32_t shadow_width_zero :1; + uint32_t value_txt_str :1; + uint32_t line_width_zerop :1; + uint32_t img_recolor_opa_transp :1; + uint32_t text_letter_space_zero :1; + uint32_t text_line_space_zero :1; + uint32_t text_decor_none :1; } lv_style_list_t; /********************** From 11cab40103e781c01ad8f2503473de58ed292dd3 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sun, 2 Aug 2020 11:36:27 +0200 Subject: [PATCH 096/173] import style caching --- src/lv_core/lv_obj.c | 218 ++++++++++++++++++++---------- src/lv_core/lv_obj.h | 16 +-- src/lv_core/lv_style.h | 4 +- src/lv_themes/lv_theme_material.c | 2 +- src/lv_themes/lv_theme_mono.c | 2 +- src/lv_themes/lv_theme_template.c | 2 +- src/lv_widgets/lv_arc.c | 2 +- src/lv_widgets/lv_bar.c | 2 +- src/lv_widgets/lv_btn.c | 2 +- src/lv_widgets/lv_btnmatrix.c | 6 + src/lv_widgets/lv_calendar.c | 5 + src/lv_widgets/lv_chart.c | 2 +- src/lv_widgets/lv_cont.c | 2 +- src/lv_widgets/lv_cpicker.c | 2 +- src/lv_widgets/lv_dropdown.c | 18 ++- src/lv_widgets/lv_gauge.c | 2 +- src/lv_widgets/lv_img.c | 2 +- src/lv_widgets/lv_imgbtn.c | 2 +- src/lv_widgets/lv_label.c | 2 +- src/lv_widgets/lv_led.c | 2 +- src/lv_widgets/lv_line.c | 2 +- src/lv_widgets/lv_linemeter.c | 2 +- src/lv_widgets/lv_list.c | 2 +- src/lv_widgets/lv_msgbox.c | 2 +- src/lv_widgets/lv_objmask.c | 2 +- src/lv_widgets/lv_roller.c | 2 +- src/lv_widgets/lv_slider.c | 2 +- src/lv_widgets/lv_spinbox.c | 2 +- src/lv_widgets/lv_spinner.c | 2 +- src/lv_widgets/lv_switch.c | 2 +- src/lv_widgets/lv_table.c | 2 +- src/lv_widgets/lv_tabview.c | 4 +- src/lv_widgets/lv_textarea.c | 2 +- src/lv_widgets/lv_tileview.c | 2 +- src/lv_widgets/lv_win.c | 2 +- 35 files changed, 199 insertions(+), 128 deletions(-) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index ec443efd3..88474cd0b 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -103,7 +103,9 @@ static void lv_event_mark_deleted(lv_obj_t * obj); static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_find); static void lv_obj_del_async_cb(void * obj); static void obj_del_core(lv_obj_t * obj); - +static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop); +static void update_style_cache_children(lv_obj_t * obj); +static void invalidate_style_cache(lv_obj_t * obj, uint8_t part); /********************** * STATIC VARIABLES **********************/ @@ -1120,7 +1122,7 @@ void lv_obj_add_style(lv_obj_t * obj, uint8_t part, lv_style_t * style) #if LV_USE_ANIMATION trans_del(obj, part, 0xFF, NULL); #endif - lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(obj, part, LV_STYLE_PROP_ALL); } /** @@ -1144,7 +1146,7 @@ void lv_obj_remove_style(lv_obj_t * obj, uint8_t part, lv_style_t * style) #if LV_USE_ANIMATION trans_del(obj, part, 0xFF, NULL); #endif - lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(obj, part, LV_STYLE_PROP_ALL); } /** @@ -1181,7 +1183,7 @@ void lv_obj_reset_style_list(lv_obj_t * obj, uint8_t part) { lv_obj_clean_style_list(obj, part); - lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(obj, part, LV_STYLE_PROP_ALL); } /** @@ -1203,7 +1205,7 @@ void _lv_obj_set_style_local_int(lv_obj_t * obj, uint8_t part, lv_style_property #if LV_USE_ANIMATION trans_del(obj, part, prop, NULL); #endif - lv_obj_refresh_style(obj, prop & (~LV_STYLE_STATE_MASK)); + lv_obj_refresh_style(obj, part, prop & (~LV_STYLE_STATE_MASK)); } /** @@ -1225,7 +1227,7 @@ void _lv_obj_set_style_local_color(lv_obj_t * obj, uint8_t part, lv_style_proper #if LV_USE_ANIMATION trans_del(obj, part, prop, NULL); #endif - lv_obj_refresh_style(obj, prop & (~LV_STYLE_STATE_MASK)); + lv_obj_refresh_style(obj, part, prop & (~LV_STYLE_STATE_MASK)); } /** @@ -1247,7 +1249,7 @@ void _lv_obj_set_style_local_opa(lv_obj_t * obj, uint8_t part, lv_style_property #if LV_USE_ANIMATION trans_del(obj, part, prop, NULL); #endif - lv_obj_refresh_style(obj, prop & (~LV_STYLE_STATE_MASK)); + lv_obj_refresh_style(obj, part, prop & (~LV_STYLE_STATE_MASK)); } /** @@ -1269,7 +1271,7 @@ void _lv_obj_set_style_local_ptr(lv_obj_t * obj, uint8_t part, lv_style_property #if LV_USE_ANIMATION trans_del(obj, part, prop, NULL); #endif - lv_obj_refresh_style(obj, prop & (~LV_STYLE_STATE_MASK)); + lv_obj_refresh_style(obj, part, prop & (~LV_STYLE_STATE_MASK)); } /** @@ -1296,11 +1298,11 @@ bool lv_obj_remove_style_local_prop(lv_obj_t * obj, uint8_t part, lv_style_prope * @param obj pointer to an object * @param prop `LV_STYLE_PROP_ALL` or an `LV_STYLE_...` property. It is used to optimize what needs to be refreshed. */ -void lv_obj_refresh_style(lv_obj_t * obj, lv_style_property_t prop) +void lv_obj_refresh_style(lv_obj_t * obj, uint8_t part, lv_style_property_t prop) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - _lv_obj_invalidate_style_cache(obj); + invalidate_style_cache(obj, part); /*If a real style refresh is required*/ bool real_refr = false; @@ -1390,63 +1392,6 @@ void lv_obj_report_style_mod(lv_style_t * style) } -/** - * Update the cache of style list - * @param obj pointer to an obejct - * @param part the part of the object - */ -void _lv_obj_update_style_cache(lv_obj_t * obj, uint8_t part) -{ - lv_style_list_t * list = lv_obj_get_style_list(obj, part); - if(list->valid_cache) return; - - bool ignore_cache_ori = list->ignore_cache; - list->ignore_cache = 1; - list->bg_grad_dir_none = lv_obj_get_style_bg_grad_dir(obj, part) == LV_GRAD_DIR_NONE ? 1 : 0; - list->bg_opa_transp = lv_obj_get_style_bg_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; - list->border_width_zero = lv_obj_get_style_border_width(obj, part) == LV_OPA_TRANSP ? 1 : 0; - list->clip_corner_off = lv_obj_get_style_clip_corner(obj, part) == false ? 1 : 0; - list->img_recolor_opa_transp = lv_obj_get_style_image_recolor_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; - list->line_width_zerop = lv_obj_get_style_line_width(obj, part) == 0 ? 1 : 0; - list->opa_scale_transp = lv_obj_get_style_opa_scale(obj, part) == LV_OPA_TRANSP ? 1 : 0; - list->outline_width_zero = lv_obj_get_style_outline_width(obj, part) == 0 ? 1 : 0; - list->pattern_img_null = lv_obj_get_style_pattern_image(obj, part) == NULL ? 1 : 0; - list->shadow_width_zero = lv_obj_get_style_shadow_width(obj, part) == 0 ? 1 : 0; - list->text_decor_none = lv_obj_get_style_text_decor(obj, part) == LV_TEXT_DECOR_NONE ? 1 : 0; - list->text_letter_space_zero = lv_obj_get_style_text_letter_space(obj, part) == 0 ? 1 : 0; - list->text_line_space_zero = lv_obj_get_style_text_line_space(obj, part) == 0 ? 1 : 0; - list->transform_angle_zero = lv_obj_get_style_transform_angle(obj, part) == 0 ? 1 : 0; - list->transform_height_zero = lv_obj_get_style_transform_width(obj, part) == 0 ? 1 : 0; - list->transform_width_zero = lv_obj_get_style_transform_height(obj, part) == 0 ? 1 : 0; - list->transform_zoom_zero = lv_obj_get_style_transform_zoom(obj, part) == LV_IMG_ZOOM_NONE ? 1 : 0; - list->value_txt_str = lv_obj_get_style_value_str(obj, part) == NULL ? 1 : 0; - - list->ignore_cache = ignore_cache_ori; - list->valid_cache = 1; -} - -/** - * Mark the object and all of it's children's style lists as invalid. - * The cache will be updated when a cached property asked nest time - * @param obj pointer to an object - */ -void _lv_obj_invalidate_style_cache(lv_obj_t * obj) -{ - uint8_t part; - for(part = 0; part != _LV_OBJ_PART_REAL_LAST; part++) { - lv_style_list_t * list = lv_obj_get_style_list(obj, part); - if(list == NULL) break; - list->valid_cache = 0; - - } - - lv_obj_t * child = lv_obj_get_child(obj, NULL); - while(child) { - _lv_obj_invalidate_style_cache(child); - child = lv_obj_get_child(obj, child); - } -} - /*----------------- * Attribute set *----------------*/ @@ -1720,10 +1665,10 @@ void lv_obj_set_state(lv_obj_t * obj, lv_state_t new_state) } } + lv_obj_refresh_style(obj, part, LV_STYLE_PROP_ALL); } #endif - lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL); } @@ -2511,7 +2456,8 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl lv_style_list_t * list = lv_obj_get_style_list(parent, part); if(!list->ignore_cache) { - _lv_obj_update_style_cache((lv_obj_t*)parent, part); + if(!list->valid_cache) update_style_cache((lv_obj_t*)parent, part, prop & (~LV_STYLE_STATE_MASK)); + bool def = false; switch(prop & (~LV_STYLE_STATE_MASK)) { case LV_STYLE_BG_GRAD_DIR: @@ -2555,7 +2501,6 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl if(def) break; } - lv_state_t state = lv_obj_get_state(parent, part); prop = (uint16_t)prop_ori + ((uint16_t)state << LV_STYLE_STATE_POS); @@ -2675,9 +2620,8 @@ lv_opa_t _lv_obj_get_style_opa(const lv_obj_t * obj, uint8_t part, lv_style_prop while(parent) { lv_style_list_t * list = lv_obj_get_style_list(parent, part); - if(!list->ignore_cache) { - _lv_obj_update_style_cache((lv_obj_t*)parent, part); + if(!list->valid_cache) update_style_cache((lv_obj_t*)parent, part, prop & (~LV_STYLE_STATE_MASK)); bool def = false; switch(prop & (~LV_STYLE_STATE_MASK)) { case LV_STYLE_OPA_SCALE: @@ -2752,8 +2696,8 @@ const void * _lv_obj_get_style_ptr(const lv_obj_t * obj, uint8_t part, lv_style_ lv_style_list_t * list = lv_obj_get_style_list(parent, part); if(!list->ignore_cache) { + if(!list->valid_cache) update_style_cache((lv_obj_t*)parent, part, prop & (~LV_STYLE_STATE_MASK)); bool def = false; - _lv_obj_update_style_cache((lv_obj_t*)parent, part); switch(prop & (~LV_STYLE_STATE_MASK)) { case LV_STYLE_VALUE_STR: if(list->opa_scale_transp) def = true; @@ -3958,7 +3902,7 @@ static void report_style_mod_core(void * style, lv_obj_t * obj) for(ci = 0; ci < list->style_cnt; ci++) { lv_style_t * class = lv_style_list_get_style(list, ci); if(class == style || style == NULL) { - lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(obj, part, LV_STYLE_PROP_ALL); break; } } @@ -4339,7 +4283,7 @@ static void trans_anim_cb(lv_style_trans_t * tr, lv_anim_value_t v) else x = tr->end_value._ptr; _lv_style_set_ptr(style, tr->prop, x); } - lv_obj_refresh_style(tr->obj, tr->prop); + lv_obj_refresh_style(tr->obj, tr->part, tr->prop); } @@ -4434,3 +4378,127 @@ static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_fin return false; } + +/** + * Update the cache of style list + * @param obj pointer to an obejct + * @param part the part of the object + * @param prop the property which triggered the update + */ +static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop) +{ + + bool cachable; + switch(prop) { + case LV_STYLE_BG_GRAD_DIR: + case LV_STYLE_CLIP_CORNER: + case LV_STYLE_TEXT_LETTER_SPACE: + case LV_STYLE_TEXT_LINE_SPACE: + case LV_STYLE_TRANSFORM_ANGLE: + case LV_STYLE_TRANSFORM_WIDTH: + case LV_STYLE_TRANSFORM_HEIGHT: + case LV_STYLE_TRANSFORM_ZOOM: + case LV_STYLE_BORDER_WIDTH: + case LV_STYLE_LINE_WIDTH: + case LV_STYLE_OUTLINE_WIDTH: + case LV_STYLE_SHADOW_WIDTH: + case LV_STYLE_OPA_SCALE: + case LV_STYLE_BG_OPA: + case LV_STYLE_IMAGE_RECOLOR_OPA: + case LV_STYLE_VALUE_STR: + case LV_STYLE_PATTERN_IMAGE: + cachable = true; + break; + default: + cachable = false; + } + + if(!cachable) return; + + lv_style_list_t * list = lv_obj_get_style_list(obj, part); + + bool ignore_cache_ori = list->ignore_cache; + list->ignore_cache = 1; + + list->opa_scale_transp = lv_obj_get_style_opa_scale(obj, part) == LV_OPA_TRANSP ? 1 : 0; + list->text_decor_none = lv_obj_get_style_text_decor(obj, part) == LV_TEXT_DECOR_NONE ? 1 : 0; + list->text_letter_space_zero = lv_obj_get_style_text_letter_space(obj, part) == 0 ? 1 : 0; + list->text_line_space_zero = lv_obj_get_style_text_line_space(obj, part) == 0 ? 1 : 0; + + list->bg_grad_dir_none = lv_obj_get_style_bg_grad_dir(obj, part) == LV_GRAD_DIR_NONE ? 1 : 0; + list->bg_opa_transp = lv_obj_get_style_bg_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; + list->border_width_zero = lv_obj_get_style_border_width(obj, part) == LV_OPA_TRANSP ? 1 : 0; + list->clip_corner_off = lv_obj_get_style_clip_corner(obj, part) == false ? 1 : 0; + list->img_recolor_opa_transp = lv_obj_get_style_image_recolor_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; + list->line_width_zerop = lv_obj_get_style_line_width(obj, part) == 0 ? 1 : 0; + list->outline_width_zero = lv_obj_get_style_outline_width(obj, part) == 0 ? 1 : 0; + list->pattern_img_null = lv_obj_get_style_pattern_image(obj, part) == NULL ? 1 : 0; + list->shadow_width_zero = lv_obj_get_style_shadow_width(obj, part) == 0 ? 1 : 0; + list->transform_angle_zero = lv_obj_get_style_transform_angle(obj, part) == 0 ? 1 : 0; + list->transform_height_zero = lv_obj_get_style_transform_width(obj, part) == 0 ? 1 : 0; + list->transform_width_zero = lv_obj_get_style_transform_height(obj, part) == 0 ? 1 : 0; + list->transform_zoom_zero = lv_obj_get_style_transform_zoom(obj, part) == LV_IMG_ZOOM_NONE ? 1 : 0; + list->value_txt_str = lv_obj_get_style_value_str(obj, part) == NULL ? 1 : 0; + + list->ignore_cache = ignore_cache_ori; + list->valid_cache = 1; +} + +void _lv_obj_disable_style_cahcing(lv_obj_t * obj, bool dis) +{ + uint8_t part; + for(part = 0; part < _LV_OBJ_PART_REAL_FIRST; part++) { + lv_style_list_t * list = lv_obj_get_style_list(obj, part); + if(list == NULL) break; + list->ignore_cache = dis; + } + for(part = _LV_OBJ_PART_REAL_FIRST; part < 0xFF; part++) { + lv_style_list_t * list = lv_obj_get_style_list(obj, part); + if(list == NULL) break; + list->ignore_cache = dis; + } +} + +/** + * Update the cache of style list + * @param obj pointer to an object + * @param part the part of the object + */ +static void update_style_cache_children(lv_obj_t * obj) +{ + uint8_t part; + for(part = 0; part != _LV_OBJ_PART_REAL_LAST; part++) { + lv_style_list_t * list = lv_obj_get_style_list(obj, part); + if(list == NULL) break; + + bool ignore_cache_ori = list->ignore_cache; + list->ignore_cache = 1; + + list->opa_scale_transp = lv_obj_get_style_opa_scale(obj, part) == LV_OPA_TRANSP ? 1 : 0; + list->text_decor_none = lv_obj_get_style_text_decor(obj, part) == LV_TEXT_DECOR_NONE ? 1 : 0; + list->text_letter_space_zero = lv_obj_get_style_text_letter_space(obj, part) == 0 ? 1 : 0; + list->text_line_space_zero = lv_obj_get_style_text_line_space(obj, part) == 0 ? 1 : 0; + list->img_recolor_opa_transp = lv_obj_get_style_image_recolor_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; + + list->ignore_cache = ignore_cache_ori; + } +} + +/** + * Mark the object and all of it's children's style lists as invalid. + * The cache will be updated when a cached property asked nest time + * @param obj pointer to an object + */ +static void invalidate_style_cache(lv_obj_t * obj, uint8_t part) +{ + lv_style_list_t * list = lv_obj_get_style_list(obj, part); + if(list == NULL) return; + list->valid_cache = 0; + + lv_obj_t * child = lv_obj_get_child(obj, NULL); + while(child) { + update_style_cache_children(child); + child = lv_obj_get_child(obj, child); + } +} + diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index 06d2bc070..c5f9b0cd4 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -586,7 +586,7 @@ void lv_obj_reset_style_list(lv_obj_t * obj, uint8_t part); * @param obj pointer to an object * @param prop `LV_STYLE_PROP_ALL` or an `LV_STYLE_...` property. It is used to optimize what needs to be refreshed. */ -void lv_obj_refresh_style(lv_obj_t * obj, lv_style_property_t prop); +void lv_obj_refresh_style(lv_obj_t * obj, uint8_t part, lv_style_property_t prop); /** * Notify all object if a style is modified @@ -595,20 +595,6 @@ void lv_obj_refresh_style(lv_obj_t * obj, lv_style_property_t prop); */ void lv_obj_report_style_mod(lv_style_t * style); -/** - * Update the cache of style list - * @param obj pointer to an obejct - * @param part the part of the object - */ -void _lv_obj_update_style_cache(lv_obj_t * obj, uint8_t part); - -/** - * Mark the object and all of it's children's style lists as invalid. - * The cache will be updated when a cached property asked nest time - * @param obj pointer to an object - */ -void _lv_obj_invalidate_style_cache(lv_obj_t * obj); - /** * Set a local style property of a part of an object in a given state. * @param obj pointer to an object diff --git a/src/lv_core/lv_style.h b/src/lv_core/lv_style.h index 391c17459..0db481ec8 100644 --- a/src/lv_core/lv_style.h +++ b/src/lv_core/lv_style.h @@ -226,8 +226,8 @@ typedef struct { uint32_t has_trans :1; uint32_t skip_trans :1; /*1: Temporally skip the transition style if any*/ uint32_t ignore_trans :1; /*1: Mark that this style list shouldn't receive transitions at all*/ - uint32_t ignore_cache :1; /*1: Ignore cache while getting value of properties*/ - uint32_t valid_cache :1; /*1: The cache is invalid and needs to be updated*/ + uint32_t valid_cache :1; /*1: The cache is invalid and needs to be updated*/ + uint8_t ignore_cache :1; /**1: Ignore style cache while getting value of properties*/ uint32_t opa_scale_transp :1; uint32_t clip_corner_off :1; diff --git a/src/lv_themes/lv_theme_material.c b/src/lv_themes/lv_theme_material.c index 1aa9fe580..031cd2a06 100644 --- a/src/lv_themes/lv_theme_material.c +++ b/src/lv_themes/lv_theme_material.c @@ -1366,7 +1366,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name) break; } - lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(obj, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } /********************** diff --git a/src/lv_themes/lv_theme_mono.c b/src/lv_themes/lv_theme_mono.c index ba5357088..e9f0f9015 100644 --- a/src/lv_themes/lv_theme_mono.c +++ b/src/lv_themes/lv_theme_mono.c @@ -1023,7 +1023,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name) } - lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(obj, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } diff --git a/src/lv_themes/lv_theme_template.c b/src/lv_themes/lv_theme_template.c index 2a22fad4e..722e72e07 100644 --- a/src/lv_themes/lv_theme_template.c +++ b/src/lv_themes/lv_theme_template.c @@ -855,7 +855,7 @@ void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name) break; } - lv_obj_refresh_style(obj, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(obj, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } /********************** diff --git a/src/lv_widgets/lv_arc.c b/src/lv_widgets/lv_arc.c index 4dd7d9f45..f7cf087f1 100644 --- a/src/lv_widgets/lv_arc.c +++ b/src/lv_widgets/lv_arc.c @@ -101,7 +101,7 @@ lv_obj_t * lv_arc_create(lv_obj_t * par, const lv_obj_t * copy) lv_style_list_copy(&ext->style_arc, ©_ext->style_arc); /*Refresh the style with new signal function*/ - lv_obj_refresh_style(arc, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(arc, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("arc created"); diff --git a/src/lv_widgets/lv_bar.c b/src/lv_widgets/lv_bar.c index f76a2e13f..f787e2680 100644 --- a/src/lv_widgets/lv_bar.c +++ b/src/lv_widgets/lv_bar.c @@ -130,7 +130,7 @@ lv_obj_t * lv_bar_create(lv_obj_t * par, const lv_obj_t * copy) lv_style_list_copy(&ext->style_indic, &ext_copy->style_indic); /*Refresh the style with new signal function*/ - lv_obj_refresh_style(bar, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(bar, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); lv_bar_set_value(bar, ext->cur_value, LV_ANIM_OFF); } diff --git a/src/lv_widgets/lv_btn.c b/src/lv_widgets/lv_btn.c index fa327bd6e..3d5556083 100644 --- a/src/lv_widgets/lv_btn.c +++ b/src/lv_widgets/lv_btn.c @@ -100,7 +100,7 @@ lv_obj_t * lv_btn_create(lv_obj_t * par, const lv_obj_t * copy) ext->checkable = copy_ext->checkable; /*Refresh the style with new signal function*/ - lv_obj_refresh_style(btn, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(btn, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("button created"); diff --git a/src/lv_widgets/lv_btnmatrix.c b/src/lv_widgets/lv_btnmatrix.c index 5501fcfa6..f604cb10f 100644 --- a/src/lv_widgets/lv_btnmatrix.c +++ b/src/lv_widgets/lv_btnmatrix.c @@ -660,6 +660,7 @@ static lv_design_res_t lv_btnmatrix_design(lv_obj_t * btnm, const lv_area_t * cl /*The state changes without re-caching the styles, disable the use of cache*/ lv_state_t state_ori = btnm->state; + _lv_obj_disable_style_cahcing(btnm, true); btnm->state = LV_STATE_DEFAULT; lv_draw_rect_dsc_init(&draw_rect_rel_dsc); lv_draw_label_dsc_init(&draw_label_rel_dsc); @@ -667,6 +668,7 @@ static lv_design_res_t lv_btnmatrix_design(lv_obj_t * btnm, const lv_area_t * cl lv_obj_init_draw_label_dsc(btnm, LV_BTNMATRIX_PART_BTN, &draw_label_rel_dsc); draw_label_rel_dsc.flag = txt_flag; btnm->state = state_ori; + _lv_obj_disable_style_cahcing(btnm, false); bool chk_inited = false; bool disabled_inited = false; @@ -700,12 +702,14 @@ static lv_design_res_t lv_btnmatrix_design(lv_obj_t * btnm, const lv_area_t * cl if(tgl_state) { if(!chk_inited) { btnm->state = LV_STATE_CHECKED; + _lv_obj_disable_style_cahcing(btnm, true); lv_draw_rect_dsc_init(&draw_rect_chk_dsc); lv_draw_label_dsc_init(&draw_label_chk_dsc); lv_obj_init_draw_rect_dsc(btnm, LV_BTNMATRIX_PART_BTN, &draw_rect_chk_dsc); lv_obj_init_draw_label_dsc(btnm, LV_BTNMATRIX_PART_BTN, &draw_label_chk_dsc); draw_label_chk_dsc.flag = txt_flag; btnm->state = state_ori; + _lv_obj_disable_style_cahcing(btnm, false); chk_inited = true; } } @@ -713,12 +717,14 @@ static lv_design_res_t lv_btnmatrix_design(lv_obj_t * btnm, const lv_area_t * cl if(button_is_inactive(ext->ctrl_bits[btn_i])) { if(!disabled_inited) { btnm->state = LV_STATE_DISABLED; + _lv_obj_disable_style_cahcing(btnm, true); lv_draw_rect_dsc_init(&draw_rect_ina_dsc); lv_draw_label_dsc_init(&draw_label_ina_dsc); lv_obj_init_draw_rect_dsc(btnm, LV_BTNMATRIX_PART_BTN, &draw_rect_ina_dsc); lv_obj_init_draw_label_dsc(btnm, LV_BTNMATRIX_PART_BTN, &draw_label_ina_dsc); draw_label_ina_dsc.flag = txt_flag; btnm->state = state_ori; + _lv_obj_disable_style_cahcing(btnm, false); disabled_inited = true; } draw_rect_dsc_act = &draw_rect_ina_dsc; diff --git a/src/lv_widgets/lv_calendar.c b/src/lv_widgets/lv_calendar.c index 9936b624b..ab9835007 100644 --- a/src/lv_widgets/lv_calendar.c +++ b/src/lv_widgets/lv_calendar.c @@ -705,6 +705,7 @@ static void draw_header(lv_obj_t * calendar, const lv_area_t * mask) strcpy(&txt_buf[5], get_month_name(calendar, ext->showed_date.month)); calendar->state = LV_STATE_DEFAULT; + _lv_obj_disable_style_cahcing(calendar, true); lv_draw_label_dsc_t label_dsc; lv_draw_label_dsc_init(&label_dsc); @@ -738,6 +739,7 @@ static void draw_header(lv_obj_t * calendar, const lv_area_t * mask) lv_draw_label(&header_area, mask, &label_dsc, LV_SYMBOL_RIGHT, NULL); calendar->state = state_ori; /*Restore the state*/ + _lv_obj_disable_style_cahcing(calendar, false); } /** @@ -810,6 +812,7 @@ static void draw_dates(lv_obj_t * calendar, const lv_area_t * clip_area) /*The state changes without re-caching the styles, disable the use of cache*/ lv_state_t state_ori = calendar->state; calendar->state = LV_STATE_DEFAULT; + _lv_obj_disable_style_cahcing(calendar, true); lv_state_t month_state = LV_STATE_DISABLED; @@ -856,6 +859,7 @@ static void draw_dates(lv_obj_t * calendar, const lv_area_t * clip_area) if(box_area.y1 > clip_area->y2) { calendar->state = state_ori; + _lv_obj_disable_style_cahcing(calendar, false); return; } @@ -926,6 +930,7 @@ static void draw_dates(lv_obj_t * calendar, const lv_area_t * clip_area) } } calendar->state = state_ori; + _lv_obj_disable_style_cahcing(calendar, false); } diff --git a/src/lv_widgets/lv_chart.c b/src/lv_widgets/lv_chart.c index d7308cf88..75d0a146c 100644 --- a/src/lv_widgets/lv_chart.c +++ b/src/lv_widgets/lv_chart.c @@ -152,7 +152,7 @@ lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy) _lv_memcpy(&ext->secondary_y_axis, &ext_copy->secondary_y_axis, sizeof(lv_chart_axis_cfg_t)); /*Refresh the style with new signal function*/ - lv_obj_refresh_style(chart, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(chart, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("chart created"); diff --git a/src/lv_widgets/lv_cont.c b/src/lv_widgets/lv_cont.c index ffb716832..04a81343e 100644 --- a/src/lv_widgets/lv_cont.c +++ b/src/lv_widgets/lv_cont.c @@ -112,7 +112,7 @@ lv_obj_t * lv_cont_create(lv_obj_t * par, const lv_obj_t * copy) ext->layout = copy_ext->layout; /*Refresh the style with new signal function*/ - lv_obj_refresh_style(cont, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(cont, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("container created"); diff --git a/src/lv_widgets/lv_cpicker.c b/src/lv_widgets/lv_cpicker.c index d80c9a56c..bc46ffcc4 100644 --- a/src/lv_widgets/lv_cpicker.c +++ b/src/lv_widgets/lv_cpicker.c @@ -144,7 +144,7 @@ lv_obj_t * lv_cpicker_create(lv_obj_t * par, const lv_obj_t * copy) lv_style_list_copy(&ext->knob.style_list, ©_ext->knob.style_list); /*Refresh the style with new signal function*/ - lv_obj_refresh_style(cpicker, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(cpicker, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } refr_knob_pos(cpicker); diff --git a/src/lv_widgets/lv_dropdown.c b/src/lv_widgets/lv_dropdown.c index c7bbd8746..09c073318 100644 --- a/src/lv_widgets/lv_dropdown.c +++ b/src/lv_widgets/lv_dropdown.c @@ -609,7 +609,7 @@ void lv_dropdown_open(lv_obj_t * ddlist) lv_style_list_copy(lv_obj_get_style_list(ext->page, LV_PAGE_PART_BG), &ext->style_page); lv_style_list_copy(lv_obj_get_style_list(ext->page, LV_PAGE_PART_SCROLLBAR), &ext->style_scrlbar); lv_obj_clean_style_list(ext->page, LV_PAGE_PART_SCROLLABLE); - lv_obj_refresh_style(ext->page, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(ext->page, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); lv_obj_t * label = lv_label_create(ext->page, NULL); lv_label_set_text_static(label, ext->options); @@ -965,7 +965,7 @@ static lv_res_t lv_dropdown_signal(lv_obj_t * ddlist, lv_signal_t sign, void * p const lv_font_t * font = lv_obj_get_style_text_font(ddlist, LV_DROPDOWN_PART_MAIN); lv_obj_set_height(ddlist, top + bottom + lv_font_get_line_height(font)); - if(ext->page) lv_obj_refresh_style(ext->page, LV_STYLE_PROP_ALL); + if(ext->page) lv_obj_refresh_style(ext->page, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } else if(sign == LV_SIGNAL_CONTROL) { #if LV_USE_GROUP @@ -1134,8 +1134,10 @@ static void draw_box(lv_obj_t * ddlist, const lv_area_t * clip_area, uint16_t id lv_obj_t * page = ext->page; lv_state_t state_orig = page->state; - page->state = LV_STATE_DEFAULT; - page->state |= state; + if(state != page->state) { + _lv_obj_disable_style_cahcing(ddlist, true); + page->state = state; + } /*Draw a rectangle under the selected item*/ const lv_font_t * font = lv_obj_get_style_text_font(ddlist, LV_DROPDOWN_PART_LIST); @@ -1159,6 +1161,7 @@ static void draw_box(lv_obj_t * ddlist, const lv_area_t * clip_area, uint16_t id lv_draw_rect(&rect_area, clip_area, &sel_rect); page->state = state_orig; + _lv_obj_disable_style_cahcing(ddlist, false); } @@ -1169,8 +1172,10 @@ static void draw_box_label(lv_obj_t * ddlist, const lv_area_t * clip_area, uint1 lv_obj_t * page = ext->page; lv_state_t state_orig = page->state; - page->state = LV_STATE_DEFAULT; - page->state |= state; + if(state != page->state) { + page->state = state; + _lv_obj_disable_style_cahcing(ddlist, true); + } lv_draw_label_dsc_t label_dsc; lv_draw_label_dsc_init(&label_dsc); @@ -1204,6 +1209,7 @@ static void draw_box_label(lv_obj_t * ddlist, const lv_area_t * clip_area, uint1 lv_draw_label(&label->coords, &mask_sel, &label_dsc, lv_label_get_text(label), NULL); } page->state = state_orig; + _lv_obj_disable_style_cahcing(ddlist, false); } /** diff --git a/src/lv_widgets/lv_gauge.c b/src/lv_widgets/lv_gauge.c index ad7cb32e1..4457c9ba5 100644 --- a/src/lv_widgets/lv_gauge.c +++ b/src/lv_widgets/lv_gauge.c @@ -124,7 +124,7 @@ lv_obj_t * lv_gauge_create(lv_obj_t * par, const lv_obj_t * copy) ext->format_cb = copy_ext->format_cb; /*Refresh the style with new signal function*/ - lv_obj_refresh_style(gauge, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(gauge, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("gauge created"); diff --git a/src/lv_widgets/lv_img.c b/src/lv_widgets/lv_img.c index 6c6f65791..d92dcc2d8 100644 --- a/src/lv_widgets/lv_img.c +++ b/src/lv_widgets/lv_img.c @@ -121,7 +121,7 @@ lv_obj_t * lv_img_create(lv_obj_t * par, const lv_obj_t * copy) lv_img_set_src(img, copy_ext->src); /*Refresh the style with new signal function*/ - lv_obj_refresh_style(img, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(img, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("image created"); diff --git a/src/lv_widgets/lv_imgbtn.c b/src/lv_widgets/lv_imgbtn.c index 1c37d92a9..43bf7e37b 100644 --- a/src/lv_widgets/lv_imgbtn.c +++ b/src/lv_widgets/lv_imgbtn.c @@ -100,7 +100,7 @@ lv_obj_t * lv_imgbtn_create(lv_obj_t * par, const lv_obj_t * copy) #endif ext->tiled = copy_ext->tiled; /*Refresh the style with new signal function*/ - lv_obj_refresh_style(imgbtn, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(imgbtn, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("image button created"); diff --git a/src/lv_widgets/lv_label.c b/src/lv_widgets/lv_label.c index 1113a6b10..65e6397f6 100644 --- a/src/lv_widgets/lv_label.c +++ b/src/lv_widgets/lv_label.c @@ -161,7 +161,7 @@ lv_obj_t * lv_label_create(lv_obj_t * par, const lv_obj_t * copy) ext->dot_end = copy_ext->dot_end; /*Refresh the style with new signal function*/ - lv_obj_refresh_style(new_label, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(new_label, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("label created"); diff --git a/src/lv_widgets/lv_led.c b/src/lv_widgets/lv_led.c index 53c679c2f..dea778d7d 100644 --- a/src/lv_widgets/lv_led.c +++ b/src/lv_widgets/lv_led.c @@ -88,7 +88,7 @@ lv_obj_t * lv_led_create(lv_obj_t * par, const lv_obj_t * copy) ext->bright = copy_ext->bright; /*Refresh the style with new signal function*/ - lv_obj_refresh_style(led, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(led, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("led created"); diff --git a/src/lv_widgets/lv_line.c b/src/lv_widgets/lv_line.c index e2c53e925..c54a0ecf5 100644 --- a/src/lv_widgets/lv_line.c +++ b/src/lv_widgets/lv_line.c @@ -95,7 +95,7 @@ lv_obj_t * lv_line_create(lv_obj_t * par, const lv_obj_t * copy) lv_line_set_points(line, copy_ext->point_array, copy_ext->point_num); /*Refresh the style with new signal function*/ - lv_obj_refresh_style(line, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(line, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("line created"); diff --git a/src/lv_widgets/lv_linemeter.c b/src/lv_widgets/lv_linemeter.c index c8e7ae724..5b643058f 100644 --- a/src/lv_widgets/lv_linemeter.c +++ b/src/lv_widgets/lv_linemeter.c @@ -96,7 +96,7 @@ lv_obj_t * lv_linemeter_create(lv_obj_t * par, const lv_obj_t * copy) ext->cur_value = copy_ext->cur_value; /*Refresh the style with new signal function*/ - lv_obj_refresh_style(linemeter, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(linemeter, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("line meter created"); diff --git a/src/lv_widgets/lv_list.c b/src/lv_widgets/lv_list.c index dfd2b32af..526e53adf 100644 --- a/src/lv_widgets/lv_list.c +++ b/src/lv_widgets/lv_list.c @@ -115,7 +115,7 @@ lv_obj_t * lv_list_create(lv_obj_t * par, const lv_obj_t * copy) } /*Refresh the style with new signal function*/ - lv_obj_refresh_style(list, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(list, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("list created"); diff --git a/src/lv_widgets/lv_msgbox.c b/src/lv_widgets/lv_msgbox.c index 60f4cdc9c..9448bec58 100644 --- a/src/lv_widgets/lv_msgbox.c +++ b/src/lv_widgets/lv_msgbox.c @@ -127,7 +127,7 @@ lv_obj_t * lv_msgbox_create(lv_obj_t * par, const lv_obj_t * copy) if(copy_ext->btnm) ext->btnm = lv_btnmatrix_create(mbox, copy_ext->btnm); /*Refresh the style with new signal function*/ - lv_obj_refresh_style(mbox, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(mbox, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("message box created"); diff --git a/src/lv_widgets/lv_objmask.c b/src/lv_widgets/lv_objmask.c index 2c817fb17..ed22bb30b 100644 --- a/src/lv_widgets/lv_objmask.c +++ b/src/lv_widgets/lv_objmask.c @@ -86,7 +86,7 @@ lv_obj_t * lv_objmask_create(lv_obj_t * par, const lv_obj_t * copy) /* lv_objmask_ext_t * copy_ext = lv_obj_get_ext_attr(copy); */ /*Refresh the style with new signal function*/ - lv_obj_refresh_style(objmask, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(objmask, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("object mask created"); diff --git a/src/lv_widgets/lv_roller.c b/src/lv_widgets/lv_roller.c index 7c67fcb68..8b6818edc 100644 --- a/src/lv_widgets/lv_roller.c +++ b/src/lv_widgets/lv_roller.c @@ -135,7 +135,7 @@ lv_obj_t * lv_roller_create(lv_obj_t * par, const lv_obj_t * copy) lv_obj_set_signal_cb(scrl, lv_roller_scrl_signal); lv_style_list_copy(&ext->style_sel, ©_ext->style_sel); - lv_obj_refresh_style(roller, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(roller, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("roller created"); diff --git a/src/lv_widgets/lv_slider.c b/src/lv_widgets/lv_slider.c index bb83f9298..7e658226d 100644 --- a/src/lv_widgets/lv_slider.c +++ b/src/lv_widgets/lv_slider.c @@ -103,7 +103,7 @@ lv_obj_t * lv_slider_create(lv_obj_t * par, const lv_obj_t * copy) lv_area_copy(&ext->left_knob_area, ©_ext->left_knob_area); lv_area_copy(&ext->right_knob_area, ©_ext->right_knob_area); - lv_obj_refresh_style(slider, LV_OBJ_PART_ALL); + lv_obj_refresh_style(slider, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("slider created"); diff --git a/src/lv_widgets/lv_spinbox.c b/src/lv_widgets/lv_spinbox.c index 669c72d38..1fac9de80 100644 --- a/src/lv_widgets/lv_spinbox.c +++ b/src/lv_widgets/lv_spinbox.c @@ -106,7 +106,7 @@ lv_obj_t * lv_spinbox_create(lv_obj_t * par, const lv_obj_t * copy) lv_spinbox_set_rollover(spinbox, copy_ext->rollover); /*Refresh the style with new signal function*/ - lv_obj_refresh_style(spinbox, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(spinbox, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } lv_spinbox_updatevalue(spinbox); diff --git a/src/lv_widgets/lv_spinner.c b/src/lv_widgets/lv_spinner.c index 16c0e570b..8e0e2dcd0 100644 --- a/src/lv_widgets/lv_spinner.c +++ b/src/lv_widgets/lv_spinner.c @@ -106,7 +106,7 @@ lv_obj_t * lv_spinner_create(lv_obj_t * par, const lv_obj_t * copy) ext->time = copy_ext->time; ext->anim_dir = copy_ext->anim_dir; /*Refresh the style with new signal function*/ - lv_obj_refresh_style(spinner, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(spinner, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } lv_spinner_set_type(spinner, ext->anim_type); diff --git a/src/lv_widgets/lv_switch.c b/src/lv_widgets/lv_switch.c index dfc1aa964..9340f1efa 100644 --- a/src/lv_widgets/lv_switch.c +++ b/src/lv_widgets/lv_switch.c @@ -100,7 +100,7 @@ lv_obj_t * lv_switch_create(lv_obj_t * par, const lv_obj_t * copy) lv_switch_ext_t * copy_ext = lv_obj_get_ext_attr(copy); lv_style_list_copy(&ext->style_knob, ©_ext->style_knob); - lv_obj_refresh_style(sw, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(sw, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } /*Refresh the style with new signal function*/ diff --git a/src/lv_widgets/lv_table.c b/src/lv_widgets/lv_table.c index 0e44d1e5c..b35484e9a 100644 --- a/src/lv_widgets/lv_table.c +++ b/src/lv_widgets/lv_table.c @@ -110,7 +110,7 @@ lv_obj_t * lv_table_create(lv_obj_t * par, const lv_obj_t * copy) } /*Refresh the style with new signal function*/ - lv_obj_refresh_style(table, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(table, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("table created"); diff --git a/src/lv_widgets/lv_tabview.c b/src/lv_widgets/lv_tabview.c index f68d69a36..3f4efb3e8 100644 --- a/src/lv_widgets/lv_tabview.c +++ b/src/lv_widgets/lv_tabview.c @@ -180,11 +180,11 @@ lv_obj_t * lv_tabview_create(lv_obj_t * par, const lv_obj_t * copy) LV_PAGE_PART_SCROLLABLE)); lv_style_list_copy(lv_obj_get_style_list(new_tab, LV_PAGE_PART_SCROLLBAR), lv_obj_get_style_list(copy_tab, LV_PAGE_PART_SCROLLBAR)); - lv_obj_refresh_style(new_tab, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(new_tab, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } /*Refresh the style with new signal function*/ - lv_obj_refresh_style(tabview, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(tabview, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } tabview_realign(tabview); diff --git a/src/lv_widgets/lv_textarea.c b/src/lv_widgets/lv_textarea.c index 9cf859f82..e8a332c9e 100644 --- a/src/lv_widgets/lv_textarea.c +++ b/src/lv_widgets/lv_textarea.c @@ -187,7 +187,7 @@ lv_obj_t * lv_textarea_create(lv_obj_t * par, const lv_obj_t * copy) if(copy_ext->one_line) lv_textarea_set_one_line(ta, true); /*Refresh the style with new signal function*/ - lv_obj_refresh_style(ta, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(ta, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } #if LV_USE_ANIMATION diff --git a/src/lv_widgets/lv_tileview.c b/src/lv_widgets/lv_tileview.c index 0ea0f8133..3fa01503c 100644 --- a/src/lv_widgets/lv_tileview.c +++ b/src/lv_widgets/lv_tileview.c @@ -133,7 +133,7 @@ lv_obj_t * lv_tileview_create(lv_obj_t * par, const lv_obj_t * copy) #endif /*Refresh the style with new signal function*/ - lv_obj_refresh_style(new_tileview, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(new_tileview, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); } LV_LOG_INFO("tileview created"); diff --git a/src/lv_widgets/lv_win.c b/src/lv_widgets/lv_win.c index 20fbb7426..0e122976d 100644 --- a/src/lv_widgets/lv_win.c +++ b/src/lv_widgets/lv_win.c @@ -156,7 +156,7 @@ lv_obj_t * lv_win_create(lv_obj_t * par, const lv_obj_t * copy) } /*Refresh the style with new signal function*/ - lv_obj_refresh_style(new_win, LV_STYLE_PROP_ALL); + lv_obj_refresh_style(new_win, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); lv_win_realign(new_win); From ae0e855d912af9b3cbe4a0e1387f6b8d90dfe09f Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sun, 2 Aug 2020 20:49:21 +0200 Subject: [PATCH 097/173] style cache fixes --- src/lv_core/lv_obj.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 88474cd0b..0d32a25e1 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -2454,8 +2454,7 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl const lv_obj_t * parent = obj; while(parent) { lv_style_list_t * list = lv_obj_get_style_list(parent, part); - - if(!list->ignore_cache) { + if(!list->ignore_cache && list->style_cnt > 0) { if(!list->valid_cache) update_style_cache((lv_obj_t*)parent, part, prop & (~LV_STYLE_STATE_MASK)); bool def = false; @@ -2620,7 +2619,7 @@ lv_opa_t _lv_obj_get_style_opa(const lv_obj_t * obj, uint8_t part, lv_style_prop while(parent) { lv_style_list_t * list = lv_obj_get_style_list(parent, part); - if(!list->ignore_cache) { + if(!list->ignore_cache && list->style_cnt > 0) { if(!list->valid_cache) update_style_cache((lv_obj_t*)parent, part, prop & (~LV_STYLE_STATE_MASK)); bool def = false; switch(prop & (~LV_STYLE_STATE_MASK)) { @@ -2695,7 +2694,7 @@ const void * _lv_obj_get_style_ptr(const lv_obj_t * obj, uint8_t part, lv_style_ while(parent) { lv_style_list_t * list = lv_obj_get_style_list(parent, part); - if(!list->ignore_cache) { + if(!list->ignore_cache && list->style_cnt > 0) { if(!list->valid_cache) update_style_cache((lv_obj_t*)parent, part, prop & (~LV_STYLE_STATE_MASK)); bool def = false; switch(prop & (~LV_STYLE_STATE_MASK)) { @@ -4482,6 +4481,14 @@ static void update_style_cache_children(lv_obj_t * obj) list->ignore_cache = ignore_cache_ori; } + + + lv_obj_t * child = lv_obj_get_child(obj, NULL); + while(child) { + update_style_cache_children(child); + child = lv_obj_get_child(obj, child); + } + } /** @@ -4491,9 +4498,23 @@ static void update_style_cache_children(lv_obj_t * obj) */ static void invalidate_style_cache(lv_obj_t * obj, uint8_t part) { - lv_style_list_t * list = lv_obj_get_style_list(obj, part); - if(list == NULL) return; - list->valid_cache = 0; + if(part != LV_OBJ_PART_ALL) { + lv_style_list_t * list = lv_obj_get_style_list(obj, part); + if(list == NULL) return; + list->valid_cache = 0; + } else { + + for(part = 0; part < _LV_OBJ_PART_REAL_FIRST; part++) { + lv_style_list_t * list = lv_obj_get_style_list(obj, part); + if(list == NULL) break; + list->valid_cache = 0; + } + for(part = _LV_OBJ_PART_REAL_FIRST; part < 0xFF; part++) { + lv_style_list_t * list = lv_obj_get_style_list(obj, part); + if(list == NULL) break; + list->valid_cache = 0; + } + } lv_obj_t * child = lv_obj_get_child(obj, NULL); while(child) { From 1b29814e1ea4bdd6cf8b365e467e16e9c29c3036 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sun, 2 Aug 2020 22:25:26 +0200 Subject: [PATCH 098/173] improve style caching --- src/lv_core/lv_obj.c | 248 +++++++++++++++++++++++++++++----------- src/lv_core/lv_obj.h | 16 +++ src/lv_core/lv_style.c | 3 - src/lv_core/lv_style.h | 12 +- src/lv_widgets/lv_arc.c | 3 + 5 files changed, 204 insertions(+), 78 deletions(-) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 0d32a25e1..d3de68f0a 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -105,7 +105,7 @@ static void lv_obj_del_async_cb(void * obj); static void obj_del_core(lv_obj_t * obj); static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop); static void update_style_cache_children(lv_obj_t * obj); -static void invalidate_style_cache(lv_obj_t * obj, uint8_t part); +static void invalidate_style_cache(lv_obj_t * obj, uint8_t part, lv_style_property_t prop); /********************** * STATIC VARIABLES **********************/ @@ -505,43 +505,11 @@ void lv_obj_invalidate_area(const lv_obj_t * obj, const lv_area_t * area) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - if(lv_obj_get_hidden(obj)) return; + lv_area_t area_tmp; + lv_area_copy(&area_tmp, area); + bool visible = lv_obj_area_is_visible(obj, &area_tmp); - /*Invalidate the object only if it belongs to the curent or previous'*/ - lv_obj_t * obj_scr = lv_obj_get_screen(obj); - lv_disp_t * disp = lv_obj_get_disp(obj_scr); - if(obj_scr == lv_disp_get_scr_act(disp) || - obj_scr == lv_disp_get_scr_prev(disp) || - obj_scr == lv_disp_get_layer_top(disp) || - obj_scr == lv_disp_get_layer_sys(disp)) { - - /*Truncate the area to the object*/ - lv_area_t obj_coords; - lv_coord_t ext_size = obj->ext_draw_pad; - lv_area_copy(&obj_coords, &obj->coords); - obj_coords.x1 -= ext_size; - obj_coords.y1 -= ext_size; - obj_coords.x2 += ext_size; - obj_coords.y2 += ext_size; - - bool is_common; - lv_area_t area_trunc; - - is_common = _lv_area_intersect(&area_trunc, area, &obj_coords); - if(is_common == false) return; /*The area is not on the object*/ - - /*Truncate recursively to the parents*/ - lv_obj_t * par = lv_obj_get_parent(obj); - while(par != NULL) { - is_common = _lv_area_intersect(&area_trunc, &area_trunc, &par->coords); - if(is_common == false) break; /*If no common parts with parent break;*/ - if(lv_obj_get_hidden(par)) return; /*If the parent is hidden then the child is hidden and won't be drawn*/ - - par = lv_obj_get_parent(par); - } - - if(is_common) _lv_inv_area(disp, &area_trunc); - } + if(visible) _lv_inv_area(lv_obj_get_disp(obj), &area_tmp); } /** @@ -564,6 +532,74 @@ void lv_obj_invalidate(const lv_obj_t * obj) lv_obj_invalidate_area(obj, &obj_coords); } + +/** + * 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) +{ + if(lv_obj_get_hidden(obj)) return false; + + /*Invalidate the object only if it belongs to the curent or previous'*/ + lv_obj_t * obj_scr = lv_obj_get_screen(obj); + lv_disp_t * disp = lv_obj_get_disp(obj_scr); + if(obj_scr == lv_disp_get_scr_act(disp) || + obj_scr == lv_disp_get_scr_prev(disp) || + obj_scr == lv_disp_get_layer_top(disp) || + obj_scr == lv_disp_get_layer_sys(disp)) { + + /*Truncate the area to the object*/ + lv_area_t obj_coords; + lv_coord_t ext_size = obj->ext_draw_pad; + lv_area_copy(&obj_coords, &obj->coords); + obj_coords.x1 -= ext_size; + obj_coords.y1 -= ext_size; + obj_coords.x2 += ext_size; + obj_coords.y2 += ext_size; + + bool is_common; + + is_common = _lv_area_intersect(area, area, &obj_coords); + if(is_common == false) return false; /*The area is not on the object*/ + + /*Truncate recursively to the parents*/ + lv_obj_t * par = lv_obj_get_parent(obj); + while(par != NULL) { + is_common = _lv_area_intersect(area, area, &par->coords); + if(is_common == false) return false; /*If no common parts with parent break;*/ + if(lv_obj_get_hidden(par)) return false; /*If the parent is hidden then the child is hidden and won't be drawn*/ + + par = lv_obj_get_parent(par); + } + } + + return true; +} + +/** + * 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) +{ + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); + + lv_area_t obj_coords; + lv_coord_t ext_size = obj->ext_draw_pad; + lv_area_copy(&obj_coords, &obj->coords); + obj_coords.x1 -= ext_size; + obj_coords.y1 -= ext_size; + obj_coords.x2 += ext_size; + obj_coords.y2 += ext_size; + + return lv_obj_area_is_visible(obj, &obj_coords); + +} + /*===================== * Setter functions *====================*/ @@ -1302,7 +1338,7 @@ void lv_obj_refresh_style(lv_obj_t * obj, uint8_t part, lv_style_property_t prop { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - invalidate_style_cache(obj, part); + invalidate_style_cache(obj, part, prop); /*If a real style refresh is required*/ bool real_refr = false; @@ -2472,16 +2508,10 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl if(list->text_line_space_zero) def = true; break; case LV_STYLE_TRANSFORM_ANGLE: - if(list->transform_angle_zero) def = true; - break; case LV_STYLE_TRANSFORM_WIDTH: - if(list->transform_width_zero) def = true; - break; case LV_STYLE_TRANSFORM_HEIGHT: - if(list->transform_height_zero) def = true; - break; case LV_STYLE_TRANSFORM_ZOOM: - if(list->transform_zoom_zero) def = true; + if(list->transform_all_zero) def = true; break; case LV_STYLE_BORDER_WIDTH: if(list->border_width_zero) def = true; @@ -2495,9 +2525,28 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl case LV_STYLE_SHADOW_WIDTH: if(list->shadow_width_zero) def = true; break; + case LV_STYLE_PAD_TOP: + case LV_STYLE_PAD_BOTTOM: + case LV_STYLE_PAD_LEFT: + case LV_STYLE_PAD_RIGHT: + if(list->pad_all_zero) def = true; + break; + case LV_STYLE_BG_BLEND_MODE: + case LV_STYLE_BORDER_BLEND_MODE: + case LV_STYLE_IMAGE_BLEND_MODE: + case LV_STYLE_LINE_BLEND_MODE: + case LV_STYLE_OUTLINE_BLEND_MODE: + case LV_STYLE_PATTERN_BLEND_MODE: + case LV_STYLE_SHADOW_BLEND_MODE: + case LV_STYLE_TEXT_BLEND_MODE: + case LV_STYLE_VALUE_BLEND_MODE: + if(list->blend_mode_all_normal) def = true; + break; } - if(def) break; + if(def) { + break; + } } lv_state_t state = lv_obj_get_state(parent, part); @@ -2624,7 +2673,7 @@ lv_opa_t _lv_obj_get_style_opa(const lv_obj_t * obj, uint8_t part, lv_style_prop bool def = false; switch(prop & (~LV_STYLE_STATE_MASK)) { case LV_STYLE_OPA_SCALE: - if(list->opa_scale_transp) def = true; + if(list->opa_scale_cover) def = true; break; case LV_STYLE_BG_OPA: if(list->bg_opa_transp) def = true; @@ -2633,7 +2682,10 @@ lv_opa_t _lv_obj_get_style_opa(const lv_obj_t * obj, uint8_t part, lv_style_prop if(list->img_recolor_opa_transp) def = true; break; } - if(def) break; + + if(def) { + break; + } } @@ -2699,14 +2751,19 @@ const void * _lv_obj_get_style_ptr(const lv_obj_t * obj, uint8_t part, lv_style_ bool def = false; switch(prop & (~LV_STYLE_STATE_MASK)) { case LV_STYLE_VALUE_STR: - if(list->opa_scale_transp) def = true; + if(list->value_txt_str) def = true; break; case LV_STYLE_PATTERN_IMAGE: if(list->pattern_img_null) def = true; break; + case LV_STYLE_TEXT_FONT: + if(list->text_font_normal) def = true; + break; } - if(def) break; + if(def) { + break; + } } lv_state_t state = lv_obj_get_state(parent, part); @@ -4378,17 +4435,11 @@ static bool obj_valid_child(const lv_obj_t * parent, const lv_obj_t * obj_to_fin return false; } -/** - * Update the cache of style list - * @param obj pointer to an obejct - * @param part the part of the object - * @param prop the property which triggered the update - */ -static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop) +static bool style_prop_is_cacheble(lv_style_property_t prop) { - bool cachable; switch(prop) { + case LV_STYLE_PROP_ALL: case LV_STYLE_BG_GRAD_DIR: case LV_STYLE_CLIP_CORNER: case LV_STYLE_TEXT_LETTER_SPACE: @@ -4406,23 +4457,50 @@ static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop) case LV_STYLE_IMAGE_RECOLOR_OPA: case LV_STYLE_VALUE_STR: case LV_STYLE_PATTERN_IMAGE: - cachable = true; + case LV_STYLE_PAD_TOP: + case LV_STYLE_PAD_BOTTOM: + case LV_STYLE_PAD_LEFT: + case LV_STYLE_PAD_RIGHT: + case LV_STYLE_BG_BLEND_MODE: + case LV_STYLE_BORDER_BLEND_MODE: + case LV_STYLE_IMAGE_BLEND_MODE: + case LV_STYLE_LINE_BLEND_MODE: + case LV_STYLE_OUTLINE_BLEND_MODE: + case LV_STYLE_PATTERN_BLEND_MODE: + case LV_STYLE_SHADOW_BLEND_MODE: + case LV_STYLE_TEXT_BLEND_MODE: + case LV_STYLE_VALUE_BLEND_MODE: + return true; break; default: - cachable = false; + return false; } +} - if(!cachable) return; +/** + * Update the cache of style list + * @param obj pointer to an obejct + * @param part the part of the object + * @param prop the property which triggered the update + */ +static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop) +{ + if(style_prop_is_cacheble(prop) == false) return; lv_style_list_t * list = lv_obj_get_style_list(obj, part); bool ignore_cache_ori = list->ignore_cache; list->ignore_cache = 1; - list->opa_scale_transp = lv_obj_get_style_opa_scale(obj, part) == LV_OPA_TRANSP ? 1 : 0; +#if LV_USE_OPA_SCALE + list->opa_scale_cover = lv_obj_get_style_opa_scale(obj, part) == LV_OPA_COVER ? 1 : 0; +#else + list->opa_scale_cover = 1; +#endif list->text_decor_none = lv_obj_get_style_text_decor(obj, part) == LV_TEXT_DECOR_NONE ? 1 : 0; list->text_letter_space_zero = lv_obj_get_style_text_letter_space(obj, part) == 0 ? 1 : 0; list->text_line_space_zero = lv_obj_get_style_text_line_space(obj, part) == 0 ? 1 : 0; + list->text_font_normal = lv_obj_get_style_text_font(obj, part) == LV_THEME_DEFAULT_FONT_NORMAL ? 1 : 0; list->bg_grad_dir_none = lv_obj_get_style_bg_grad_dir(obj, part) == LV_GRAD_DIR_NONE ? 1 : 0; list->bg_opa_transp = lv_obj_get_style_bg_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; @@ -4433,12 +4511,42 @@ static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop) list->outline_width_zero = lv_obj_get_style_outline_width(obj, part) == 0 ? 1 : 0; list->pattern_img_null = lv_obj_get_style_pattern_image(obj, part) == NULL ? 1 : 0; list->shadow_width_zero = lv_obj_get_style_shadow_width(obj, part) == 0 ? 1 : 0; - list->transform_angle_zero = lv_obj_get_style_transform_angle(obj, part) == 0 ? 1 : 0; - list->transform_height_zero = lv_obj_get_style_transform_width(obj, part) == 0 ? 1 : 0; - list->transform_width_zero = lv_obj_get_style_transform_height(obj, part) == 0 ? 1 : 0; - list->transform_zoom_zero = lv_obj_get_style_transform_zoom(obj, part) == LV_IMG_ZOOM_NONE ? 1 : 0; list->value_txt_str = lv_obj_get_style_value_str(obj, part) == NULL ? 1 : 0; + + list->transform_all_zero = 1; + if(lv_obj_get_style_transform_angle(obj, part) != 0 || + lv_obj_get_style_transform_width(obj, part) != 0 || + lv_obj_get_style_transform_height(obj, part) != 0 || + lv_obj_get_style_transform_zoom(obj, part) != LV_IMG_ZOOM_NONE) + { + list->transform_all_zero = 0; + } + + list->pad_all_zero = 1; + if(lv_obj_get_style_pad_top(obj, part) != 0 || + lv_obj_get_style_pad_bottom(obj, part) != 0 || + lv_obj_get_style_pad_left(obj, part) != 0 || + lv_obj_get_style_pad_right(obj, part) != 0) + { + list->pad_all_zero = 0; + } + + list->blend_mode_all_normal = 1; +#if LV_USE_BLEND_MODES + if(lv_obj_get_style_bg_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_border_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_pattern_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_outline_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_value_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_text_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_line_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_image_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_shadow_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL) + { + list->blend_mode_all_normal = 0; + } +#endif list->ignore_cache = ignore_cache_ori; list->valid_cache = 1; } @@ -4473,16 +4581,16 @@ static void update_style_cache_children(lv_obj_t * obj) bool ignore_cache_ori = list->ignore_cache; list->ignore_cache = 1; - list->opa_scale_transp = lv_obj_get_style_opa_scale(obj, part) == LV_OPA_TRANSP ? 1 : 0; + list->opa_scale_cover = lv_obj_get_style_opa_scale(obj, part) == LV_OPA_COVER ? 1 : 0; list->text_decor_none = lv_obj_get_style_text_decor(obj, part) == LV_TEXT_DECOR_NONE ? 1 : 0; list->text_letter_space_zero = lv_obj_get_style_text_letter_space(obj, part) == 0 ? 1 : 0; list->text_line_space_zero = lv_obj_get_style_text_line_space(obj, part) == 0 ? 1 : 0; + list->text_font_normal = lv_obj_get_style_text_font(obj, part) == lv_theme_get_font_normal() ? 1 : 0; list->img_recolor_opa_transp = lv_obj_get_style_image_recolor_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; list->ignore_cache = ignore_cache_ori; } - lv_obj_t * child = lv_obj_get_child(obj, NULL); while(child) { update_style_cache_children(child); @@ -4496,8 +4604,10 @@ static void update_style_cache_children(lv_obj_t * obj) * The cache will be updated when a cached property asked nest time * @param obj pointer to an object */ -static void invalidate_style_cache(lv_obj_t * obj, uint8_t part) +static void invalidate_style_cache(lv_obj_t * obj, uint8_t part, lv_style_property_t prop) { + if(style_prop_is_cacheble(prop) == false) return; + if(part != LV_OBJ_PART_ALL) { lv_style_list_t * list = lv_obj_get_style_list(obj, part); if(list == NULL) return; diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index c5f9b0cd4..0a68c4d1e 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -353,6 +353,22 @@ void lv_obj_invalidate_area(const lv_obj_t * obj, const lv_area_t * area); */ 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); + /*===================== * Setter functions *====================*/ diff --git a/src/lv_core/lv_style.c b/src/lv_core/lv_style.c index 7428ac731..ce3665e0d 100644 --- a/src/lv_core/lv_style.c +++ b/src/lv_core/lv_style.c @@ -1052,9 +1052,6 @@ bool lv_debug_check_style_list(const lv_style_list_t * list) */ LV_ATTRIBUTE_FAST_MEM static inline int32_t get_property_index(const lv_style_t * style, lv_style_property_t prop) { - static uint32_t c = 0; - c++; - if(c % 100 == 0) printf("%d\n", c); LV_ASSERT_STYLE(style); if(style->map == NULL) return -1; diff --git a/src/lv_core/lv_style.h b/src/lv_core/lv_style.h index 0db481ec8..c2eb75e77 100644 --- a/src/lv_core/lv_style.h +++ b/src/lv_core/lv_style.h @@ -227,19 +227,18 @@ typedef struct { uint32_t skip_trans :1; /*1: Temporally skip the transition style if any*/ uint32_t ignore_trans :1; /*1: Mark that this style list shouldn't receive transitions at all*/ uint32_t valid_cache :1; /*1: The cache is invalid and needs to be updated*/ - uint8_t ignore_cache :1; /**1: Ignore style cache while getting value of properties*/ + uint32_t ignore_cache :1; /**1: Ignore style cache while getting value of properties*/ - uint32_t opa_scale_transp :1; + uint32_t opa_scale_cover :1; uint32_t clip_corner_off :1; - uint32_t transform_width_zero :1; - uint32_t transform_height_zero :1; - uint32_t transform_angle_zero :1; - uint32_t transform_zoom_zero :1; + uint32_t transform_all_zero :1; uint32_t bg_opa_transp :1; uint32_t bg_grad_dir_none :1; + uint32_t blend_mode_all_normal :1; uint32_t border_width_zero :1; uint32_t outline_width_zero :1; uint32_t pattern_img_null :1; + uint32_t pad_all_zero :1; uint32_t shadow_width_zero :1; uint32_t value_txt_str :1; uint32_t line_width_zerop :1; @@ -247,6 +246,7 @@ typedef struct { uint32_t text_letter_space_zero :1; uint32_t text_line_space_zero :1; uint32_t text_decor_none :1; + uint32_t text_font_normal :1; } lv_style_list_t; /********************** diff --git a/src/lv_widgets/lv_arc.c b/src/lv_widgets/lv_arc.c index f7cf087f1..f85b29c60 100644 --- a/src/lv_widgets/lv_arc.c +++ b/src/lv_widgets/lv_arc.c @@ -515,6 +515,9 @@ static lv_style_list_t * lv_arc_get_style(lv_obj_t * arc, uint8_t part) static void inv_arc_area(lv_obj_t * arc, uint16_t start_angle, uint16_t end_angle) { + /*Skip this complicated invalidation if the arc is not visible*/ + if(lv_obj_is_visible(arc) == false) return; + lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc); start_angle += ext->rotation_angle; From 6ccfd0101afbcb3cc8e60ab9b15871665643edab Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 3 Aug 2020 07:03:54 +0200 Subject: [PATCH 099/173] style cache: add missing LV_STYLE_FONT_TEXT to cachable proeprties --- src/lv_core/lv_obj.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index d3de68f0a..b4e964e44 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -4444,6 +4444,7 @@ static bool style_prop_is_cacheble(lv_style_property_t prop) case LV_STYLE_CLIP_CORNER: case LV_STYLE_TEXT_LETTER_SPACE: case LV_STYLE_TEXT_LINE_SPACE: + case LV_STYLE_TEXT_FONT: case LV_STYLE_TRANSFORM_ANGLE: case LV_STYLE_TRANSFORM_WIDTH: case LV_STYLE_TRANSFORM_HEIGHT: From 61a5cb44b8ff13237ba66cc4de0a946ee04f4395 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 3 Aug 2020 07:17:21 +0200 Subject: [PATCH 100/173] optimze style asking order in lv_obj_init_draw_xxx_dsc function --- src/lv_core/lv_obj.c | 43 +++++++++++++++++++++--------------------- src/lv_core/lv_style.h | 6 +++--- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index b4e964e44..33122c96d 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -2517,7 +2517,7 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl if(list->border_width_zero) def = true; break; case LV_STYLE_LINE_WIDTH: - if(list->line_width_zerop) def = true; + if(list->line_width_zero) def = true; break; case LV_STYLE_OUTLINE_WIDTH: if(list->outline_width_zero) def = true; @@ -3283,9 +3283,9 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint8_t part, lv_draw_rect_dsc_t } } - 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_width = lv_obj_get_style_border_width(obj, part); + if(draw_dsc->border_width) { + if(draw_dsc->border_opa != LV_OPA_TRANSP) { 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); @@ -3297,10 +3297,9 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint8_t part, lv_draw_rect_dsc_t } } - - 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_width = lv_obj_get_style_outline_width(obj, part); + if(draw_dsc->outline_width) { + if(draw_dsc->outline_opa != LV_OPA_TRANSP) { 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); @@ -3312,9 +3311,9 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint8_t part, lv_draw_rect_dsc_t } } - if(draw_dsc->pattern_opa != LV_OPA_TRANSP) { - draw_dsc->pattern_image = lv_obj_get_style_pattern_image(obj, part); - if(draw_dsc->pattern_image) { + draw_dsc->pattern_image = lv_obj_get_style_pattern_image(obj, part); + if(draw_dsc->pattern_image) { + if(draw_dsc->pattern_opa != LV_OPA_TRANSP) { draw_dsc->pattern_opa = lv_obj_get_style_pattern_opa(obj, part); if(draw_dsc->pattern_opa > LV_OPA_MIN) { draw_dsc->pattern_recolor_opa = lv_obj_get_style_pattern_recolor_opa(obj, part); @@ -3333,9 +3332,9 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint8_t part, lv_draw_rect_dsc_t } } #if LV_USE_SHADOW - if(draw_dsc->shadow_opa > LV_OPA_MIN) { - draw_dsc->shadow_width = lv_obj_get_style_shadow_width(obj, part); - if(draw_dsc->shadow_width) { + 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_ofs_x = lv_obj_get_style_shadow_ofs_x(obj, part); @@ -3350,9 +3349,9 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint8_t part, lv_draw_rect_dsc_t } #endif - if(draw_dsc->value_opa > LV_OPA_MIN) { - draw_dsc->value_str = lv_obj_get_style_value_str(obj, part); - if(draw_dsc->value_str) { + draw_dsc->value_str = lv_obj_get_style_value_str(obj, part); + if(draw_dsc->value_str) { + if(draw_dsc->value_opa > LV_OPA_MIN) { draw_dsc->value_opa = lv_obj_get_style_value_opa(obj, part); if(draw_dsc->value_opa > LV_OPA_MIN) { draw_dsc->value_ofs_x = lv_obj_get_style_value_ofs_x(obj, part); @@ -3441,6 +3440,9 @@ void lv_obj_init_draw_img_dsc(lv_obj_t * obj, uint8_t part, lv_draw_img_dsc_t * void lv_obj_init_draw_line_dsc(lv_obj_t * obj, uint8_t part, lv_draw_line_dsc_t * draw_dsc) { + draw_dsc->width = lv_obj_get_style_line_width(obj, part); + if(draw_dsc->width == 0) return; + draw_dsc->opa = lv_obj_get_style_line_opa(obj, part); if(draw_dsc->opa <= LV_OPA_MIN) return; @@ -3452,9 +3454,6 @@ void lv_obj_init_draw_line_dsc(lv_obj_t * obj, uint8_t part, lv_draw_line_dsc_t if(draw_dsc->opa <= LV_OPA_MIN) return; #endif - 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(obj, part); draw_dsc->dash_width = lv_obj_get_style_line_dash_width(obj, part); @@ -4505,10 +4504,10 @@ static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop) list->bg_grad_dir_none = lv_obj_get_style_bg_grad_dir(obj, part) == LV_GRAD_DIR_NONE ? 1 : 0; list->bg_opa_transp = lv_obj_get_style_bg_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; - list->border_width_zero = lv_obj_get_style_border_width(obj, part) == LV_OPA_TRANSP ? 1 : 0; + list->border_width_zero = lv_obj_get_style_border_width(obj, part) == 0 ? 1 : 0; list->clip_corner_off = lv_obj_get_style_clip_corner(obj, part) == false ? 1 : 0; list->img_recolor_opa_transp = lv_obj_get_style_image_recolor_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; - list->line_width_zerop = lv_obj_get_style_line_width(obj, part) == 0 ? 1 : 0; + list->line_width_zero = lv_obj_get_style_line_width(obj, part) == 0 ? 1 : 0; list->outline_width_zero = lv_obj_get_style_outline_width(obj, part) == 0 ? 1 : 0; list->pattern_img_null = lv_obj_get_style_pattern_image(obj, part) == NULL ? 1 : 0; list->shadow_width_zero = lv_obj_get_style_shadow_width(obj, part) == 0 ? 1 : 0; diff --git a/src/lv_core/lv_style.h b/src/lv_core/lv_style.h index c2eb75e77..78bb93783 100644 --- a/src/lv_core/lv_style.h +++ b/src/lv_core/lv_style.h @@ -226,8 +226,8 @@ typedef struct { uint32_t has_trans :1; uint32_t skip_trans :1; /*1: Temporally skip the transition style if any*/ uint32_t ignore_trans :1; /*1: Mark that this style list shouldn't receive transitions at all*/ - uint32_t valid_cache :1; /*1: The cache is invalid and needs to be updated*/ - uint32_t ignore_cache :1; /**1: Ignore style cache while getting value of properties*/ + uint32_t valid_cache :1; /*1: The cache is valid and can be used*/ + uint32_t ignore_cache :1; /*1: Ignore cache while getting value of properties*/ uint32_t opa_scale_cover :1; uint32_t clip_corner_off :1; @@ -241,7 +241,7 @@ typedef struct { uint32_t pad_all_zero :1; uint32_t shadow_width_zero :1; uint32_t value_txt_str :1; - uint32_t line_width_zerop :1; + uint32_t line_width_zero :1; uint32_t img_recolor_opa_transp :1; uint32_t text_letter_space_zero :1; uint32_t text_line_space_zero :1; From 07cb113c0a1b0892e67f5340a6ed402b347a26b9 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 3 Aug 2020 09:37:01 +0200 Subject: [PATCH 101/173] add radius, border_side and boder_post to style cache --- src/lv_core/lv_obj.c | 45 +++++++++++++++++++++++++++++++----------- src/lv_core/lv_style.c | 1 - src/lv_core/lv_style.h | 19 +++++++++++------- 3 files changed, 45 insertions(+), 20 deletions(-) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 33122c96d..4b51c7b04 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -2502,10 +2502,8 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl if(list->clip_corner_off) def = true; break; case LV_STYLE_TEXT_LETTER_SPACE: - if(list->text_letter_space_zero) def = true; - break; case LV_STYLE_TEXT_LINE_SPACE: - if(list->text_line_space_zero) def = true; + if(list->text_space_zero) def = true; break; case LV_STYLE_TRANSFORM_ANGLE: case LV_STYLE_TRANSFORM_WIDTH: @@ -2516,12 +2514,18 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl case LV_STYLE_BORDER_WIDTH: if(list->border_width_zero) def = true; break; - case LV_STYLE_LINE_WIDTH: - if(list->line_width_zero) def = true; + case LV_STYLE_BORDER_SIDE: + if(list->border_side_full) def = true; + break; + case LV_STYLE_BORDER_POST: + if(list->border_post_off) def = true; break; case LV_STYLE_OUTLINE_WIDTH: if(list->outline_width_zero) def = true; break; + case LV_STYLE_RADIUS: + if(list->radius_zero) def = true; + break; case LV_STYLE_SHADOW_WIDTH: if(list->shadow_width_zero) def = true; break; @@ -2676,6 +2680,7 @@ lv_opa_t _lv_obj_get_style_opa(const lv_obj_t * obj, uint8_t part, lv_style_prop if(list->opa_scale_cover) def = true; break; case LV_STYLE_BG_OPA: + if(list->bg_opa_cover) return LV_OPA_COVER; /*Special case, not the default value is used*/ if(list->bg_opa_transp) def = true; break; case LV_STYLE_IMAGE_RECOLOR_OPA: @@ -4449,11 +4454,13 @@ static bool style_prop_is_cacheble(lv_style_property_t prop) case LV_STYLE_TRANSFORM_HEIGHT: case LV_STYLE_TRANSFORM_ZOOM: case LV_STYLE_BORDER_WIDTH: - case LV_STYLE_LINE_WIDTH: case LV_STYLE_OUTLINE_WIDTH: + case LV_STYLE_RADIUS: case LV_STYLE_SHADOW_WIDTH: case LV_STYLE_OPA_SCALE: case LV_STYLE_BG_OPA: + case LV_STYLE_BORDER_SIDE: + case LV_STYLE_BORDER_POST: case LV_STYLE_IMAGE_RECOLOR_OPA: case LV_STYLE_VALUE_STR: case LV_STYLE_PATTERN_IMAGE: @@ -4498,18 +4505,28 @@ static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop) list->opa_scale_cover = 1; #endif list->text_decor_none = lv_obj_get_style_text_decor(obj, part) == LV_TEXT_DECOR_NONE ? 1 : 0; - list->text_letter_space_zero = lv_obj_get_style_text_letter_space(obj, part) == 0 ? 1 : 0; - list->text_line_space_zero = lv_obj_get_style_text_line_space(obj, part) == 0 ? 1 : 0; list->text_font_normal = lv_obj_get_style_text_font(obj, part) == LV_THEME_DEFAULT_FONT_NORMAL ? 1 : 0; + list->text_space_zero = 1; + if(lv_obj_get_style_text_letter_space(obj, part) != 0 || + lv_obj_get_style_text_line_space(obj, part) != 0) { + list->text_space_zero = 0; + } + + + lv_opa_t bg_opa = lv_obj_get_style_bg_opa(obj, part); + list->bg_opa_transp = bg_opa == LV_OPA_TRANSP ? 1 : 0; + list->bg_opa_cover = bg_opa == LV_OPA_COVER ? 1 : 0; + list->bg_grad_dir_none = lv_obj_get_style_bg_grad_dir(obj, part) == LV_GRAD_DIR_NONE ? 1 : 0; - list->bg_opa_transp = lv_obj_get_style_bg_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; list->border_width_zero = lv_obj_get_style_border_width(obj, part) == 0 ? 1 : 0; + list->border_side_full = lv_obj_get_style_border_side(obj, part) == LV_BORDER_SIDE_FULL ? 1 : 0; + list->border_post_off = lv_obj_get_style_border_post(obj, part) == 0 ? 1 : 0; list->clip_corner_off = lv_obj_get_style_clip_corner(obj, part) == false ? 1 : 0; list->img_recolor_opa_transp = lv_obj_get_style_image_recolor_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; - list->line_width_zero = lv_obj_get_style_line_width(obj, part) == 0 ? 1 : 0; list->outline_width_zero = lv_obj_get_style_outline_width(obj, part) == 0 ? 1 : 0; list->pattern_img_null = lv_obj_get_style_pattern_image(obj, part) == NULL ? 1 : 0; + list->radius_zero = lv_obj_get_style_radius(obj, part) == 0 ? 1 : 0; list->shadow_width_zero = lv_obj_get_style_shadow_width(obj, part) == 0 ? 1 : 0; list->value_txt_str = lv_obj_get_style_value_str(obj, part) == NULL ? 1 : 0; @@ -4583,11 +4600,15 @@ static void update_style_cache_children(lv_obj_t * obj) list->opa_scale_cover = lv_obj_get_style_opa_scale(obj, part) == LV_OPA_COVER ? 1 : 0; list->text_decor_none = lv_obj_get_style_text_decor(obj, part) == LV_TEXT_DECOR_NONE ? 1 : 0; - list->text_letter_space_zero = lv_obj_get_style_text_letter_space(obj, part) == 0 ? 1 : 0; - list->text_line_space_zero = lv_obj_get_style_text_line_space(obj, part) == 0 ? 1 : 0; list->text_font_normal = lv_obj_get_style_text_font(obj, part) == lv_theme_get_font_normal() ? 1 : 0; list->img_recolor_opa_transp = lv_obj_get_style_image_recolor_opa(obj, part) == LV_OPA_TRANSP ? 1 : 0; + list->text_space_zero = 1; + if(lv_obj_get_style_text_letter_space(obj, part) != 0 || + lv_obj_get_style_text_line_space(obj, part) != 0) { + list->text_space_zero = 0; + } + list->ignore_cache = ignore_cache_ori; } diff --git a/src/lv_core/lv_style.c b/src/lv_core/lv_style.c index ce3665e0d..04ccd3a16 100644 --- a/src/lv_core/lv_style.c +++ b/src/lv_core/lv_style.c @@ -1037,7 +1037,6 @@ bool lv_debug_check_style_list(const lv_style_list_t * list) return true; } - /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/lv_core/lv_style.h b/src/lv_core/lv_style.h index 78bb93783..93f7371b5 100644 --- a/src/lv_core/lv_style.h +++ b/src/lv_core/lv_style.h @@ -221,7 +221,7 @@ typedef struct { #if LV_USE_ASSERT_STYLE uint32_t sentinel; #endif - uint32_t style_cnt :7; + uint32_t style_cnt :6; uint32_t has_local :1; uint32_t has_trans :1; uint32_t skip_trans :1; /*1: Temporally skip the transition style if any*/ @@ -229,22 +229,27 @@ typedef struct { uint32_t valid_cache :1; /*1: The cache is valid and can be used*/ uint32_t ignore_cache :1; /*1: Ignore cache while getting value of properties*/ + uint32_t radius_zero :1; uint32_t opa_scale_cover :1; uint32_t clip_corner_off :1; uint32_t transform_all_zero :1; - uint32_t bg_opa_transp :1; - uint32_t bg_grad_dir_none :1; + uint32_t pad_all_zero :1; uint32_t blend_mode_all_normal :1; + uint32_t bg_opa_transp :1; + uint32_t bg_opa_cover :1; + uint32_t bg_grad_dir_none :1; + uint32_t border_width_zero :1; + uint32_t border_side_full :1; + uint32_t border_post_off :1; + uint32_t outline_width_zero :1; uint32_t pattern_img_null :1; - uint32_t pad_all_zero :1; uint32_t shadow_width_zero :1; uint32_t value_txt_str :1; - uint32_t line_width_zero :1; uint32_t img_recolor_opa_transp :1; - uint32_t text_letter_space_zero :1; - uint32_t text_line_space_zero :1; + + uint32_t text_space_zero :1; uint32_t text_decor_none :1; uint32_t text_font_normal :1; } lv_style_list_t; From 62f4ced29429052ddb5de556bf82ac5fe2830509 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 4 Aug 2020 17:34:44 +0200 Subject: [PATCH 102/173] update version number --- lvgl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lvgl.h b/lvgl.h index 94a53df2c..ae383e640 100644 --- a/lvgl.h +++ b/lvgl.h @@ -77,9 +77,9 @@ extern "C" { *********************/ /*Current version of LVGL*/ #define LVGL_VERSION_MAJOR 7 -#define LVGL_VERSION_MINOR 3 +#define LVGL_VERSION_MINOR 4 #define LVGL_VERSION_PATCH 0 -#define LVGL_VERSION_INFO "" +#define LVGL_VERSION_INFO "dev" /********************** * TYPEDEFS From f58d97d9905272665b9d412d02c0c2ac27f13d14 Mon Sep 17 00:00:00 2001 From: Fabio Guerra Date: Mon, 3 Aug 2020 19:33:52 -0300 Subject: [PATCH 103/173] Adding support to dynamic font loading. --- src/lv_font/lv_font.mk | 1 + src/lv_font/lv_font_loader.c | 589 +++++++++++++++++++++++ src/lv_font/lv_font_loader.h | 44 ++ tests/Makefile | 1 + tests/lv_test_assert.c | 9 + tests/lv_test_assert.h | 1 + tests/lv_test_core/lv_test_core.c | 2 + tests/lv_test_core/lv_test_font_loader.c | 154 ++++++ tests/lv_test_core/lv_test_font_loader.h | 39 ++ tests/lv_test_main.c | 69 +++ 10 files changed, 909 insertions(+) create mode 100644 src/lv_font/lv_font_loader.c create mode 100644 src/lv_font/lv_font_loader.h create mode 100644 tests/lv_test_core/lv_test_font_loader.c create mode 100644 tests/lv_test_core/lv_test_font_loader.h diff --git a/src/lv_font/lv_font.mk b/src/lv_font/lv_font.mk index 9f9eabede..5b2f8bc05 100644 --- a/src/lv_font/lv_font.mk +++ b/src/lv_font/lv_font.mk @@ -1,5 +1,6 @@ CSRCS += lv_font.c CSRCS += lv_font_fmt_txt.c +CSRCS += lv_font_loader.c CSRCS += lv_font_montserrat_12.c CSRCS += lv_font_montserrat_14.c CSRCS += lv_font_montserrat_16.c diff --git a/src/lv_font/lv_font_loader.c b/src/lv_font/lv_font_loader.c new file mode 100644 index 000000000..750cdc25d --- /dev/null +++ b/src/lv_font/lv_font_loader.c @@ -0,0 +1,589 @@ +/** + * @file lv_font_loader.c + * + */ + +/********************* + * INCLUDES + *********************/ +#if LV_USE_FILESYSTEM + +#include +#include + +#include "../lvgl.h" +#include "../lv_misc/lv_fs.h" +#include "lv_font_loader.h" + + +/********************** + * TYPEDEFS + **********************/ +typedef struct { + lv_fs_file_t * fp; + int8_t bit_pos; + uint8_t byte_value; +} bit_iterator_t; + +typedef struct font_header_bin { + uint32_t version; + uint16_t tables_count; + uint16_t font_size; + uint16_t ascent; + int16_t descent; + uint16_t typo_ascent; + int16_t typo_descent; + uint16_t typo_line_gap; + int16_t min_y; + int16_t max_y; + uint16_t default_advance_width; + uint16_t kerning_scale; + uint8_t index_to_loc_format; + uint8_t glyph_id_format; + uint8_t advance_width_format; + uint8_t bits_per_pixel; + uint8_t xy_bits; + uint8_t wh_bits; + uint8_t advance_width_bits; + uint8_t compression_id; + uint8_t subpixels_mode; + uint8_t padding; +} font_header_bin_t; + +typedef struct cmap_table_bin +{ + uint32_t cmaps_subtable_length; + uint32_t range_start; + uint16_t range_length; + uint16_t glyph_id_start; + uint16_t data_entries_count; + uint8_t format_type; + uint8_t padding; +} cmap_table_bin_t; + + +/********************** + * STATIC PROTOTYPES + **********************/ +static bit_iterator_t init_bit_iterator(lv_fs_file_t * fp); +static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font); + +static int read_bits_signed(bit_iterator_t *it, int n_bits, lv_fs_res_t * res); +static int read_bits(bit_iterator_t *it, int n_bits, lv_fs_res_t * res); + + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_font_t * lv_font_load(const char * font_name) +{ + bool success = false; + + lv_font_t * font = lv_mem_alloc(sizeof(lv_font_t)); + memset(font, 0, sizeof(lv_font_t)); + + lv_fs_file_t file; + lv_fs_res_t res = lv_fs_open(&file, font_name, LV_FS_MODE_RD); + + if(res == LV_FS_RES_OK) { + success = lvgl_load_font(&file, font); + } + + if (!success) + { + LV_LOG_WARN("Error opening font file: %s\n", font_name); + lv_font_free(font); + font = NULL; + } + + lv_fs_close(&file); + + return font; +} + + +void lv_font_free(lv_font_t * font) +{ + if(NULL != font) { + lv_font_fmt_txt_dsc_t * dsc = (lv_font_fmt_txt_dsc_t *) font->dsc; + + if(NULL != dsc) { + lv_font_fmt_txt_kern_classes_t * kern_dsc = + (lv_font_fmt_txt_kern_classes_t *) dsc->kern_dsc; + + if(NULL != kern_dsc) { + if(kern_dsc->class_pair_values) + lv_mem_free((void *) kern_dsc->class_pair_values); + + if(kern_dsc->left_class_mapping) + lv_mem_free((void *) kern_dsc->left_class_mapping); + + if(kern_dsc->right_class_mapping) + lv_mem_free((void *) kern_dsc->right_class_mapping); + + lv_mem_free((void *) kern_dsc); + } + + lv_font_fmt_txt_cmap_t * cmaps = + (lv_font_fmt_txt_cmap_t *) dsc->cmaps; + + if(NULL != cmaps) { + for(int i = 0; i < dsc->cmap_num; ++i) { + if(NULL != cmaps[i].glyph_id_ofs_list) + lv_mem_free((void *) cmaps[i].glyph_id_ofs_list); + if(NULL != cmaps[i].unicode_list) + lv_mem_free((void *) cmaps[i].unicode_list); + } + lv_mem_free(cmaps); + } + + if(NULL != dsc->glyph_bitmap) { + lv_mem_free((void *) dsc->glyph_bitmap); + } + if(NULL != dsc->glyph_dsc) { + lv_mem_free((void *) dsc->glyph_dsc); + } + lv_mem_free(dsc); + } + lv_mem_free(font); + } +} + + +/********************** + * STATIC FUNCTIONS + **********************/ + +static bit_iterator_t init_bit_iterator(lv_fs_file_t * fp) +{ + bit_iterator_t it; + it.fp = fp; + it.bit_pos = -1; + it.byte_value = 0; + return it; +} + +static int read_bits(bit_iterator_t *it, int n_bits, lv_fs_res_t * res) +{ + int value = 0; + while(n_bits--) { + it->byte_value = it->byte_value << 1; + it->bit_pos--; + + if(it->bit_pos < 0) { + it->bit_pos = 7; + *res = lv_fs_read(it->fp, &(it->byte_value), 1, NULL); + if (*res != LV_FS_RES_OK) { + return -1; + } + } + int8_t bit = (it->byte_value & 0x80) ? 1 : 0; + + value |= (bit << n_bits); + } + *res = LV_FS_RES_OK; + return value; +} + +static int read_bits_signed(bit_iterator_t *it, int n_bits, lv_fs_res_t * res) +{ + int value = read_bits(it, n_bits, res); + if (value & (1 << (n_bits-1))) { + for (int bit = n_bits; bit < 8; ++bit) { + value |= (1 << bit); + } + } + return value; +} + +static int read_label(lv_fs_file_t *fp, int start, const char *label) +{ + lv_fs_seek(fp, start); + + uint32_t length; + char buf[4]; + + if(lv_fs_read(fp, &length, 4, NULL) != LV_FS_RES_OK + || lv_fs_read(fp, buf, 4, NULL) != LV_FS_RES_OK + || memcmp(label, buf, 4) != 0) { + LV_LOG_WARN("Error reading '%s'.", label); + return -1; + } + + return length; +} + +static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font) +{ + lv_font_fmt_txt_dsc_t * font_dsc = (lv_font_fmt_txt_dsc_t *) + lv_mem_alloc(sizeof(lv_font_fmt_txt_dsc_t)); + + memset(font_dsc, 0, sizeof(lv_font_fmt_txt_dsc_t)); + + font->dsc = font_dsc; + + // header + int32_t header_length = read_label(fp, 0, "head"); + if (header_length < 0) { + return false; + } + + font_header_bin_t font_header; + if(lv_fs_read(fp, &font_header, sizeof(font_header_bin_t), NULL) != LV_FS_RES_OK) { + return false; + } + + font->base_line = -font_header.descent; + font->line_height = font_header.ascent - font_header.descent; + font->get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt; + font->get_glyph_bitmap = lv_font_get_bitmap_fmt_txt; + +#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) + font->subpx = LV_FONT_SUBPX_NONE; +#endif + + font_dsc->bpp = font_header.bits_per_pixel; + font_dsc->kern_scale = font_header.kerning_scale; + font_dsc->bitmap_format = font_header.compression_id; + + // cmaps + uint32_t cmaps_start = header_length; + int32_t cmaps_length = read_label(fp, cmaps_start, "cmap"); + if (cmaps_length < 0) { + return false; + } + + uint32_t cmaps_subtables_count; + if(lv_fs_read(fp, &cmaps_subtables_count, sizeof(uint32_t), NULL) != LV_FS_RES_OK) { + return false; + } + + lv_font_fmt_txt_cmap_t * cmaps = + lv_mem_alloc(cmaps_subtables_count * sizeof(lv_font_fmt_txt_cmap_t)); + + memset(cmaps, 0, cmaps_subtables_count * sizeof(lv_font_fmt_txt_cmap_t)); + + font_dsc->cmaps = cmaps; + font_dsc->cmap_num = cmaps_subtables_count; + + for(unsigned int i = 0; i < font_dsc->cmap_num; ++i) { + lv_font_fmt_txt_cmap_t * cmap = &cmaps[i]; + + cmap_table_bin_t cmap_table; + if(lv_fs_read(fp, &cmap_table, sizeof(cmap_table_bin_t), NULL) != LV_FS_RES_OK) { + return false; + } + cmap->range_start = cmap_table.range_start; + cmap->range_length = cmap_table.range_length; + cmap->glyph_id_start = cmap_table.glyph_id_start; + + switch(cmap_table.format_type) { + case 0: + { + uint8_t ids_size = sizeof(uint8_t) * cmap->range_length; + uint8_t * glyph_id_ofs_list = lv_mem_alloc(ids_size); + if(lv_fs_read(fp, glyph_id_ofs_list, ids_size, NULL) != LV_FS_RES_OK) { + return false; + } + cmap->type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL; + cmap->unicode_list = NULL; + cmap->glyph_id_ofs_list = glyph_id_ofs_list; + cmap->list_length = 0; + break; + } + case 1: + LV_LOG_WARN("cmap format: 1 not yet supported."); + return false; + case 2: + cmap->type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY; + cmap->unicode_list = NULL; + cmap->glyph_id_ofs_list = NULL; + cmap->list_length = 0; + break; + case 3: + { + uint8_t list_size = sizeof(uint16_t) * cmap_table.data_entries_count; + uint16_t * unicode_list = (uint16_t *) lv_mem_alloc(list_size); + + if(lv_fs_read(fp, unicode_list, list_size, NULL) != LV_FS_RES_OK) { + return false; + } + + cmap->type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY; + cmap->unicode_list = unicode_list; + cmap->glyph_id_ofs_list = NULL; + cmap->list_length = cmap_table.data_entries_count; + break; + } + default: + LV_LOG_WARN("Unknown cmaps format type %d.", cmap_table.format_type); + return false; + } + } + + // loca + uint32_t loca_start = cmaps_start + cmaps_length; + int32_t loca_length = read_label(fp, loca_start, "loca"); + if (loca_length < 0) { + return false; + } + + uint32_t loca_count; + if(lv_fs_read(fp, &loca_count, sizeof(uint32_t), NULL) != LV_FS_RES_OK) { + return false; + } + + bool failed = false; + uint32_t *glyph_offset = lv_mem_alloc(sizeof(uint32_t) * (loca_count + 1)); + + for(unsigned int i = 0; i < loca_count; ++i) { + if(font_header.index_to_loc_format == 0) { + uint16_t offset; + if(lv_fs_read(fp, &offset, sizeof(uint16_t), NULL) != LV_FS_RES_OK) { + failed = true; + break; + } + glyph_offset[i] = offset; + } + else if(font_header.index_to_loc_format == 1) { + uint32_t offset; + if(lv_fs_read(fp, &offset, sizeof(uint32_t), NULL) != LV_FS_RES_OK) { + failed = true; + break; + } + glyph_offset[i] = offset; + } + else { + LV_LOG_WARN("Unknown index_to_loc_format: %d.", font_header.index_to_loc_format); + failed = true; + break; + } + } + + if (failed) { + lv_mem_free(glyph_offset); + return false; + } + + // glyph + uint32_t glyph_start = loca_start + loca_length; + int32_t glyph_length = read_label(fp, glyph_start, "glyf"); + if (glyph_length < 0) { + lv_mem_free(glyph_offset); + return false; + } + + lv_font_fmt_txt_glyph_dsc_t * glyph_dsc = (lv_font_fmt_txt_glyph_dsc_t *) + lv_mem_alloc((loca_count + 1) * sizeof(lv_font_fmt_txt_glyph_dsc_t)); + + memset(glyph_dsc, 0, + (loca_count + 1) * sizeof(lv_font_fmt_txt_glyph_dsc_t)); + + font_dsc->glyph_dsc = glyph_dsc; + + int cur_bmp_size = 0; + + for(unsigned int i = 0; i < loca_count; ++i) { + lv_font_fmt_txt_glyph_dsc_t * gdsc = &glyph_dsc[i]; + + lv_fs_res_t res = lv_fs_seek(fp, glyph_start + glyph_offset[i]); + if(res != LV_FS_RES_OK) { + failed = true; + break; + } + + bit_iterator_t bit_it = init_bit_iterator(fp); + + if(font_header.advance_width_bits == 0) { + gdsc->adv_w = font_header.default_advance_width; + } + else { + gdsc->adv_w = read_bits(&bit_it, font_header.advance_width_bits, &res); + if(res != LV_FS_RES_OK) { + failed = true; + break; + } + + // TODO: understand how to interpret advance_width_format + if(font_header.advance_width_format == 0) { // uint + } + else if(font_header.advance_width_format == 1) { // unsigned with 4 bits fractional part + } + else { + LV_LOG_WARN("error unknown advance_width_format"); + failed = true; + break; + } + } + + gdsc->ofs_x = read_bits_signed(&bit_it, font_header.xy_bits, &res); + if(res != LV_FS_RES_OK) { + failed = true; + break; + } + + gdsc->ofs_y = read_bits_signed(&bit_it, font_header.xy_bits, &res); + if(res != LV_FS_RES_OK) { + failed = true; + break; + } + + gdsc->box_w = read_bits(&bit_it, font_header.wh_bits, &res); + if(res != LV_FS_RES_OK) { + failed = true; + break; + } + + gdsc->box_h = read_bits(&bit_it, font_header.wh_bits, &res); + if(res != LV_FS_RES_OK) { + failed = true; + break; + } + + int nbits = font_header.advance_width_bits + 2 * font_header.xy_bits + 2 * font_header.wh_bits; + int next_offset = (i < loca_count - 1) ? glyph_offset[i + 1] : (uint32_t) glyph_length; + int bmp_size = next_offset - glyph_offset[i] - nbits / 8; + + if(i == 0) { + gdsc->adv_w = 0; + gdsc->box_w = 0; + gdsc->box_h = 0; + gdsc->ofs_x = 0; + gdsc->ofs_y = 0; + } + + gdsc->bitmap_index = cur_bmp_size; + if(gdsc->box_w * gdsc->box_h != 0) { + cur_bmp_size += bmp_size; + } + } + + if (failed) { + lv_mem_free(glyph_offset); + return false; + } + + uint8_t * glyph_bmp = (uint8_t *) lv_mem_alloc(sizeof(uint8_t) * cur_bmp_size); + + font_dsc->glyph_bitmap = glyph_bmp; + + cur_bmp_size = 0; + + for(unsigned int i = 1; i < loca_count; ++i) { + lv_fs_res_t res = lv_fs_seek(fp, glyph_start + glyph_offset[i]); + if(res != LV_FS_RES_OK) { + failed = true; + break; + } + bit_iterator_t bit_it = init_bit_iterator(fp); + + int nbits = font_header.advance_width_bits + 2 * font_header.xy_bits + 2 * font_header.wh_bits; + + read_bits(&bit_it, nbits, &res); + if(res != LV_FS_RES_OK) { + failed = true; + break; + } + + if(glyph_dsc[i].box_w * glyph_dsc[i].box_h == 0) { + continue; + } + + int next_offset = (i < loca_count - 1) ? glyph_offset[i + 1] : (uint32_t) glyph_length; + int bmp_size = next_offset - glyph_offset[i] - nbits / 8; + + for(int k = 0; k < bmp_size; ++k) { + glyph_bmp[cur_bmp_size + k] = read_bits(&bit_it, 8, &res); + if(res != LV_FS_RES_OK) { + failed = true; + break; + } + } + if (failed) { + break; + } + cur_bmp_size += bmp_size; + } + + lv_mem_free(glyph_offset); + + if (failed) { + return false; + } + + if(lv_fs_seek(fp, glyph_start + glyph_length) != LV_FS_RES_OK) { + return false; + } + + uint32_t kern_start = glyph_start + glyph_length; + int32_t kern_length = read_label(fp, kern_start, "kern"); + if (kern_length < 0) { + return false; + } + + uint8_t kern_format_type; + int32_t padding; + if (lv_fs_read(fp, &kern_format_type, sizeof(uint8_t), NULL) != LV_FS_RES_OK || + lv_fs_read(fp, &padding, 3 * sizeof(uint8_t), NULL) != LV_FS_RES_OK) { + return false; + } + + lv_font_fmt_txt_kern_classes_t * kern_classes = + lv_mem_alloc(sizeof(lv_font_fmt_txt_kern_classes_t)); + + memset(kern_classes, 0, sizeof(lv_font_fmt_txt_kern_classes_t)); + + font_dsc->kern_dsc = kern_classes; // TODO: review + font_dsc->kern_classes = 1; // TODO: review this + + if(0 == kern_format_type) { // sorted pairs + LV_LOG_WARN("kern_format_type 0 not supported yet!"); + return false; + } + else if(3 == kern_format_type) { // array M*N of classes + + uint16_t kern_class_mapping_length; + uint8_t kern_table_rows; + uint8_t kern_table_cols; + + if(lv_fs_read(fp, &kern_class_mapping_length, sizeof(uint16_t), NULL) != LV_FS_RES_OK || + lv_fs_read(fp, &kern_table_rows, sizeof(uint8_t), NULL) != LV_FS_RES_OK || + lv_fs_read(fp, &kern_table_cols, sizeof(uint8_t), NULL) != LV_FS_RES_OK) { + return false; + } + + kern_classes->left_class_cnt = kern_table_rows; + kern_classes->right_class_cnt = kern_table_cols; + + uint8_t * kern_left = lv_mem_alloc(kern_class_mapping_length); + uint8_t * kern_right = lv_mem_alloc(kern_class_mapping_length); + + kern_classes->left_class_mapping = kern_left; + kern_classes->right_class_mapping = kern_right; + + int kern_values_length = sizeof(int8_t) * kern_table_rows * kern_table_cols; + int8_t * kern_values = (int8_t *) lv_mem_alloc(kern_values_length); + + kern_classes->class_pair_values = kern_values; + + if(lv_fs_read(fp, kern_left, kern_class_mapping_length, NULL) != LV_FS_RES_OK || + lv_fs_read(fp, kern_right, kern_class_mapping_length, NULL) != LV_FS_RES_OK || + lv_fs_read(fp, kern_values, kern_values_length, NULL) != LV_FS_RES_OK) { + return false; + } + } + else { + LV_LOG_WARN("kern_format_type %d not supported yet!", kern_format_type); + return false; + } + + return true; +} + +#endif /*LV_USE_FILESYSTEM*/ + diff --git a/src/lv_font/lv_font_loader.h b/src/lv_font/lv_font_loader.h new file mode 100644 index 000000000..773ba8f8a --- /dev/null +++ b/src/lv_font/lv_font_loader.h @@ -0,0 +1,44 @@ +/** + * @file lv_font_loader.h + * + */ + +#ifndef LV_FONT_LOADER_H +#define LV_FONT_LOADER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +#if LV_USE_FILESYSTEM + +lv_font_t * lv_font_load(const char * fontName); +void lv_font_free(lv_font_t * font); + +#endif + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_FONT_LOADER_H*/ diff --git a/tests/Makefile b/tests/Makefile index 839ee92d0..c429a5b8f 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -30,6 +30,7 @@ CSRCS += lv_test_assert.c CSRCS += lv_test_core/lv_test_core.c CSRCS += lv_test_core/lv_test_obj.c CSRCS += lv_test_core/lv_test_style.c +CSRCS += lv_test_core/lv_test_font_loader.c OBJEXT ?= .o diff --git a/tests/lv_test_assert.c b/tests/lv_test_assert.c index a72ac16f3..a81d48ea4 100644 --- a/tests/lv_test_assert.c +++ b/tests/lv_test_assert.c @@ -97,6 +97,15 @@ void lv_test_error(const char * s, ...) exit(1); } +void lv_test_assert_true(int32_t expression, const char * s) +{ + if(!expression) { + lv_test_error(" FAIL: %s. (Expected: not zero)", s, expression); + } else { + lv_test_print(" PASS: %s. (Expected: not zero)", s, expression); + } +} + void lv_test_assert_int_eq(int32_t n_ref, int32_t n_act, const char * s) { if(n_ref != n_act) { diff --git a/tests/lv_test_assert.h b/tests/lv_test_assert.h index 866a6159e..c95db784f 100644 --- a/tests/lv_test_assert.h +++ b/tests/lv_test_assert.h @@ -32,6 +32,7 @@ extern "C" { void lv_test_print(const char * s, ...); void lv_test_exit(const char * s, ...); void lv_test_error(const char * s, ...); +void lv_test_assert_true(int32_t expression, const char * s); void lv_test_assert_int_eq(int32_t n1, int32_t n2, const char * s); void lv_test_assert_int_gt(int32_t n_ref, int32_t n_act, const char * s); void lv_test_assert_int_lt(int32_t n_ref, int32_t n_act, const char * s); diff --git a/tests/lv_test_core/lv_test_core.c b/tests/lv_test_core/lv_test_core.c index f74f81611..37f65464b 100644 --- a/tests/lv_test_core/lv_test_core.c +++ b/tests/lv_test_core/lv_test_core.c @@ -12,6 +12,7 @@ #include "lv_test_core.h" #include "lv_test_obj.h" #include "lv_test_style.h" +#include "lv_test_font_loader.h" /********************* * DEFINES @@ -46,6 +47,7 @@ void lv_test_core(void) lv_test_obj(); lv_test_style(); + lv_test_font_loader(); } diff --git a/tests/lv_test_core/lv_test_font_loader.c b/tests/lv_test_core/lv_test_font_loader.c new file mode 100644 index 000000000..d34c4f004 --- /dev/null +++ b/tests/lv_test_core/lv_test_font_loader.c @@ -0,0 +1,154 @@ +/** + * @file lv_test_font_loader.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include "../lv_test_assert.h" +#if LV_BUILD_TEST +#include "../lvgl.h" +#include "../src/lv_font/lv_font_fmt_txt.h" +#include "../src/lv_font/lv_font.h" +#include "../src/lv_font/lv_font_loader.h" + +#include "lv_test_font_loader.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +static int compare_fonts(lv_font_t * f1, lv_font_t * f2); + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +void lv_test_font_loader(void) +{ + lv_font_t * font = lv_font_load("f:lv_font_montserrat_12.bin"); + compare_fonts(&lv_font_montserrat_12, font); +} + +static int compare_fonts(lv_font_t * f1, lv_font_t * f2) +{ + lv_test_assert_true(f1 != NULL && f2 != NULL, "error loading font"); + + lv_test_assert_ptr_eq(f1->get_glyph_dsc, f2->get_glyph_dsc, "glyph_dsc"); + lv_test_assert_ptr_eq(f1->get_glyph_bitmap, f2->get_glyph_bitmap, "glyph_bitmap"); + lv_test_assert_int_eq(f1->line_height, f2->line_height, "line_height"); + lv_test_assert_int_eq(f1->base_line, f2->base_line, "base_line"); +#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) + lv_test_assert_int_eq(f1->subpx, f2->subpx, "subpx"); +#endif + lv_font_fmt_txt_dsc_t * dsc1 = (lv_font_fmt_txt_dsc_t *) f1->dsc; + lv_font_fmt_txt_dsc_t * dsc2 = (lv_font_fmt_txt_dsc_t *) f2->dsc; + + lv_test_assert_int_eq(dsc1->kern_scale, dsc2->kern_scale, "kern_scale"); + lv_test_assert_int_eq(dsc1->cmap_num, dsc2->cmap_num, "cmap_num"); + lv_test_assert_int_eq(dsc1->bpp, dsc2->bpp, "bpp"); + lv_test_assert_int_eq(dsc1->kern_classes, dsc2->kern_classes, "kern_classes"); + lv_test_assert_int_eq(dsc1->bitmap_format, dsc2->bitmap_format, "bitmap_format"); + + // cmaps + int total_glyphs = 0; + for(int i = 0; i < dsc1->cmap_num; ++i) { + lv_font_fmt_txt_cmap_t * cmaps1 = (lv_font_fmt_txt_cmap_t *) &dsc1->cmaps[i]; + lv_font_fmt_txt_cmap_t * cmaps2 = (lv_font_fmt_txt_cmap_t *) &dsc2->cmaps[i]; + + lv_test_assert_int_eq(cmaps1->range_start, cmaps2->range_start, "range_start"); + lv_test_assert_int_eq(cmaps1->range_length, cmaps2->range_length, "range_length"); + lv_test_assert_int_eq(cmaps1->glyph_id_start, cmaps2->glyph_id_start, "glyph_id_start"); + lv_test_assert_int_eq(cmaps1->type, cmaps2->type, "type"); + lv_test_assert_int_eq(cmaps1->list_length, cmaps2->list_length, "list_length"); + + if(cmaps1->unicode_list != NULL && cmaps2->unicode_list != NULL) { + lv_test_assert_true(cmaps1->unicode_list && cmaps2->unicode_list, "unicode_list"); + + for(int k = 0; k < cmaps1->list_length; ++k) { + lv_test_assert_int_eq(cmaps1->unicode_list[k], cmaps2->unicode_list[k], "unicode_list"); + } + total_glyphs += cmaps1->list_length; + } + else { + total_glyphs += cmaps1->range_length; + lv_test_assert_ptr_eq(cmaps1->unicode_list, cmaps2->unicode_list, "unicode_list"); + } + + if(cmaps1->glyph_id_ofs_list != NULL && cmaps2->glyph_id_ofs_list != NULL) { + uint8_t * ids1 = (uint8_t *) cmaps1->glyph_id_ofs_list; + uint8_t * ids2 = (uint8_t *) cmaps2->glyph_id_ofs_list; + + for(int j = 0; j < cmaps1->range_length; j++) { + lv_test_assert_int_eq(ids1[j], ids2[j], "glyph_id_ofs_list"); + } + } + else { + lv_test_assert_ptr_eq(cmaps1->glyph_id_ofs_list, cmaps2->glyph_id_ofs_list, "glyph_id_ofs_list"); + } + } + + // kern_dsc + lv_font_fmt_txt_kern_classes_t * kern1 = (lv_font_fmt_txt_kern_classes_t *) dsc1->kern_dsc; + lv_font_fmt_txt_kern_classes_t * kern2 = (lv_font_fmt_txt_kern_classes_t *) dsc2->kern_dsc; + + lv_test_assert_int_eq(kern1->right_class_cnt, kern2->right_class_cnt, "right_class_cnt"); + lv_test_assert_int_eq(kern1->left_class_cnt, kern2->left_class_cnt, "left_class_cnt"); + + for(int i = 0; i < kern1->left_class_cnt; ++i) { + lv_test_assert_int_eq(kern1->left_class_mapping[i], + kern2->left_class_mapping[i], "left_class_mapping"); + } + for(int i = 0; i < kern1->right_class_cnt; ++i) { + lv_test_assert_int_eq(kern1->right_class_mapping[i], + kern2->right_class_mapping[i], "right_class_mapping"); + } + + for(int i = 0; i < kern1->right_class_cnt * kern1->left_class_cnt; ++i) { + lv_test_assert_int_eq(kern1->class_pair_values[i], + kern2->class_pair_values[i], "class_pair_values"); + } + + // TODO: glyph_bitmap + + lv_font_fmt_txt_glyph_dsc_t * glyph_dsc1 = (lv_font_fmt_txt_glyph_dsc_t *) dsc1->glyph_dsc; + lv_font_fmt_txt_glyph_dsc_t * glyph_dsc2 = (lv_font_fmt_txt_glyph_dsc_t *) dsc2->glyph_dsc; + + for(int i = 0; i < total_glyphs; ++i) { + //lv_test_assert_int_eq(glyph_dsc1[i].bitmap_index, glyph_dsc2[i].bitmap_index, "bitmap_index"); + lv_test_assert_int_eq(glyph_dsc1[i].adv_w, glyph_dsc2[i].adv_w, "adv_w"); + lv_test_assert_int_eq(glyph_dsc1[i].box_w, glyph_dsc2[i].box_w, "box_w"); + lv_test_assert_int_eq(glyph_dsc1[i].box_h, glyph_dsc2[i].box_h, "box_h"); + lv_test_assert_int_eq(glyph_dsc1[i].ofs_x, glyph_dsc2[i].ofs_x, "ofs_x"); + lv_test_assert_int_eq(glyph_dsc1[i].ofs_y, glyph_dsc2[i].ofs_y, "ofs_y"); + } + + LV_LOG_INFO("No differences found!"); + return 0; +} + + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif // LV_BUILD_TEST + diff --git a/tests/lv_test_core/lv_test_font_loader.h b/tests/lv_test_core/lv_test_font_loader.h new file mode 100644 index 000000000..fe29926bf --- /dev/null +++ b/tests/lv_test_core/lv_test_font_loader.h @@ -0,0 +1,39 @@ +/** + * @file lv_font_loader.h + * + */ + +#ifndef LV_TEST_FONT_LOADER_H +#define LV_TEST_FONT_LOADER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ +void lv_test_font_loader(void); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_TEST_FONT_LOADER_H*/ + diff --git a/tests/lv_test_main.c b/tests/lv_test_main.c index 8c69a98df..061b6b1ef 100644 --- a/tests/lv_test_main.c +++ b/tests/lv_test_main.c @@ -23,6 +23,61 @@ int main(void) } +static lv_fs_res_t open_cb(struct _lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode) +{ + (void) drv; + (void) mode; + + FILE * fp = fopen(path, "rb"); // only reading is supported + + *((FILE **)file_p) = fp; + return NULL == fp ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; +} + +static lv_fs_res_t close_cb(struct _lv_fs_drv_t * drv, void * file_p) +{ + (void) drv; + + FILE * fp = *((FILE **) file_p); + fclose(fp); + return LV_FS_RES_OK; +} + +static lv_fs_res_t read_cb(struct _lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br) +{ + (void) drv; + + FILE * fp = *((FILE **) file_p); + *br = fread(buf, 1, btr, fp); + return (*br <= 0) ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; +} + +static lv_fs_res_t seek_cb(struct _lv_fs_drv_t * drv, void * file_p, uint32_t pos) +{ + (void) drv; + + FILE * fp = *((FILE **) file_p); + fseek (fp, pos, SEEK_SET); + + return LV_FS_RES_OK; +} + +static lv_fs_res_t tell_cb(struct _lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p) +{ + (void) drv; + + FILE * fp = *((FILE **) file_p); + *pos_p = ftell(fp); + + return LV_FS_RES_OK; +} + +static bool ready_cb(struct _lv_fs_drv_t * drv) +{ + (void) drv; + return true; +} + static void hal_init(void) { static lv_disp_buf_t disp_buf; @@ -35,6 +90,20 @@ static void hal_init(void) disp_drv.buffer = &disp_buf; disp_drv.flush_cb = dummy_flush_cb; lv_disp_drv_register(&disp_drv); + + lv_fs_drv_t drv; + lv_fs_drv_init(&drv); /*Basic initialization*/ + + drv.letter = 'f'; /*An uppercase letter to identify the drive */ + drv.file_size = sizeof(FILE *); /*Size required to store a file object*/ + drv.ready_cb = ready_cb; /*Callback to tell if the drive is ready to use */ + drv.open_cb = open_cb; /*Callback to open a file */ + drv.close_cb = close_cb; /*Callback to close a file */ + drv.read_cb = read_cb; /*Callback to read a file */ + drv.seek_cb = seek_cb; /*Callback to seek in a file (Move cursor) */ + drv.tell_cb = tell_cb; /*Callback to tell the cursor position */ + + lv_fs_drv_register(&drv); /*Finally register the drive*/ } From 004adac31d0ef1bc34b3d17ca3b74aa731d66506 Mon Sep 17 00:00:00 2001 From: Fabio Guerra Date: Wed, 5 Aug 2020 01:29:54 -0300 Subject: [PATCH 104/173] Adding changes to changelog and replacing line style comments with block comments. --- CHANGELOG.md | 2 ++ src/lv_font/lv_font_loader.c | 31 ++++++++++++++++++++----------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4afdd3327..c54f12402 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ - Add `lv_tabview_set_tab_name()` function - used to change a tab's name - Add `LV_THEME_MATERIAL_FLAG_NO_TRANSITION` and `LV_THEME_MATERIAL_FLAG_NO_FOCUS` flags - Reduce code size by adding: `LV_USE_FONT_COMPRESSED` and `LV_FONT_USE_SUBPX` and applying some optimization +- Add `lv_font_load()` function - Loads a `lv_font_t` object from a binary font file +- Add `lv_font_free()` function - Frees the memory allocated by the `lv_font_load()` function ### Bugfixes diff --git a/src/lv_font/lv_font_loader.c b/src/lv_font/lv_font_loader.c index 750cdc25d..9a4035408 100644 --- a/src/lv_font/lv_font_loader.c +++ b/src/lv_font/lv_font_loader.c @@ -80,6 +80,11 @@ static int read_bits(bit_iterator_t *it, int n_bits, lv_fs_res_t * res); * GLOBAL FUNCTIONS **********************/ +/** + * Loads a `lv_font_t` object from a binary font file + * @param font_name filename where the font file is located + * @return a pointer to the font or NULL in case of error + */ lv_font_t * lv_font_load(const char * font_name) { bool success = false; @@ -107,6 +112,10 @@ lv_font_t * lv_font_load(const char * font_name) } +/** + * Frees the memory allocated by the `lv_font_load()` function + * @param font lv_font_t object created by the lv_font_load function + */ void lv_font_free(lv_font_t * font) { if(NULL != font) { @@ -227,7 +236,7 @@ static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font) font->dsc = font_dsc; - // header + /* header */ int32_t header_length = read_label(fp, 0, "head"); if (header_length < 0) { return false; @@ -251,7 +260,7 @@ static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font) font_dsc->kern_scale = font_header.kerning_scale; font_dsc->bitmap_format = font_header.compression_id; - // cmaps + /* cmaps */ uint32_t cmaps_start = header_length; int32_t cmaps_length = read_label(fp, cmaps_start, "cmap"); if (cmaps_length < 0) { @@ -326,7 +335,7 @@ static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font) } } - // loca + /* loca */ uint32_t loca_start = cmaps_start + cmaps_length; int32_t loca_length = read_label(fp, loca_start, "loca"); if (loca_length < 0) { @@ -370,7 +379,7 @@ static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font) return false; } - // glyph + /* glyph */ uint32_t glyph_start = loca_start + loca_length; int32_t glyph_length = read_label(fp, glyph_start, "glyf"); if (glyph_length < 0) { @@ -409,10 +418,10 @@ static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font) break; } - // TODO: understand how to interpret advance_width_format - if(font_header.advance_width_format == 0) { // uint + /* TODO: understand how to interpret advance_width_format */ + if(font_header.advance_width_format == 0) { /* uint */ } - else if(font_header.advance_width_format == 1) { // unsigned with 4 bits fractional part + else if(font_header.advance_width_format == 1) { /* unsigned with 4 bits fractional part */ } else { LV_LOG_WARN("error unknown advance_width_format"); @@ -538,14 +547,14 @@ static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font) memset(kern_classes, 0, sizeof(lv_font_fmt_txt_kern_classes_t)); - font_dsc->kern_dsc = kern_classes; // TODO: review - font_dsc->kern_classes = 1; // TODO: review this + font_dsc->kern_dsc = kern_classes; /* TODO: review */ + font_dsc->kern_classes = 1; /* TODO: review this */ - if(0 == kern_format_type) { // sorted pairs + if(0 == kern_format_type) { /* sorted pairs */ LV_LOG_WARN("kern_format_type 0 not supported yet!"); return false; } - else if(3 == kern_format_type) { // array M*N of classes + else if(3 == kern_format_type) { /* array M*N of classes */ uint16_t kern_class_mapping_length; uint8_t kern_table_rows; From 28f74bd91d2ca6597f74152ea9f095d51c78e076 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sven=20Krau=C3=9F?= Date: Wed, 5 Aug 2020 10:53:03 +0200 Subject: [PATCH 105/173] Make several descriptor parameters const, update parameter docs. Making the descriptor const allows to use static initialized variables. --- src/lv_draw/lv_draw_arc.c | 17 +++++++++-------- src/lv_draw/lv_draw_arc.h | 6 +++--- src/lv_draw/lv_draw_img.c | 24 ++++++++---------------- src/lv_draw/lv_draw_img.h | 8 ++------ src/lv_draw/lv_draw_label.c | 6 ++++-- src/lv_draw/lv_draw_label.h | 3 ++- src/lv_draw/lv_draw_line.c | 5 ++--- src/lv_draw/lv_draw_line.h | 7 +++---- src/lv_draw/lv_draw_rect.c | 34 ++++++++++++++++++---------------- src/lv_draw/lv_draw_rect.h | 4 ++-- src/lv_draw/lv_draw_triangle.c | 4 ++-- src/lv_draw/lv_draw_triangle.h | 4 ++-- src/lv_draw/lv_img_buf.c | 2 +- src/lv_draw/lv_img_buf.h | 2 +- src/lv_widgets/lv_canvas.c | 21 +++++++++++---------- src/lv_widgets/lv_canvas.h | 24 ++++++++++++++---------- 16 files changed, 84 insertions(+), 87 deletions(-) diff --git a/src/lv_draw/lv_draw_arc.c b/src/lv_draw/lv_draw_arc.c index 27f6f1667..bcf94d000 100644 --- a/src/lv_draw/lv_draw_arc.c +++ b/src/lv_draw/lv_draw_arc.c @@ -65,17 +65,18 @@ static void get_rounded_area(int16_t angle, lv_coord_t radius, uint8_t tickness, * @param mask the arc will be drawn only in this mask * @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 style style of the arc (`body.thickness`, `body.main_color`, `body.opa` is used) - * @param opa_scale scale down all opacities by the factor + * @param clip_area the arc will be drawn only in this area + * @param dsc pointer to an initialized `lv_draw_line_dsc_t` variable */ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, uint16_t start_angle, uint16_t end_angle, - const lv_area_t * clip_area, lv_draw_line_dsc_t * dsc) + const lv_area_t * clip_area, const lv_draw_line_dsc_t * dsc) { if(dsc->opa <= LV_OPA_MIN) return; if(dsc->width == 0) return; if(start_angle == end_angle) return; - if(dsc->width > radius) dsc->width = radius; + lv_style_int_t width = dsc->width; + if(width > radius) width = radius; lv_draw_rect_dsc_t cir_dsc; lv_draw_rect_dsc_init(&cir_dsc); @@ -83,7 +84,7 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, uin cir_dsc.bg_opa = LV_OPA_TRANSP; cir_dsc.border_opa = dsc->opa; cir_dsc.border_color = dsc->color; - cir_dsc.border_width = dsc->width; + cir_dsc.border_width = width; cir_dsc.border_blend_mode = dsc->blend_mode; lv_area_t area; @@ -123,7 +124,7 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, uin q_dsc.end_angle = end_angle; q_dsc.start_quarter = (start_angle / 90) & 0x3; q_dsc.end_quarter = (end_angle / 90) & 0x3; - q_dsc.width = dsc->width; + q_dsc.width = width; q_dsc.draw_dsc = &cir_dsc; q_dsc.draw_area = &area; q_dsc.clip_area = clip_area; @@ -146,7 +147,7 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, uin lv_area_t round_area; if(dsc->round_start) { - get_rounded_area(start_angle, radius, dsc->width, &round_area); + get_rounded_area(start_angle, radius, width, &round_area); round_area.x1 += center_x; round_area.x2 += center_x; round_area.y1 += center_y; @@ -156,7 +157,7 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, uin } if(dsc->round_end) { - get_rounded_area(end_angle, radius, dsc->width, &round_area); + get_rounded_area(end_angle, radius, width, &round_area); round_area.x1 += center_x; round_area.x2 += center_x; round_area.y1 += center_y; diff --git a/src/lv_draw/lv_draw_arc.h b/src/lv_draw/lv_draw_arc.h index 7e1352eb9..a4b182410 100644 --- a/src/lv_draw/lv_draw_arc.h +++ b/src/lv_draw/lv_draw_arc.h @@ -35,11 +35,11 @@ extern "C" { * @param mask the arc will be drawn only in this mask * @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 style style of the arc (`body.thickness`, `body.main_color`, `body.opa` is used) - * @param opa_scale scale down all opacities by the factor + * @param clip_area the arc will be drawn only in this area + * @param dsc pointer to an initialized `lv_draw_line_dsc_t` variable */ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, uint16_t start_angle, uint16_t end_angle, - const lv_area_t * clip_area, lv_draw_line_dsc_t * dsc); + const lv_area_t * clip_area, const lv_draw_line_dsc_t * dsc); /********************** * MACROS diff --git a/src/lv_draw/lv_draw_img.c b/src/lv_draw/lv_draw_img.c index b447d615e..47615724a 100644 --- a/src/lv_draw/lv_draw_img.c +++ b/src/lv_draw/lv_draw_img.c @@ -29,11 +29,11 @@ **********************/ LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * clip_area, const void * src, - lv_draw_img_dsc_t * draw_dsc); + const lv_draw_img_dsc_t * draw_dsc); LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const lv_area_t * clip_area, const uint8_t * map_p, - lv_draw_img_dsc_t * draw_dsc, + const lv_draw_img_dsc_t * draw_dsc, bool chroma_key, bool alpha_byte); static void show_error(const lv_area_t * coords, const lv_area_t * clip_area, const char * msg); @@ -65,13 +65,9 @@ void lv_draw_img_dsc_init(lv_draw_img_dsc_t * dsc) * @param coords the coordinates of the image * @param mask the image will be drawn only in this area * @param src pointer to a lv_color_t array which contains the pixels of the image - * @param style style of the image - * @param angle rotation angle of the image - * @param center rotation center of the image - * @param antialias anti-alias transformations (rotate, zoom) or not - * @param opa_scale scale down all opacities by the factor + * @param dsc pointer to an initialized `lv_draw_img_dsc_t` variable */ -void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * src, lv_draw_img_dsc_t * dsc) +void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * src, const lv_draw_img_dsc_t * dsc) { if(src == NULL) { LV_LOG_WARN("Image draw: src is NULL"); @@ -232,7 +228,7 @@ lv_img_src_t lv_img_src_get_type(const void * src) LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * clip_area, const void * src, - lv_draw_img_dsc_t * draw_dsc) + const lv_draw_img_dsc_t * draw_dsc) { if(draw_dsc->opa <= LV_OPA_MIN) return LV_RES_OK; @@ -327,18 +323,14 @@ LV_ATTRIBUTE_FAST_MEM static lv_res_t lv_img_draw_core(const lv_area_t * coords, * @param cords_p coordinates the color map * @param mask_p the map will drawn only on this area (truncated to VDB area) * @param map_p pointer to a lv_color_t array - * @param opa opacity of the map + * @param draw_dsc pointer to an initialized `lv_draw_img_dsc_t` variable * @param chroma_keyed true: enable transparency of LV_IMG_LV_COLOR_TRANSP color pixels * @param alpha_byte true: extra alpha byte is inserted for every pixel - * @param style style of the image - * @param angle angle in degree - * @param pivot center of rotation - * @param zoom zoom factor - * @param antialias anti-alias transformations (rotate, zoom) or not */ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const lv_area_t * clip_area, const uint8_t * map_p, - lv_draw_img_dsc_t * draw_dsc, bool chroma_key, bool alpha_byte) + const lv_draw_img_dsc_t * draw_dsc, + bool chroma_key, bool alpha_byte) { /* Use the clip area as draw area*/ lv_area_t draw_area; diff --git a/src/lv_draw/lv_draw_img.h b/src/lv_draw/lv_draw_img.h index 735777684..e4531d725 100644 --- a/src/lv_draw/lv_draw_img.h +++ b/src/lv_draw/lv_draw_img.h @@ -53,13 +53,9 @@ void lv_draw_img_dsc_init(lv_draw_img_dsc_t * dsc); * @param coords the coordinates of the image * @param mask the image will be drawn only in this area * @param src pointer to a lv_color_t array which contains the pixels of the image - * @param style style of the image - * @param angle rotation angle of the image - * @param center rotation center of the image - * @param antialias anti-alias transformations (rotate, zoom) or not - * @param opa_scale scale down all opacities by the factor + * @param dsc pointer to an initialized `lv_draw_img_dsc_t` variable */ -void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * src, lv_draw_img_dsc_t * dsc); +void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * src, const lv_draw_img_dsc_t * dsc); /** * Get the type of an image source diff --git a/src/lv_draw/lv_draw_label.c b/src/lv_draw/lv_draw_label.c index 136b4d0d7..4bdcb65f4 100644 --- a/src/lv_draw/lv_draw_label.c +++ b/src/lv_draw/lv_draw_label.c @@ -111,8 +111,10 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_label_dsc_init(lv_draw_label_dsc_t * dsc) * @param hint pointer to a `lv_draw_label_hint_t` variable. * It is managed by the drawer to speed up the drawing of very long texts (thousands of lines). */ -LV_ATTRIBUTE_FAST_MEM void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, lv_draw_label_dsc_t * dsc, - const char * txt, lv_draw_label_hint_t * hint) +LV_ATTRIBUTE_FAST_MEM void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, + const lv_draw_label_dsc_t * dsc, + const char * txt, + lv_draw_label_hint_t * hint) { if(dsc->opa <= LV_OPA_MIN) return; diff --git a/src/lv_draw/lv_draw_label.h b/src/lv_draw/lv_draw_label.h index a81aeae74..b28381002 100644 --- a/src/lv_draw/lv_draw_label.h +++ b/src/lv_draw/lv_draw_label.h @@ -77,7 +77,8 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_label_dsc_init(lv_draw_label_dsc_t * dsc); * @param hint pointer to a `lv_draw_label_hint_t` variable. * It is managed by the drawer to speed up the drawing of very long texts (thousands of lines). */ -LV_ATTRIBUTE_FAST_MEM void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, lv_draw_label_dsc_t * dsc, +LV_ATTRIBUTE_FAST_MEM void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, + const lv_draw_label_dsc_t * dsc, const char * txt, lv_draw_label_hint_t * hint); //! @endcond diff --git a/src/lv_draw/lv_draw_line.c b/src/lv_draw/lv_draw_line.c index 0c84b2c49..38e29cdfb 100644 --- a/src/lv_draw/lv_draw_line.c +++ b/src/lv_draw/lv_draw_line.c @@ -58,9 +58,8 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_line_dsc_init(lv_draw_line_dsc_t * dsc) * Draw a line * @param point1 first point of the line * @param point2 second point of the line - * @param mask the line will be drawn only on this area - * @param style pointer to a line's style - * @param opa_scale scale down all opacities by the factor + * @param clip the line will be drawn only in this area + * @param dsc pointer to an initialized `lv_draw_line_dsc_t` variable */ LV_ATTRIBUTE_FAST_MEM void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, const lv_draw_line_dsc_t * dsc) diff --git a/src/lv_draw/lv_draw_line.h b/src/lv_draw/lv_draw_line.h index 83abe6818..eb4bbaf58 100644 --- a/src/lv_draw/lv_draw_line.h +++ b/src/lv_draw/lv_draw_line.h @@ -43,11 +43,10 @@ typedef struct { * Draw a line * @param point1 first point of the line * @param point2 second point of the line - * @param mask the line will be drawn only on this area - * @param style pointer to a line's style - * @param opa_scale scale down all opacities by the factor + * @param clip the line will be drawn only in this area + * @param dsc pointer to an initialized `lv_draw_line_dsc_t` variable */ -LV_ATTRIBUTE_FAST_MEM void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * mask, +LV_ATTRIBUTE_FAST_MEM void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * clip, const lv_draw_line_dsc_t * dsc); LV_ATTRIBUTE_FAST_MEM void lv_draw_line_dsc_init(lv_draw_line_dsc_t * dsc); diff --git a/src/lv_draw/lv_draw_rect.c b/src/lv_draw/lv_draw_rect.c index 47ed3dc70..34b033428 100644 --- a/src/lv_draw/lv_draw_rect.c +++ b/src/lv_draw/lv_draw_rect.c @@ -27,20 +27,21 @@ /********************** * STATIC PROTOTYPES **********************/ -LV_ATTRIBUTE_FAST_MEM static void draw_bg(const lv_area_t * coords, const lv_area_t * clip, lv_draw_rect_dsc_t * dsc); +LV_ATTRIBUTE_FAST_MEM static void draw_bg(const lv_area_t * coords, const lv_area_t * clip, + const lv_draw_rect_dsc_t * dsc); LV_ATTRIBUTE_FAST_MEM static void draw_border(const lv_area_t * coords, const lv_area_t * clip, - lv_draw_rect_dsc_t * dsc); -static void draw_outline(const lv_area_t * coords, const lv_area_t * clip, lv_draw_rect_dsc_t * dsc); -LV_ATTRIBUTE_FAST_MEM static inline lv_color_t grad_get(lv_draw_rect_dsc_t * dsc, lv_coord_t s, lv_coord_t i); + const lv_draw_rect_dsc_t * dsc); +static void draw_outline(const lv_area_t * coords, const lv_area_t * clip, const lv_draw_rect_dsc_t * dsc); +LV_ATTRIBUTE_FAST_MEM static inline lv_color_t grad_get(const lv_draw_rect_dsc_t * dsc, lv_coord_t s, lv_coord_t i); #if LV_USE_SHADOW LV_ATTRIBUTE_FAST_MEM static void draw_shadow(const lv_area_t * coords, const lv_area_t * clip, - lv_draw_rect_dsc_t * dsc); + const lv_draw_rect_dsc_t * dsc); LV_ATTRIBUTE_FAST_MEM static void shadow_draw_corner_buf(const lv_area_t * coords, uint16_t * sh_buf, lv_coord_t s, lv_coord_t r); LV_ATTRIBUTE_FAST_MEM static void shadow_blur_corner(lv_coord_t size, lv_coord_t sw, uint16_t * sh_ups_buf); #endif -static void draw_pattern(const lv_area_t * coords, const lv_area_t * clip, lv_draw_rect_dsc_t * dsc); -static void draw_value(const lv_area_t * coords, const lv_area_t * clip, lv_draw_rect_dsc_t * dsc); +static void draw_pattern(const lv_area_t * coords, const lv_area_t * clip, const lv_draw_rect_dsc_t * dsc); +static void draw_value(const lv_area_t * coords, const lv_area_t * clip, const lv_draw_rect_dsc_t * dsc); /********************** * STATIC VARIABLES @@ -85,9 +86,9 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_rect_dsc_init(lv_draw_rect_dsc_t * dsc) * Draw a rectangle * @param coords the coordinates of the rectangle * @param mask the rectangle will be drawn only in this mask - * @param style pointer to a style + * @param dsc pointer to an initialized `lv_draw_rect_dsc_t` variable */ -void lv_draw_rect(const lv_area_t * coords, const lv_area_t * clip, lv_draw_rect_dsc_t * dsc) +void lv_draw_rect(const lv_area_t * coords, const lv_area_t * clip, const lv_draw_rect_dsc_t * dsc) { if(lv_area_get_height(coords) < 1 || lv_area_get_width(coords) < 1) return; #if LV_USE_SHADOW @@ -142,7 +143,8 @@ void lv_draw_px(const lv_point_t * point, const lv_area_t * clip_area, const lv_ * STATIC FUNCTIONS **********************/ -LV_ATTRIBUTE_FAST_MEM static void draw_bg(const lv_area_t * coords, const lv_area_t * clip, lv_draw_rect_dsc_t * dsc) +LV_ATTRIBUTE_FAST_MEM static void draw_bg(const lv_area_t * coords, const lv_area_t * clip, + const lv_draw_rect_dsc_t * dsc) { if(dsc->bg_opa <= LV_OPA_MIN) return; @@ -364,7 +366,7 @@ LV_ATTRIBUTE_FAST_MEM static void draw_bg(const lv_area_t * coords, const lv_are } LV_ATTRIBUTE_FAST_MEM static void draw_border(const lv_area_t * coords, const lv_area_t * clip, - lv_draw_rect_dsc_t * dsc) + const lv_draw_rect_dsc_t * dsc) { if(dsc->border_opa <= LV_OPA_MIN) return; if(dsc->border_width == 0) return; @@ -581,7 +583,7 @@ LV_ATTRIBUTE_FAST_MEM static void draw_border(const lv_area_t * coords, const lv _lv_mem_buf_release(mask_buf); } -LV_ATTRIBUTE_FAST_MEM static inline lv_color_t grad_get(lv_draw_rect_dsc_t * dsc, lv_coord_t s, lv_coord_t i) +LV_ATTRIBUTE_FAST_MEM static inline lv_color_t grad_get(const lv_draw_rect_dsc_t * dsc, lv_coord_t s, lv_coord_t i) { int32_t min = (dsc->bg_main_color_stop * s) >> 8; if(i <= min) return dsc->bg_color; @@ -598,7 +600,7 @@ LV_ATTRIBUTE_FAST_MEM static inline lv_color_t grad_get(lv_draw_rect_dsc_t * dsc #if LV_USE_SHADOW LV_ATTRIBUTE_FAST_MEM static void draw_shadow(const lv_area_t * coords, const lv_area_t * clip, - lv_draw_rect_dsc_t * dsc) + const lv_draw_rect_dsc_t * dsc) { /*Check whether the shadow is visible*/ if(dsc->shadow_width == 0) return; @@ -1226,7 +1228,7 @@ LV_ATTRIBUTE_FAST_MEM static void shadow_blur_corner(lv_coord_t size, lv_coord_t #endif -static void draw_outline(const lv_area_t * coords, const lv_area_t * clip, lv_draw_rect_dsc_t * dsc) +static void draw_outline(const lv_area_t * coords, const lv_area_t * clip, const lv_draw_rect_dsc_t * dsc) { if(dsc->outline_opa <= LV_OPA_MIN) return; if(dsc->outline_width == 0) return; @@ -1424,7 +1426,7 @@ static void draw_outline(const lv_area_t * coords, const lv_area_t * clip, lv_dr _lv_mem_buf_release(mask_buf); } -static void draw_pattern(const lv_area_t * coords, const lv_area_t * clip, lv_draw_rect_dsc_t * dsc) +static void draw_pattern(const lv_area_t * coords, const lv_area_t * clip, const lv_draw_rect_dsc_t * dsc) { if(dsc->pattern_image == NULL) return; if(dsc->pattern_opa <= LV_OPA_MIN) return; @@ -1526,7 +1528,7 @@ static void draw_pattern(const lv_area_t * coords, const lv_area_t * clip, lv_dr } -static void draw_value(const lv_area_t * coords, const lv_area_t * clip, lv_draw_rect_dsc_t * dsc) +static void draw_value(const lv_area_t * coords, const lv_area_t * clip, const lv_draw_rect_dsc_t * dsc) { if(dsc->value_str == NULL) return; if(dsc->value_opa <= LV_OPA_MIN) return; diff --git a/src/lv_draw/lv_draw_rect.h b/src/lv_draw/lv_draw_rect.h index 3b6dc5bf3..17f4a7248 100644 --- a/src/lv_draw/lv_draw_rect.h +++ b/src/lv_draw/lv_draw_rect.h @@ -92,9 +92,9 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_rect_dsc_init(lv_draw_rect_dsc_t * dsc); * Draw a rectangle * @param coords the coordinates of the rectangle * @param mask the rectangle will be drawn only in this mask - * @param style pointer to a style + * @param dsc pointer to an initialized `lv_draw_rect_dsc_t` variable */ -void lv_draw_rect(const lv_area_t * coords, const lv_area_t * mask, lv_draw_rect_dsc_t * dsc); +void lv_draw_rect(const lv_area_t * coords, const lv_area_t * mask, const lv_draw_rect_dsc_t * dsc); /** * Draw a pixel diff --git a/src/lv_draw/lv_draw_triangle.c b/src/lv_draw/lv_draw_triangle.c index 72a4a7fe2..08bcf6af2 100644 --- a/src/lv_draw/lv_draw_triangle.c +++ b/src/lv_draw/lv_draw_triangle.c @@ -40,7 +40,7 @@ * @param clip_area the triangle will be drawn only in this area * @param draw_dsc pointer to an initialized `lv_draw_rect_dsc_t` variable */ -void lv_draw_triangle(const lv_point_t points[], const lv_area_t * clip_area, lv_draw_rect_dsc_t * draw_dsc) +void lv_draw_triangle(const lv_point_t points[], const lv_area_t * clip_area, const lv_draw_rect_dsc_t * draw_dsc) { lv_draw_polygon(points, 3, clip_area, draw_dsc); } @@ -53,7 +53,7 @@ void lv_draw_triangle(const lv_point_t points[], const lv_area_t * clip_area, lv * @param draw_dsc pointer to an initialized `lv_draw_rect_dsc_t` variable */ void lv_draw_polygon(const lv_point_t points[], uint16_t point_cnt, const lv_area_t * clip_area, - lv_draw_rect_dsc_t * draw_dsc) + const lv_draw_rect_dsc_t * draw_dsc) { if(point_cnt < 3) return; if(points == NULL) return; diff --git a/src/lv_draw/lv_draw_triangle.h b/src/lv_draw/lv_draw_triangle.h index 242ce30f9..64a7b1c81 100644 --- a/src/lv_draw/lv_draw_triangle.h +++ b/src/lv_draw/lv_draw_triangle.h @@ -33,7 +33,7 @@ extern "C" { * @param clip_area the triangle will be drawn only in this area * @param draw_dsc pointer to an initialized `lv_draw_rect_dsc_t` variable */ -void lv_draw_triangle(const lv_point_t points[], const lv_area_t * clip, lv_draw_rect_dsc_t * draw_dsc); +void lv_draw_triangle(const lv_point_t points[], const lv_area_t * clip, const lv_draw_rect_dsc_t * draw_dsc); /** * Draw a polygon. Only convex polygons are supported. @@ -43,7 +43,7 @@ void lv_draw_triangle(const lv_point_t points[], const lv_area_t * clip, lv_draw * @param draw_dsc pointer to an initialized `lv_draw_rect_dsc_t` variable */ void lv_draw_polygon(const lv_point_t points[], uint16_t point_cnt, const lv_area_t * mask, - lv_draw_rect_dsc_t * draw_dsc); + const lv_draw_rect_dsc_t * draw_dsc); /********************** * MACROS diff --git a/src/lv_draw/lv_img_buf.c b/src/lv_draw/lv_img_buf.c index 8838c32ab..741ad0439 100644 --- a/src/lv_draw/lv_img_buf.c +++ b/src/lv_draw/lv_img_buf.c @@ -468,7 +468,7 @@ void _lv_img_buf_transform_init(lv_img_transform_dsc_t * dsc) * @param pivot x,y pivot coordinates of rotation */ void _lv_img_buf_get_transformed_area(lv_area_t * res, lv_coord_t w, lv_coord_t h, int16_t angle, uint16_t zoom, - lv_point_t * pivot) + const lv_point_t * pivot) { #if LV_USE_IMG_TRANSFORM if(angle == 0 && zoom == LV_IMG_ZOOM_NONE) { diff --git a/src/lv_draw/lv_img_buf.h b/src/lv_draw/lv_img_buf.h index 204f3c1d8..afde70c55 100644 --- a/src/lv_draw/lv_img_buf.h +++ b/src/lv_draw/lv_img_buf.h @@ -380,7 +380,7 @@ static inline bool _lv_img_buf_transform(lv_img_transform_dsc_t * dsc, lv_coord_ * @param pivot x,y pivot coordinates of rotation */ void _lv_img_buf_get_transformed_area(lv_area_t * res, lv_coord_t w, lv_coord_t h, int16_t angle, uint16_t zoom, - lv_point_t * pivot); + const lv_point_t * pivot); /********************** * MACROS diff --git a/src/lv_widgets/lv_canvas.c b/src/lv_widgets/lv_canvas.c index d16d40a22..14fb5e023 100644 --- a/src/lv_widgets/lv_canvas.c +++ b/src/lv_widgets/lv_canvas.c @@ -657,6 +657,7 @@ void lv_canvas_blur_ver(lv_obj_t * canvas, const lv_area_t * area, uint16_t r) * Fill the canvas with color * @param canvas pointer to a canvas * @param color the background color + * @param opa the desired opacity */ void lv_canvas_fill_bg(lv_obj_t * canvas, lv_color_t color, lv_opa_t opa) { @@ -694,10 +695,10 @@ void lv_canvas_fill_bg(lv_obj_t * canvas, lv_color_t color, lv_opa_t opa) * @param y top coordinate of the rectangle * @param w width of the rectangle * @param h height of the rectangle - * @param style style of the rectangle (`body` properties are used except `padding`) + * @param rect_dsc descriptor of the rectangle */ void lv_canvas_draw_rect(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_t w, lv_coord_t h, - lv_draw_rect_dsc_t * rect_dsc) + const lv_draw_rect_dsc_t * rect_dsc) { LV_ASSERT_OBJ(canvas, LV_OBJX_NAME); @@ -763,7 +764,7 @@ void lv_canvas_draw_rect(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord * @param x left coordinate of the text * @param y top coordinate of the text * @param max_w max width of the text. The text will be wrapped to fit into this size - * @param style style of the text (`text` properties are used) + * @param label_draw_dsc pointer to a valid label descriptor `lv_draw_label_dsc_t` * @param txt text to display * @param align align of the text (`LV_LABEL_ALIGN_LEFT/RIGHT/CENTER`) */ @@ -841,10 +842,10 @@ void lv_canvas_draw_text(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord * Draw an image on the canvas * @param canvas pointer to a canvas object * @param src image source. Can be a pointer an `lv_img_dsc_t` variable or a path an image. - * @param style style of the image (`image` properties are used) + * @param img_draw_dsc pointer to a valid label descriptor `lv_draw_img_dsc_t` */ void lv_canvas_draw_img(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, const void * src, - lv_draw_img_dsc_t * img_draw_dsc) + const lv_draw_img_dsc_t * img_draw_dsc) { LV_ASSERT_OBJ(canvas, LV_OBJX_NAME); @@ -906,7 +907,7 @@ void lv_canvas_draw_img(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, const voi * @param canvas pointer to a canvas object * @param points point of the line * @param point_cnt number of points - * @param style style of the line (`line` properties are used) + * @param line_draw_dsc pointer to an initialized `lv_draw_line_dsc_t` variable */ void lv_canvas_draw_line(lv_obj_t * canvas, const lv_point_t points[], uint32_t point_cnt, const lv_draw_line_dsc_t * line_draw_dsc) @@ -969,10 +970,10 @@ void lv_canvas_draw_line(lv_obj_t * canvas, const lv_point_t points[], uint32_t * @param canvas pointer to a canvas object * @param points point of the polygon * @param point_cnt number of points - * @param style style of the polygon (`body.main_color` and `body.opa` is used) + * @param poly_draw_dsc pointer to an initialized `lv_draw_rect_dsc_t` variable */ void lv_canvas_draw_polygon(lv_obj_t * canvas, const lv_point_t points[], uint32_t point_cnt, - lv_draw_rect_dsc_t * poly_draw_dsc) + const lv_draw_rect_dsc_t * poly_draw_dsc) { LV_ASSERT_OBJ(canvas, LV_OBJX_NAME); @@ -1033,10 +1034,10 @@ void lv_canvas_draw_polygon(lv_obj_t * canvas, const lv_point_t points[], uint32 * @param r radius of the arc * @param start_angle start angle in degrees * @param end_angle end angle in degrees - * @param style style of the polygon (`body.main_color` and `body.opa` is used) + * @param arc_draw_dsc pointer to an initialized `lv_draw_line_dsc_t` variable */ void lv_canvas_draw_arc(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_t r, int32_t start_angle, - int32_t end_angle, lv_draw_line_dsc_t * arc_draw_dsc) + int32_t end_angle, const lv_draw_line_dsc_t * arc_draw_dsc) { LV_ASSERT_OBJ(canvas, LV_OBJX_NAME); diff --git a/src/lv_widgets/lv_canvas.h b/src/lv_widgets/lv_canvas.h index 14958c1d8..de1a26bf4 100644 --- a/src/lv_widgets/lv_canvas.h +++ b/src/lv_widgets/lv_canvas.h @@ -153,6 +153,7 @@ void lv_canvas_transform(lv_obj_t * canvas, lv_img_dsc_t * img, int16_t angle, u /** * Apply horizontal blur on the canvas * @param canvas pointer to a canvas object + * @param area the area to blur. If `NULL` the whole canvas will be blurred. * @param r radius of the blur */ void lv_canvas_blur_hor(lv_obj_t * canvas, const lv_area_t * area, uint16_t r); @@ -169,6 +170,7 @@ void lv_canvas_blur_ver(lv_obj_t * canvas, const lv_area_t * area, uint16_t r); * Fill the canvas with color * @param canvas pointer to a canvas * @param color the background color + * @param opa the desired opacity */ void lv_canvas_fill_bg(lv_obj_t * canvas, lv_color_t color, lv_opa_t opa); @@ -179,10 +181,10 @@ void lv_canvas_fill_bg(lv_obj_t * canvas, lv_color_t color, lv_opa_t opa); * @param y top coordinate of the rectangle * @param w width of the rectangle * @param h height of the rectangle - * @param style style of the rectangle (`body` properties are used except `padding`) + * @param rect_dsc descriptor of the rectangle */ void lv_canvas_draw_rect(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_t w, lv_coord_t h, - lv_draw_rect_dsc_t * rect_dsc); + const lv_draw_rect_dsc_t * rect_dsc); /** * Draw a text on the canvas. @@ -190,7 +192,7 @@ void lv_canvas_draw_rect(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord * @param x left coordinate of the text * @param y top coordinate of the text * @param max_w max width of the text. The text will be wrapped to fit into this size - * @param style style of the text (`text` properties are used) + * @param label_draw_dsc pointer to a valid label descriptor `lv_draw_label_dsc_t` * @param txt text to display * @param align align of the text (`LV_LABEL_ALIGN_LEFT/RIGHT/CENTER`) */ @@ -201,18 +203,20 @@ void lv_canvas_draw_text(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord /** * Draw an image on the canvas * @param canvas pointer to a canvas object + * @param x left coordinate of the image + * @param y top coordinate of the image * @param src image source. Can be a pointer an `lv_img_dsc_t` variable or a path an image. - * @param style style of the image (`image` properties are used) + * @param img_draw_dsc pointer to a valid label descriptor `lv_draw_img_dsc_t` */ void lv_canvas_draw_img(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, const void * src, - lv_draw_img_dsc_t * img_draw_dsc); + const lv_draw_img_dsc_t * img_draw_dsc); /** * Draw a line on the canvas * @param canvas pointer to a canvas object * @param points point of the line * @param point_cnt number of points - * @param style style of the line (`line` properties are used) + * @param line_draw_dsc pointer to an initialized `lv_draw_line_dsc_t` variable */ void lv_canvas_draw_line(lv_obj_t * canvas, const lv_point_t points[], uint32_t point_cnt, const lv_draw_line_dsc_t * line_draw_dsc); @@ -222,10 +226,10 @@ void lv_canvas_draw_line(lv_obj_t * canvas, const lv_point_t points[], uint32_t * @param canvas pointer to a canvas object * @param points point of the polygon * @param point_cnt number of points - * @param style style of the polygon (`body.main_color` and `body.opa` is used) + * @param poly_draw_dsc pointer to an initialized `lv_draw_rect_dsc_t` variable */ void lv_canvas_draw_polygon(lv_obj_t * canvas, const lv_point_t points[], uint32_t point_cnt, - lv_draw_rect_dsc_t * poly_draw_dsc); + const lv_draw_rect_dsc_t * poly_draw_dsc); /** * Draw an arc on the canvas @@ -235,10 +239,10 @@ void lv_canvas_draw_polygon(lv_obj_t * canvas, const lv_point_t points[], uint32 * @param r radius of the arc * @param start_angle start angle in degrees * @param end_angle end angle in degrees - * @param style style of the polygon (`body.main_color` and `body.opa` is used) + * @param arc_draw_dsc pointer to an initialized `lv_draw_line_dsc_t` variable */ void lv_canvas_draw_arc(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y, lv_coord_t r, int32_t start_angle, - int32_t end_angle, lv_draw_line_dsc_t * arc_draw_dsc); + int32_t end_angle, const lv_draw_line_dsc_t * arc_draw_dsc); /********************** * MACROS From 7827d948d8d26863b71a372b97bbd2077512700a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sven=20Krau=C3=9F?= Date: Wed, 5 Aug 2020 11:18:56 +0200 Subject: [PATCH 106/173] Fix evaluation of return value --- src/lv_draw/lv_img_decoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_draw/lv_img_decoder.c b/src/lv_draw/lv_img_decoder.c index 0c2f67d72..57e99e297 100644 --- a/src/lv_draw/lv_img_decoder.c +++ b/src/lv_draw/lv_img_decoder.c @@ -559,7 +559,7 @@ static lv_res_t lv_img_decoder_built_in_line_true_color(lv_img_decoder_dsc_t * d } uint32_t btr = len * (px_size >> 3); uint32_t br = 0; - lv_fs_read(user_data->f, buf, btr, &br); + res = lv_fs_read(user_data->f, buf, btr, &br); if(res != LV_FS_RES_OK || btr != br) { LV_LOG_WARN("Built-in image decoder read failed"); return LV_RES_INV; From 21985e9a146b246acad9b3b0030cc03f798ef7ff Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Thu, 6 Aug 2020 11:40:30 +0200 Subject: [PATCH 107/173] Update FUNDING.yml --- .github/FUNDING.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 1b34d7088..0c08541e1 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +1 @@ -custom: ["https://www.paypal.com/paypalme/my/profile"] +custom: ["https://paypal.me/littlevgl?locale.x=en_US"] From 7af20516a51dd8a1ab76e039a084a110941cb240 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 5 Aug 2020 11:06:48 +0200 Subject: [PATCH 108/173] add linemeter's mirror feature again the drawing part was somehow removed --- CHANGELOG.md | 1 + src/lv_widgets/lv_linemeter.c | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b0748227c..62fc6fec0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ### Bugfixes - Fix drawing value string twice - Rename `lv_chart_clear_serie` to `lv_chart_clear_series` and `lv_obj_align_origo` to `lv_obj_align_mid` +- Add linemeter's mirror feature again ## v7.3.0 (04.08.2020) diff --git a/src/lv_widgets/lv_linemeter.c b/src/lv_widgets/lv_linemeter.c index c8e7ae724..d8043f876 100644 --- a/src/lv_widgets/lv_linemeter.c +++ b/src/lv_widgets/lv_linemeter.c @@ -392,15 +392,15 @@ void lv_linemeter_draw_scale(lv_obj_t * lmeter, const lv_area_t * clip_area, uin lv_coord_t x_ofs = lmeter->coords.x1 + r_out + left; lv_coord_t y_ofs = lmeter->coords.y1 + r_out + top; int16_t angle_ofs = ext->angle_ofs + 90 + (360 - ext->scale_angle) / 2; - int16_t level = - (int32_t)((int32_t)(ext->cur_value - ext->min_value) * (ext->line_cnt - 1)) / (ext->max_value - ext->min_value); + int16_t level = ext->mirrored ? + (int32_t)((int32_t)(ext->max_value - ext->cur_value) * (ext->line_cnt - 1)) / (ext->max_value - ext->min_value) : + (int32_t)((int32_t)(ext->cur_value - ext->min_value) * (ext->line_cnt - 1)) / (ext->max_value - ext->min_value); uint8_t i; lv_color_t main_color = lv_obj_get_style_line_color(lmeter, part); lv_color_t grad_color = lv_obj_get_style_scale_grad_color(lmeter, part); lv_color_t end_color = lv_obj_get_style_scale_end_color(lmeter, part); - lv_draw_line_dsc_t line_dsc; lv_draw_line_dsc_init(&line_dsc); lv_obj_init_draw_line_dsc(lmeter, part, &line_dsc); @@ -520,11 +520,11 @@ void lv_linemeter_draw_scale(lv_obj_t * lmeter, const lv_area_t * clip_area, uin p1.y = y_out_extra; /* Set the color of the lines */ - if(i > level) { + uint16_t index = ext->mirrored ? ext->line_cnt - i : i; + if((!ext->mirrored && i >= level) || (ext->mirrored && i <= level)) { line_dsc.color = end_color; line_dsc.width = end_line_width; - } - else { + } else { line_dsc.color = lv_color_mix(grad_color, main_color, (255 * i) / ext->line_cnt); } From cda21694c48f163b99a5abe9c1047ee9a11d428d Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Thu, 6 Aug 2020 14:48:23 +0200 Subject: [PATCH 109/173] Fix text decor (udnerline strikethrough) with older versions of font converter --- CHANGELOG.md | 1 + src/lv_draw/lv_draw_label.c | 3 +-- src/lv_themes/lv_theme_empty.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62fc6fec0..2a92f840d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - Fix drawing value string twice - Rename `lv_chart_clear_serie` to `lv_chart_clear_series` and `lv_obj_align_origo` to `lv_obj_align_mid` - Add linemeter's mirror feature again +- Fix text decor (udnerline strikethrough) with older versions of font converter ## v7.3.0 (04.08.2020) diff --git a/src/lv_draw/lv_draw_label.c b/src/lv_draw/lv_draw_label.c index 3f5ac09da..4e2c7f922 100644 --- a/src/lv_draw/lv_draw_label.c +++ b/src/lv_draw/lv_draw_label.c @@ -214,11 +214,10 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_label(const lv_area_t * coords, const lv_area sel_end = tmp; } lv_draw_line_dsc_t line_dsc; - dsc->decor = LV_TEXT_DECOR_UNDERLINE; if((dsc->decor & LV_TEXT_DECOR_UNDERLINE) || (dsc->decor & LV_TEXT_DECOR_STRIKETHROUGH)) { lv_draw_line_dsc_init(&line_dsc); line_dsc.color = dsc->color; - line_dsc.width = font->underline_thickness; + line_dsc.width = font->underline_thickness ? font->underline_thickness : LV_MATH_MAX(font->line_height / 10, 1); line_dsc.opa = dsc->opa; line_dsc.blend_mode = dsc->blend_mode; } diff --git a/src/lv_themes/lv_theme_empty.c b/src/lv_themes/lv_theme_empty.c index 821bbd510..6900ef23c 100644 --- a/src/lv_themes/lv_theme_empty.c +++ b/src/lv_themes/lv_theme_empty.c @@ -95,7 +95,7 @@ lv_theme_t * lv_theme_empty_init(lv_color_t color_primary, lv_color_t color_seco } -void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name) +static void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name) { LV_UNUSED(th); if(name == LV_THEME_SCR) { From 5d981f56adc0505cf992a6327431912c68a13dc4 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Thu, 6 Aug 2020 14:54:51 +0200 Subject: [PATCH 110/173] remove unused variable --- src/lv_widgets/lv_linemeter.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lv_widgets/lv_linemeter.c b/src/lv_widgets/lv_linemeter.c index d8043f876..0de65871c 100644 --- a/src/lv_widgets/lv_linemeter.c +++ b/src/lv_widgets/lv_linemeter.c @@ -520,7 +520,6 @@ void lv_linemeter_draw_scale(lv_obj_t * lmeter, const lv_area_t * clip_area, uin p1.y = y_out_extra; /* Set the color of the lines */ - uint16_t index = ext->mirrored ? ext->line_cnt - i : i; if((!ext->mirrored && i >= level) || (ext->mirrored && i <= level)) { line_dsc.color = end_color; line_dsc.width = end_line_width; From 81caeaa7253fdf76c1e1930a21bad4443428c2ba Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Fri, 7 Aug 2020 07:31:31 -0400 Subject: [PATCH 111/173] Fix `lv_obj_set_height_fit` --- src/lv_core/lv_obj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index e8b50b0e1..c20904733 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -856,7 +856,7 @@ void lv_obj_set_height_fit(lv_obj_t * obj, lv_coord_t h) lv_style_int_t ptop = lv_obj_get_style_pad_top(obj, LV_OBJ_PART_MAIN); lv_style_int_t pbottom = lv_obj_get_style_pad_bottom(obj, LV_OBJ_PART_MAIN); - lv_obj_set_width(obj, h - ptop - pbottom); + lv_obj_set_height(obj, h - ptop - pbottom); } /** From c4e7254aed793126e364a45ded82393741148cf0 Mon Sep 17 00:00:00 2001 From: Fabio Guerra Date: Fri, 7 Aug 2020 10:56:37 -0300 Subject: [PATCH 112/173] Some changes to support binary fonts without the kernel table. --- lvgl.h | 1 + src/lv_font/lv_font_loader.c | 43 ++++++++++++++++-------- tests/lv_test_core/lv_test_font_loader.c | 34 ++++++++++--------- 3 files changed, 49 insertions(+), 29 deletions(-) diff --git a/lvgl.h b/lvgl.h index ae383e640..9590f00a4 100644 --- a/lvgl.h +++ b/lvgl.h @@ -31,6 +31,7 @@ extern "C" { #include "src/lv_themes/lv_theme.h" #include "src/lv_font/lv_font.h" +#include "src/lv_font/lv_font_loader.h" #include "src/lv_font/lv_font_fmt_txt.h" #include "src/lv_misc/lv_printf.h" diff --git a/src/lv_font/lv_font_loader.c b/src/lv_font/lv_font_loader.c index 9a4035408..456b0cb6b 100644 --- a/src/lv_font/lv_font_loader.c +++ b/src/lv_font/lv_font_loader.c @@ -6,7 +6,6 @@ /********************* * INCLUDES *********************/ -#if LV_USE_FILESYSTEM #include #include @@ -15,6 +14,8 @@ #include "../lv_misc/lv_fs.h" #include "lv_font_loader.h" +#if LV_USE_FILESYSTEM + /********************** * TYPEDEFS @@ -101,7 +102,7 @@ lv_font_t * lv_font_load(const char * font_name) if (!success) { - LV_LOG_WARN("Error opening font file: %s\n", font_name); + LV_LOG_WARN("Error loading font file: %s\n", font_name); lv_font_free(font); font = NULL; } @@ -220,7 +221,7 @@ static int read_label(lv_fs_file_t *fp, int start, const char *label) if(lv_fs_read(fp, &length, 4, NULL) != LV_FS_RES_OK || lv_fs_read(fp, buf, 4, NULL) != LV_FS_RES_OK || memcmp(label, buf, 4) != 0) { - LV_LOG_WARN("Error reading '%s'.", label); + LV_LOG_WARN("Error reading '%s' label.", label); return -1; } @@ -408,20 +409,31 @@ static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font) bit_iterator_t bit_it = init_bit_iterator(fp); - if(font_header.advance_width_bits == 0) { + /* + * TODO: understand how to interpret advance_width_format + * When it is set to zero, in my understanding should be used the default value, + * and no data should be written on the advance_width, but it is not occurring. + * + * The following code is not working for most monospaced fonts. + */ + + /*if(font_header.advance_width_bits == 0) { gdsc->adv_w = font_header.default_advance_width; } - else { - gdsc->adv_w = read_bits(&bit_it, font_header.advance_width_bits, &res); - if(res != LV_FS_RES_OK) { - failed = true; - break; - } - - /* TODO: understand how to interpret advance_width_format */ + else */ { if(font_header.advance_width_format == 0) { /* uint */ + gdsc->adv_w = 16 * read_bits(&bit_it, 4, &res); // TODO: review the number of bits that should be read + if(res != LV_FS_RES_OK) { + failed = true; + break; + } } else if(font_header.advance_width_format == 1) { /* unsigned with 4 bits fractional part */ + gdsc->adv_w = read_bits(&bit_it, font_header.advance_width_bits, &res); + if(res != LV_FS_RES_OK) { + failed = true; + break; + } } else { LV_LOG_WARN("error unknown advance_width_format"); @@ -525,8 +537,11 @@ static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font) return false; } - if(lv_fs_seek(fp, glyph_start + glyph_length) != LV_FS_RES_OK) { - return false; + if (font_header.tables_count < 4) { + font_dsc->kern_dsc = NULL; + font_dsc->kern_classes = 0; + font_dsc->kern_scale = 0; + return true; } uint32_t kern_start = glyph_start + glyph_length; diff --git a/tests/lv_test_core/lv_test_font_loader.c b/tests/lv_test_core/lv_test_font_loader.c index d34c4f004..d0fda75b9 100644 --- a/tests/lv_test_core/lv_test_font_loader.c +++ b/tests/lv_test_core/lv_test_font_loader.c @@ -44,8 +44,8 @@ static int compare_fonts(lv_font_t * f1, lv_font_t * f2); void lv_test_font_loader(void) { - lv_font_t * font = lv_font_load("f:lv_font_montserrat_12.bin"); - compare_fonts(&lv_font_montserrat_12, font); + lv_font_t * montserrat_12_bin = lv_font_load("f:lv_font_montserrat_12.bin"); + compare_fonts(&lv_font_montserrat_12, montserrat_12_bin); } static int compare_fonts(lv_font_t * f1, lv_font_t * f2) @@ -109,22 +109,26 @@ static int compare_fonts(lv_font_t * f1, lv_font_t * f2) // kern_dsc lv_font_fmt_txt_kern_classes_t * kern1 = (lv_font_fmt_txt_kern_classes_t *) dsc1->kern_dsc; lv_font_fmt_txt_kern_classes_t * kern2 = (lv_font_fmt_txt_kern_classes_t *) dsc2->kern_dsc; + if (kern1 != NULL && kern2 != NULL) { + lv_test_assert_int_eq(kern1->right_class_cnt, kern2->right_class_cnt, "right_class_cnt"); + lv_test_assert_int_eq(kern1->left_class_cnt, kern2->left_class_cnt, "left_class_cnt"); - lv_test_assert_int_eq(kern1->right_class_cnt, kern2->right_class_cnt, "right_class_cnt"); - lv_test_assert_int_eq(kern1->left_class_cnt, kern2->left_class_cnt, "left_class_cnt"); + for(int i = 0; i < kern1->left_class_cnt; ++i) { + lv_test_assert_int_eq(kern1->left_class_mapping[i], + kern2->left_class_mapping[i], "left_class_mapping"); + } + for(int i = 0; i < kern1->right_class_cnt; ++i) { + lv_test_assert_int_eq(kern1->right_class_mapping[i], + kern2->right_class_mapping[i], "right_class_mapping"); + } - for(int i = 0; i < kern1->left_class_cnt; ++i) { - lv_test_assert_int_eq(kern1->left_class_mapping[i], - kern2->left_class_mapping[i], "left_class_mapping"); + for(int i = 0; i < kern1->right_class_cnt * kern1->left_class_cnt; ++i) { + lv_test_assert_int_eq(kern1->class_pair_values[i], + kern2->class_pair_values[i], "class_pair_values"); + } } - for(int i = 0; i < kern1->right_class_cnt; ++i) { - lv_test_assert_int_eq(kern1->right_class_mapping[i], - kern2->right_class_mapping[i], "right_class_mapping"); - } - - for(int i = 0; i < kern1->right_class_cnt * kern1->left_class_cnt; ++i) { - lv_test_assert_int_eq(kern1->class_pair_values[i], - kern2->class_pair_values[i], "class_pair_values"); + else { + lv_test_assert_ptr_eq(kern1, kern2, "kern"); } // TODO: glyph_bitmap From 90be42c4931039a63821b7bd0e9e6a65bc563f44 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sat, 8 Aug 2020 16:21:51 +0200 Subject: [PATCH 113/173] Fix setting local style property multiple times Realted to https://forum.lvgl.io/t/how-to-change-button-object-color-on-demand/2922/2 --- CHANGELOG.md | 1 + src/lv_core/lv_style.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a92f840d..28a0c4fac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - Rename `lv_chart_clear_serie` to `lv_chart_clear_series` and `lv_obj_align_origo` to `lv_obj_align_mid` - Add linemeter's mirror feature again - Fix text decor (udnerline strikethrough) with older versions of font converter +- Fix setting local style property multiple times ## v7.3.0 (04.08.2020) diff --git a/src/lv_core/lv_style.c b/src/lv_core/lv_style.c index df1debc4d..887c4733b 100644 --- a/src/lv_core/lv_style.c +++ b/src/lv_core/lv_style.c @@ -1104,7 +1104,7 @@ static lv_style_t * get_alloc_local_style(lv_style_list_t * list) { LV_ASSERT_STYLE_LIST(list); - if(list->has_local) return lv_style_list_get_style(list, 0); + if(list->has_local) return lv_style_list_get_style(list, list->has_trans ? 1 : 0); lv_style_t * local_style = lv_mem_alloc(sizeof(lv_style_t)); LV_ASSERT_MEM(local_style); From b6c18ed1717059734a868dcd1123c6527ddf7758 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sun, 9 Aug 2020 12:41:25 +0200 Subject: [PATCH 114/173] Update ROADMAP.md --- docs/ROADMAP.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 5affba5f7..9b5914e58 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -23,6 +23,10 @@ Planned to September/October 2020 - Work in progress - Add new label alignment modes - See [#1656](https://github.com/lvgl/lvgl/issues/1656) +- Remove the align parameter from `lv_canvas_draw_text` + +## v9 +- Simplify `group`s. Discussion is [here](https://forum.lvgl.io/t/lv-group-tabindex/2927/3). ## Ideas - Unit testing (gtest?). See [#1658](https://github.com/lvgl/lvgl/issues/1658) From bd8ac58b6b9bbf005165e650aa317d6f8e108160 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 10 Aug 2020 06:17:03 +0200 Subject: [PATCH 115/173] add missing background drawing and radius handling to image button --- CHANGELOG.md | 1 + src/lv_widgets/lv_img.c | 28 ++++++++++++--- src/lv_widgets/lv_imgbtn.c | 70 +++++++++++++++++++++++++++++++++++++- 3 files changed, 93 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 28a0c4fac..87e94bb18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - Add linemeter's mirror feature again - Fix text decor (udnerline strikethrough) with older versions of font converter - Fix setting local style property multiple times +- Add missing background drawing and radius handling to image button ## v7.3.0 (04.08.2020) diff --git a/src/lv_widgets/lv_img.c b/src/lv_widgets/lv_img.c index 6c6f65791..66ada123c 100644 --- a/src/lv_widgets/lv_img.c +++ b/src/lv_widgets/lv_img.c @@ -620,8 +620,6 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area int32_t zoom_final = lv_obj_get_style_transform_zoom(img, LV_IMG_PART_MAIN); zoom_final = (zoom_final * ext->zoom) >> 8; - if(zoom_final == 0) return LV_DESIGN_RES_OK; - int32_t angle_final = lv_obj_get_style_transform_angle(img, LV_IMG_PART_MAIN); angle_final += ext->angle; @@ -639,6 +637,8 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area lv_draw_rect(&bg_coords, clip_area, &bg_dsc); + if(zoom_final == 0) return LV_DESIGN_RES_OK; + if(lv_obj_get_style_clip_corner(img, LV_OBJ_PART_MAIN)) { lv_draw_mask_radius_param_t * mp = _lv_mem_buf_get(sizeof(lv_draw_mask_radius_param_t)); @@ -705,15 +705,33 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area _lv_mem_buf_release(param); } - lv_draw_rect_dsc_t draw_dsc; - lv_draw_rect_dsc_init(&draw_dsc); - /*If the border is drawn later disable loading other properties*/ if(lv_obj_get_style_border_post(img, LV_OBJ_PART_MAIN)) { + lv_draw_rect_dsc_t draw_dsc; + lv_draw_rect_dsc_init(&draw_dsc); draw_dsc.bg_opa = LV_OPA_TRANSP; draw_dsc.pattern_opa = LV_OPA_TRANSP; draw_dsc.shadow_opa = LV_OPA_TRANSP; lv_obj_init_draw_rect_dsc(img, LV_OBJ_PART_MAIN, &draw_dsc); + + int32_t zoom_final = lv_obj_get_style_transform_zoom(img, LV_IMG_PART_MAIN); + zoom_final = (zoom_final * ext->zoom) >> 8; + + int32_t angle_final = lv_obj_get_style_transform_angle(img, LV_IMG_PART_MAIN); + angle_final += ext->angle; + + lv_area_t bg_coords; + _lv_img_buf_get_transformed_area(&bg_coords, lv_area_get_width(&img->coords), lv_area_get_height(&img->coords), + angle_final, zoom_final, &ext->pivot); + bg_coords.x1 += img->coords.x1; + bg_coords.y1 += img->coords.y1; + bg_coords.x2 += img->coords.x1; + bg_coords.y2 += img->coords.y1; + bg_coords.x1 -= lv_obj_get_style_pad_left(img, LV_IMG_PART_MAIN); + bg_coords.x2 += lv_obj_get_style_pad_right(img, LV_IMG_PART_MAIN); + bg_coords.y1 -= lv_obj_get_style_pad_top(img, LV_IMG_PART_MAIN); + bg_coords.y2 += lv_obj_get_style_pad_bottom(img, LV_IMG_PART_MAIN); + lv_draw_rect(&img->coords, clip_area, &draw_dsc); } } diff --git a/src/lv_widgets/lv_imgbtn.c b/src/lv_widgets/lv_imgbtn.c index 1c37d92a9..5cdc8e15a 100644 --- a/src/lv_widgets/lv_imgbtn.c +++ b/src/lv_widgets/lv_imgbtn.c @@ -273,7 +273,38 @@ static lv_design_res_t lv_imgbtn_design(lv_obj_t * imgbtn, const lv_area_t * cli } /*Draw the object*/ else if(mode == LV_DESIGN_DRAW_MAIN) { - ancestor_design(imgbtn, clip_area, mode); + lv_area_t img_coords; + + lv_obj_get_coords(imgbtn, &img_coords); + + lv_draw_rect_dsc_t bg_dsc; + lv_draw_rect_dsc_init(&bg_dsc); + lv_obj_init_draw_rect_dsc(imgbtn, LV_IMGBTN_PART_MAIN, &bg_dsc); + + /*If the border is drawn later disable loading its properties*/ + if(lv_obj_get_style_border_post(imgbtn, LV_OBJ_PART_MAIN)) { + bg_dsc.border_opa = LV_OPA_TRANSP; + } + + lv_area_t bg_coords; + lv_area_copy(&bg_coords, &img_coords); + bg_coords.x1 -= lv_obj_get_style_pad_left(imgbtn, LV_IMGBTN_PART_MAIN); + bg_coords.x2 += lv_obj_get_style_pad_right(imgbtn, LV_IMGBTN_PART_MAIN); + bg_coords.y1 -= lv_obj_get_style_pad_top(imgbtn, LV_IMGBTN_PART_MAIN); + bg_coords.y2 += lv_obj_get_style_pad_bottom(imgbtn, LV_IMGBTN_PART_MAIN); + + lv_draw_rect(&bg_coords, clip_area, &bg_dsc); + + if(lv_obj_get_style_clip_corner(imgbtn, LV_OBJ_PART_MAIN)) { + lv_draw_mask_radius_param_t * mp = _lv_mem_buf_get(sizeof(lv_draw_mask_radius_param_t)); + + lv_coord_t r = lv_obj_get_style_radius(imgbtn, LV_OBJ_PART_MAIN); + + lv_draw_mask_radius_init(mp, &bg_coords, r, false); + /*Add the mask and use `img+8` as custom id. Don't use `obj` directly because it might be used by the user*/ + lv_draw_mask_add(mp, imgbtn + 8); + } + /*Just draw an image*/ lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn); lv_btn_state_t state = lv_imgbtn_get_state(imgbtn); @@ -374,6 +405,31 @@ static lv_design_res_t lv_imgbtn_design(lv_obj_t * imgbtn, const lv_area_t * cli } /*Post draw when the children are drawn*/ else if(mode == LV_DESIGN_DRAW_POST) { + if(lv_obj_get_style_clip_corner(imgbtn, LV_OBJ_PART_MAIN)) { + lv_draw_mask_radius_param_t * param = lv_draw_mask_remove_custom(imgbtn + 8); + _lv_mem_buf_release(param); + } + + lv_draw_rect_dsc_t draw_dsc; + lv_draw_rect_dsc_init(&draw_dsc); + + /*If the border is drawn later disable loading other properties*/ + if(lv_obj_get_style_border_post(imgbtn, LV_OBJ_PART_MAIN)) { + draw_dsc.bg_opa = LV_OPA_TRANSP; + draw_dsc.pattern_opa = LV_OPA_TRANSP; + draw_dsc.shadow_opa = LV_OPA_TRANSP; + lv_obj_init_draw_rect_dsc(imgbtn, LV_OBJ_PART_MAIN, &draw_dsc); + + + lv_area_t bg_coords; + lv_area_copy(&bg_coords, &imgbtn->coords); + bg_coords.x1 -= lv_obj_get_style_pad_left(imgbtn, LV_IMGBTN_PART_MAIN); + bg_coords.x2 += lv_obj_get_style_pad_right(imgbtn, LV_IMGBTN_PART_MAIN); + bg_coords.y1 -= lv_obj_get_style_pad_top(imgbtn, LV_IMGBTN_PART_MAIN); + bg_coords.y2 += lv_obj_get_style_pad_bottom(imgbtn, LV_IMGBTN_PART_MAIN); + + lv_draw_rect(&bg_coords, clip_area, &draw_dsc); + } } return LV_DESIGN_RES_OK; @@ -400,6 +456,18 @@ static lv_res_t lv_imgbtn_signal(lv_obj_t * imgbtn, lv_signal_t sign, void * par * changed as well Set the new image for the new state.*/ refr_img(imgbtn); } + else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) { + /*Handle the padding of the background*/ + lv_style_int_t left = lv_obj_get_style_pad_left(imgbtn, LV_IMGBTN_PART_MAIN); + lv_style_int_t right = lv_obj_get_style_pad_right(imgbtn, LV_IMGBTN_PART_MAIN); + lv_style_int_t top = lv_obj_get_style_pad_top(imgbtn, LV_IMGBTN_PART_MAIN); + lv_style_int_t bottom = lv_obj_get_style_pad_bottom(imgbtn, LV_IMGBTN_PART_MAIN); + + imgbtn->ext_draw_pad = LV_MATH_MAX(imgbtn->ext_draw_pad, left); + imgbtn->ext_draw_pad = LV_MATH_MAX(imgbtn->ext_draw_pad, right); + imgbtn->ext_draw_pad = LV_MATH_MAX(imgbtn->ext_draw_pad, top); + imgbtn->ext_draw_pad = LV_MATH_MAX(imgbtn->ext_draw_pad, bottom); + } else if(sign == LV_SIGNAL_CLEANUP) { /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ } From 6fd7bcf17222214d0da7392e2d68657a9cfa0a6b Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 10 Aug 2020 11:36:43 +0200 Subject: [PATCH 116/173] allow adding extra label to list buttons --- CHANGELOG.md | 1 + src/lv_widgets/lv_list.c | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87e94bb18..874bce62d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ - Fix text decor (udnerline strikethrough) with older versions of font converter - Fix setting local style property multiple times - Add missing background drawing and radius handling to image button +- Allow adding extra label to list buttons ## v7.3.0 (04.08.2020) diff --git a/src/lv_widgets/lv_list.c b/src/lv_widgets/lv_list.c index acb165a81..ecda79c9b 100644 --- a/src/lv_widgets/lv_list.c +++ b/src/lv_widgets/lv_list.c @@ -365,11 +365,11 @@ lv_obj_t * lv_list_get_btn_label(const lv_obj_t * btn) { LV_ASSERT_OBJ(btn, "lv_btn"); - lv_obj_t * label = lv_obj_get_child(btn, NULL); + lv_obj_t * label = lv_obj_get_child_back(btn, NULL); if(label == NULL) return NULL; while(lv_list_is_list_label(label) == false) { - label = lv_obj_get_child(btn, label); + label = lv_obj_get_child_back(btn, label); if(label == NULL) break; } @@ -386,11 +386,11 @@ lv_obj_t * lv_list_get_btn_img(const lv_obj_t * btn) LV_ASSERT_OBJ(btn, "lv_btn"); #if LV_USE_IMG != 0 - lv_obj_t * img = lv_obj_get_child(btn, NULL); + lv_obj_t * img = lv_obj_get_child_back(btn, NULL); if(img == NULL) return NULL; while(lv_list_is_list_img(img) == false) { - img = lv_obj_get_child(btn, img); + img = lv_obj_get_child_back(btn, img); if(img == NULL) break; } From d2e1094159ecea84ea2662af65f3df0894670ca1 Mon Sep 17 00:00:00 2001 From: Sergei Kolotovchenkov Date: Mon, 10 Aug 2020 21:13:26 +0300 Subject: [PATCH 117/173] Fix Visual Studio 2019 compile errors (#1711) Fixed msvc 2019 compiler error C4576 when using the LVGL inside C++ code --- src/lv_misc/lv_color.h | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/lv_misc/lv_color.h b/src/lv_misc/lv_color.h index 1b557788c..8268668e6 100644 --- a/src/lv_misc/lv_color.h +++ b/src/lv_misc/lv_color.h @@ -596,19 +596,26 @@ static inline uint8_t lv_color_brightness(lv_color_t color) return (uint8_t)(bright >> 3); } +#ifdef __cplusplus +/* Fix of msvc 2019 compiler error C4576 inside C++ code */ +#define _LV_COLOR_MAKE_TYPE_HELPER lv_color_t +#else +#define _LV_COLOR_MAKE_TYPE_HELPER (lv_color_t) +#endif + /* The most simple macro to create a color from R,G and B values */ #if LV_COLOR_DEPTH == 1 -#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){.full = (uint8_t)((b8 >> 7) | (g8 >> 7) | (r8 >> 7))}) +#define LV_COLOR_MAKE(r8, g8, b8) (_LV_COLOR_MAKE_TYPE_HELPER{.full = (uint8_t)((b8 >> 7) | (g8 >> 7) | (r8 >> 7))}) #elif LV_COLOR_DEPTH == 8 -#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{(uint8_t)((b8 >> 6) & 0x3U), (uint8_t)((g8 >> 5) & 0x7U), (uint8_t)((r8 >> 5) & 0x7U)}}) +#define LV_COLOR_MAKE(r8, g8, b8) (_LV_COLOR_MAKE_TYPE_HELPER{{(uint8_t)((b8 >> 6) & 0x3U), (uint8_t)((g8 >> 5) & 0x7U), (uint8_t)((r8 >> 5) & 0x7U)}}) #elif LV_COLOR_DEPTH == 16 #if LV_COLOR_16_SWAP == 0 -#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{(uint16_t)((b8 >> 3) & 0x1FU), (uint16_t)((g8 >> 2) & 0x3FU), (uint16_t)((r8 >> 3) & 0x1FU)}}) +#define LV_COLOR_MAKE(r8, g8, b8) (_LV_COLOR_MAKE_TYPE_HELPER{{(uint16_t)((b8 >> 3) & 0x1FU), (uint16_t)((g8 >> 2) & 0x3FU), (uint16_t)((r8 >> 3) & 0x1FU)}}) #else -#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{(uint16_t)((g8 >> 5) & 0x7U), (uint16_t)((r8 >> 3) & 0x1FU), (uint16_t)((b8 >> 3) & 0x1FU), (uint16_t)((g8 >> 2) & 0x7U)}}) +#define LV_COLOR_MAKE(r8, g8, b8) (_LV_COLOR_MAKE_TYPE_HELPER{{(uint16_t)((g8 >> 5) & 0x7U), (uint16_t)((r8 >> 3) & 0x1FU), (uint16_t)((b8 >> 3) & 0x1FU), (uint16_t)((g8 >> 2) & 0x7U)}}) #endif #elif LV_COLOR_DEPTH == 32 -#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8, g8, r8, 0xff}}) /*Fix 0xff alpha*/ +#define LV_COLOR_MAKE(r8, g8, b8) (_LV_COLOR_MAKE_TYPE_HELPER{{b8, g8, r8, 0xff}}) /*Fix 0xff alpha*/ #endif static inline lv_color_t lv_color_make(uint8_t r, uint8_t g, uint8_t b) From f066f0b8d8d9d47aabab7b81880632dd4dd58bb7 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 11 Aug 2020 10:09:31 +0200 Subject: [PATCH 118/173] fix overflow in large image transformations --- CHANGELOG.md | 1 + src/lv_draw/lv_img_buf.c | 24 ++++++++++++++++-------- src/lv_draw/lv_img_buf.h | 10 ++++++---- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 874bce62d..8e4b928be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - Fix setting local style property multiple times - Add missing background drawing and radius handling to image button - Allow adding extra label to list buttons +- Fix overflow in large image transformations ## v7.3.0 (04.08.2020) diff --git a/src/lv_draw/lv_img_buf.c b/src/lv_draw/lv_img_buf.c index 741ad0439..5ddf40577 100644 --- a/src/lv_draw/lv_img_buf.c +++ b/src/lv_draw/lv_img_buf.c @@ -435,6 +435,10 @@ void _lv_img_buf_transform_init(lv_img_transform_dsc_t * dsc) dsc->tmp.sinma = (s1 * (10 - angle_rem) + s2 * angle_rem) / 10; dsc->tmp.cosma = (c1 * (10 - angle_rem) + c2 * angle_rem) / 10; + /*Use smaller value to avoid overflow*/ + dsc->tmp.sinma = dsc->tmp.sinma >> (LV_TRIGO_SHIFT - _LV_TRANSFORM_TRIGO_SHIFT); + dsc->tmp.cosma = dsc->tmp.cosma >> (LV_TRIGO_SHIFT - _LV_TRANSFORM_TRIGO_SHIFT); + dsc->tmp.chroma_keyed = lv_img_cf_is_chroma_keyed(dsc->cfg.cf) ? 1 : 0; dsc->tmp.has_alpha = lv_img_cf_has_alpha(dsc->cfg.cf) ? 1 : 0; if(dsc->cfg.cf == LV_IMG_CF_TRUE_COLOR || dsc->cfg.cf == LV_IMG_CF_TRUE_COLOR_ALPHA || @@ -493,6 +497,10 @@ void _lv_img_buf_get_transformed_area(lv_area_t * res, lv_coord_t w, lv_coord_t int32_t sinma = (s1 * (10 - angle_rem) + s2 * angle_rem) / 10; int32_t cosma = (c1 * (10 - angle_rem) + c2 * angle_rem) / 10; + /*Use smaller value to avoid overflow*/ + sinma = sinma >> (LV_TRIGO_SHIFT - _LV_TRANSFORM_TRIGO_SHIFT); + cosma = cosma >> (LV_TRIGO_SHIFT - _LV_TRANSFORM_TRIGO_SHIFT); + lv_point_t lt; lv_point_t rt; lv_point_t lb; @@ -509,23 +517,23 @@ void _lv_img_buf_get_transformed_area(lv_area_t * res, lv_coord_t w, lv_coord_t xt = a.x1; yt = a.y1; - lt.x = ((cosma * xt - sinma * yt) >> LV_TRIGO_SHIFT) + pivot->x; - lt.y = ((sinma * xt + cosma * yt) >> LV_TRIGO_SHIFT) + pivot->y; + lt.x = ((cosma * xt - sinma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->x; + lt.y = ((sinma * xt + cosma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->y; xt = a.x2; yt = a.y1; - rt.x = ((cosma * xt - sinma * yt) >> LV_TRIGO_SHIFT) + pivot->x; - rt.y = ((sinma * xt + cosma * yt) >> LV_TRIGO_SHIFT) + pivot->y; + rt.x = ((cosma * xt - sinma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->x; + rt.y = ((sinma * xt + cosma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->y; xt = a.x1; yt = a.y2; - lb.x = ((cosma * xt - sinma * yt) >> LV_TRIGO_SHIFT) + pivot->x; - lb.y = ((sinma * xt + cosma * yt) >> LV_TRIGO_SHIFT) + pivot->y; + lb.x = ((cosma * xt - sinma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->x; + lb.y = ((sinma * xt + cosma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->y; xt = a.x2; yt = a.y2; - rb.x = ((cosma * xt - sinma * yt) >> LV_TRIGO_SHIFT) + pivot->x; - rb.y = ((sinma * xt + cosma * yt) >> LV_TRIGO_SHIFT) + pivot->y; + rb.x = ((cosma * xt - sinma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->x; + rb.y = ((sinma * xt + cosma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->y; res->x1 = LV_MATH_MIN4(lb.x, lt.x, rb.x, rt.x); res->x2 = LV_MATH_MAX4(lb.x, lt.x, rb.x, rt.x); diff --git a/src/lv_draw/lv_img_buf.h b/src/lv_draw/lv_img_buf.h index afde70c55..d0d3991fc 100644 --- a/src/lv_draw/lv_img_buf.h +++ b/src/lv_draw/lv_img_buf.h @@ -48,6 +48,8 @@ extern "C" { #define LV_IMG_ZOOM_NONE 256 +#define _LV_TRANSFORM_TRIGO_SHIFT 10 + /********************** * TYPEDEFS **********************/ @@ -301,8 +303,8 @@ static inline bool _lv_img_buf_transform(lv_img_transform_dsc_t * dsc, lv_coord_ int32_t ys; if(dsc->cfg.zoom == LV_IMG_ZOOM_NONE) { /*Get the source pixel from the upscaled image*/ - xs = ((dsc->tmp.cosma * xt - dsc->tmp.sinma * yt) >> (LV_TRIGO_SHIFT - 8)) + dsc->tmp.pivot_x_256; - ys = ((dsc->tmp.sinma * xt + dsc->tmp.cosma * yt) >> (LV_TRIGO_SHIFT - 8)) + dsc->tmp.pivot_y_256; + xs = ((dsc->tmp.cosma * xt - dsc->tmp.sinma * yt) >> (_LV_TRANSFORM_TRIGO_SHIFT - 8)) + dsc->tmp.pivot_x_256; + ys = ((dsc->tmp.sinma * xt + dsc->tmp.cosma * yt) >> (_LV_TRANSFORM_TRIGO_SHIFT - 8)) + dsc->tmp.pivot_y_256; } else if(dsc->cfg.angle == 0) { xt *= dsc->tmp.zoom_inv; @@ -313,8 +315,8 @@ static inline bool _lv_img_buf_transform(lv_img_transform_dsc_t * dsc, lv_coord_ else { xt *= dsc->tmp.zoom_inv; yt *= dsc->tmp.zoom_inv; - xs = ((dsc->tmp.cosma * xt - dsc->tmp.sinma * yt) >> (LV_TRIGO_SHIFT)) + dsc->tmp.pivot_x_256; - ys = ((dsc->tmp.sinma * xt + dsc->tmp.cosma * yt) >> (LV_TRIGO_SHIFT)) + dsc->tmp.pivot_y_256; + xs = ((dsc->tmp.cosma * xt - dsc->tmp.sinma * yt) >> (_LV_TRANSFORM_TRIGO_SHIFT)) + dsc->tmp.pivot_x_256; + ys = ((dsc->tmp.sinma * xt + dsc->tmp.cosma * yt) >> (_LV_TRANSFORM_TRIGO_SHIFT)) + dsc->tmp.pivot_y_256; } /*Get the integer part of the source pixel*/ From 28807b6a77b96ffcb144bc433f932a2f0b67a36e Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 11 Aug 2020 10:34:04 +0200 Subject: [PATCH 119/173] lv_img_design: fix cover check if angle != 0 --- src/lv_widgets/lv_img.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_img.c b/src/lv_widgets/lv_img.c index 66ada123c..aaeb59d5c 100644 --- a/src/lv_widgets/lv_img.c +++ b/src/lv_widgets/lv_img.c @@ -578,7 +578,7 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area int32_t angle_final = lv_obj_get_style_transform_angle(img, LV_IMG_PART_MAIN); angle_final += ext->angle; - if(angle_final == 0) return LV_DESIGN_RES_NOT_COVER; + if(angle_final != 0) return LV_DESIGN_RES_NOT_COVER; int32_t zoom_final = lv_obj_get_style_transform_zoom(img, LV_IMG_PART_MAIN); zoom_final = (zoom_final * ext->zoom) >> 8; From 2068ab3211ab4df04f283f39c7b6a4b58c64ee20 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 11 Aug 2020 10:38:16 +0200 Subject: [PATCH 120/173] bar, switch, slider: fix drawing background's 'value_str' twice --- src/lv_widgets/lv_bar.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lv_widgets/lv_bar.c b/src/lv_widgets/lv_bar.c index f76a2e13f..c30da9f01 100644 --- a/src/lv_widgets/lv_bar.c +++ b/src/lv_widgets/lv_bar.c @@ -395,7 +395,9 @@ static lv_design_res_t lv_bar_design(lv_obj_t * bar, const lv_area_t * clip_area lv_draw_rect_dsc_init(&draw_dsc); draw_dsc.bg_opa = LV_OPA_TRANSP; draw_dsc.pattern_opa = LV_OPA_TRANSP; + draw_dsc.outline_opa = LV_OPA_TRANSP; draw_dsc.shadow_opa = LV_OPA_TRANSP; + draw_dsc.value_opa = LV_OPA_TRANSP; lv_obj_init_draw_rect_dsc(bar, LV_OBJ_PART_MAIN, &draw_dsc); lv_draw_rect(&bar->coords, clip_area, &draw_dsc); @@ -414,6 +416,8 @@ static void draw_bg(lv_obj_t * bar, const lv_area_t * clip_area) draw_dsc.border_opa = LV_OPA_TRANSP; } + /*value will be drawn later*/ + draw_dsc.value_opa = LV_OPA_TRANSP; lv_obj_init_draw_rect_dsc(bar, LV_BAR_PART_BG, &draw_dsc); lv_draw_rect(&bar->coords, clip_area, &draw_dsc); From 14a4c190c91686dd7cd9deb25ff5a7d759313ff7 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 11 Aug 2020 14:17:05 +0200 Subject: [PATCH 121/173] merge rotary to arc --- CHANGELOG.md | 2 +- lvgl.h | 1 - src/lv_themes/lv_theme_material.c | 75 +--- src/lv_widgets/lv_arc.c | 398 ++++++++++++++++++++- src/lv_widgets/lv_arc.h | 94 ++++- src/lv_widgets/lv_rotary.c | 566 ------------------------------ src/lv_widgets/lv_rotary.h | 322 ----------------- 7 files changed, 490 insertions(+), 968 deletions(-) delete mode 100644 src/lv_widgets/lv_rotary.c delete mode 100644 src/lv_widgets/lv_rotary.h diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e4b928be..b9e472b24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # Changelog ## v7.4.0 (planned on 01.09.2020) -*Available in the `dev` branch* +- arc: add set value by click feature ## v7.3.1 (planned on 18.08.2020) diff --git a/lvgl.h b/lvgl.h index 4edd6d364..ae383e640 100644 --- a/lvgl.h +++ b/lvgl.h @@ -53,7 +53,6 @@ extern "C" { #include "src/lv_widgets/lv_keyboard.h" #include "src/lv_widgets/lv_dropdown.h" #include "src/lv_widgets/lv_roller.h" -#include "src/lv_widgets/lv_rotary.h" #include "src/lv_widgets/lv_textarea.h" #include "src/lv_widgets/lv_canvas.h" #include "src/lv_widgets/lv_win.h" diff --git a/src/lv_themes/lv_theme_material.c b/src/lv_themes/lv_theme_material.c index 45911d074..85a24c881 100644 --- a/src/lv_themes/lv_theme_material.c +++ b/src/lv_themes/lv_theme_material.c @@ -86,6 +86,7 @@ typedef struct { #if LV_USE_ARC lv_style_t arc_indic; lv_style_t arc_bg; + lv_style_t arc_knob; #endif #if LV_USE_BAR @@ -148,10 +149,6 @@ typedef struct { lv_style_t roller_bg, roller_sel; #endif -#if LV_USE_ROTARY - lv_style_t rotary_bg, rotary_indic, rotary_knob; -#endif - #if LV_USE_SLIDER lv_style_t slider_knob, slider_bg; #endif @@ -509,6 +506,14 @@ static void arc_init(void) lv_style_set_line_color(&styles->arc_bg, LV_STATE_DEFAULT, COLOR_BG_SEC); lv_style_set_line_width(&styles->arc_bg, LV_STATE_DEFAULT, LV_DPX(25)); lv_style_set_line_rounded(&styles->arc_bg, LV_STATE_DEFAULT, true); + + style_init_reset(&styles->arc_knob); + lv_style_set_radius(&styles->arc_knob, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE); + lv_style_set_pad_top(&styles->arc_knob, LV_STATE_DEFAULT, LV_DPX(10)); + lv_style_set_pad_bottom(&styles->arc_knob, LV_STATE_DEFAULT, LV_DPX(10)); + lv_style_set_pad_left(&styles->arc_knob, LV_STATE_DEFAULT, LV_DPX(10)); + lv_style_set_pad_right(&styles->arc_knob, LV_STATE_DEFAULT, LV_DPX(10)); + #endif } @@ -795,41 +800,6 @@ static void roller_init(void) #endif } -static void rotary_init(void) -{ -#if LV_USE_ROTARY != 0 - style_init_reset(&styles->rotary_bg); - lv_style_set_clip_corner(&styles->rotary_bg, LV_STATE_DEFAULT, true); - lv_style_set_pad_left(&styles->rotary_bg, LV_STATE_DEFAULT, LV_DPX(6)); - lv_style_set_pad_right(&styles->rotary_bg, LV_STATE_DEFAULT, LV_DPX(6)); - lv_style_set_pad_top(&styles->rotary_bg, LV_STATE_DEFAULT, LV_DPX(6)); - lv_style_set_pad_bottom(&styles->rotary_bg, LV_STATE_DEFAULT, LV_DPX(6)); - lv_style_set_pad_inner(&styles->rotary_bg, LV_STATE_DEFAULT, LV_DPX(6)); - lv_style_set_border_width(&styles->rotary_bg, LV_STATE_DEFAULT, LV_DPX(2)); - lv_style_set_line_color(&styles->rotary_bg, LV_STATE_DEFAULT, COLOR_BG_SEC); - lv_style_set_line_width(&styles->rotary_bg, LV_STATE_DEFAULT, LV_DPX(8)); - lv_style_set_line_rounded(&styles->rotary_bg, LV_STATE_DEFAULT, true); - - style_init_reset(&styles->rotary_indic); - lv_style_set_line_color(&styles->rotary_indic, LV_STATE_DEFAULT, theme.color_primary); - lv_style_set_line_width(&styles->rotary_indic, LV_STATE_DEFAULT, LV_DPX(8)); - lv_style_set_line_rounded(&styles->rotary_indic, LV_STATE_DEFAULT, true); - - style_init_reset(&styles->rotary_knob); - lv_style_set_bg_color(&styles->rotary_knob, LV_STATE_CHECKED, COLOR_BTN); - lv_style_set_text_color(&styles->rotary_knob, LV_STATE_CHECKED, IS_LIGHT ? lv_color_hex(0x31404f) : lv_color_hex(0xffffff)); - lv_style_set_value_color(&styles->rotary_knob, LV_STATE_CHECKED, IS_LIGHT ? lv_color_hex(0x31404f) : lv_color_hex(0xffffff)); - lv_style_set_bg_opa(&styles->rotary_knob, LV_STATE_DEFAULT, LV_OPA_COVER); - lv_style_set_bg_color(&styles->rotary_knob, LV_STATE_DEFAULT, LV_COLOR_WHITE); - lv_style_set_radius(&styles->rotary_knob, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE); - lv_style_set_pad_top(&styles->rotary_knob, LV_STATE_DEFAULT, - LV_DPX(4)); - lv_style_set_pad_bottom(&styles->rotary_knob, LV_STATE_DEFAULT, - LV_DPX(4)); - lv_style_set_pad_left(&styles->rotary_knob, LV_STATE_DEFAULT, - LV_DPX(4)); - lv_style_set_pad_right(&styles->rotary_knob, LV_STATE_DEFAULT, - LV_DPX(4)); - lv_style_set_pad_inner(&styles->rotary_knob, LV_STATE_DEFAULT, LV_DPX(6)); -#endif -} - static void tabview_init(void) { #if LV_USE_TABVIEW != 0 @@ -969,7 +939,6 @@ lv_theme_t * lv_theme_material_init(lv_color_t color_primary, lv_color_t color_s list_init(); ddlist_init(); roller_init(); - rotary_init(); tabview_init(); tileview_init(); table_init(); @@ -1099,6 +1068,11 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name) list = lv_obj_get_style_list(obj, LV_ARC_PART_INDIC); _lv_style_list_add_style(list, &styles->arc_indic); + + list = lv_obj_get_style_list(obj, LV_ARC_PART_KNOB); + _lv_style_list_add_style(list, &styles->bg); + _lv_style_list_add_style(list, &styles->bg_click); + _lv_style_list_add_style(list, &styles->arc_knob); break; #endif @@ -1225,27 +1199,6 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj, lv_theme_style_t name) break; #endif -#if LV_USE_ROTARY - case LV_THEME_ROTARY: - lv_obj_clean_style_list(obj, LV_ROTARY_PART_BG); - list = lv_obj_get_style_list(obj, LV_ROTARY_PART_BG); - _lv_style_list_add_style(list, &styles->bg); - _lv_style_list_add_style(list, &styles->arc_bg); - _lv_style_list_add_style(list, &styles->rotary_bg); - - lv_obj_clean_style_list(obj, LV_ROTARY_PART_INDIC); - list = lv_obj_get_style_list(obj, LV_ROTARY_PART_INDIC); - _lv_style_list_add_style(list, &styles->arc_indic); - _lv_style_list_add_style(list, &styles->rotary_indic); - - lv_obj_clean_style_list(obj, LV_ROTARY_PART_KNOB); - list = lv_obj_get_style_list(obj, LV_ROTARY_PART_KNOB); - _lv_style_list_add_style(list, &styles->btn); - _lv_style_list_add_style(list, &styles->rotary_knob); - - break; -#endif - #if LV_USE_OBJMASK case LV_THEME_OBJMASK: list = lv_obj_get_style_list(obj, LV_OBJMASK_PART_MAIN); diff --git a/src/lv_widgets/lv_arc.c b/src/lv_widgets/lv_arc.c index 4dd7d9f45..8849d3895 100644 --- a/src/lv_widgets/lv_arc.c +++ b/src/lv_widgets/lv_arc.c @@ -9,6 +9,8 @@ #include "lv_arc.h" #if LV_USE_ARC != 0 +#include "../lv_core/lv_group.h" +#include "../lv_core/lv_indev.h" #include "../lv_misc/lv_debug.h" #include "../lv_misc/lv_math.h" #include "../lv_draw/lv_draw_arc.h" @@ -30,6 +32,7 @@ static lv_design_res_t lv_arc_design(lv_obj_t * arc, const lv_area_t * clip_area static lv_res_t lv_arc_signal(lv_obj_t * arc, lv_signal_t sign, void * param); static lv_style_list_t * lv_arc_get_style(lv_obj_t * arc, uint8_t part); static void inv_arc_area(lv_obj_t * arc, uint16_t start_angle, uint16_t end_angle); +static void get_areas(lv_obj_t * arc, lv_point_t * center, lv_coord_t * arc_r, lv_area_t * knob_area); /********************** * STATIC VARIABLES @@ -78,7 +81,16 @@ lv_obj_t * lv_arc_create(lv_obj_t * par, const lv_obj_t * copy) ext->bg_angle_end = 45; ext->arc_angle_start = 135; ext->arc_angle_end = 270; + ext->type = LV_ARC_TYPE_NORMAL; + ext->cur_value = -1; + ext->min_value = 0; + ext->max_value = 100; + ext->dragging = false; + ext->chg_rate = 540; + ext->last_tick = lv_tick_get(); + ext->last_angle = ext->arc_angle_end; lv_style_list_init(&ext->style_arc); + lv_style_list_init(&ext->style_knob); lv_obj_set_size(arc, LV_DPI, LV_DPI); @@ -88,6 +100,10 @@ lv_obj_t * lv_arc_create(lv_obj_t * par, const lv_obj_t * copy) /*Init the new arc arc*/ if(copy == NULL) { + lv_obj_set_click(arc, true); + lv_obj_add_protect(arc, LV_PROTECT_PRESS_LOST); + lv_obj_set_ext_click_area(arc, LV_DPI / 10, LV_DPI / 10, LV_DPI / 10, LV_DPI / 10); + lv_arc_set_value(arc, ext->min_value); lv_theme_apply(arc, LV_THEME_ARC); } /*Copy an existing arc*/ @@ -97,7 +113,15 @@ lv_obj_t * lv_arc_create(lv_obj_t * par, const lv_obj_t * copy) ext->arc_angle_end = copy_ext->arc_angle_end; ext->bg_angle_start = copy_ext->bg_angle_start; ext->bg_angle_end = copy_ext->bg_angle_end; - + ext->type = copy_ext->type; + ext->cur_value = copy_ext->cur_value; + ext->min_value = copy_ext->min_value; + ext->max_value = copy_ext->max_value; + ext->dragging = copy_ext->dragging; + ext->chg_rate = copy_ext->chg_rate; + ext->last_tick = copy_ext->last_tick; + ext->last_angle = copy_ext->last_angle; + lv_style_list_copy(&ext->style_knob, ©_ext->style_knob); lv_style_list_copy(&ext->style_arc, ©_ext->style_arc); /*Refresh the style with new signal function*/ @@ -316,6 +340,131 @@ void lv_arc_set_rotation(lv_obj_t * arc, uint16_t rotation_angle) lv_obj_invalidate(arc); } + +/** + * Set the type of arc. + * @param arc pointer to arc object + * @param type arc type + */ +void lv_arc_set_type(lv_obj_t * arc, lv_arc_type_t type) +{ + LV_ASSERT_OBJ(arc, LV_OBJX_NAME); + + lv_arc_ext_t *ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); + int16_t val = ext->cur_value; + + ext->type = type; + ext->cur_value = -1; /** Force set_value handling*/ + + int16_t bg_midpoint, bg_end = ext->bg_angle_end; + if (ext->bg_angle_end < ext->bg_angle_start) bg_end = ext->bg_angle_end + 360; + + switch(ext->type) { + case LV_ARC_TYPE_SYMMETRIC: + bg_midpoint = (ext->bg_angle_start + bg_end) / 2; + lv_arc_set_start_angle(arc, bg_midpoint); + lv_arc_set_end_angle(arc, bg_midpoint); + break; + case LV_ARC_TYPE_REVERSE: + lv_arc_set_end_angle(arc, ext->bg_angle_end); + break; + default: /** LV_ARC_TYPE_NORMAL*/ + lv_arc_set_start_angle(arc, ext->bg_angle_start); + } + + lv_arc_set_value(arc, val); +} + +/** + * Set a new value on the arc + * @param arc pointer to a arc object + * @param value new value + */ +void lv_arc_set_value(lv_obj_t * arc, int16_t value) +{ + LV_ASSERT_OBJ(arc, LV_OBJX_NAME); + + lv_arc_ext_t * ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); + if(ext->cur_value == value) return; + + int16_t new_value; + new_value = value > ext->max_value ? ext->max_value : value; + new_value = new_value < ext->min_value ? ext->min_value : new_value; + + if(ext->cur_value == new_value) return; + ext->cur_value = new_value; + + int16_t bg_midpoint, range_midpoint, bg_end = ext->bg_angle_end; + if (ext->bg_angle_end < ext->bg_angle_start) bg_end = ext->bg_angle_end + 360; + + int16_t angle; + switch(ext->type) { + case LV_ARC_TYPE_SYMMETRIC: + bg_midpoint = (ext->bg_angle_start + bg_end) / 2; + range_midpoint = (int32_t)(ext->min_value + ext->max_value) / 2; + + if (ext->cur_value < range_midpoint) { + angle = _lv_map(ext->cur_value, ext->min_value, range_midpoint, ext->bg_angle_start, bg_midpoint); + lv_arc_set_start_angle(arc, angle); + lv_arc_set_end_angle(arc, bg_midpoint); + } else { + angle = _lv_map(ext->cur_value, range_midpoint, ext->max_value, bg_midpoint, bg_end); + lv_arc_set_start_angle(arc, bg_midpoint); + lv_arc_set_end_angle(arc, angle); + } + break; + case LV_ARC_TYPE_REVERSE: + angle = _lv_map(ext->cur_value, ext->min_value, ext->max_value, ext->bg_angle_start, bg_end); + lv_arc_set_start_angle(arc, angle); + break; + default: /** LV_ARC_TYPE_NORMAL*/ + angle = _lv_map(ext->cur_value, ext->min_value, ext->max_value, ext->bg_angle_start, bg_end); + lv_arc_set_end_angle(arc, angle); + } + ext->last_angle = angle; /*Cache angle for slew rate limiting*/ +} + +/** + * Set minimum and the maximum values of a arc + * @param arc pointer to the arc object + * @param min minimum value + * @param max maximum value + */ +void lv_arc_set_range(lv_obj_t * arc, int16_t min, int16_t max) +{ + LV_ASSERT_OBJ(arc, LV_OBJX_NAME); + + lv_arc_ext_t * ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); + if(ext->min_value == min && ext->max_value == max) return; + + ext->min_value = min; + ext->max_value = max; + + if(ext->cur_value < min) { + ext->cur_value = min; + } + if(ext->cur_value > max) { + ext->cur_value = max; + } + + lv_arc_set_value(arc, ext->cur_value); +} + +/** + * Set the threshold of arc knob increments + * position. + * @param arc pointer to a arc object + * @param threshold increment threshold + */ +void lv_arc_set_chg_rate(lv_obj_t * arc, uint16_t rate) +{ + LV_ASSERT_OBJ(arc, LV_OBJX_NAME); + + lv_arc_ext_t *ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); + ext->chg_rate = rate; +} + + /*===================== * Getter functions *====================*/ @@ -376,6 +525,72 @@ uint16_t lv_arc_get_bg_angle_end(lv_obj_t * arc) return ext->bg_angle_end; } + +/** + * Get the value of a arc + * @param arc pointer to a arc object + * @return the value of the arc + */ +int16_t lv_arc_get_value(const lv_obj_t * arc) +{ + LV_ASSERT_OBJ(arc, LV_OBJX_NAME); + + lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc); + return ext->cur_value; +} + +/** + * Get the minimum value of a arc + * @param arc pointer to a arc object + * @return the minimum value of the arc + */ +int16_t lv_arc_get_min_value(const lv_obj_t * arc) +{ + LV_ASSERT_OBJ(arc, LV_OBJX_NAME); + + lv_arc_ext_t *ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); + return ext->min_value; +} + +/** + * Get the maximum value of a arc + * @param arc pointer to a arc object + * @return the maximum value of the arc + */ +int16_t lv_arc_get_max_value(const lv_obj_t * arc) +{ + LV_ASSERT_OBJ(arc, LV_OBJX_NAME); + + lv_arc_ext_t *ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); + return ext->max_value; +} + +/** + * Give the arc is being dragged or not + * @param arc pointer to a arc object + * @return true: drag in progress false: not dragged + */ +bool lv_arc_is_dragged(const lv_obj_t * arc) +{ + LV_ASSERT_OBJ(arc, LV_OBJX_NAME); + + lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc); + return ext->dragging; +} + +/** + * Get whether the arc is type or not. + * @param arc pointer to a arc object + * @return arc type + */ +lv_arc_type_t lv_arc_get_type(const lv_obj_t * arc) +{ + LV_ASSERT_OBJ(arc, LV_OBJX_NAME); + + lv_arc_ext_t * ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); + return ext->type; +} + /*===================== * Other functions *====================*/ @@ -414,21 +629,18 @@ static lv_design_res_t lv_arc_design(lv_obj_t * arc, const lv_area_t * clip_area lv_draw_rect(&arc->coords, clip_area, &bg_dsc); - lv_coord_t left_bg = lv_obj_get_style_pad_left(arc, LV_ARC_PART_BG); - lv_coord_t right_bg = lv_obj_get_style_pad_right(arc, LV_ARC_PART_BG); - lv_coord_t top_bg = lv_obj_get_style_pad_top(arc, LV_ARC_PART_BG); - lv_coord_t bottom_bg = lv_obj_get_style_pad_bottom(arc, LV_ARC_PART_BG); - lv_coord_t r = (LV_MATH_MIN(lv_obj_get_width(arc) - left_bg - right_bg, - lv_obj_get_height(arc) - top_bg - bottom_bg)) / 2; - lv_draw_line_dsc_t arc_dsc; - lv_coord_t x = arc->coords.x1 + r + left_bg; - lv_coord_t y = arc->coords.y1 + r + top_bg; + lv_point_t center; + lv_coord_t arc_r; + lv_area_t knob_area; + get_areas(arc, ¢er, &arc_r, &knob_area); - if(r > 0) { + /*Draw the background arc*/ + lv_draw_line_dsc_t arc_dsc; + if(arc_r > 0) { lv_draw_line_dsc_init(&arc_dsc); lv_obj_init_draw_line_dsc(arc, LV_ARC_PART_BG, &arc_dsc); - lv_draw_arc(x, y, r, ext->bg_angle_start + ext->rotation_angle, ext->bg_angle_end + ext->rotation_angle, clip_area, + lv_draw_arc(center.x, center.y, arc_r, ext->bg_angle_start + ext->rotation_angle, ext->bg_angle_end + ext->rotation_angle, clip_area, &arc_dsc); } @@ -438,15 +650,23 @@ static lv_design_res_t lv_arc_design(lv_obj_t * arc, const lv_area_t * clip_area lv_coord_t right_indic = lv_obj_get_style_pad_right(arc, LV_ARC_PART_INDIC); lv_coord_t top_indic = lv_obj_get_style_pad_top(arc, LV_ARC_PART_INDIC); lv_coord_t bottom_indic = lv_obj_get_style_pad_bottom(arc, LV_ARC_PART_INDIC); - r -= LV_MATH_MAX4(left_indic, right_indic, top_indic, bottom_indic); + arc_r -= LV_MATH_MAX4(left_indic, right_indic, top_indic, bottom_indic); - if(r > 0) { + if(arc_r > 0) { lv_draw_line_dsc_init(&arc_dsc); lv_obj_init_draw_line_dsc(arc, LV_ARC_PART_INDIC, &arc_dsc); - lv_draw_arc(x, y, r, ext->arc_angle_start + ext->rotation_angle, ext->arc_angle_end + ext->rotation_angle, clip_area, + lv_draw_arc(center.x, center.y, arc_r, ext->arc_angle_start + ext->rotation_angle, ext->arc_angle_end + ext->rotation_angle, clip_area, &arc_dsc); } + + + lv_draw_rect_dsc_t knob_rect_dsc; + lv_draw_rect_dsc_init(&knob_rect_dsc); + lv_obj_init_draw_rect_dsc(arc, LV_ARC_PART_KNOB, &knob_rect_dsc); + + lv_draw_rect(&knob_area, clip_area, &knob_rect_dsc); + } /*Post draw when the children are drawn*/ else if(mode == LV_DESIGN_DRAW_POST) { @@ -478,7 +698,118 @@ static lv_res_t lv_arc_signal(lv_obj_t * arc, lv_signal_t sign, void * param) if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME); - if(sign == LV_SIGNAL_CLEANUP) { + lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc); + + if(sign == LV_SIGNAL_PRESSING) { + lv_indev_t * indev = lv_indev_get_act(); + if(indev == NULL) return res; + + /*Handle only pointers here*/ + lv_indev_type_t indev_type = lv_indev_get_type(indev); + if(indev_type != LV_INDEV_TYPE_POINTER) return res; + + lv_point_t p; + lv_indev_get_point(indev, &p); + + /*Make point relative to the arc's center*/ + lv_point_t center; + lv_coord_t r; + lv_area_t knob_area; + get_areas(arc, ¢er, &r, &knob_area); + + p.x -= center.x; + p.y -= center.y; + + /*Enter dragging mode if pressed out of the knob*/ + if(ext->dragging == false) { + lv_coord_t indic_width = lv_obj_get_style_line_width(arc, LV_ARC_PART_INDIC); + r -= indic_width; + if(p.x * p.x + p.y * p.y > r * r) { + ext->dragging = true; + ext->last_tick = lv_tick_get(); /*Capture timestamp at dragging start*/ + } + } + + /*It must be in "dragging" mode to turn the arc*/ + if(ext->dragging == false) return res; + + /*Calculate the angle of the pressed point*/ + int16_t angle; + int16_t bg_end = ext->bg_angle_end; + if (ext->bg_angle_end < ext->bg_angle_start) { + bg_end = ext->bg_angle_end + 360; + } + + angle = 360 - _lv_atan2(p.x, p.y) + 90; /*Some transformation is required*/ + if(angle < ext->bg_angle_start) angle = ext->bg_angle_start; + if(angle > bg_end) angle = bg_end; + + /*Calculate the slew rate limited angle based on change rate (degrees/sec)*/ + int16_t delta_angle = angle - ext->last_angle; + uint32_t delta_tick = lv_tick_elaps(ext->last_tick); + int16_t delta_angle_max = (ext->chg_rate * delta_tick) / 1000; + + if (delta_angle > delta_angle_max) { + delta_angle = delta_angle_max; + } else if (delta_angle < -delta_angle_max) { + delta_angle = -delta_angle_max; + } + + angle = ext->last_angle + delta_angle; /*Apply the limited angle change*/ + + /*Rounding for symmetry*/ + int32_t round = ((bg_end - ext->bg_angle_start) * 8) / (ext->max_value - ext->min_value); + round = (round + 4) >> 4; + angle += round; + + /*Set the new value*/ + int16_t new_value = _lv_map(angle, ext->bg_angle_start, bg_end, ext->min_value, ext->max_value); + if(new_value != lv_arc_get_value(arc)) { + ext->last_tick = lv_tick_get(); /*Cache timestamp for the next iteration*/ + lv_arc_set_value(arc, new_value); /*set_value caches the last_angle for the next iteration*/ + if(new_value != ext->cur_value) { + res = lv_event_send(arc, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + } + + /*Don1't let the elapsed time to big while sitting on an end point*/ + if(new_value == ext->min_value || new_value == ext->max_value) { + ext->last_tick = lv_tick_get(); /*Cache timestamp for the next iteration*/ + } + } + else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) { + ext->dragging = false; + +#if LV_USE_GROUP + /*Leave edit mode if released. (No need to wait for LONG_PRESS) */ + lv_group_t * g = lv_obj_get_group(arc); + bool editing = lv_group_get_editing(g); + lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act()); + if(indev_type == LV_INDEV_TYPE_ENCODER) { + if(editing) lv_group_set_editing(g, false); + } +#endif + + } + else if(sign == LV_SIGNAL_CONTROL) { + char c = *((char *)param); + + int16_t old_value = ext->cur_value; + if(c == LV_KEY_RIGHT || c == LV_KEY_UP) { + lv_arc_set_value(arc, lv_arc_get_value(arc) + 1); + } + else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) { + lv_arc_set_value(arc, lv_arc_get_value(arc) - 1); + } + + if (old_value != ext->cur_value) { + res = lv_event_send(arc, LV_EVENT_VALUE_CHANGED, NULL); + if(res != LV_RES_OK) return res; + } + } + else if(sign == LV_SIGNAL_CLEANUP) { + lv_obj_clean_style_list(arc, LV_ARC_PART_KNOB); lv_obj_clean_style_list(arc, LV_ARC_PART_INDIC); } @@ -506,6 +837,9 @@ static lv_style_list_t * lv_arc_get_style(lv_obj_t * arc, uint8_t part) case LV_ARC_PART_INDIC: style_dsc_p = &ext->style_arc; break; + case LV_ARC_PART_KNOB: + style_dsc_p = &ext->style_knob; + break; default: style_dsc_p = NULL; } @@ -617,4 +951,36 @@ static void inv_arc_area(lv_obj_t * arc, uint16_t start_angle, uint16_t end_angl lv_obj_invalidate(arc); } } + + +static void get_areas(lv_obj_t * arc, lv_point_t * center, lv_coord_t * arc_r, lv_area_t * knob_area) +{ + lv_coord_t left_bg = lv_obj_get_style_pad_left(arc, LV_ARC_PART_BG); + lv_coord_t right_bg = lv_obj_get_style_pad_right(arc, LV_ARC_PART_BG); + lv_coord_t top_bg = lv_obj_get_style_pad_top(arc, LV_ARC_PART_BG); + lv_coord_t bottom_bg = lv_obj_get_style_pad_bottom(arc, LV_ARC_PART_BG); + + lv_coord_t r = (LV_MATH_MIN(lv_obj_get_width(arc) - left_bg - right_bg, + lv_obj_get_height(arc) - top_bg - bottom_bg)) / 2; + + *arc_r = r; + center->x = arc->coords.x1 + r + left_bg; + center->y = arc->coords.y1 + r + top_bg; + + + lv_coord_t indic_width = lv_obj_get_style_line_width(arc, LV_ARC_PART_INDIC); + r -= indic_width; + + lv_coord_t left_knob = lv_obj_get_style_pad_left(arc, LV_ARC_PART_KNOB); + lv_coord_t right_knob = lv_obj_get_style_pad_right(arc, LV_ARC_PART_KNOB); + lv_coord_t top_knob = lv_obj_get_style_pad_top(arc, LV_ARC_PART_KNOB); + lv_coord_t bottom_knob = lv_obj_get_style_pad_bottom(arc, LV_ARC_PART_KNOB); + + knob_area->x1 = center->x - r + left_knob; + knob_area->x2 = center->x + r - right_knob; + knob_area->y1 = center->y - r + top_knob; + knob_area->y2 = center->y + r - bottom_knob; +} + + #endif diff --git a/src/lv_widgets/lv_arc.h b/src/lv_widgets/lv_arc.h index 10481f405..94f711661 100644 --- a/src/lv_widgets/lv_arc.h +++ b/src/lv_widgets/lv_arc.h @@ -26,6 +26,14 @@ extern "C" { /********************** * TYPEDEFS **********************/ + +enum { + LV_ARC_TYPE_NORMAL, + LV_ARC_TYPE_SYMMETRIC, + LV_ARC_TYPE_REVERSE +}; +typedef uint8_t lv_arc_type_t; + /*Data of arc*/ typedef struct { /*New data for this type */ @@ -35,14 +43,24 @@ typedef struct { uint16_t bg_angle_start; uint16_t bg_angle_end; lv_style_list_t style_arc; + lv_style_list_t style_knob; /* Style of the knob */ + + int16_t cur_value; /*Current value of the arc*/ + int16_t min_value; /*Minimum value of the arc*/ + int16_t max_value; /*Maximum value of the arc*/ + uint16_t dragging :1; + uint16_t type :2; + uint16_t chg_rate; /*Drag angle rate of change of the arc (degrees/sec)*/ + uint32_t last_tick; /*Last dragging event timestamp of the arc*/ + int16_t last_angle; /*Last dragging angle of the arc*/ } lv_arc_ext_t; /*Parts of the arc*/ enum { LV_ARC_PART_BG = LV_OBJ_PART_MAIN, LV_ARC_PART_INDIC, + LV_ARC_PART_KNOB, _LV_ARC_PART_VIRTUAL_LAST, - _LV_ARC_PART_REAL_LAST = _LV_OBJ_PART_REAL_LAST, }; typedef uint8_t lv_arc_part_t; @@ -118,6 +136,45 @@ void lv_arc_set_bg_angles(lv_obj_t * arc, uint16_t start, uint16_t end); */ void lv_arc_set_rotation(lv_obj_t * arc, uint16_t rotation_angle); + +/** + * Set the type of arc. + * @param arc pointer to arc object + * @param type arc type + */ +void lv_arc_set_type(lv_obj_t * arc, lv_arc_type_t type); + +/** + * Set a new value on the arc + * @param arc pointer to a arc object + * @param value new value + */ +void lv_arc_set_value(lv_obj_t * arc, int16_t value); + +/** + * Set minimum and the maximum values of a arc + * @param arc pointer to the arc object + * @param min minimum value + * @param max maximum value + */ +void lv_arc_set_range(lv_obj_t * arc, int16_t min, int16_t max); + +/** + * Reverse arc behavior. The indicator will grow from arc end instead of arc start. + * position. + * @param arc pointer to a arc object + * @param reverse true: enable disable reverse behavior; false: disable + */ +void lv_arc_set_reverse(lv_obj_t * arc, bool reverse); + +/** + * Set the threshold of arc knob increments + * position. + * @param arc pointer to a arc object + * @param threshold increment threshold + */ +void lv_arc_set_chg_rate(lv_obj_t * arc, uint16_t threshold); + /*===================== * Getter functions *====================*/ @@ -150,6 +207,41 @@ uint16_t lv_arc_get_bg_angle_start(lv_obj_t * arc); */ uint16_t lv_arc_get_bg_angle_end(lv_obj_t * arc); +/** + * Get whether the arc is type or not. + * @param arc pointer to a arc object + * @return arc type + */ +lv_arc_type_t lv_arc_get_type(const lv_obj_t * arc); + +/** + * Get the value of the of a arc + * @param arc pointer to a arc object + * @return the value of the of the arc + */ +int16_t lv_arc_get_value(const lv_obj_t * arc); + +/** + * Get the minimum value of a arc + * @param arc pointer to a arc object + * @return the minimum value of the arc + */ +int16_t lv_arc_get_min_value(const lv_obj_t * arc); + +/** + * Get the maximum value of a arc + * @param arc pointer to a arc object + * @return the maximum value of the arc + */ +int16_t lv_arc_get_max_value(const lv_obj_t * arc); + +/** + * Give the arc is being dragged or not + * @param arc pointer to a arc object + * @return true: drag in progress false: not dragged + */ +bool lv_arc_is_dragged(const lv_obj_t * arc); + /*===================== * Other functions *====================*/ diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c deleted file mode 100644 index 92ac3172b..000000000 --- a/src/lv_widgets/lv_rotary.c +++ /dev/null @@ -1,566 +0,0 @@ - -/** - * @file lv_rotary.c - * - */ - -/********************* - * INCLUDES - *********************/ -#include "lv_rotary.h" -#if LV_USE_ROTARY != 0 - -#include "../lv_misc/lv_debug.h" -#include "../lv_core/lv_group.h" -#include "../lv_core/lv_indev.h" -#include "../lv_draw/lv_draw.h" -#include "../lv_themes/lv_theme.h" -#include "../lv_misc/lv_math.h" -#include "lv_img.h" - -/********************* - * DEFINES - *********************/ -#define LV_OBJX_NAME "lv_rotary" - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * STATIC PROTOTYPES - **********************/ -static lv_design_res_t lv_rotary_design(lv_obj_t * rotary, const lv_area_t * clip_area, lv_design_mode_t mode); -static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * param); -static lv_style_list_t * lv_rotary_get_style(lv_obj_t * rotary, uint8_t part); -static void draw_knob(lv_obj_t * rotary, const lv_area_t * clip_area); - -/********************** - * STATIC VARIABLES - **********************/ -static lv_design_cb_t ancestor_design; -static lv_signal_cb_t ancestor_signal; - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -/** - * Create a rotary objects - * @param par pointer to an object, it will be the parent of the new rotary - * @param copy pointer to a rotary object, if not NULL then the new object will be copied from it - * @return pointer to the created rotary - */ -lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) -{ - LV_LOG_TRACE("rotary create started"); - - /*Create the ancestor rotary*/ - lv_obj_t * rotary = lv_arc_create(par, copy); - LV_ASSERT_MEM(rotary); - if(rotary == NULL) return NULL; - - if(ancestor_design == NULL) ancestor_design = lv_obj_get_design_cb(rotary); - if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(rotary); - - /*Allocate the rotary type specific extended data*/ - lv_rotary_ext_t * ext = lv_obj_allocate_ext_attr(rotary, sizeof(lv_rotary_ext_t)); - LV_ASSERT_MEM(ext); - if(ext == NULL) { - lv_obj_del(rotary); - return NULL; - } - - /*Initialize the allocated 'ext' */ - ext->arc.rotation_angle = 0; - ext->arc.bg_angle_start = 135; - ext->arc.bg_angle_end = 45; - ext->arc.arc_angle_start = 135; - ext->arc.arc_angle_end = 270; - ext->type = LV_ROTARY_TYPE_NORMAL; - ext->cur_value = -1; - ext->min_value = 0; - ext->max_value = 100; - ext->sensitivity = 1; - ext->dragging = false; - ext->chg_rate = 540; - ext->last_tick = lv_tick_get(); - ext->last_angle = ext->arc.arc_angle_end; - lv_style_list_init(&ext->style_knob); - - /*The signal and design functions are not copied so set them here*/ - lv_obj_set_signal_cb(rotary, lv_rotary_signal); - lv_obj_set_design_cb(rotary, lv_rotary_design); - - /*Init the new rotary rotary*/ - if(copy == NULL) { - lv_obj_set_click(rotary, true); - lv_obj_add_protect(rotary, LV_PROTECT_PRESS_LOST); - lv_obj_set_ext_click_area(rotary, LV_DPI / 10, LV_DPI / 10, LV_DPI / 10, LV_DPI / 10); - lv_rotary_set_value(rotary, 50, LV_ANIM_OFF); - lv_theme_apply(rotary, LV_THEME_ROTARY); - } - /*Copy an existing rotary*/ - else { - lv_rotary_ext_t * copy_ext = lv_obj_get_ext_attr(copy); - ext->type = copy_ext->type; - ext->cur_value = copy_ext->cur_value; - ext->min_value = copy_ext->min_value; - ext->max_value = copy_ext->max_value; - ext->sensitivity = copy_ext->sensitivity; - ext->dragging = copy_ext->dragging; - ext->chg_rate = copy_ext->chg_rate; - ext->last_tick = copy_ext->last_tick; - ext->last_angle = copy_ext->last_angle; - lv_style_list_copy(&ext->style_knob, ©_ext->style_knob); - - lv_obj_refresh_style(rotary, LV_OBJ_PART_ALL); - } - - LV_LOG_INFO("rotary created"); - - return rotary; -} - -/*===================== - * Setter functions - *====================*/ - -/** - * Set the type of rotary. - * @param rotary pointer to rotary object - * @param type rotary type - */ -void lv_rotary_set_type(lv_obj_t * rotary, lv_rotary_type_t type) -{ - LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); - - lv_rotary_ext_t *ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); - int16_t val = ext->cur_value; - - ext->type = type; - ext->cur_value = -1; /** Force set_value handling*/ - - int16_t bg_midpoint, bg_end = ext->arc.bg_angle_end; - if (ext->arc.bg_angle_end < ext->arc.bg_angle_start) bg_end = ext->arc.bg_angle_end + 360; - - switch(ext->type) { - case LV_ROTARY_TYPE_SYMMETRIC: - bg_midpoint = (ext->arc.bg_angle_start + bg_end) / 2; - lv_rotary_set_start_angle(rotary, bg_midpoint); - lv_rotary_set_end_angle(rotary, bg_midpoint); - break; - case LV_ROTARY_TYPE_REVERSE: - lv_rotary_set_end_angle(rotary, ext->arc.bg_angle_end); - break; - default: /** LV_ROTARY_TYPE_NORMAL*/ - lv_rotary_set_start_angle(rotary, ext->arc.bg_angle_start); - } - - lv_rotary_set_value(rotary, val, false); -} - -/** - * Set a new value on the rotary - * @param rotary pointer to a rotary object - * @param value new value - * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately - */ -bool lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim) -{ - LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); - - lv_rotary_ext_t * ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); - if(ext->cur_value == value) return false; - - int16_t new_value; - new_value = value > ext->max_value ? ext->max_value : value; - new_value = new_value < ext->min_value ? ext->min_value : new_value; - - if(ext->cur_value == new_value) return false; - ext->cur_value = new_value; - - int16_t bg_midpoint, range_midpoint, bg_end = ext->arc.bg_angle_end; - if (ext->arc.bg_angle_end < ext->arc.bg_angle_start) bg_end = ext->arc.bg_angle_end + 360; - - int16_t angle; - switch(ext->type) { - case LV_ROTARY_TYPE_SYMMETRIC: - bg_midpoint = (ext->arc.bg_angle_start + bg_end) / 2; - range_midpoint = (int32_t)(ext->min_value + ext->max_value) / 2; - - if (ext->cur_value < range_midpoint) { - angle = _lv_map(ext->cur_value, ext->min_value, range_midpoint, ext->arc.bg_angle_start, bg_midpoint); - lv_arc_set_start_angle(rotary, angle); - lv_arc_set_end_angle(rotary, bg_midpoint); - } else { - angle = _lv_map(ext->cur_value, range_midpoint, ext->max_value, bg_midpoint, bg_end); - lv_arc_set_start_angle(rotary, bg_midpoint); - lv_arc_set_end_angle(rotary, angle); - } - break; - case LV_ROTARY_TYPE_REVERSE: - angle = _lv_map(ext->cur_value, ext->min_value, ext->max_value, ext->arc.bg_angle_start, bg_end); - lv_arc_set_start_angle(rotary, angle); - break; - default: /** LV_ROTARY_TYPE_NORMAL*/ - angle = _lv_map(ext->cur_value, ext->min_value, ext->max_value, ext->arc.bg_angle_start, bg_end); - lv_arc_set_end_angle(rotary, angle); - } - ext->last_angle = angle; /*Cache angle for slew rate limiting*/ - - return true; -} - -/** - * Set minimum and the maximum values of a rotary - * @param rotary pointer to the rotary object - * @param min minimum value - * @param max maximum value - */ -void lv_rotary_set_range(lv_obj_t * rotary, int16_t min, int16_t max) -{ - LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); - - lv_rotary_ext_t * ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); - if(ext->min_value == min && ext->max_value == max) return; - - ext->min_value = min; - ext->max_value = max; - - if(ext->cur_value < min) { - ext->cur_value = min; - } - if(ext->cur_value > max) { - ext->cur_value = max; - } - - lv_rotary_set_value(rotary, ext->cur_value, false); -} - -/** - * Set the sesitivity of rotary knob increments - * position. - * @param rotary pointer to a rotary object - * @param sensitivity increment multiplier - */ -void lv_rotary_set_sensitivity(lv_obj_t * rotary, uint16_t sensitivity) -{ - LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); - - lv_rotary_ext_t *ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); - ext->sensitivity = sensitivity; -} - -/** - * Set the threshold of rotary knob increments - * position. - * @param rotary pointer to a rotary object - * @param threshold increment threshold - */ -void lv_rotary_set_chg_rate(lv_obj_t * rotary, uint16_t rate) -{ - LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); - - lv_rotary_ext_t *ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); - ext->chg_rate = rate; -} - -/*===================== - * Getter functions - *====================*/ - -/** - * Get the value of a rotary - * @param rotary pointer to a rotary object - * @return the value of the rotary - */ -int16_t lv_rotary_get_value(const lv_obj_t * rotary) -{ - LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); - - lv_rotary_ext_t * ext = lv_obj_get_ext_attr(rotary); - return ext->cur_value; -} - -/** - * Get the minimum value of a rotary - * @param rotary pointer to a rotary object - * @return the minimum value of the rotary - */ -int16_t lv_rotary_get_min_value(const lv_obj_t * rotary) -{ - LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); - - lv_rotary_ext_t *ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); - return ext->min_value; -} - -/** - * Get the maximum value of a rotary - * @param rotary pointer to a rotary object - * @return the maximum value of the rotary - */ -int16_t lv_rotary_get_max_value(const lv_obj_t * rotary) -{ - LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); - - lv_rotary_ext_t *ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); - return ext->max_value; -} - -/** - * Give the rotary is being dragged or not - * @param rotary pointer to a rotary object - * @return true: drag in progress false: not dragged - */ -bool lv_rotary_is_dragged(const lv_obj_t * rotary) -{ - LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); - - lv_rotary_ext_t * ext = lv_obj_get_ext_attr(rotary); - return ext->dragging; -} - -/** - * Get whether the rotary is type or not. - * @param rotary pointer to a rotary object - * @return rotary type - */ -lv_rotary_type_t lv_rotary_get_type(const lv_obj_t * rotary) -{ - LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); - - lv_rotary_ext_t * ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); - return ext->type; -} - -/********************** - * STATIC FUNCTIONS - **********************/ - -/** - * Handle the drawing related tasks of the rotarys - * @param rotary pointer to an object - * @param clip_area the object will be drawn only in this area - * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area - * (return 'true' if yes) - * LV_DESIGN_DRAW: draw the object (always return 'true') - * LV_DESIGN_DRAW_POST: drawing after every children are drawn - * @param return an element of `lv_design_res_t` - */ -static lv_design_res_t lv_rotary_design(lv_obj_t * rotary, const lv_area_t * clip_area, lv_design_mode_t mode) -{ - /*Return false if the object is not covers the mask_p area*/ - if(mode == LV_DESIGN_COVER_CHK) { - return LV_DESIGN_RES_NOT_COVER; - } - /*Draw the object*/ - else if(mode == LV_DESIGN_DRAW_MAIN) { - /*The ancestor design function will draw the background and the indicator.*/ - ancestor_design(rotary, clip_area, mode); - draw_knob(rotary, clip_area); - } - /*Post draw when the children are drawn*/ - else if(mode == LV_DESIGN_DRAW_POST) { - return ancestor_design(rotary, clip_area, mode); - } - - return LV_DESIGN_RES_OK; -} - -/** - * Signal function of the rotary - * @param rotary pointer to a rotary object - * @param sign a signal type from lv_signal_t enum - * @param param pointer to a signal specific variable - * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted - */ -static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * param) -{ - lv_res_t res; - - if(sign == LV_SIGNAL_GET_STYLE) { - lv_get_style_info_t * info = param; - info->result = lv_rotary_get_style(rotary, info->part); - if(info->result != NULL) return LV_RES_OK; - else return ancestor_signal(rotary, sign, param); - } - - /* Include the ancient signal function */ - res = ancestor_signal(rotary, sign, param); - if(res != LV_RES_OK) return res; - if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME); - - lv_rotary_ext_t * ext = lv_obj_get_ext_attr(rotary); - - if(sign == LV_SIGNAL_PRESSING) { - lv_indev_t * indev = lv_indev_get_act(); - if(indev == NULL) return res; - - /*Handle only pointers here*/ - lv_indev_type_t indev_type = lv_indev_get_type(indev); - if(indev_type != LV_INDEV_TYPE_POINTER) return res; - - lv_point_t p; - lv_indev_get_point(indev, &p); - - /*Make point relative to the rotary's center*/ - lv_coord_t w_half = lv_obj_get_width(rotary) / 2; - p.x -= rotary->coords.x1 + w_half; - p.y -= rotary->coords.y1 + w_half; - - /*Enter dragging mode if pressed out of the knob*/ - if(ext->dragging == false) { - lv_coord_t r_in = lv_area_get_width(&ext->knob_area) / 2; - - if(p.x * p.x + p.y * p.y > r_in * r_in) { - ext->dragging = true; - ext->last_tick = lv_tick_get(); /*Capture timestamp at dragging start*/ - } - } - - /*It must be in "dragging" mode to turn the arc*/ - if(ext->dragging == false) return res; - - /*Calculate the angle of the pressed point*/ - int16_t angle; - int16_t bg_end = ext->arc.bg_angle_end; - if (ext->arc.bg_angle_end < ext->arc.bg_angle_start) { - bg_end = ext->arc.bg_angle_end + 360; - } - - angle = 360 - _lv_atan2(p.x, p.y) + 90; /*Some transformation is required*/ - if(angle < ext->arc.bg_angle_start) angle = ext->arc.bg_angle_start; - if(angle > bg_end) angle = bg_end; - - /*Calculate the slew rate limited angle based on change rate (degrees/sec)*/ - int16_t delta_angle = angle - ext->last_angle; - uint32_t delta_tick = lv_tick_elaps(ext->last_tick); - int16_t delta_angle_max = (ext->chg_rate * delta_tick) / 1000; - - if (delta_angle > delta_angle_max) { - delta_angle = delta_angle_max; - } else if (delta_angle < -delta_angle_max) { - delta_angle = -delta_angle_max; - } - - angle = ext->last_angle + delta_angle; /*Apply the limited angle change*/ - - /*Rounding for symmetry*/ - int32_t round = ((bg_end - ext->arc.bg_angle_start) * 8) / (ext->max_value - ext->min_value); - round = (round + 4) >> 4; - angle += round; - - /*Set the new value*/ - int16_t new_value = _lv_map(angle, ext->arc.bg_angle_start, bg_end, ext->min_value, ext->max_value); - if(new_value != lv_rotary_get_value(rotary)) { - ext->last_tick = lv_tick_get(); /*Cache timestamp for the next iteration*/ - if (lv_rotary_set_value(rotary, new_value, LV_ANIM_OFF)) { /*set_value caches the last_angle for the next interation*/ - res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - } - - /*Don1't let the elapsed time to big while sitting on an end point*/ - if(new_value == ext->min_value || new_value == ext->max_value) { - ext->last_tick = lv_tick_get(); /*Cache timestamp for the next iteration*/ - } - } - else if(sign == LV_SIGNAL_RELEASED || sign == LV_SIGNAL_PRESS_LOST) { - ext->dragging = false; - -#if LV_USE_GROUP - /*Leave edit mode if released. (No need to wait for LONG_PRESS) */ - lv_group_t * g = lv_obj_get_group(rotary); - bool editing = lv_group_get_editing(g); - lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act()); - if(indev_type == LV_INDEV_TYPE_ENCODER) { - if(editing) lv_group_set_editing(g, false); - } -#endif - - } - else if(sign == LV_SIGNAL_CONTROL) { - char c = *((char *)param); - - if(c == LV_KEY_RIGHT || c == LV_KEY_UP) { - if (lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) + ext->sensitivity, LV_ANIM_ON)) { - res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - } - else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) { - if (lv_rotary_set_value(rotary, lv_rotary_get_value(rotary) - ext->sensitivity, LV_ANIM_ON)) { - res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL); - if(res != LV_RES_OK) return res; - } - } - } - else if(sign == LV_SIGNAL_CLEANUP) { - lv_obj_clean_style_list(rotary, LV_ROTARY_PART_KNOB); - } - else if(sign == LV_SIGNAL_GET_EDITABLE) { - bool * editable = (bool *)param; - *editable = true; - } - - return res; -} - - -static lv_style_list_t * lv_rotary_get_style(lv_obj_t * rotary, uint8_t part) -{ - LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); - - lv_rotary_ext_t * ext = lv_obj_get_ext_attr(rotary); - lv_style_list_t * style_dsc_p; - - switch(part) { - case LV_ROTARY_PART_KNOB: - style_dsc_p = &ext->style_knob; - break; - default: - style_dsc_p = NULL; - } - - return style_dsc_p; -} - -static void draw_knob(lv_obj_t * rotary, const lv_area_t * clip_area) -{ - lv_coord_t left_bg = lv_obj_get_style_pad_left(rotary, LV_ROTARY_PART_BG); - lv_coord_t right_bg = lv_obj_get_style_pad_right(rotary, LV_ROTARY_PART_BG); - lv_coord_t top_bg = lv_obj_get_style_pad_top(rotary, LV_ROTARY_PART_BG); - lv_coord_t bottom_bg = lv_obj_get_style_pad_bottom(rotary, LV_ROTARY_PART_BG); - lv_coord_t r = (LV_MATH_MIN(lv_obj_get_width(rotary) - left_bg - right_bg, - lv_obj_get_height(rotary) - top_bg - bottom_bg)) / 2; - lv_coord_t indic_width = lv_obj_get_style_line_width(rotary, LV_ROTARY_PART_INDIC); - lv_area_t knob_area; - lv_draw_rect_dsc_t knob_rect_dsc; - lv_coord_t center_x = rotary->coords.x1 + r + left_bg; - lv_coord_t center_y = rotary->coords.y1 + r + top_bg; - lv_coord_t knob_inner = lv_obj_get_style_pad_inner(rotary, LV_ROTARY_PART_KNOB); - - lv_rotary_ext_t * ext = lv_obj_get_ext_attr(rotary); - - if(r > 0) { - knob_area.x1 = center_x - r + indic_width + knob_inner; - knob_area.x2 = center_x + r - indic_width - knob_inner; - knob_area.y1 = center_y - r + indic_width + knob_inner; - knob_area.y2 = center_y + r - indic_width - knob_inner; - - lv_draw_rect_dsc_init(&knob_rect_dsc); - lv_obj_init_draw_rect_dsc(rotary, LV_ROTARY_PART_KNOB, &knob_rect_dsc); - - lv_draw_rect(&knob_area, clip_area, &knob_rect_dsc); - } - - lv_area_copy(&ext->knob_area, &knob_area); -} - -#endif diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h deleted file mode 100644 index 81c9bc488..000000000 --- a/src/lv_widgets/lv_rotary.h +++ /dev/null @@ -1,322 +0,0 @@ -/** - * @file lv_rotary.h - * - */ - -#ifndef LV_ROTARY_H -#define LV_ROTARY_H - -#ifdef __cplusplus -extern "C" { -#endif - -/********************* - * INCLUDES - *********************/ -#include "../lv_conf_internal.h" - -#if LV_USE_ROTARY != 0 - -/*Testing of dependencies*/ -#if LV_USE_ARC == 0 -#error "lv_rotary: lv_arc is required. Enable it in lv_conf.h (LV_USE_ARC 1) " -#endif - -#if LV_USE_BTN == 0 -#error "lv_rotary: lv_btn is required. Enable it in lv_conf.h (LV_USE_BTN 1) " -#endif - -#include "../lv_core/lv_obj.h" -#include "lv_arc.h" -#include "lv_btn.h" - -/********************* - * DEFINES - *********************/ - -#define LV_ROTARY_KNOB_SIZE_MIN 4 /* cannot make the knob smaller then this [px] */ - -/********************** - * TYPEDEFS - **********************/ - -enum { - LV_ROTARY_TYPE_NORMAL, - LV_ROTARY_TYPE_SYMMETRIC, - LV_ROTARY_TYPE_REVERSE -}; -typedef uint8_t lv_rotary_type_t; - -/** Possible states of a rotary.*/ -enum { - LV_ROTARY_STATE_RELEASED = LV_BTN_STATE_RELEASED, - LV_ROTARY_STATE_PRESSED = LV_BTN_STATE_PRESSED, - LV_ROTARY_STATE_DISABLED = LV_BTN_STATE_DISABLED, - LV_ROTARY_STATE_CHECKED_RELEASED = LV_BTN_STATE_CHECKED_RELEASED, - LV_ROTARY_STATE_CHECKED_PRESSED = LV_BTN_STATE_CHECKED_PRESSED, - LV_ROTARY_STATE_CHECKED_DISABLED = LV_BTN_STATE_CHECKED_DISABLED, - _LV_ROTARY_STATE_LAST = _LV_BTN_STATE_LAST, /* Number of states*/ -}; -typedef uint8_t lv_rotary_state_t; - -/*Data of rotary*/ -typedef struct { - /*Ext. of ancestor*/ - lv_arc_ext_t arc; - /*New data for this type*/ - lv_style_list_t style_knob; /* Style of the knob */ - lv_area_t knob_area; /* Area of the knob */ - uint16_t type :2; - int16_t cur_value; /*Current value of the rotary*/ - int16_t min_value; /*Minimum value of the rotary*/ - int16_t max_value; /*Maximum value of the rotary*/ - int16_t sensitivity; /*Control signal increment multiplier of the rotary*/ - uint16_t dragging :1; - uint16_t chg_rate; /*Drag angle rate of change of the rotary (degrees/sec)*/ - int32_t last_tick; /*Last dragging event timestamp of the rotary*/ - int16_t last_angle; /*Last dragging angle of the rotary*/ -} lv_rotary_ext_t; - -/** Built-in styles of rotary*/ -enum { - LV_ROTARY_PART_BG = LV_ARC_PART_BG, /** Rotary background style. */ - LV_ROTARY_PART_INDIC = LV_ARC_PART_INDIC, /** Rotary indicator (filled area) style. */ - LV_ROTARY_PART_KNOB = _LV_ARC_PART_VIRTUAL_LAST, /** Rotary knob style. */ - _LV_ROTARY_PART_VIRTUAL_LAST, - _LV_ROTARY_PART_REAL_LAST = _LV_ARC_PART_REAL_LAST -}; - -/********************** - * GLOBAL PROTOTYPES - **********************/ - -/** - * Create a rotary objects - * @param par pointer to an object, it will be the parent of the new rotary - * @param copy pointer to a rotary object, if not NULL then the new object will be copied from it - * @return pointer to the created rotary - */ -lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy); - -/*===================== - * Setter functions - *====================*/ - -/** - * Set the type of rotary. - * @param rotary pointer to rotary object - * @param type rotary type - */ -void lv_rotary_set_type(lv_obj_t * rotary, lv_rotary_type_t type); - -/** - * Set a new value on the rotary - * @param rotary pointer to a rotary object - * @param value new value - * @param anim LV_ANIM_ON: set the value with an animation; LV_ANIM_OFF: change the value immediately - * @return true if value changed, otw false - */ -bool lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim); - -/** - * Set minimum and the maximum values of a rotary - * @param rotary pointer to the rotary object - * @param min minimum value - * @param max maximum value - */ -void lv_rotary_set_range(lv_obj_t * rotary, int16_t min, int16_t max); - -/** - * Reverse rotary behavior. The indicator will grow from arc end instead of arc start. - * position. - * @param rotary pointer to a rotary object - * @param reverse true: enable disable reverse behavior; false: disable - */ -void lv_rotary_set_reverse(lv_obj_t * rotary, bool reverse); - -/** - * Set the sesitivity of rotary knob increments - * position. - * @param rotary pointer to a rotary object - * @param sensitivity increment multiplier - */ -void lv_rotary_set_sensitivity(lv_obj_t * rotary, uint16_t sensitivity); - -/** - * Set the threshold of rotary knob increments - * position. - * @param rotary pointer to a rotary object - * @param threshold increment threshold - */ -void lv_rotary_set_chg_rate(lv_obj_t * rotary, uint16_t threshold); - -/** - * Set the start angle of rotary indicator. 0 deg: right, 90 bottom, etc. - * @param arc pointer to an arc object - * @param start the start angle - */ -static inline void lv_rotary_set_start_angle(lv_obj_t * rotary, uint16_t start) { - lv_arc_set_start_angle(rotary, start); -} - -/** - * Set the start angle of rotary indicator. 0 deg: right, 90 bottom, etc. - * @param rotary pointer to an rotary object - * @param end the end angle - */ -static inline void lv_rotary_set_end_angle(lv_obj_t * rotary, uint16_t end) { - lv_arc_set_end_angle(rotary, end); -} - -/** - * Set the start and end angles - * @param rotary pointer to an rotary object - * @param start the start angle - * @param end the end angle - */ -static inline void lv_rotary_set_angles(lv_obj_t * rotary, uint16_t start, uint16_t end) { - lv_arc_set_angles(rotary, start, end); -} - -/** - * Set the start angle of ar otary indicator background. 0 deg: right, 90 bottom, etc. - * @param rotary pointer to an rotary object - * @param start the start angle - */ -static inline void lv_rotary_set_bg_start_angle(lv_obj_t * rotary, uint16_t start) { - lv_arc_set_bg_start_angle(rotary, start); -} - -/** - * Set the start angle of rotary indicator background. 0 deg: right, 90 bottom etc. - * @param rotary pointer to an rotary object - * @param end the end angle - */ -static inline void lv_rotary_set_bg_end_angle(lv_obj_t * rotary, uint16_t end) { - lv_arc_set_bg_end_angle(rotary, end); -} - -/** - * Set the start and end angles of the rotary indicator background - * @param rotary pointer to an rotary object - * @param start the start angle - * @param end the end angle - */ -static inline void lv_rotary_set_bg_angles(lv_obj_t * rotary, uint16_t start, uint16_t end) { - lv_arc_set_bg_angles(rotary, start, end); -} - -/** - * Set the rotation for the whole rotary indicator - * @param rotary pointer to an rotary object - * @param rotation_angle rotation angle - */ -static inline void lv_rotary_set_rotation(lv_obj_t * rotary, uint16_t rotation_angle) { - lv_arc_set_rotation(rotary, rotation_angle); -} - -/** - * Set the state of the rotary - * @param rotary pointer to a rotary object - * @param state the new state of the rotary (from lv_rotary_state_t enum) - */ -static inline void lv_rotary_set_state(lv_obj_t * rotary, lv_rotary_state_t state) { - lv_btn_set_state(rotary, state); -} - -/*===================== - * Getter functions - *====================*/ - -/** - * Get the start angle of a rotary indicator. - * @param rotary pointer to an rotary object - * @return the start angle [0..360] - */ -static inline uint16_t lv_rotary_get_angle_start(lv_obj_t * rotary) { - return lv_rotary_get_angle_start(rotary); -} - -/** - * Get the end angle of a rotary indicator. - * @param rotary pointer to an rotary object - * @return the end angle [0..360] - */ -static inline uint16_t lv_rotary_get_angle_end(lv_obj_t * rotary) { - return lv_arc_get_angle_end(rotary); -} - -/** - * Get the start angle of a rotary indicator background. - * @param rotary pointer to an rotary object - * @return the start angle [0..360] - */ -static inline uint16_t lv_rotary_get_bg_angle_start(lv_obj_t * rotary) { - return lv_arc_get_bg_angle_start(rotary); -} - -/** - * Get the end angle of a rotary indicator background. - * @param rotary pointer to an rotary object - * @return the end angle [0..360] - */ -static inline uint16_t lv_rotary_get_bg_angle_end(lv_obj_t * rotary) { - return lv_arc_get_bg_angle_end(rotary); -} - -/** - * Get whether the rotary is type or not. - * @param rotary pointer to a rotary object - * @return rotary type - */ -lv_rotary_type_t lv_rotary_get_type(const lv_obj_t * rotary); - -/** - * Get the value of the of a rotary - * @param rotary pointer to a rotary object - * @return the value of the of the rotary - */ -int16_t lv_rotary_get_value(const lv_obj_t * rotary); - -/** - * Get the minimum value of a rotary - * @param rotary pointer to a rotary object - * @return the minimum value of the rotary - */ -int16_t lv_rotary_get_min_value(const lv_obj_t * rotary); - -/** - * Get the maximum value of a rotary - * @param rotary pointer to a rotary object - * @return the maximum value of the rotary - */ -int16_t lv_rotary_get_max_value(const lv_obj_t * rotary); - -/** - * Give the rotary is being dragged or not - * @param rotary pointer to a rotary object - * @return true: drag in progress false: not dragged - */ -bool lv_rotary_is_dragged(const lv_obj_t * rotary); - -/** - * Get the current state of the rotary - * @param rotary pointer to a rotary object - * @return the state of the rotary (from lv_rotary_state_t enum). - * If the rotary is in disabled state `LV_ROTARY_STATE_DISABLED` will be ORed to the other rotary states. - */ -static inline lv_rotary_state_t lv_rotary_get_state(const lv_obj_t * rotary) { - return lv_btn_get_state(rotary); -} - -/********************** - * MACROS - **********************/ - -#endif /*LV_USE_rotary*/ - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /*LV_ROTARY_H*/ From d95cf0a3d6f808094c08766be34983c60bac0c4c Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 11 Aug 2020 15:03:57 +0200 Subject: [PATCH 122/173] arc: rework knob to indicate the current positoin --- src/lv_core/lv_disp.h | 2 +- src/lv_themes/lv_theme_material.c | 8 ++-- src/lv_widgets/lv_arc.c | 72 +++++++++++++++++++++++++------ 3 files changed, 64 insertions(+), 18 deletions(-) diff --git a/src/lv_core/lv_disp.h b/src/lv_core/lv_disp.h index a0757accf..888a0c093 100644 --- a/src/lv_core/lv_disp.h +++ b/src/lv_core/lv_disp.h @@ -209,7 +209,7 @@ static inline void lv_scr_load(lv_obj_t * scr) * 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(n) LV_MATH_MAX((( lv_disp_get_dpi(NULL) * (n) + 80) / 160), 1) /*+80 for rounding*/ +#define LV_DPX(n) (n == 0 ? 0 :LV_MATH_MAX((( lv_disp_get_dpi(NULL) * (n) + 80) / 160), 1)) /*+80 for rounding*/ static inline lv_coord_t lv_dpx(lv_coord_t n) { diff --git a/src/lv_themes/lv_theme_material.c b/src/lv_themes/lv_theme_material.c index 85a24c881..a28d69766 100644 --- a/src/lv_themes/lv_theme_material.c +++ b/src/lv_themes/lv_theme_material.c @@ -509,10 +509,10 @@ static void arc_init(void) style_init_reset(&styles->arc_knob); lv_style_set_radius(&styles->arc_knob, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE); - lv_style_set_pad_top(&styles->arc_knob, LV_STATE_DEFAULT, LV_DPX(10)); - lv_style_set_pad_bottom(&styles->arc_knob, LV_STATE_DEFAULT, LV_DPX(10)); - lv_style_set_pad_left(&styles->arc_knob, LV_STATE_DEFAULT, LV_DPX(10)); - lv_style_set_pad_right(&styles->arc_knob, LV_STATE_DEFAULT, LV_DPX(10)); + lv_style_set_pad_top(&styles->arc_knob, LV_STATE_DEFAULT, LV_DPX(0)); + lv_style_set_pad_bottom(&styles->arc_knob, LV_STATE_DEFAULT, LV_DPX(0)); + lv_style_set_pad_left(&styles->arc_knob, LV_STATE_DEFAULT, LV_DPX(0)); + lv_style_set_pad_right(&styles->arc_knob, LV_STATE_DEFAULT, LV_DPX(0)); #endif } diff --git a/src/lv_widgets/lv_arc.c b/src/lv_widgets/lv_arc.c index 8849d3895..58d5df0fc 100644 --- a/src/lv_widgets/lv_arc.c +++ b/src/lv_widgets/lv_arc.c @@ -32,7 +32,9 @@ static lv_design_res_t lv_arc_design(lv_obj_t * arc, const lv_area_t * clip_area static lv_res_t lv_arc_signal(lv_obj_t * arc, lv_signal_t sign, void * param); static lv_style_list_t * lv_arc_get_style(lv_obj_t * arc, uint8_t part); static void inv_arc_area(lv_obj_t * arc, uint16_t start_angle, uint16_t end_angle); -static void get_areas(lv_obj_t * arc, lv_point_t * center, lv_coord_t * arc_r, lv_area_t * knob_area); +static void get_center(lv_obj_t * arc, lv_point_t * center, lv_coord_t * arc_r); +static void get_knob_area(lv_obj_t * arc, const lv_point_t * center, lv_coord_t r, lv_area_t * knob_area); +static bool has_large_knob(lv_obj_t * arc); /********************** * STATIC VARIABLES @@ -631,8 +633,7 @@ static lv_design_res_t lv_arc_design(lv_obj_t * arc, const lv_area_t * clip_area lv_point_t center; lv_coord_t arc_r; - lv_area_t knob_area; - get_areas(arc, ¢er, &arc_r, &knob_area); + get_center(arc, ¢er, &arc_r); /*Draw the background arc*/ lv_draw_line_dsc_t arc_dsc; @@ -650,16 +651,18 @@ static lv_design_res_t lv_arc_design(lv_obj_t * arc, const lv_area_t * clip_area lv_coord_t right_indic = lv_obj_get_style_pad_right(arc, LV_ARC_PART_INDIC); lv_coord_t top_indic = lv_obj_get_style_pad_top(arc, LV_ARC_PART_INDIC); lv_coord_t bottom_indic = lv_obj_get_style_pad_bottom(arc, LV_ARC_PART_INDIC); - arc_r -= LV_MATH_MAX4(left_indic, right_indic, top_indic, bottom_indic); + lv_coord_t indic_r = arc_r - LV_MATH_MAX4(left_indic, right_indic, top_indic, bottom_indic); - if(arc_r > 0) { + if(indic_r > 0) { lv_draw_line_dsc_init(&arc_dsc); lv_obj_init_draw_line_dsc(arc, LV_ARC_PART_INDIC, &arc_dsc); - lv_draw_arc(center.x, center.y, arc_r, ext->arc_angle_start + ext->rotation_angle, ext->arc_angle_end + ext->rotation_angle, clip_area, + lv_draw_arc(center.x, center.y, indic_r, ext->arc_angle_start + ext->rotation_angle, ext->arc_angle_end + ext->rotation_angle, clip_area, &arc_dsc); } + lv_area_t knob_area; + get_knob_area(arc, ¢er, arc_r, &knob_area); lv_draw_rect_dsc_t knob_rect_dsc; lv_draw_rect_dsc_init(&knob_rect_dsc); @@ -714,8 +717,7 @@ static lv_res_t lv_arc_signal(lv_obj_t * arc, lv_signal_t sign, void * param) /*Make point relative to the arc's center*/ lv_point_t center; lv_coord_t r; - lv_area_t knob_area; - get_areas(arc, ¢er, &r, &knob_area); + get_center(arc, ¢er, &r); p.x -= center.x; p.y -= center.y; @@ -724,6 +726,7 @@ static lv_res_t lv_arc_signal(lv_obj_t * arc, lv_signal_t sign, void * param) if(ext->dragging == false) { lv_coord_t indic_width = lv_obj_get_style_line_width(arc, LV_ARC_PART_INDIC); r -= indic_width; + r -= r / 2; /*Add some more sensitive area*/ if(p.x * p.x + p.y * p.y > r * r) { ext->dragging = true; ext->last_tick = lv_tick_get(); /*Capture timestamp at dragging start*/ @@ -849,6 +852,13 @@ static lv_style_list_t * lv_arc_get_style(lv_obj_t * arc, uint8_t part) static void inv_arc_area(lv_obj_t * arc, uint16_t start_angle, uint16_t end_angle) { + /* If the knob is large it's much harder to find which area to invalidate. + * For simplicity invalidate the whole arc in this case*/ + if(has_large_knob(arc)) { + lv_obj_invalidate(arc); + return; + } + lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc); start_angle += ext->rotation_angle; @@ -953,7 +963,7 @@ static void inv_arc_area(lv_obj_t * arc, uint16_t start_angle, uint16_t end_angl } -static void get_areas(lv_obj_t * arc, lv_point_t * center, lv_coord_t * arc_r, lv_area_t * knob_area) +static void get_center(lv_obj_t * arc, lv_point_t * center, lv_coord_t * arc_r) { lv_coord_t left_bg = lv_obj_get_style_pad_left(arc, LV_ARC_PART_BG); lv_coord_t right_bg = lv_obj_get_style_pad_right(arc, LV_ARC_PART_BG); @@ -970,17 +980,53 @@ static void get_areas(lv_obj_t * arc, lv_point_t * center, lv_coord_t * arc_r, l lv_coord_t indic_width = lv_obj_get_style_line_width(arc, LV_ARC_PART_INDIC); r -= indic_width; +} + +static void get_knob_area(lv_obj_t * arc, const lv_point_t * center, lv_coord_t r, lv_area_t * knob_area) +{ + lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc); + + lv_coord_t indic_width = lv_obj_get_style_line_width(arc, LV_ARC_PART_INDIC); + lv_coord_t indic_width_half = indic_width / 2; + r -= indic_width_half; + + uint16_t angle = ext->rotation_angle; + if(ext->type == LV_ARC_TYPE_NORMAL) { + angle += ext->arc_angle_end; + } else if(ext->type == LV_ARC_TYPE_REVERSE) { + angle += ext->arc_angle_start; + } else if(ext->type == LV_ARC_TYPE_SYMMETRIC) { + int32_t range_midpoint = (int32_t)(ext->min_value + ext->max_value) / 2; + if(ext->cur_value < range_midpoint) angle += ext->arc_angle_start; + else angle += ext->arc_angle_end; + } + lv_coord_t knob_x = (r * _lv_trigo_sin(angle + 90)) >> LV_TRIGO_SHIFT; + lv_coord_t knob_y = (r * _lv_trigo_sin(angle)) >> LV_TRIGO_SHIFT; lv_coord_t left_knob = lv_obj_get_style_pad_left(arc, LV_ARC_PART_KNOB); lv_coord_t right_knob = lv_obj_get_style_pad_right(arc, LV_ARC_PART_KNOB); lv_coord_t top_knob = lv_obj_get_style_pad_top(arc, LV_ARC_PART_KNOB); lv_coord_t bottom_knob = lv_obj_get_style_pad_bottom(arc, LV_ARC_PART_KNOB); - knob_area->x1 = center->x - r + left_knob; - knob_area->x2 = center->x + r - right_knob; - knob_area->y1 = center->y - r + top_knob; - knob_area->y2 = center->y + r - bottom_knob; + knob_area->x1 = center->x + knob_x - left_knob - indic_width_half; + knob_area->x2 = center->x + knob_x + right_knob + indic_width_half; + knob_area->y1 = center->y + knob_y - top_knob - indic_width_half; + knob_area->y2 = center->y + knob_y + bottom_knob + indic_width_half; } +static bool has_large_knob(lv_obj_t * arc) +{ + if(lv_obj_get_style_pad_left(arc, LV_ARC_PART_KNOB) > 0) return true; + if(lv_obj_get_style_pad_right(arc, LV_ARC_PART_KNOB) > 0) return true; + if(lv_obj_get_style_pad_top(arc, LV_ARC_PART_KNOB) > 0) return true; + if(lv_obj_get_style_pad_bottom(arc, LV_ARC_PART_KNOB) > 0) return true; + if(lv_obj_get_style_shadow_width(arc, LV_ARC_PART_KNOB) > 0) return true; + if(lv_obj_get_style_shadow_ofs_x(arc, LV_ARC_PART_KNOB) > 0) return true; + if(lv_obj_get_style_shadow_ofs_y(arc, LV_ARC_PART_KNOB) > 0) return true; + if(lv_obj_get_style_outline_width(arc, LV_ARC_PART_KNOB) > 0) return true; + if(lv_obj_get_style_value_str(arc, LV_ARC_PART_KNOB) != NULL) return true; + + return false; +} #endif From 3dad4c724e8e39e67450f7c09e04f30de1b4b63d Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Tue, 11 Aug 2020 10:49:57 -0400 Subject: [PATCH 123/173] Fade in checkmark for material theme --- src/lv_themes/lv_theme_material.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lv_themes/lv_theme_material.c b/src/lv_themes/lv_theme_material.c index 661db996d..f692b3b66 100644 --- a/src/lv_themes/lv_theme_material.c +++ b/src/lv_themes/lv_theme_material.c @@ -620,6 +620,9 @@ static void checkbox_init(void) lv_style_set_radius(&styles->cb_bullet, LV_STATE_DEFAULT, LV_DPX(4)); lv_style_set_pattern_image(&styles->cb_bullet, LV_STATE_CHECKED, LV_SYMBOL_OK); lv_style_set_pattern_recolor(&styles->cb_bullet, LV_STATE_CHECKED, LV_COLOR_WHITE); + lv_style_set_pattern_opa(&styles->cb_bullet, LV_STATE_DEFAULT, LV_OPA_TRANSP); + lv_style_set_pattern_opa(&styles->cb_bullet, LV_STATE_CHECKED, LV_OPA_COVER); + lv_style_set_transition_prop_3(&styles->cb_bullet, LV_STATE_DEFAULT, LV_STYLE_PATTERN_OPA); lv_style_set_text_font(&styles->cb_bullet, LV_STATE_CHECKED, theme.font_small); lv_style_set_pad_left(&styles->cb_bullet, LV_STATE_DEFAULT, LV_DPX(3)); lv_style_set_pad_right(&styles->cb_bullet, LV_STATE_DEFAULT, LV_DPX(3)); From b3634790cdaf66fc91e542fb86d322cbac123b29 Mon Sep 17 00:00:00 2001 From: Fabio Guerra Date: Wed, 12 Aug 2020 00:11:02 -0300 Subject: [PATCH 124/173] Implementing missing formats for font loading. --- src/lv_font/lv_font_loader.c | 581 +++++---- tests/Makefile | 3 + tests/font_1.fnt | Bin 0 -> 6876 bytes tests/font_2.fnt | Bin 0 -> 7252 bytes tests/font_3.fnt | Bin 0 -> 4892 bytes tests/lv_test_assert.c | 11 + tests/lv_test_assert.h | 1 + tests/lv_test_core/lv_test_font_loader.c | 110 +- tests/lv_test_fonts/font_1.c | 1383 +++++++++++++++++++++ tests/lv_test_fonts/font_2.c | 1413 ++++++++++++++++++++++ tests/lv_test_fonts/font_3.c | 953 +++++++++++++++ 11 files changed, 4171 insertions(+), 284 deletions(-) create mode 100644 tests/font_1.fnt create mode 100644 tests/font_2.fnt create mode 100644 tests/font_3.fnt create mode 100644 tests/lv_test_fonts/font_1.c create mode 100644 tests/lv_test_fonts/font_2.c create mode 100644 tests/lv_test_fonts/font_3.c diff --git a/src/lv_font/lv_font_loader.c b/src/lv_font/lv_font_loader.c index 456b0cb6b..3a292a766 100644 --- a/src/lv_font/lv_font_loader.c +++ b/src/lv_font/lv_font_loader.c @@ -53,7 +53,7 @@ typedef struct font_header_bin { typedef struct cmap_table_bin { - uint32_t cmaps_subtable_length; + uint32_t data_offset; uint32_t range_start; uint16_t range_length; uint16_t glyph_id_start; @@ -68,6 +68,7 @@ typedef struct cmap_table_bin **********************/ static bit_iterator_t init_bit_iterator(lv_fs_file_t * fp); static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font); +int32_t load_kern(lv_fs_file_t *fp, lv_font_fmt_txt_dsc_t * font_dsc, uint8_t format, uint32_t start); static int read_bits_signed(bit_iterator_t *it, int n_bits, lv_fs_res_t * res); static int read_bits(bit_iterator_t *it, int n_bits, lv_fs_res_t * res); @@ -123,20 +124,37 @@ void lv_font_free(lv_font_t * font) lv_font_fmt_txt_dsc_t * dsc = (lv_font_fmt_txt_dsc_t *) font->dsc; if(NULL != dsc) { - lv_font_fmt_txt_kern_classes_t * kern_dsc = - (lv_font_fmt_txt_kern_classes_t *) dsc->kern_dsc; - if(NULL != kern_dsc) { - if(kern_dsc->class_pair_values) - lv_mem_free((void *) kern_dsc->class_pair_values); + if (dsc->kern_classes == 0) { + lv_font_fmt_txt_kern_pair_t * kern_dsc = + (lv_font_fmt_txt_kern_pair_t *) dsc->kern_dsc; - if(kern_dsc->left_class_mapping) - lv_mem_free((void *) kern_dsc->left_class_mapping); + if(NULL != kern_dsc) { + if(kern_dsc->glyph_ids) + lv_mem_free((void *) kern_dsc->glyph_ids); - if(kern_dsc->right_class_mapping) - lv_mem_free((void *) kern_dsc->right_class_mapping); + if(kern_dsc->values) + lv_mem_free((void *) kern_dsc->values); - lv_mem_free((void *) kern_dsc); + lv_mem_free((void *) kern_dsc); + } + } + else { + lv_font_fmt_txt_kern_classes_t * kern_dsc = + (lv_font_fmt_txt_kern_classes_t *) dsc->kern_dsc; + + if(NULL != kern_dsc) { + if(kern_dsc->class_pair_values) + lv_mem_free((void *) kern_dsc->class_pair_values); + + if(kern_dsc->left_class_mapping) + lv_mem_free((void *) kern_dsc->left_class_mapping); + + if(kern_dsc->right_class_mapping) + lv_mem_free((void *) kern_dsc->right_class_mapping); + + lv_mem_free((void *) kern_dsc); + } } lv_font_fmt_txt_cmap_t * cmaps = @@ -228,6 +246,237 @@ static int read_label(lv_fs_file_t *fp, int start, const char *label) return length; } +static bool load_cmaps_tables(lv_fs_file_t *fp, lv_font_fmt_txt_dsc_t * font_dsc, + uint32_t cmaps_start, cmap_table_bin_t * cmap_table) +{ + for(unsigned int i = 0; i < font_dsc->cmap_num; ++i) { + if(lv_fs_read(fp, &cmap_table[i], sizeof(cmap_table_bin_t), NULL) != LV_FS_RES_OK) { + return false; + } + + lv_font_fmt_txt_cmap_t * cmap = (lv_font_fmt_txt_cmap_t *) &(font_dsc->cmaps[i]); + + cmap->range_start = cmap_table[i].range_start; + cmap->range_length = cmap_table[i].range_length; + cmap->glyph_id_start = cmap_table[i].glyph_id_start; + } + + for(unsigned int i = 0; i < font_dsc->cmap_num; ++i) { + lv_fs_res_t res = lv_fs_seek(fp, cmaps_start + cmap_table[i].data_offset); + if(res != LV_FS_RES_OK) { + return false; + } + + lv_font_fmt_txt_cmap_t * cmap = (lv_font_fmt_txt_cmap_t *) &(font_dsc->cmaps[i]); + + switch(cmap_table[i].format_type) { + case 0: + { + uint8_t ids_size = sizeof(uint8_t) * cmap_table[i].data_entries_count; + uint8_t * glyph_id_ofs_list = lv_mem_alloc(ids_size); + + cmap->glyph_id_ofs_list = glyph_id_ofs_list; + + if(lv_fs_read(fp, glyph_id_ofs_list, ids_size, NULL) != LV_FS_RES_OK) { + return false; + } + + cmap->type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL; + cmap->list_length = cmap->range_length; + cmap->unicode_list = NULL; + break; + } + case 2: + cmap->type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY; + cmap->list_length = 0; + cmap->unicode_list = NULL; + cmap->glyph_id_ofs_list = NULL; + break; + case 1: + case 3: + { + uint32_t list_size = sizeof(uint16_t) * cmap_table[i].data_entries_count; + uint16_t * unicode_list = (uint16_t *) lv_mem_alloc(list_size); + + cmap->unicode_list = unicode_list; + cmap->list_length = cmap_table[i].data_entries_count; + + if(lv_fs_read(fp, unicode_list, list_size, NULL) != LV_FS_RES_OK) { + return false; + } + + if (cmap_table[i].format_type == 1) + { + uint16_t * buf = lv_mem_alloc(sizeof(uint16_t) * cmap->list_length); + + cmap->type = LV_FONT_FMT_TXT_CMAP_SPARSE_FULL; + cmap->glyph_id_ofs_list = buf; + + if(lv_fs_read(fp, buf, sizeof(uint16_t) * cmap->list_length, NULL) != LV_FS_RES_OK) { + return false; + } + } + else + { + cmap->type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY; + cmap->glyph_id_ofs_list = NULL; + } + break; + } + default: + LV_LOG_WARN("Unknown cmaps format type %d.", cmap_table[i].format_type); + return false; + } + } + return true; +} + +static int32_t load_cmaps(lv_fs_file_t *fp, lv_font_fmt_txt_dsc_t * font_dsc, uint32_t cmaps_start) +{ + int32_t cmaps_length = read_label(fp, cmaps_start, "cmap"); + if (cmaps_length < 0) { + return -1; + } + + uint32_t cmaps_subtables_count; + if(lv_fs_read(fp, &cmaps_subtables_count, sizeof(uint32_t), NULL) != LV_FS_RES_OK) { + return -1; + } + + lv_font_fmt_txt_cmap_t * cmaps = + lv_mem_alloc(cmaps_subtables_count * sizeof(lv_font_fmt_txt_cmap_t)); + + memset(cmaps, 0, cmaps_subtables_count * sizeof(lv_font_fmt_txt_cmap_t)); + + font_dsc->cmaps = cmaps; + font_dsc->cmap_num = cmaps_subtables_count; + + cmap_table_bin_t * cmaps_tables = lv_mem_alloc(sizeof(cmap_table_bin_t) * font_dsc->cmap_num); + + bool success = load_cmaps_tables(fp, font_dsc, cmaps_start, cmaps_tables); + + lv_mem_free(cmaps_tables); + + return success ? cmaps_length : -1; +} + +static int32_t load_glyph(lv_fs_file_t *fp, lv_font_fmt_txt_dsc_t * font_dsc, + uint32_t start, uint32_t *glyph_offset, uint32_t loca_count, font_header_bin_t *header) +{ + int32_t glyph_length = read_label(fp, start, "glyf"); + if (glyph_length < 0) { + return -1; + } + + lv_font_fmt_txt_glyph_dsc_t * glyph_dsc = (lv_font_fmt_txt_glyph_dsc_t *) + lv_mem_alloc(loca_count * sizeof(lv_font_fmt_txt_glyph_dsc_t)); + + memset(glyph_dsc, 0, loca_count * sizeof(lv_font_fmt_txt_glyph_dsc_t)); + + font_dsc->glyph_dsc = glyph_dsc; + + int cur_bmp_size = 0; + + for(unsigned int i = 0; i < loca_count; ++i) { + lv_font_fmt_txt_glyph_dsc_t * gdsc = &glyph_dsc[i]; + + lv_fs_res_t res = lv_fs_seek(fp, start + glyph_offset[i]); + if(res != LV_FS_RES_OK) { + return -1; + } + + bit_iterator_t bit_it = init_bit_iterator(fp); + + if(header->advance_width_bits == 0) { + gdsc->adv_w = header->default_advance_width; + } + else { + gdsc->adv_w = read_bits(&bit_it, header->advance_width_bits, &res); + if(res != LV_FS_RES_OK) { + return -1; + } + } + + if(header->advance_width_format == 0) { + gdsc->adv_w *= 16; + } + + gdsc->ofs_x = read_bits_signed(&bit_it, header->xy_bits, &res); + if(res != LV_FS_RES_OK) { + return -1; + } + + gdsc->ofs_y = read_bits_signed(&bit_it, header->xy_bits, &res); + if(res != LV_FS_RES_OK) { + return -1; + } + + gdsc->box_w = read_bits(&bit_it, header->wh_bits, &res); + if(res != LV_FS_RES_OK) { + return -1; + } + + gdsc->box_h = read_bits(&bit_it, header->wh_bits, &res); + if(res != LV_FS_RES_OK) { + return -1; + } + + int nbits = header->advance_width_bits + 2 * header->xy_bits + 2 * header->wh_bits; + int next_offset = (i < loca_count - 1) ? glyph_offset[i + 1] : (uint32_t) (glyph_length - 1); + int bmp_size = next_offset - glyph_offset[i] - nbits / 8; + + if(i == 0) { + gdsc->adv_w = 0; + gdsc->box_w = 0; + gdsc->box_h = 0; + gdsc->ofs_x = 0; + gdsc->ofs_y = 0; + } + + gdsc->bitmap_index = cur_bmp_size; + if(gdsc->box_w * gdsc->box_h != 0) { + cur_bmp_size += bmp_size; + } + } + + uint8_t * glyph_bmp = (uint8_t *) lv_mem_alloc(sizeof(uint8_t) * cur_bmp_size); + + font_dsc->glyph_bitmap = glyph_bmp; + + cur_bmp_size = 0; + + for(unsigned int i = 1; i < loca_count; ++i) { + lv_fs_res_t res = lv_fs_seek(fp, start + glyph_offset[i]); + if(res != LV_FS_RES_OK) { + return -1; + } + bit_iterator_t bit_it = init_bit_iterator(fp); + + int nbits = header->advance_width_bits + 2 * header->xy_bits + 2 * header->wh_bits; + + read_bits(&bit_it, nbits, &res); + if(res != LV_FS_RES_OK) { + return -1; + } + + if(glyph_dsc[i].box_w * glyph_dsc[i].box_h == 0) { + continue; + } + + int next_offset = (i < loca_count - 1) ? glyph_offset[i + 1] : (uint32_t) (glyph_length - 1); + int bmp_size = next_offset - glyph_offset[i] - nbits / 8; + + for(int k = 0; k < bmp_size; ++k) { + glyph_bmp[cur_bmp_size + k] = read_bits(&bit_it, 8, &res); + if(res != LV_FS_RES_OK) { + return -1; + } + } + cur_bmp_size += bmp_size; + } + return glyph_length; +} + static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font) { lv_font_fmt_txt_dsc_t * font_dsc = (lv_font_fmt_txt_dsc_t *) @@ -246,7 +495,7 @@ static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font) font_header_bin_t font_header; if(lv_fs_read(fp, &font_header, sizeof(font_header_bin_t), NULL) != LV_FS_RES_OK) { return false; - } + } font->base_line = -font_header.descent; font->line_height = font_header.ascent - font_header.descent; @@ -263,79 +512,11 @@ static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font) /* cmaps */ uint32_t cmaps_start = header_length; - int32_t cmaps_length = read_label(fp, cmaps_start, "cmap"); + int32_t cmaps_length = load_cmaps(fp, font_dsc, cmaps_start); if (cmaps_length < 0) { return false; } - uint32_t cmaps_subtables_count; - if(lv_fs_read(fp, &cmaps_subtables_count, sizeof(uint32_t), NULL) != LV_FS_RES_OK) { - return false; - } - - lv_font_fmt_txt_cmap_t * cmaps = - lv_mem_alloc(cmaps_subtables_count * sizeof(lv_font_fmt_txt_cmap_t)); - - memset(cmaps, 0, cmaps_subtables_count * sizeof(lv_font_fmt_txt_cmap_t)); - - font_dsc->cmaps = cmaps; - font_dsc->cmap_num = cmaps_subtables_count; - - for(unsigned int i = 0; i < font_dsc->cmap_num; ++i) { - lv_font_fmt_txt_cmap_t * cmap = &cmaps[i]; - - cmap_table_bin_t cmap_table; - if(lv_fs_read(fp, &cmap_table, sizeof(cmap_table_bin_t), NULL) != LV_FS_RES_OK) { - return false; - } - cmap->range_start = cmap_table.range_start; - cmap->range_length = cmap_table.range_length; - cmap->glyph_id_start = cmap_table.glyph_id_start; - - switch(cmap_table.format_type) { - case 0: - { - uint8_t ids_size = sizeof(uint8_t) * cmap->range_length; - uint8_t * glyph_id_ofs_list = lv_mem_alloc(ids_size); - if(lv_fs_read(fp, glyph_id_ofs_list, ids_size, NULL) != LV_FS_RES_OK) { - return false; - } - cmap->type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL; - cmap->unicode_list = NULL; - cmap->glyph_id_ofs_list = glyph_id_ofs_list; - cmap->list_length = 0; - break; - } - case 1: - LV_LOG_WARN("cmap format: 1 not yet supported."); - return false; - case 2: - cmap->type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY; - cmap->unicode_list = NULL; - cmap->glyph_id_ofs_list = NULL; - cmap->list_length = 0; - break; - case 3: - { - uint8_t list_size = sizeof(uint16_t) * cmap_table.data_entries_count; - uint16_t * unicode_list = (uint16_t *) lv_mem_alloc(list_size); - - if(lv_fs_read(fp, unicode_list, list_size, NULL) != LV_FS_RES_OK) { - return false; - } - - cmap->type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY; - cmap->unicode_list = unicode_list; - cmap->glyph_id_ofs_list = NULL; - cmap->list_length = cmap_table.data_entries_count; - break; - } - default: - LV_LOG_WARN("Unknown cmaps format type %d.", cmap_table.format_type); - return false; - } - } - /* loca */ uint32_t loca_start = cmaps_start + cmaps_length; int32_t loca_length = read_label(fp, loca_start, "loca"); @@ -382,158 +563,12 @@ static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font) /* glyph */ uint32_t glyph_start = loca_start + loca_length; - int32_t glyph_length = read_label(fp, glyph_start, "glyf"); - if (glyph_length < 0) { - lv_mem_free(glyph_offset); - return false; - } - - lv_font_fmt_txt_glyph_dsc_t * glyph_dsc = (lv_font_fmt_txt_glyph_dsc_t *) - lv_mem_alloc((loca_count + 1) * sizeof(lv_font_fmt_txt_glyph_dsc_t)); - - memset(glyph_dsc, 0, - (loca_count + 1) * sizeof(lv_font_fmt_txt_glyph_dsc_t)); - - font_dsc->glyph_dsc = glyph_dsc; - - int cur_bmp_size = 0; - - for(unsigned int i = 0; i < loca_count; ++i) { - lv_font_fmt_txt_glyph_dsc_t * gdsc = &glyph_dsc[i]; - - lv_fs_res_t res = lv_fs_seek(fp, glyph_start + glyph_offset[i]); - if(res != LV_FS_RES_OK) { - failed = true; - break; - } - - bit_iterator_t bit_it = init_bit_iterator(fp); - - /* - * TODO: understand how to interpret advance_width_format - * When it is set to zero, in my understanding should be used the default value, - * and no data should be written on the advance_width, but it is not occurring. - * - * The following code is not working for most monospaced fonts. - */ - - /*if(font_header.advance_width_bits == 0) { - gdsc->adv_w = font_header.default_advance_width; - } - else */ { - if(font_header.advance_width_format == 0) { /* uint */ - gdsc->adv_w = 16 * read_bits(&bit_it, 4, &res); // TODO: review the number of bits that should be read - if(res != LV_FS_RES_OK) { - failed = true; - break; - } - } - else if(font_header.advance_width_format == 1) { /* unsigned with 4 bits fractional part */ - gdsc->adv_w = read_bits(&bit_it, font_header.advance_width_bits, &res); - if(res != LV_FS_RES_OK) { - failed = true; - break; - } - } - else { - LV_LOG_WARN("error unknown advance_width_format"); - failed = true; - break; - } - } - - gdsc->ofs_x = read_bits_signed(&bit_it, font_header.xy_bits, &res); - if(res != LV_FS_RES_OK) { - failed = true; - break; - } - - gdsc->ofs_y = read_bits_signed(&bit_it, font_header.xy_bits, &res); - if(res != LV_FS_RES_OK) { - failed = true; - break; - } - - gdsc->box_w = read_bits(&bit_it, font_header.wh_bits, &res); - if(res != LV_FS_RES_OK) { - failed = true; - break; - } - - gdsc->box_h = read_bits(&bit_it, font_header.wh_bits, &res); - if(res != LV_FS_RES_OK) { - failed = true; - break; - } - - int nbits = font_header.advance_width_bits + 2 * font_header.xy_bits + 2 * font_header.wh_bits; - int next_offset = (i < loca_count - 1) ? glyph_offset[i + 1] : (uint32_t) glyph_length; - int bmp_size = next_offset - glyph_offset[i] - nbits / 8; - - if(i == 0) { - gdsc->adv_w = 0; - gdsc->box_w = 0; - gdsc->box_h = 0; - gdsc->ofs_x = 0; - gdsc->ofs_y = 0; - } - - gdsc->bitmap_index = cur_bmp_size; - if(gdsc->box_w * gdsc->box_h != 0) { - cur_bmp_size += bmp_size; - } - } - - if (failed) { - lv_mem_free(glyph_offset); - return false; - } - - uint8_t * glyph_bmp = (uint8_t *) lv_mem_alloc(sizeof(uint8_t) * cur_bmp_size); - - font_dsc->glyph_bitmap = glyph_bmp; - - cur_bmp_size = 0; - - for(unsigned int i = 1; i < loca_count; ++i) { - lv_fs_res_t res = lv_fs_seek(fp, glyph_start + glyph_offset[i]); - if(res != LV_FS_RES_OK) { - failed = true; - break; - } - bit_iterator_t bit_it = init_bit_iterator(fp); - - int nbits = font_header.advance_width_bits + 2 * font_header.xy_bits + 2 * font_header.wh_bits; - - read_bits(&bit_it, nbits, &res); - if(res != LV_FS_RES_OK) { - failed = true; - break; - } - - if(glyph_dsc[i].box_w * glyph_dsc[i].box_h == 0) { - continue; - } - - int next_offset = (i < loca_count - 1) ? glyph_offset[i + 1] : (uint32_t) glyph_length; - int bmp_size = next_offset - glyph_offset[i] - nbits / 8; - - for(int k = 0; k < bmp_size; ++k) { - glyph_bmp[cur_bmp_size + k] = read_bits(&bit_it, 8, &res); - if(res != LV_FS_RES_OK) { - failed = true; - break; - } - } - if (failed) { - break; - } - cur_bmp_size += bmp_size; - } + int32_t glyph_length = load_glyph( + fp, font_dsc, glyph_start, glyph_offset, loca_count, &font_header); lv_mem_free(glyph_offset); - if (failed) { + if (glyph_length < 0) { return false; } @@ -545,32 +580,72 @@ static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font) } uint32_t kern_start = glyph_start + glyph_length; - int32_t kern_length = read_label(fp, kern_start, "kern"); + + int32_t kern_length = load_kern(fp, font_dsc, font_header.glyph_id_format, kern_start); + + return kern_length >= 0; +} + +int32_t load_kern(lv_fs_file_t *fp, lv_font_fmt_txt_dsc_t * font_dsc, uint8_t format, uint32_t start) +{ + int32_t kern_length = read_label(fp, start, "kern"); if (kern_length < 0) { - return false; + return -1; } uint8_t kern_format_type; int32_t padding; if (lv_fs_read(fp, &kern_format_type, sizeof(uint8_t), NULL) != LV_FS_RES_OK || lv_fs_read(fp, &padding, 3 * sizeof(uint8_t), NULL) != LV_FS_RES_OK) { - return false; + return -1; } - lv_font_fmt_txt_kern_classes_t * kern_classes = - lv_mem_alloc(sizeof(lv_font_fmt_txt_kern_classes_t)); - - memset(kern_classes, 0, sizeof(lv_font_fmt_txt_kern_classes_t)); - - font_dsc->kern_dsc = kern_classes; /* TODO: review */ - font_dsc->kern_classes = 1; /* TODO: review this */ - if(0 == kern_format_type) { /* sorted pairs */ - LV_LOG_WARN("kern_format_type 0 not supported yet!"); - return false; + lv_font_fmt_txt_kern_pair_t * kern_pair = lv_mem_alloc(sizeof(lv_font_fmt_txt_kern_pair_t)); + + memset(kern_pair, 0, sizeof(lv_font_fmt_txt_kern_pair_t)); + + font_dsc->kern_dsc = kern_pair; + font_dsc->kern_classes = 0; + + uint32_t glyph_entries; + if (lv_fs_read(fp, &glyph_entries, sizeof(uint32_t), NULL) != LV_FS_RES_OK) { + return -1; + } + + int ids_size; + if (format == 0) { + ids_size = sizeof(int8_t) * 2 * glyph_entries; + } + else { + ids_size = sizeof(int16_t) * 2 * glyph_entries; + } + + uint8_t * glyph_ids = lv_mem_alloc(ids_size); + int8_t * values = lv_mem_alloc(glyph_entries); + + kern_pair->glyph_ids_size = format; + kern_pair->pair_cnt = glyph_entries; + kern_pair->glyph_ids = glyph_ids; + kern_pair->values = values; + + if (lv_fs_read(fp, glyph_ids, ids_size, NULL) != LV_FS_RES_OK) { + return -1; + } + + if (lv_fs_read(fp, values, glyph_entries, NULL) != LV_FS_RES_OK) { + return -1; + } } else if(3 == kern_format_type) { /* array M*N of classes */ + lv_font_fmt_txt_kern_classes_t * kern_classes = lv_mem_alloc(sizeof(lv_font_fmt_txt_kern_classes_t)); + + memset(kern_classes, 0, sizeof(lv_font_fmt_txt_kern_classes_t)); + + font_dsc->kern_dsc = kern_classes; + font_dsc->kern_classes = 1; + uint16_t kern_class_mapping_length; uint8_t kern_table_rows; uint8_t kern_table_cols; @@ -578,35 +653,33 @@ static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font) if(lv_fs_read(fp, &kern_class_mapping_length, sizeof(uint16_t), NULL) != LV_FS_RES_OK || lv_fs_read(fp, &kern_table_rows, sizeof(uint8_t), NULL) != LV_FS_RES_OK || lv_fs_read(fp, &kern_table_cols, sizeof(uint8_t), NULL) != LV_FS_RES_OK) { - return false; + return -1; } - kern_classes->left_class_cnt = kern_table_rows; - kern_classes->right_class_cnt = kern_table_cols; + int kern_values_length = sizeof(int8_t) * kern_table_rows * kern_table_cols; uint8_t * kern_left = lv_mem_alloc(kern_class_mapping_length); uint8_t * kern_right = lv_mem_alloc(kern_class_mapping_length); + int8_t * kern_values = lv_mem_alloc(kern_values_length); kern_classes->left_class_mapping = kern_left; kern_classes->right_class_mapping = kern_right; - - int kern_values_length = sizeof(int8_t) * kern_table_rows * kern_table_cols; - int8_t * kern_values = (int8_t *) lv_mem_alloc(kern_values_length); - + kern_classes->left_class_cnt = kern_table_rows; + kern_classes->right_class_cnt = kern_table_cols; kern_classes->class_pair_values = kern_values; if(lv_fs_read(fp, kern_left, kern_class_mapping_length, NULL) != LV_FS_RES_OK || lv_fs_read(fp, kern_right, kern_class_mapping_length, NULL) != LV_FS_RES_OK || lv_fs_read(fp, kern_values, kern_values_length, NULL) != LV_FS_RES_OK) { - return false; + return -1; } } else { - LV_LOG_WARN("kern_format_type %d not supported yet!", kern_format_type); - return false; + LV_LOG_WARN("Unknown kern_format_type: %d", kern_format_type); + return -1; } - return true; + return kern_length; } #endif /*LV_USE_FILESYSTEM*/ diff --git a/tests/Makefile b/tests/Makefile index c429a5b8f..429862de6 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -31,6 +31,9 @@ CSRCS += lv_test_core/lv_test_core.c CSRCS += lv_test_core/lv_test_obj.c CSRCS += lv_test_core/lv_test_style.c CSRCS += lv_test_core/lv_test_font_loader.c +CSRCS += lv_test_fonts/font_1.c +CSRCS += lv_test_fonts/font_2.c +CSRCS += lv_test_fonts/font_3.c OBJEXT ?= .o diff --git a/tests/font_1.fnt b/tests/font_1.fnt new file mode 100644 index 0000000000000000000000000000000000000000..bc701d5f99670f0ea498f2bf56dbdb31e0af4eda GIT binary patch literal 6876 zcmbtY3tUuHw_p1_=FALFd83FUZ+SW3BSefrK}pSTBz)#$tTf9PmKjzy8_+;gulat} zHx?CwnW-ga*TzR?YKEod^@&-g{E`7hdCknZYo7tZzWe>UzkBy^=Ipcg+H0--U;nlC z8R7w8=JaXL5xfha#*b5G7btfCZyYCrAZSpa6#LK4nU=@lJsvL|UQ>bK#VOCb@%dh( z2?hd>y_b57wvD$vZJT79Y@23#);8Vtf^D{KzHOoHRa?Gom2H!4t8JU@UE6ls`?e2k zrMCUHO4}iu)ppo+%=WGAgzY=qDccR(?>4_W|GL1s$Ldn+hSbfjTToX~H?V$n{X6w* z>etqxp&JOd>ZdI0%W3}v*$fKZ7X`fcH<8I&>i%U1ruQ&EQF=78n(d4 zunYFW0XPF!;U+u)6$vJ>WFQ$qo+h)%%VaTGNj8#?$$oN{{7#yPmJ8*2bLm_T_Y60a zTgWZr)^cUs0qzWUoonXY_-=eO{}?}#pTRHUSMnCVfR{}?5fz#C-96n_@B4bhh#CDMb!SS_TiY00J(zZk}eQy5i%hPCRP(3>mdE*OU6BrlRMb#lGyGb%92r z!-L_8)$zGp%?Y}%BocO%p6=C0JMsw5l&E?Y^6%9@k>Ixum^aD>L?amvS}P2ej*_Ea z`f2Yi(!BWihZ_y)xo@1fvApi}UbJ_9DjlZ_I^(U4GQ!a18D8IQH0WvahSNJUZVt8F z8*W*&i!NF>Gm$12T`_LlRW`xUEr#zs*+~0A>c%k_teSCC$dOXAG}~v_R}crW8^`E; zcEJ5isazMCV~C+`1M4$|a-9T89cs8V3m7hPXSUJqLO`0!HdvqRSd{J>{DyxB89 zw(#e&1S8*iENUerGMTfWvJ~uB!@!d;|DT2^h+Pln`X9@x2SMrv7)BF;a`T7L(P7m4 z7zNb2p~N4mRP%PbziV~>0+4e>SB|^=@?!l-&?XvT^cd`--i>1-V10(ceUv8ms8Ftl z{?b9dlbo=8*TJtcYPBm6fQO=9a<75TN37-P~da6OMe#dYb}7U+cbNvK?j?-*f*$S9B8KIb#wc8!I`(Kwg| z*UJl2OL_IMCuuaqx}Vl_(ILxTXtB@$8ZH{uF$tFgRuOx=RK9ZLuGDGPaCJ>Fr)Nu1 zZ^T9J`+T(<&GP}@Zd*$s-^aYQpt4(mRk}A6q7{*IbU=(I2gd$_BDjJMp@XBIJa&;g z9deD*5~%Khs$!#_w8Z~HX{7|nH0ED_^3(bLam9N+8dFBff8+15=w?A&arw%exv6F3 zR*l6Y$IunRBCB8~7(#UrmT~Ku;PLe`Nz#SUSBH0*bdT)%StOym4^T95y&tdj$qr0ic`Rh~2Nid3w z!2m<1+?+gi&gOq?=`*JR>?NfPtRMOCt5#*;fXpogC-_ub&gkP!imK%L@6Q@sQMYzOnRy^vvv!qRU4%m{LVeN zWYq1Tf-O2-wsabv<#ei@WfT@f_`#bWgx#7i8nQ~Jdg}tm3kyx%Mng#zvo*Ea%Q>Wp zzYKrE^U|s@3)0fm+pD=uYc`DFZR+xQMJxY$nV7EY0&f@$QWm^n8t2@5 zgIPMEiCc^Myh(AL68WZv+KA?pWlK70joZpx=U>|U-sN2U0=E4 zWC=HETuG>f+)&-g7z|JE5D27}U5bb|_@^(s{VVA|?f4nUHeZHkZ-C=Qb&sTN*3iNu z)U!aJMAh5GB_UW&{k#PTf>b<57%TD%yh+q2lZ)fSD_={?2cyxgGWCr`xp{6FB9Z>bFoXL0ATkNecUN`4B@{16VWf!i zzUI^&JX*bs7TyUUTZ8y83psn>9czsFD_-8jRdFy9UuwNc9ZBq|lL}sf6(&A`8gOaa z-$g8So@3;c0%=2o6(ew{lD`$V$#?G+@9w{lS8&aZ;hq-&qw=+Tpfd!Br8 zQtcnFdN1jXsKJ!^q$OaO=NtlbNZ8A#dAiLJ!k^btTAwF`_gUuHMox890{H)w#88}kM zl}OLiH(vm&5uWmiuD&LJROG){8yfxx%>H3}kNt1xJB=@#6qCQIE>Cs(PWG@nSFU!R zn)Rh$+ECa=_9jQF9S6-vp<`KKVna-RlPXVj=KYz&?%3=d%Q)MuJg+m5*`kr1p+@O4 z7V2vz{*Mt>kN#<+-v7;W&44~*-kLqQF8w(*RYmRg`u+l8q2lN6J{(b5+4tK3=}mrAyb>e6=sv@w*Q0Iua__af zGnZaE0@`G?B*$3ws||DnRzps&-t88%JWqOi?m4KRbHzF#bG!lH;~U%oW=(%-F8gJ+ z6$T~YuR0ERLF81DTBFry-Q2;$)62VykFUF*AIkU#1O^2MbnO<>y?ba6UH9$*J;TEJ zh|tK$sOXqpv2hR&35mV+Ny&W@`u6RoPe@2i?EhHGfIg|I15?v_0cZwkP|5$b{na(a zGj|_fKYxEz$vg`T4rW(Zyx~1Cm~V3wy@UurC!?bwIx41DR8(wiG=AdZ(Zk+}dVp|E z(*MV`jxFI&3k0#_`G4-IfOoK&<|d-zxmKbAkqDhc)dYWPcQhXC%7cT$K*=Bz_9ZJC zP|oROgUXX4CClK%$9ljo9<@3M5qKxAZ0^tqt)2SVbvRp~)n!uzJL@o|_{;fWdmxJs z``GEUUSRv}FyAgE{w)galAUz553xJpiGZH)vb~n@JUS%eX)HhkIPoU)Og-DZ7PL4j zavTHDrAh|kbUGMH?IYO1hA(4}wr1Cm3?5D=LCl?~v@=Q#kA|`d|8;;S1ZZq%bfCFL z;2aF7j>Zdh9S;Diw)KQK89?X{bIF0<4hJ~wb{41hFcN4Bx^k1*k5nZJ?1qhFQB@+1 zhM5-DFx1#@e^Q?1hyE~*bedA+nF_mXM>04Vri%A1L?+G5S~E1u_ho2dtYQDn!G_#o z)MIK~s!-!Y3rZh{JB%nEIB@{MM=)J`XcxdC=2E+VuJABzP7EhA!?!fIvZyt&AqVGd zV%R9K5U{sGi^JitBaSSxE}b}sz4oR6fhZxgZTaHzOu_S^pvooQuA+Uh^AS}p^@^u0 zZ2y=YEbEj|xmMs@`$m)j;(FwOp!tWJw4(?3Uo-TZC8(0bTBSTNbEp$rgHsUXRwOL6 z$WGEIbHLf1t+-vJrsVPi!|1Rh@BeLUgO%~>uMJ)1F_;bn!NGjN3;kw6RBmh-moOe+ z2DC3mfH8gG-O6()Px%&SQF4H4|1y$8Pnn|SN+L0Q2yvihCXGW* zOx*VN&{q3E+x-zx|1$U2$A8^zX9+afsi9uBVP&l2%LN$ALPiQ#35U5rJ90StY z+JbXLgAxo0hqJX6JFZoYvcNkqOm>u$`3B~Ale3xC%tlrwTt;Lps!G*iOaMEh5yI-4 zY?1AD)QJE)WUK^Egb7)J;IUeVjd4l*H(X-C0~S8U+P_j4TqlEKgl(94>|pgnX$tTh zkAX*o+cI&=to{q^%xQKC&Q@@un^?>lNgd`6qi=oM;q*f9;TryMaVR*P^P)1%di*kcMf32#U21(`HB zd4wDD9=XHlk1h#v6Er#a)<%?XVHT8_5+{#;kEVPZ{On9splnM>W$&!+h^)Rj5oiTK zrbub*czL8X0p=r)d2kLqMOkSCRp&#bQS|97-+8L@IQG#EhSa|_SN@?JT^x*0=pmjJ zouq7k@d&3F7D^>zfyExe)@ecKGaKiXQi{`R-9 z>fl&bBRN_6%0#hupHUSv1lPI}388c%K>z#JChICxN*PyNV#%TGp#d3%okrB#t`se> zK8IvgVP)Y|9Pi*nPQcTvqp4L0uB=sILa>a$8T`~7bgxLz#U zgn?slpS+!Df(R-vl)BZOW+5*>hJ~0cJ9!^=1Q5DM)WGh<0 zi~~%TR!mC=MvE0;8Oe;<{RmN%YRzEoF#7204+c<~!aX?AbC$-Km*{Ng1&vIpGQiGs z*B>%L#QbJwyB#+!;5!-)u{x-5i}3|N$Ov103+53nz=NEXSP+>b xEGL!X!?umnN(!J$otfUnXbM!z#P@C<#l{Wm+RS1SMj literal 0 HcmV?d00001 diff --git a/tests/font_2.fnt b/tests/font_2.fnt new file mode 100644 index 0000000000000000000000000000000000000000..3b648e9d098c26e6c144d4c76043d5ee9dde0403 GIT binary patch literal 7252 zcmbtY4Rlo1wch9c%p@TR6Ou^+h=hid^2*#ixvHPPgxL6l3=>1Xr+ zl~W~cr>CioUZz*+&-4*pq_3!xqSzpo!zQy?Y$3asJ;Dt3U+igiko}pRVP7+o#VHxe zc%?|WQ(3J%qEsq1N}cki(x`l)_>?#`O}$AiROhR!)h+68)R)wE)Q{A^sa~~HB~91j zwPD%>ZH88+t2kM@c7-&(7t>hbzueYk$JUaZg8@6p%lTlE_Kclsao zxAl{HqkdKw`as(h+g-K?Z98p8ZJ*h6dz!t}{&V|d_Wky^?Pu+#{l9WJQ)mJ|4L<@}?6a`X+CIXguW~${W2|8%Xho##U?bJ5)!Z zV}$*P*1+|>6#bcF>bBBBGfzPT#Z<%{y_v{awP&-VEQWbvs7!M>t9BgSTDe8vdX)FC zc{sRZsH#dY)X7{9S@}`?IdG_X}fq67@R=mrpoleQ%*g*5IJ=znmdGcUAw}iE)@+V1Jjrdn_varT1tscLrN*hU6RGa>m)bUPNLC0 zeBuuAq2S4HqA@$k=_F^8dm--lQUdkc=>*V_HQ5`_)KNZH>!?6$;v*&P$Ih7TiA#Cn z);cHMP8pQFlbB?VTar6(GUe|g_SrrB?u1hXOG++mNvPn9A!ApyGqKF+OyB8LzHriH znTnfQ&TTwNmrijl6$4h1|894QlM0+PXSX{S3e$M|8)|R5#gdM0IK|27^^K*m>cUdW@#R-mEA?r-j26GZ zmDxnLJSw3X@6(!!Q;j#(-?BxotmKnCh4tiTYh>;nVx`*TYFfwj^y-PMjD~@OL+3G@ zYbeKqz6}mU*)-<0d8;U*_S!ez;29fhHsvCZ6B^jeRRy-l3zzwDJ~j>MMwH>MOQ*&7 zX1KFt`o*}TQ>cKbsT4HBiONXd=3Y=c=zUi9$!VTR+0hMK8>SU--c-gD`B1&oNwez{ zxctxv`@wB9FVx1)V2hjFTW2MMK^iG8%9ypUB<2A9+-0MF6hDxs0jQs`r=p&i=LUSo z)n;~)rs=7(lQUjZToXA+B_T+s@q&z5$Iqu#H0uXgsVxl`4d>at*dkY@;)4oUqg1@= zmEZL;3s%zbs)O6+UXW%qH_hTyHh@yo8`I$cY^G3Z&in7yuw!rDK?8W|Q#@=CY70V! z^YisF2Uzpm(>!g>7@Zd=^<{Kd9gXL7GcPE!J4&+;z2nkL=Q=dcI8H-(_SkKFR<(Yo zTGvcz#w(T8Q!6};vs|j;i)59cys0U*)u7zYENbEVw=)zqs4k|ynV-02^PqW z4|ti*e^JTHZsqB0Si;l4+~lHx>^D1xZrV|oKu_|K738uX=P->Zei0Q3!HxEp`C4x0 zYY3Naob~DJ=Qm>8Mbqy7`%3qFTs^en$hdj(nvS`|aqt)rl{!ScEkx7vEiHGCT(Mlv zk34aFn$d-m&x6Y>yibJY^4l8cH-tzxz<4H?uMJ~I^QkMJUl%J5>qgD|xBP!4oEG-u zWXs~QZ@r#ZwB;4w=UWaxe9tDw!?U@vw(rst9{TWeXeDVDQ*?3AbwZQ}lUnU-2+yzD-ru1gi7o^A{B zNt5q*SA;GKfg3NOTNNQXc^hY~X!Y8Bad-lDgfQg=m8ZixfzClZ*M5X+e85UB#5R0e1ea*yVGB^w zR1$aY>6H~rE(+iIKN(`%3(FVz5(iOc#h@CBP->-*?}r+`DMAESHeU?A$SqsEQnkFk zhf*kMd$IpE@uigcvf)o!UmeZ!?31C4t&x)v;C5lw8bX|ft%mr@4hP&Dfn7kJ{n)IN zvpy14Lij+@d+-loL*zc}Op=_hhv34N3k2~F%Jd|OQ$|?+DD%n3t7CYcf#5hGpx8q+ z1p-G2QD--Vpb>?IS$6Q^?v|ED%Ca9K)q$6%&W!=;TSiIv=Hg8b_;^wt<4S<5>-eIG zMUDv$prt;fAQXPQh}5d@t)JE*M60rnup(;al*ewKR9HAg3PMb&XoZWued5N;UmpDa z2dj=>Ek+NZ(^0>Bc0cm9t6W-80H2wFU;@ZqFYbi5D z;-U4Yd`47i3M~pQyjZQ>b(kLDdM)*J&|UjRZKzXQE{yVk47_F1gb@934nw6dSV<$x zOFK!j46JhKDve2*ozp~nv0;^j%V^+|6HL8=TR9B149~2`yI8CGZHAwhi#D!5nkS=j zoN=NRml7{M>@Rnui#Afw1Xcut{NdIqC(~1uEGu$GVE^yM{vZULKq`la(6PcP$cAvH zrBt=Fw4p_L_oW)bG(>Q-5MOz%Ov^Hksp2rr_mj%i;d*Vc}7&49(3m=T+GIMOm8Y9_;vN42jun>D;>9NAXT$w;f7a2J3R@d>q z!o7UHab=#n+~*-zR|_!Q(ialaFA79YlKBvuyW+Fvz- zWkztlFbfTE?*+Wn{s}1)Ye^G-H%_joCFMRi?mVMV_F1HyL$WBBOr~L0N_U_PQ&ZNr zw6y&5v5xZcQPO+6JCBSV>wXWobNqUWJW1h60!8+ZQ#?SR@DV7+r2Z(yzwj0rgnyGd zU)lF#6yL0Ya-)2>C3Ql#d0l$gQ6?6s-(XPpq>$Epvigbb<;PbSuC8#XX~-8+9}Ux3 zVN>t>Y@_k)s@Xq#d1qkTx<#Ig&;0F`wV8e|jsL#J3hVvfOgvsV4JmVcMbWaNWh)B9 zLxJqrE@LJ~he<|Q@H4jfbUhV|T3jA<9S_+J54=BVskx_l3DJHhBBd%Y3bV34XoQX-v{SyZaykXFw8waNh z8k9IBb*P$lV|scN`$*Fbg!ToTC-(De!_4}AjRRYXLI@5ZQMKI(>52zHh79j7aHK%5Ii?}AlLBFxItArKGQ~d@ zSK)i1U!7yp>v>Ju+atc4O8-eObW`@?)s2!PQ<(-$R1y4^sVWrGNyDd|ObkMm?4|Wl z6a}oVDAIvpR)UymhNPFeF_-{k?Oy}_FiKF2X)^fS1k>JLYQHv=K6#=CAg!alBLs0B zq=clSdO+1=PrVAZuICvurGuc4R4IgeC`6%PP{ye{jEuU1ZViH2?(1Q$$f#P8hG5A> z0z!>>_sUwMDRhC%kzQLCy<`y-K_o*+`qa|ClL_XR(){EXR|NiWLe?l@Cde(BdXi0; z6*yj%V9kN<5n^dz0s-g4nPD5c34oF+b?X-nkK|?|oKlS1=?}=L`6Mc&m_F$n%Pow8 z0qP8eLP7XZMmEe7dto)LyX6RY39jv`m#}7*Kd%zvH>ref7U7jl_p1~ZO4?*;+9~Zv zb;zo-LKS`jd)vFdU2^ znn9UA-SO(mC8VJgB7bMVFovE0sVa$piHzwq@oyxo4_bvJ{li!YoFz3-CJMJ3uFC30 zbdA?I^}4<5mp`<&Hw8rY0`QdvTezNE*kQ5?Wy-J+3_(=jr~n*}fCK`a*kh5Pke&#c zfdD4qr#ghDh7hJ8=!DuX75ABb*)uz2n+OXLXsTA%k(oe2nMQDHc(YRkgWw4VhXgu- z2{$1t;5^yu05X^Kf0Ikn@r1@Fv-bMbrSQpM36Ta%jYEXMSztL{Q4x5^)PliKNLSbu zp+YGJ*@Bru_J2*DIet?!17t!?G;`@CriI`E+4&?LdRG8igF8fMszCohyYPc?P?%mhcG-9E_p98IEG(R41(3(fHQ*!EBXBWF2&brQ zjb!V6h;-=vdeisb>W#-7YDiE00K)YLHR3`tpP&uSie6OS>omfa^o7-lWMDCa+j>3F z`^?6^)k?9A>I1FJ4A~_*WpaFP2GDqrtrj1Pg_VOA(~u&o8p$ckS1?Q76`8825Ih?$ zB)HOqgZ}r>MH_BZRvWielEq=!(2k74qyv1rnL>h`D@a!Sb_psrMGYysqT%%Ffe0I% zE23;D2pLcm$JOVhrD3pyUok~kLN~U1{D}v`FBaXz;Zbsi5rQcUF~Rv@ekZD zJwmU2{Xqb&E!bc}b6LiyODNm>fey*kLdY{c{6!|{sBd|;2VuB|cQl}6AGC5y<_kW^ z3bYZ#!OCyECE*=IX0GIdI>G}u$YqNqT`D4L(rP}^Y;0R40F``AmvGd0rc>~8=y2$njTo-m2sd{Do_kUmF~(nvhBmR!+k+%S;~tn zAmE(R&wq1ewxm26<>w0{U>uafe_#}P3l*W`XaJ2PW)q8vNv7@xhwY#+^wTy0@&Zc`ycSzTy z>(F_1Q@C~9VXlcA;KKPtegl7u@8uKqf7UnXKi5CfGkySh`5SW;R|IwU3-ESU(>Wv) z^!g46smyfKF8VYwGE}^iw1csWT`m<#p;&TCVRxYio;XnkTGDsJ^Ty+_3ETwE!d&ya z?x##}FsbOKs1?|V#rhZuZk=4-@wt@HKC^XRp9X^2V3xSVUxMyN#3Rh@wX!D!vu8Fw z3OCfRtcB8|TP!1pa4?i2E3r<8qFk9XowV-5?d!#s4 z8)SB@^e>-tY`dL!Bl{t*<8{hei|)dvYTpg;%ztblXQYI%C`nzr{jKFNYVn%met6B} z%%iw4m0ykeK7^zL`h+uZ+I6m>6l~inDl<_m6dyeqV04k^+8hEC*hS<$f`UJ~+VC39 zJ`=R)P@LLo&vt2(CysR+uXQw#+rfZNZb5avXUK^olj|bY>WmG3lc2$Qkhc*|l2Tn+ z#)yH3r_UZCL~MQaDRe-b5u46SI$paAWwxTrv>JH7_k_x8j$W&JiEbkeg!;HO%%)wqvmOxJ>jUH%-0;gTa>Ol2HJ0h0L|Ap zHz%{5icYuggb{A?I4~J5Ef1a}$b0qYzHLLD5tv%~d_~v|NE#5$jP$w4`!wP5JyKu| z=&MFMo-F+CsK8h&C#|m*yMitQmx~K`;sjAPH)prddvSb|Xu4$88JwKeLVv=L zl}E`dEb6pz7CVg@Ll=?tf+zm8ID07`U$p9uSQY`nDyzVTpI}icb`T>rz@3&x_@Sf$ zG0_hI$D43mdOT@a!#Y&bft5WI#=uLTTK^C8%Kb=#{F@)|hUnLD*lITd?{f@+U2vgT zR8L&BVly0Ed%0phq=*_4mWz{ciUw6#$zBpRkBUJ5T_tgmVNm$XQSxN{ZS+f+!2K~~ zdUt6_%SI6lzb`^1wmlqxFFxI|PD-|E%E(6KZFY4r%Qx&7M{W(5*{ny?MQ-#q>>&Au zx4~W$EKqVu)7v|C;R&lYZ041taOOVpIWC@ri-J>NpcyC5EP;VJa^kuwt|9;ut6bds z^Ro`6*Nh6#}BV6sy>y;~|^qB>lh8-dD zp7PYy^utY%=DGQPX}JS!PZ8zl(n7kC!txa4Ov76F)R|6~I3x1MjwY=A?z1}46cb19 zo&}>$xGut1b38Iwn6F-N)R>n?o(1pikHk4&7Y4&%PEIAT955o@fdZ-C4<{`!WK#j=w#!L5 zxJVD165Qr;Y*koMJ7T~cI_+O;{svdBw+fTg;Z;#KP?2= zODwRA@Ye~5@%6zh#is9>dB1|#gQDzT=Kl$neY|efbwNF^Jf(ro`1@=72xV#A1sL*I zfyd3kpwj`K9d(jPJmU+`%C=kReJutDs?0}{Gvs8HB(u)SQxuQ%-#sP35K9V$Bm(P) zPzUj)m@)KvZ&jf8Yqn&-XRDU2!R9oHK5arBE}N=lbejX#cKS=2q(`AvZZrj(B&S&+ z%61JjmOlyw?ae0RFcwhO3nMXa(WG>2NLqOM^hp90&M(6&7iRNxMl~+(W#lBQgFF-) zN{;Yn85Igo>3M0kHGN5T4KRVvy~m7X+vDJi@U#DynW(=e9Sx9Tl8-=l;o^N1*@JNr z&vit?Aaa_gkAN(H*HX0iW=x&3bC1^}6S+^YU*2it{prmi%C=j{Nz?9df*klb=4cm-%+yigVFex#g4_2Vv3p9&_0Nt&EFUd+?)zN_!Xq2Ri zp>2d{_Cz`Mk=K7q^MNHp0^z_(tJCPt(IVqOg|`m%T3~tGxy>SD=MNe5u#Nc)uhCyw-3$^pl(|seKS@x?Op{>zDT1h%H;TXUNo)LfTzNSZhsmi z=oT1gC|Vfj4a)w4lh+Hi;*MWIZnbrRs&OCuCuEWkf08gFUY;UD65VF}S z)As|Re`_fDzy$rL#H2L3$3gdE#dGEA473vIDbcTE%RA9pb+CZsf0B^P7Vv8QR3lv} z57$Gwc^0}8CX!$wS?Aw3kAgKUzR;W1wov;~6n<*=pt%-ZX*g5QeBaA)W{-VyC|M@s<=eaka} zJ>Fj=-IVo)c6C~L_hFn=SV-SS;1LD$@i;;m`VwY6&aQ<#ugy;13*xzU7WHoxlMXH; zdnl~P8ih+N>SZ$*EW+w-Yrp2*xCN!zD8YEB3GE?cAb*@uoH|+eF2sHA%o5`#wq*+30r%txGy<5=4aqH7XJjMfE<~1;#PJ}eK^=>D zD~Ty&HG)ha-i}19oVDwMjZNy{7`Vy{Ytms<5I6-CE*bYNYrjGs%sVN^Tcft39vnyZ z;z+V%-AWsmnMy$1l|9R9$ig&Y1_g(5z_$_$@uc|mu=9h^F+|L;X~PA^2hOn&BdddW z4Iu{lp{hL@HR3cPClK8mJz3z6AVC3}Y#z)5?|mi09*$p|pEm12W|yE5_}&+Gbr7|BdtPkn}Zsu+Wd z$a`j?u1>gf2<^JI-v?50DxPs4l@q}~_lx6mK5cN3EnGVn>xq=XU=1{t|2YZ2L`6n1ictC%p~FJnrCz zz2P!B@~e3~S;j*R>cD1W9DQ1co^ORs?iL6DcIOZAII1pVH7FBZioUT>?>5}C!Nu!4 zr$hw{n&eHnMD_eqznB-=PWM9GGfw<9}oOaqg|LYbdhiNCOPBF=ZYW|+}aBEYN$dAC4G-P zZgZhTf6t0Yg4SObwh(JZy=`ZYy`Wg$sUO4ZJ{vbf44QCHVJ1WGb0wHz-ZZ=fpT3R) zZ$1ddtQbJxc#@%&n>$=Ny4atv+0N4!&!IkXy0?amnS~yFh?9mcPgbSx3$7<~Z9$w> z8!sAL#E?cgPAu*_^`W52wQ=5Rus4Lx*dzp8`$Yb|fOxw^Sb| zcpP8nhX$_PCBOe5-D&1jJbfnIZLXb*m94#u`=@}OqetFmFQjI>vI z>msrS+KE3eUU37>+4S$Wxuq@evO#hO!%d3hr(@AtRwJmzX$%kYf?I& z@mud1X9CsSsHCgbF`TZ-|DP@!$anwUO1%5>aJmMSif1$O$GhGbvQe#$2uK(jfR`ZN zX;!4e?|^QkYCdZUgsT1z>O>wdOb-n0qz-ET9Na7VW!;$IGY$N5#ur2&hH;));jS_5 z-TyH#2Di^X@~KRFb;T{_zL#^tV@iUzve!uO6K~_7w;qQeV!{P z`%2_!Jpbhjhfr$Z8aF_o>u2cjXjJgMLHYb>Fsf`Kk&oM@pHg*re^TO>j#pnu0nqBR#LbVK7a^c{3XcB_wV85~G zDqAL)vQMa?e|x5wSfx@_bT||hbaAIBY?`KIdGG98~wa=x=1IP%4T5tD+%UMIpDNSbs?T1BJ$C zpvY#6T9jE)GV!e74$X!8K5%xP7+fSzR84o$UdhbOJqhi7lHQi4_7ioAV(3!-B{5pm z)qfYjoq?B4bkkGIL5fq`d9E)NmG2>KqH0GjdQ(s%qnI#gV^2?8vq2#C77W~5dn9l! LubT6T1OWd7oV(KG literal 0 HcmV?d00001 diff --git a/tests/lv_test_assert.c b/tests/lv_test_assert.c index a81d48ea4..c4edc0d37 100644 --- a/tests/lv_test_assert.c +++ b/tests/lv_test_assert.c @@ -143,6 +143,17 @@ void lv_test_assert_str_eq(const char * s_ref, const char * s_act, const char * } } + +void lv_test_assert_array_eq(const uint8_t *p_ref, const uint8_t *p_act, int32_t size, const char * s) +{ + if(memcmp(p_ref, p_act, size) != 0) { + lv_test_error(" FAIL: %s. (Expected: all %d bytes should be equal)", s, size); + } else { + lv_test_print(" PASS: %s. (Expected: all %d bytes should be equal)", s, size); + } +} + + void lv_test_assert_ptr_eq(const void * p_ref, const void * p_act, const char * s) { if(p_ref != p_act) { diff --git a/tests/lv_test_assert.h b/tests/lv_test_assert.h index c95db784f..8d006ecf4 100644 --- a/tests/lv_test_assert.h +++ b/tests/lv_test_assert.h @@ -40,6 +40,7 @@ void lv_test_assert_str_eq(const char * str1, const char * str2, const char * s) void lv_test_assert_ptr_eq(const void * p_ref, const void * p_act, const char * s); void lv_test_assert_color_eq(lv_color_t c_ref, lv_color_t c_act, const char * s); void lv_test_assert_img_eq(const char * ref_img_fn, const char * s); +void lv_test_assert_array_eq(const uint8_t *p_ref, const uint8_t *p_act, int32_t size, const char * s); /********************** * MACROS diff --git a/tests/lv_test_core/lv_test_font_loader.c b/tests/lv_test_core/lv_test_font_loader.c index d0fda75b9..2d15b33ab 100644 --- a/tests/lv_test_core/lv_test_font_loader.c +++ b/tests/lv_test_core/lv_test_font_loader.c @@ -42,15 +42,28 @@ static int compare_fonts(lv_font_t * f1, lv_font_t * f2); * GLOBAL FUNCTIONS **********************/ +extern lv_font_t font_1; +extern lv_font_t font_2; +extern lv_font_t font_3; + void lv_test_font_loader(void) { - lv_font_t * montserrat_12_bin = lv_font_load("f:lv_font_montserrat_12.bin"); - compare_fonts(&lv_font_montserrat_12, montserrat_12_bin); + lv_font_t * font_1_bin = lv_font_load("f:font_1.fnt"); + lv_font_t * font_2_bin = lv_font_load("f:font_2.fnt"); + lv_font_t * font_3_bin = lv_font_load("f:font_3.fnt"); + + compare_fonts(&font_1, font_1_bin); + compare_fonts(&font_2, font_2_bin); + compare_fonts(&font_3, font_3_bin); + + lv_font_free(font_1_bin); + lv_font_free(font_2_bin); + lv_font_free(font_3_bin); } static int compare_fonts(lv_font_t * f1, lv_font_t * f2) { - lv_test_assert_true(f1 != NULL && f2 != NULL, "error loading font"); + lv_test_assert_true(f1 != NULL && f2 != NULL, "font not null"); lv_test_assert_ptr_eq(f1->get_glyph_dsc, f2->get_glyph_dsc, "glyph_dsc"); lv_test_assert_ptr_eq(f1->get_glyph_bitmap, f2->get_glyph_bitmap, "glyph_bitmap"); @@ -83,9 +96,11 @@ static int compare_fonts(lv_font_t * f1, lv_font_t * f2) if(cmaps1->unicode_list != NULL && cmaps2->unicode_list != NULL) { lv_test_assert_true(cmaps1->unicode_list && cmaps2->unicode_list, "unicode_list"); - for(int k = 0; k < cmaps1->list_length; ++k) { - lv_test_assert_int_eq(cmaps1->unicode_list[k], cmaps2->unicode_list[k], "unicode_list"); - } + lv_test_assert_array_eq( + (uint8_t *) cmaps1->unicode_list, + (uint8_t *) cmaps2->unicode_list, + sizeof(uint16_t) * cmaps1->list_length, + "unicode_list"); total_glyphs += cmaps1->list_length; } else { @@ -97,9 +112,7 @@ static int compare_fonts(lv_font_t * f1, lv_font_t * f2) uint8_t * ids1 = (uint8_t *) cmaps1->glyph_id_ofs_list; uint8_t * ids2 = (uint8_t *) cmaps2->glyph_id_ofs_list; - for(int j = 0; j < cmaps1->range_length; j++) { - lv_test_assert_int_eq(ids1[j], ids2[j], "glyph_id_ofs_list"); - } + lv_test_assert_array_eq(ids1, ids2, cmaps1->list_length, "glyph_id_ofs_list"); } else { lv_test_assert_ptr_eq(cmaps1->glyph_id_ofs_list, cmaps2->glyph_id_ofs_list, "glyph_id_ofs_list"); @@ -107,37 +120,74 @@ static int compare_fonts(lv_font_t * f1, lv_font_t * f2) } // kern_dsc - lv_font_fmt_txt_kern_classes_t * kern1 = (lv_font_fmt_txt_kern_classes_t *) dsc1->kern_dsc; - lv_font_fmt_txt_kern_classes_t * kern2 = (lv_font_fmt_txt_kern_classes_t *) dsc2->kern_dsc; - if (kern1 != NULL && kern2 != NULL) { - lv_test_assert_int_eq(kern1->right_class_cnt, kern2->right_class_cnt, "right_class_cnt"); - lv_test_assert_int_eq(kern1->left_class_cnt, kern2->left_class_cnt, "left_class_cnt"); + if (dsc1->kern_classes == 1 && dsc2->kern_classes == 1) { + lv_font_fmt_txt_kern_classes_t * kern1 = (lv_font_fmt_txt_kern_classes_t *) dsc1->kern_dsc; + lv_font_fmt_txt_kern_classes_t * kern2 = (lv_font_fmt_txt_kern_classes_t *) dsc2->kern_dsc; + if (kern1 != NULL && kern2 != NULL) { + lv_test_assert_int_eq(kern1->right_class_cnt, kern2->right_class_cnt, "right_class_cnt"); + lv_test_assert_int_eq(kern1->left_class_cnt, kern2->left_class_cnt, "left_class_cnt"); - for(int i = 0; i < kern1->left_class_cnt; ++i) { - lv_test_assert_int_eq(kern1->left_class_mapping[i], - kern2->left_class_mapping[i], "left_class_mapping"); - } - for(int i = 0; i < kern1->right_class_cnt; ++i) { - lv_test_assert_int_eq(kern1->right_class_mapping[i], - kern2->right_class_mapping[i], "right_class_mapping"); - } + lv_test_assert_array_eq( + (uint8_t *) kern1->left_class_mapping, + (uint8_t *) kern2->left_class_mapping, + kern1->left_class_cnt, + "left_class_mapping"); - for(int i = 0; i < kern1->right_class_cnt * kern1->left_class_cnt; ++i) { - lv_test_assert_int_eq(kern1->class_pair_values[i], - kern2->class_pair_values[i], "class_pair_values"); + lv_test_assert_array_eq( + (uint8_t *) kern1->right_class_mapping, + (uint8_t *) kern2->right_class_mapping, + kern1->right_class_cnt, + "right_class_mapping"); + + lv_test_assert_array_eq( + (uint8_t *) kern1->class_pair_values, + (uint8_t *) kern2->class_pair_values, + kern1->right_class_cnt * kern1->left_class_cnt, + "class_pair_values"); + } + else { + lv_test_assert_ptr_eq(kern1, kern2, "kern"); } } - else { - lv_test_assert_ptr_eq(kern1, kern2, "kern"); - } + else if (dsc1->kern_classes == 0 && dsc2->kern_classes == 0) { + lv_font_fmt_txt_kern_pair_t * kern1 = (lv_font_fmt_txt_kern_pair_t *) dsc1->kern_dsc; + lv_font_fmt_txt_kern_pair_t * kern2 = (lv_font_fmt_txt_kern_pair_t *) dsc2->kern_dsc; + if (kern1 != NULL && kern2 != NULL) { + lv_test_assert_int_eq(kern1->glyph_ids_size, kern2->glyph_ids_size, "glyph_ids_size"); + lv_test_assert_int_eq(kern1->pair_cnt, kern2->pair_cnt, "pair_cnt"); - // TODO: glyph_bitmap + int ids_size; + + if (kern1->glyph_ids_size == 0) { + ids_size = sizeof(int8_t) * 2 * kern1->pair_cnt; + } + else { + ids_size = sizeof(int16_t) * 2 * kern1->pair_cnt; + } + + lv_test_assert_array_eq(kern1->glyph_ids, kern2->glyph_ids, ids_size, "glyph_ids"); + lv_test_assert_array_eq( + (uint8_t * ) kern1->values, + (uint8_t * ) kern2->values, + kern1->pair_cnt, + "glyph_values"); + } + } lv_font_fmt_txt_glyph_dsc_t * glyph_dsc1 = (lv_font_fmt_txt_glyph_dsc_t *) dsc1->glyph_dsc; lv_font_fmt_txt_glyph_dsc_t * glyph_dsc2 = (lv_font_fmt_txt_glyph_dsc_t *) dsc2->glyph_dsc; for(int i = 0; i < total_glyphs; ++i) { - //lv_test_assert_int_eq(glyph_dsc1[i].bitmap_index, glyph_dsc2[i].bitmap_index, "bitmap_index"); + if (i < total_glyphs - 1) { + int size1 = glyph_dsc1[i+1].bitmap_index - glyph_dsc1[i].bitmap_index; + + if (size1 > 0) { + lv_test_assert_array_eq( + dsc1->glyph_bitmap + glyph_dsc1[i].bitmap_index, + dsc2->glyph_bitmap + glyph_dsc2[i].bitmap_index, + size1 - 1, "glyph_bitmap"); + } + } lv_test_assert_int_eq(glyph_dsc1[i].adv_w, glyph_dsc2[i].adv_w, "adv_w"); lv_test_assert_int_eq(glyph_dsc1[i].box_w, glyph_dsc2[i].box_w, "box_w"); lv_test_assert_int_eq(glyph_dsc1[i].box_h, glyph_dsc2[i].box_h, "box_h"); diff --git a/tests/lv_test_fonts/font_1.c b/tests/lv_test_fonts/font_1.c new file mode 100644 index 000000000..e94b63ff3 --- /dev/null +++ b/tests/lv_test_fonts/font_1.c @@ -0,0 +1,1383 @@ +#include "lvgl/lvgl.h" + +/******************************************************************************* + * Size: 8 px + * Bpp: 4 + * Opts: --bpp 4 --size 8 --font ../Montserrat-Medium.ttf -r 0x20-0x7F,0xB0,0x2022 --font ../FontAwesome5-Solid+Brands+Regular.woff -r 61441,61448,61451,61452,61452,61453,61457,61459,61461,61465,61468,61473,61478,61479,61480,61502,61512,61515,61516,61517,61521,61522,61523,61524,61543,61544,61550,61552,61553,61556,61559,61560,61561,61563,61587,61589,61636,61637,61639,61671,61674,61683,61724,61732,61787,61931,62016,62017,62018,62019,62020,62087,62099,62212,62189,62810,63426,63650 --format lvgl -o ..\generated_fonts/font_1.c + ******************************************************************************/ + +#ifndef FONT_1 +#define FONT_1 1 +#endif + +#if FONT_1 + +/*----------------- + * BITMAPS + *----------------*/ + +/*Store the image of the glyphs*/ +static LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = { + /* U+20 " " */ + + /* U+21 "!" */ + 0x58, 0xf, 0x11, 0x32, 0xb2, 0x80, + + /* U+22 "\"" */ + 0x73, 0x90, 0x10, 0x72, 0x90, + + /* U+23 "#" */ + 0x4, 0x52, 0x60, 0x4f, 0xc9, 0xc3, 0x43, 0x9c, + 0x83, 0x64, 0x8b, 0xa1, 0x65, 0x85, 0x81, + + /* U+24 "$" */ + 0x0, 0x40, 0x0, 0xad, 0x68, 0x97, 0x56, 0x89, + 0xf9, 0x60, 0x42, 0x17, 0x21, 0x69, 0x7e, 0x96, + 0x96, 0xcc, + + /* U+25 "%" */ + 0x58, 0x70, 0x63, 0xd, 0x8f, 0x30, 0x30, 0xa7, + 0xdb, 0x7, 0x12, 0x7d, 0xa1, 0x57, 0x6, 0xa2, + 0xfa, 0x40, + + /* U+26 "&" */ + 0x9, 0x98, 0x2, 0x2a, 0x30, 0x0, 0x97, 0xc1, + 0x4, 0xd6, 0xc4, 0x2, 0xe6, 0xc, 0xc4, 0x75, + 0x33, 0x10, + + /* U+27 "'" */ + 0x72, 0x0, 0x39, 0x0, + + /* U+28 "(" */ + 0x8, 0x20, 0x32, 0x11, 0x1, 0x10, 0x8, 0x80, + 0x22, 0x0, 0x19, 0x0, + + /* U+29 ")" */ + 0x73, 0x6a, 0x12, 0x7, 0x7, 0x12, 0x6a, + + /* U+2A "*" */ + 0x48, 0x40, 0x26, 0xc0, 0x7b, 0x90, + + /* U+2B "+" */ + 0x0, 0x10, 0x6, 0x80, 0x2, 0x4b, 0xc8, 0xa4, + 0xbc, 0x88, + + /* U+2C "," */ + 0x0, 0x3a, 0x82, 0x0, + + /* U+2D "-" */ + 0x5a, 0x60, + + /* U+2E "." */ + 0x0, 0x3a, 0x0, + + /* U+2F "/" */ + 0x0, 0xa8, 0x2, 0x22, 0x0, 0x55, 0x40, 0x8, + 0x88, 0x0, 0x4c, 0x0, 0xb5, 0xc0, 0x2, 0x2, + 0x0, + + /* U+30 "0" */ + 0xa, 0xbb, 0x13, 0x65, 0xd4, 0xfa, 0x80, 0xbf, + 0xa8, 0xb, 0xb6, 0x5d, 0x48, + + /* U+31 "1" */ + 0x9e, 0x29, 0x40, 0xf, 0xf0, + + /* U+32 "2" */ + 0x6a, 0xb9, 0x6, 0xab, 0x50, 0x9, 0x50, 0x1, + 0x5, 0x1, 0x2d, 0xb4, 0x60, + + /* U+33 "3" */ + 0x7a, 0xbe, 0x7, 0xa1, 0xc0, 0x2, 0x5, 0x80, + 0x12, 0x8c, 0xa2, 0xa8, 0x64, + + /* U+34 "4" */ + 0x0, 0x24, 0x80, 0x47, 0xd2, 0x0, 0x18, 0xa8, + 0x20, 0x90, 0xa5, 0x92, 0x8b, 0xa4, 0x82, + + /* U+35 "5" */ + 0x3d, 0xaa, 0x3, 0x5d, 0x50, 0x1, 0xb5, 0x0, + 0xb7, 0x42, 0x6f, 0x54, 0x33, 0x0, + + /* U+36 "6" */ + 0x9, 0xaa, 0x1b, 0x75, 0x50, 0xff, 0xd3, 0x45, + 0xe1, 0x31, 0x6, 0x19, 0x8e, + + /* U+37 "7" */ + 0xca, 0xa6, 0xb5, 0xd5, 0x5, 0x9c, 0x1a, 0xc0, + 0x2a, 0x70, 0x3, 0x58, 0x0, + + /* U+38 "8" */ + 0x1a, 0xa5, 0x92, 0x65, 0x7d, 0x25, 0xd4, 0xdc, + 0xca, 0xb2, 0x2f, 0xa6, 0xfc, + + /* U+39 "9" */ + 0x4a, 0x99, 0x7, 0xdc, 0x82, 0xc5, 0xc8, 0x69, + 0xd4, 0x86, 0x9d, 0x58, 0xa8, + + /* U+3A ":" */ + 0x74, 0x74, 0x0, 0x3a, 0x0, + + /* U+3B ";" */ + 0x74, 0x74, 0x0, 0x3a, 0x8b, 0xb1, 0x0, + + /* U+3C "<" */ + 0x0, 0x84, 0x0, 0x93, 0x20, 0x58, 0xa8, 0x5, + 0xd5, 0x91, 0x1, 0x69, 0x10, + + /* U+3D "=" */ + 0x49, 0x98, 0x52, 0x66, 0x14, 0x99, 0x84, + + /* U+3E ">" */ + 0x10, 0xc, 0x53, 0x4, 0x7, 0x3d, 0xe2, 0x92, + 0x5a, 0x29, 0x28, 0x0, + + /* U+3F "?" */ + 0x6a, 0xb9, 0x6, 0xab, 0x50, 0xa, 0xa0, 0x2, + 0x94, 0x0, 0x15, 0x80, 0x0, + + /* U+40 "@" */ + 0x3, 0x87, 0x74, 0x28, 0x15, 0xe6, 0xf2, 0x12, + 0xd4, 0x7d, 0x4b, 0x2e, 0x80, 0x7e, 0xa8, 0xf9, + 0x91, 0xc7, 0x15, 0xe0, 0xf6, 0x53, 0x0, + + /* U+41 "A" */ + 0x0, 0xae, 0x40, 0x31, 0x9c, 0x20, 0x14, 0x4c, + 0xa0, 0x0, 0x8d, 0x14, 0x82, 0x1f, 0x93, 0x2e, + 0x80, + + /* U+42 "B" */ + 0x2d, 0x99, 0x58, 0x83, 0xcc, 0x8d, 0x41, 0xe6, + 0x95, 0x40, 0xf3, 0x5d, 0x0, 0xf3, 0x28, 0xd0, + + /* U+43 "C" */ + 0x7, 0xba, 0xa1, 0x2f, 0x5d, 0x50, 0xb2, 0x80, + 0x36, 0x50, 0x6, 0x5e, 0xba, 0xa1, 0x0, + + /* U+44 "D" */ + 0x2e, 0xab, 0xb1, 0x80, 0x12, 0xae, 0xbc, 0x3, + 0x85, 0x48, 0x3, 0xa, 0x90, 0x25, 0x5d, 0x78, + 0x0, + + /* U+45 "E" */ + 0x2e, 0xaa, 0x40, 0x25, 0x52, 0x1, 0xea, 0x88, + 0xf, 0x54, 0x40, 0x4a, 0xa4, 0x80, + + /* U+46 "F" */ + 0x2e, 0xaa, 0x40, 0x25, 0x52, 0x1, 0x2a, 0x88, + 0x9, 0x54, 0x40, 0xe, + + /* U+47 "G" */ + 0x7, 0xba, 0xa1, 0x2f, 0x5d, 0x50, 0xb2, 0x80, + 0x4, 0x79, 0x40, 0x6, 0x45, 0xeb, 0xae, 0x40, + + /* U+48 "H" */ + 0x2a, 0x0, 0x15, 0x0, 0x7c, 0x95, 0x49, 0x0, + 0x25, 0x52, 0x40, 0x3e, + + /* U+49 "I" */ + 0x2a, 0x0, 0xfc, + + /* U+4A "J" */ + 0x5, 0xad, 0x50, 0x5a, 0xa0, 0x7, 0xf7, 0x88, + 0x4d, 0x1a, 0x0, + + /* U+4B "K" */ + 0x2a, 0x1, 0xa2, 0x0, 0xd, 0x41, 0x3, 0x6e, + 0x10, 0x0, 0x77, 0x94, 0x0, 0xe3, 0x3e, 0x80, + + /* U+4C "L" */ + 0x2a, 0x0, 0xff, 0xe3, 0xa5, 0x51, 0xc0, + + /* U+4D "M" */ + 0x2c, 0x0, 0x8f, 0x0, 0x5c, 0x1, 0x0, 0x4, + 0xe2, 0x8f, 0x0, 0xa2, 0x45, 0x0, 0x21, 0x89, + 0x0, 0x0, + + /* U+4E "N" */ + 0x2d, 0x10, 0x2a, 0x1, 0xa0, 0xc, 0xdf, 0x60, + 0x19, 0x3b, 0x80, 0x19, 0x6c, 0x0, + + /* U+4F "O" */ + 0x7, 0xbb, 0x8c, 0x17, 0xae, 0xd5, 0xe3, 0x94, + 0x0, 0x14, 0x5c, 0xa0, 0x0, 0xa2, 0xab, 0xae, + 0xd5, 0xe2, + + /* U+50 "P" */ + 0x2e, 0xaa, 0x48, 0x1, 0x2a, 0x82, 0x80, 0x18, + 0x9c, 0x12, 0xa9, 0x86, 0x9, 0x54, 0x60, + + /* U+51 "Q" */ + 0x7, 0xbb, 0x8c, 0x17, 0xae, 0xd5, 0xe3, 0x94, + 0x0, 0x14, 0x5c, 0xa0, 0x9, 0x15, 0x5d, 0x77, + 0x78, 0x83, 0xdc, 0x15, 0x18, + + /* U+52 "R" */ + 0x2e, 0xaa, 0x48, 0x1, 0x2a, 0x82, 0x80, 0x18, + 0x9c, 0x1e, 0xb0, 0x8c, 0x1e, 0xb4, 0x84, + + /* U+53 "S" */ + 0x2a, 0xa8, 0x97, 0x2a, 0x84, 0xfd, 0x30, 0x21, + 0x13, 0x90, 0xb5, 0x4e, 0xa0, + + /* U+54 "T" */ + 0xaa, 0x75, 0x35, 0x50, 0xa9, 0x80, 0x3f, 0xf8, + 0x60, + + /* U+55 "U" */ + 0x39, 0x0, 0x24, 0x0, 0x7f, 0xf0, 0x9, 0x40, + 0x5, 0xc3, 0x57, 0x58, 0xc0, + + /* U+56 "V" */ + 0xb, 0x10, 0x2, 0xb8, 0x7c, 0x0, 0x39, 0xc1, + 0x14, 0x57, 0x0, 0x28, 0x84, 0xb8, 0x4, 0x8b, + 0x60, 0x0, + + /* U+57 "W" */ + 0x94, 0x0, 0x78, 0x81, 0xcd, 0x70, 0x33, 0x41, + 0x54, 0x36, 0xd, 0x9c, 0x2, 0x30, 0xb9, 0x30, + 0x39, 0xc0, 0x3, 0x32, 0x82, 0x99, 0x80, + + /* U+58 "X" */ + 0x58, 0x2, 0xa0, 0x50, 0x79, 0xb0, 0x4, 0x43, + 0x84, 0x1, 0x57, 0xc2, 0xf, 0x89, 0x34, 0x0, + + /* U+59 "Y" */ + 0xa, 0x20, 0x5, 0x80, 0x2e, 0x42, 0x60, 0x0, + 0x3d, 0x62, 0x60, 0x12, 0xb4, 0x0, 0x70, 0x80, + 0x40, + + /* U+5A "Z" */ + 0x6a, 0xa6, 0x68, 0x35, 0x5b, 0xe0, 0x5, 0x52, + 0x20, 0xb, 0x82, 0x0, 0x43, 0x4d, 0x50, 0x0, + + /* U+5B "[" */ + 0x2d, 0x40, 0x44, 0x0, 0x7f, 0xf0, 0x51, 0x0, + + /* U+5C "\\" */ + 0x19, 0x0, 0x84, 0xc0, 0x37, 0xa8, 0x4, 0xbe, + 0x1, 0x8c, 0x40, 0x2a, 0x60, 0x8, 0xf4, 0x0, + + /* U+5D "]" */ + 0x8c, 0x80, 0xf, 0xe8, 0x0, + + /* U+5E "^" */ + 0x3, 0xc0, 0xa, 0xa1, 0x40, 0xb9, 0x30, 0x0, + + /* U+5F "_" */ + 0x77, 0xc0, + + /* U+60 "`" */ + 0x6, 0x60, + + /* U+61 "a" */ + 0x29, 0x94, 0x0, 0x42, 0xa1, 0x5b, 0x2, 0x2b, + 0xf9, 0x10, + + /* U+62 "b" */ + 0x48, 0x0, 0xff, 0x92, 0xad, 0x40, 0xd, 0x57, + 0x20, 0x1f, 0x9a, 0xa9, 0x20, + + /* U+63 "c" */ + 0x1a, 0xa8, 0x67, 0xaa, 0x82, 0x1, 0xd3, 0xd5, + 0x41, + + /* U+64 "d" */ + 0x0, 0xd6, 0x1, 0xc3, 0x55, 0x4, 0x75, 0x48, + 0x6, 0x10, 0x8e, 0x9b, 0x0, + + /* U+65 "e" */ + 0x19, 0x98, 0x60, 0x4, 0x4e, 0x39, 0x12, 0xd3, + 0xf5, 0x41, + + /* U+66 "f" */ + 0xa, 0xa0, 0x10, 0x50, 0x5b, 0xb8, 0x2d, 0x1c, + 0x3, 0xf8, + + /* U+67 "g" */ + 0x1a, 0x99, 0x5c, 0x74, 0xc3, 0x80, 0x46, 0x11, + 0xd5, 0xe, 0x4, 0x61, 0x0, + + /* U+68 "h" */ + 0x48, 0x0, 0xfe, 0x49, 0xb4, 0x5, 0x9a, 0xf0, + 0x10, 0x17, 0x0, 0xe0, + + /* U+69 "i" */ + 0x37, 0x37, 0x48, 0x0, 0xf0, + + /* U+6A "j" */ + 0x3, 0x70, 0x37, 0x3, 0x80, 0xf, 0xe6, 0x8c, + + /* U+6B "k" */ + 0x48, 0x0, 0xff, 0xa9, 0x0, 0x72, 0x50, 0x12, + 0xa4, 0x0, 0xad, 0xae, + + /* U+6C "l" */ + 0x48, 0x0, 0xff, 0x0, + + /* U+6D "m" */ + 0x4c, 0x9b, 0x89, 0xb4, 0x5, 0x98, 0x39, 0xbf, + 0x1, 0x1, 0x10, 0x1, 0xc0, 0x3f, 0x0, + + /* U+6E "n" */ + 0x4c, 0x9b, 0x40, 0x59, 0xaf, 0x1, 0x1, 0x70, + 0xe, + + /* U+6F "o" */ + 0x1a, 0xa8, 0x67, 0xaa, 0x6c, 0x3, 0xa7, 0xaa, + 0x6c, + + /* U+70 "p" */ + 0x4c, 0xab, 0x50, 0x3, 0x55, 0xc8, 0x7, 0xe6, + 0xaa, 0x48, 0x1, 0x2a, 0x8a, 0x0, + + /* U+71 "q" */ + 0x1a, 0xa4, 0xdc, 0x75, 0x50, 0x3, 0xd1, 0xd5, + 0x40, 0x1a, 0xa4, 0x80, + + /* U+72 "r" */ + 0x4b, 0xa0, 0x0, 0xd0, 0x0, 0x80, 0x3c, + + /* U+73 "s" */ + 0x5b, 0x95, 0xdc, 0xa5, 0x84, 0x44, 0xbc, 0xef, + 0x80, + + /* U+74 "t" */ + 0x29, 0x0, 0x5a, 0x38, 0x5a, 0x38, 0x7, 0x11, + 0x24, 0x0, + + /* U+75 "u" */ + 0x57, 0x1, 0xb0, 0xe, 0x1f, 0x2, 0x4, 0x29, + 0xa0, + + /* U+76 "v" */ + 0xb, 0x0, 0x42, 0x7, 0x38, 0x1a, 0x2, 0xe3, + 0xf0, 0x5, 0xb4, 0xa0, + + /* U+77 "w" */ + 0xb0, 0x7, 0x10, 0x50, 0x72, 0xa9, 0xe8, 0x88, + 0xb, 0xfe, 0x92, 0xaa, 0x0, 0xc, 0x83, 0xc, + 0x80, + + /* U+78 "x" */ + 0x67, 0x1b, 0x6, 0xea, 0xa0, 0x0, 0xc0, 0xc1, + 0xfe, 0xa4, 0x0, + + /* U+79 "y" */ + 0xb, 0x10, 0x83, 0x8, 0x91, 0x23, 0x3, 0x2b, + 0x90, 0xb, 0x80, 0xc0, 0x15, 0xf0, 0x0, + + /* U+7A "z" */ + 0x59, 0xbb, 0x2c, 0x5, 0x5, 0x48, 0xcb, 0xdc, + 0x0, + + /* U+7B "{" */ + 0xa, 0x60, 0x66, 0x0, 0x4a, 0xe0, 0xae, 0x1, + 0xcc, 0xc0, + + /* U+7C "|" */ + 0x28, 0x0, 0xff, 0xe0, 0x0, + + /* U+7D "}" */ + 0x97, 0x9, 0xc0, 0xe, 0x63, 0x6, 0x30, 0xa, + 0x70, 0x0, + + /* U+7E "~" */ + 0x29, 0x35, 0x17, 0x95, 0xd1, + + /* U+B0 "°" */ + 0x26, 0x45, 0x63, 0x57, 0x20, + + /* U+2022 "•" */ + 0x0, 0x2e, 0xaf, 0x80, + + /* U+F001 "" */ + 0x0, 0xff, 0xe0, 0x13, 0x5f, 0x0, 0x23, 0x75, + 0x28, 0x20, 0x7, 0x21, 0x6a, 0x0, 0xd9, 0xd2, + 0xa0, 0x18, 0xc0, 0x3f, 0xab, 0xc2, 0xbc, 0x3, + 0x94, 0x0, 0xa0, 0xa, 0xfa, + + /* U+F008 "" */ + 0xbd, 0xcc, 0xba, 0xac, 0xdb, 0x32, 0x9f, 0x34, + 0x66, 0xdb, 0xe8, 0x1, 0xf9, 0x19, 0xb6, 0xfa, + 0x1b, 0x66, 0x53, 0xe6, + + /* U+F00B "" */ + 0x34, 0x14, 0x4c, 0x79, 0x6d, 0x77, 0xb1, 0x50, + 0xd1, 0x32, 0x8b, 0x8b, 0xbe, 0x14, 0x32, 0x33, + 0xc9, 0x30, 0xd0, 0xef, 0x4c, 0xa1, 0xa1, 0xde, + 0x95, 0x43, 0x44, 0xca, + + /* U+F00C "" */ + 0x0, 0xf4, 0xd0, 0x7, 0x4b, 0x5, 0x48, 0x2, + 0x59, 0x68, 0x1a, 0x64, 0xcb, 0x41, 0x4a, 0xcc, + 0x5a, 0x0, 0xa9, 0x99, 0x40, 0x10, + + /* U+F00D "" */ + 0x63, 0x0, 0x41, 0x56, 0x25, 0x3b, 0x69, 0x5a, + 0xca, 0xb, 0x80, 0x14, 0x29, 0x60, 0xb0, 0xc2, + 0x5f, 0x10, 0x0, + + /* U+F011 "" */ + 0x0, 0xb1, 0x44, 0x0, 0x3a, 0xe2, 0x7e, 0xe1, + 0x20, 0xe0, 0xb, 0x81, 0x4a, 0x0, 0x94, 0x5c, + 0x40, 0x16, 0x80, 0x12, 0x50, 0x31, 0x20, 0xa4, + 0x1e, 0x3c, 0x5b, 0x90, 0xfa, 0xd2, 0x4c, 0x0, + + /* U+F013 "" */ + 0x0, 0xb3, 0x0, 0x10, 0xc4, 0xc, 0xd1, 0x1, + 0x97, 0x70, 0x89, 0xdd, 0x34, 0x3, 0xdc, 0x10, + 0xa0, 0xf, 0xd4, 0x3, 0xdc, 0x10, 0xa9, 0x77, + 0x8, 0x9d, 0xd2, 0x31, 0x3, 0x34, 0x40, 0x40, + + /* U+F015 "" */ + 0x0, 0xc6, 0x4, 0x40, 0xd, 0x59, 0x51, 0x0, + 0x0, 0xe8, 0x48, 0x28, 0x0, 0xfd, 0x46, 0x45, + 0xd0, 0xe2, 0xa, 0x80, 0x8b, 0x10, 0xbe, 0x20, + 0x40, 0x2e, 0xb0, 0x8, 0xec, 0xc0, 0x36, 0xa2, + 0x1, 0x11, 0xa0, + + /* U+F019 "" */ + 0x0, 0xbf, 0xc0, 0x1f, 0xfc, 0x87, 0xf0, 0x7, + 0xb8, 0x1, 0xd8, 0x0, 0xce, 0xf, 0x1c, 0xaa, + 0xe8, 0x78, 0x78, 0x11, 0x43, 0xc0, 0x4, 0x89, + 0x80, + + /* U+F01C "" */ + 0x5, 0xff, 0xe5, 0x1, 0xbc, 0xff, 0xb2, 0xc6, + 0xd8, 0xc0, 0x23, 0x6b, 0x57, 0xf6, 0x6, 0xf7, + 0x50, 0xa, 0x7e, 0x40, 0x22, 0x0, 0xf8, 0x80, + + /* U+F021 "" */ + 0x0, 0xf8, 0xc0, 0xaf, 0xfd, 0x67, 0x85, 0x85, + 0xdc, 0x3c, 0xb, 0x49, 0x17, 0x40, 0x5, 0x58, + 0x1, 0x22, 0xec, 0xea, 0x84, 0x44, 0x57, 0xbb, + 0x42, 0x0, 0x2a, 0x80, 0x2c, 0x6b, 0x6d, 0x1, + 0x85, 0x32, 0x3c, 0x1c, 0x28, 0xcc, 0x40, 0x80, + + /* U+F026 "" */ + 0x0, 0xa4, 0xd3, 0x1b, 0x2c, 0xc0, 0x39, 0x50, + 0x1, 0x57, 0x60, 0x9, 0x38, + + /* U+F027 "" */ + 0x0, 0xa4, 0x0, 0x69, 0x8c, 0x3, 0x96, 0x60, + 0x34, 0x1, 0xe4, 0x40, 0x0, 0x6a, 0xee, 0x0, + 0x8, 0x1, 0x38, 0x0, + + /* U+F028 "" */ + 0x0, 0xf2, 0xa0, 0x6, 0x90, 0x26, 0xf3, 0x32, + 0x63, 0x0, 0x3e, 0x21, 0x96, 0x60, 0x33, 0x25, + 0x70, 0xf, 0xe5, 0x40, 0x0, 0xcc, 0x95, 0xaa, + 0xec, 0x1, 0x7c, 0x48, 0x1, 0x38, 0x9, 0xbc, + 0xc0, + + /* U+F03E "" */ + 0xdf, 0xff, 0x69, 0x7c, 0x0, 0x62, 0x8, 0xb0, + 0x4e, 0x40, 0x1, 0xca, 0x58, 0xd8, 0x2, 0xd6, + 0xc0, 0x31, 0x7f, 0xf8, 0x80, + + /* U+F048 "" */ + 0x40, 0x8, 0xac, 0x82, 0x34, 0x1, 0x2e, 0x0, + 0xe6, 0x0, 0x8c, 0x3, 0x50, 0x80, 0x4f, 0x82, + 0x8, 0x65, 0xec, + + /* U+F04B "" */ + 0x0, 0xfb, 0x68, 0x40, 0x31, 0x2f, 0x38, 0x7, + 0xa3, 0x50, 0x3, 0x8a, 0xe8, 0x3, 0xfe, 0x2b, + 0xa0, 0xa, 0x35, 0x0, 0x97, 0x9c, 0x2, 0xda, + 0x10, 0xc, + + /* U+F04C "" */ + 0x9b, 0x90, 0x9b, 0x96, 0x46, 0x6, 0x46, 0x0, + 0xff, 0xeb, 0xed, 0xe8, 0x6d, 0xe8, + + /* U+F04D "" */ + 0x24, 0x4e, 0x2d, 0xbb, 0xed, 0x0, 0xff, 0xeb, + 0xba, 0x27, 0x38, + + /* U+F051 "" */ + 0x20, 0x9, 0x36, 0x0, 0xac, 0x1e, 0x40, 0x33, + 0x70, 0x6, 0x30, 0x8, 0x68, 0x0, 0x58, 0xe0, + 0xd8, 0x46, 0x80, + + /* U+F052 "" */ + 0x0, 0xc4, 0x1, 0xf4, 0x6c, 0x0, 0x73, 0xb8, + 0x1d, 0xc0, 0x12, 0xc0, 0x5, 0xa, 0x0, 0xb0, + 0xe, 0xb0, 0x5, 0xbb, 0xf5, 0x80, 0x29, 0xdf, + 0xa8, 0x0, 0xa8, 0x9c, 0xa0, + + /* U+F053 "" */ + 0x0, 0x98, 0x80, 0xf, 0x2c, 0xf, 0x14, 0x8b, + 0x12, 0xa0, 0x83, 0xa0, 0x1, 0xc5, 0xb0, 0x1, + 0x62, 0xb0, 0x0, 0xbd, 0x80, + + /* U+F054 "" */ + 0x26, 0x0, 0x9a, 0x5c, 0x0, 0x95, 0xe, 0x0, + 0x59, 0x85, 0x0, 0x68, 0xa0, 0x5a, 0xe0, 0xb2, + 0xe1, 0x3, 0x79, 0x0, 0x0, + + /* U+F067 "" */ + 0x0, 0x90, 0x3, 0x8e, 0xcc, 0x3, 0x38, 0x38, + 0x1, 0xe3, 0x83, 0xa1, 0xe5, 0xd4, 0x15, 0xe7, + 0xbe, 0xc2, 0xff, 0x80, 0x3f, 0x95, 0x14, 0x0, + + /* U+F068 "" */ + 0x78, 0x8e, 0x79, 0x77, 0xe9, + + /* U+F06E "" */ + 0x0, 0x46, 0x65, 0x0, 0x1, 0xd5, 0xda, 0xf5, + 0xd1, 0xd2, 0x84, 0x8e, 0x82, 0xd7, 0x0, 0x40, + 0x80, 0x6a, 0x28, 0xe8, 0xe8, 0x2d, 0x1d, 0x5e, + 0xbf, 0x5c, 0x10, + + /* U+F070 "" */ + 0x1d, 0x30, 0xf, 0xc3, 0x1b, 0x19, 0x95, 0x10, + 0x4, 0xb8, 0xaf, 0x10, 0x3d, 0x40, 0x3, 0xc6, + 0xd, 0xda, 0x82, 0x84, 0x0, 0xb7, 0x52, 0x8, + 0x2, 0x0, 0x75, 0x51, 0xb6, 0x48, 0x58, 0x80, + 0x2a, 0x7f, 0x13, 0xd3, 0xc4, 0x2, 0x6c, 0xc3, + 0x8d, 0x9c, 0x0, + + /* U+F071 "" */ + 0x0, 0xc7, 0xc6, 0x1, 0xfb, 0xc7, 0xc0, 0x3e, + 0x63, 0x39, 0x80, 0x3d, 0x5, 0x85, 0x0, 0x1d, + 0x2, 0x60, 0x63, 0x0, 0x11, 0x38, 0xb, 0x8, + 0x39, 0x0, 0x24, 0x0, 0x28, 0x20, 0x8, 0x0, + 0x30, 0x0, 0x74, 0x40, 0xe, 0x0, + + /* U+F074 "" */ + 0x0, 0xf1, 0x2, 0x20, 0x2, 0x4d, 0x5a, 0xbb, + 0xe, 0x58, 0x47, 0x70, 0xf4, 0x78, 0xf0, 0x0, + 0xa0, 0xa0, 0x17, 0x70, 0x74, 0xf8, 0xf2, 0xaf, + 0x6, 0xec, 0x10, 0x88, 0x0, 0x93, 0x54, + + /* U+F077 "" */ + 0x0, 0xfe, 0x4e, 0x40, 0x9, 0x2c, 0xad, 0x1, + 0x2d, 0xf1, 0xed, 0x3d, 0xe0, 0x21, 0xfe, 0xe0, + 0x2, 0x8b, + + /* U+F078 "" */ + 0x0, 0xfa, 0xe0, 0x2, 0x8b, 0xf7, 0x80, 0x87, + 0xf4, 0xb7, 0xc7, 0xb4, 0x4, 0xb2, 0xb4, 0x0, + 0x93, 0x90, 0x0, + + /* U+F079 "" */ + 0x0, 0x4a, 0xa, 0x26, 0x0, 0xad, 0xae, 0x7f, + 0xeb, 0x10, 0x1, 0xa4, 0x75, 0xdc, 0x20, 0x14, + 0x1, 0xb0, 0x0, 0x40, 0xc0, 0x31, 0xa2, 0x17, + 0xc7, 0xd4, 0x1, 0x98, 0xff, 0x6d, 0x82, 0xa8, + 0x0, 0xf7, 0x74, 0x2e, 0xc0, 0x0, + + /* U+F07B "" */ + 0xdf, 0xf5, 0x80, 0x62, 0x0, 0x27, 0xfd, 0xa0, + 0x1f, 0x10, 0x7, 0xff, 0x10, 0x80, 0x3c, 0x40, + + /* U+F093 "" */ + 0x0, 0xa6, 0x40, 0x1d, 0x2c, 0xc9, 0x0, 0x9d, + 0x80, 0xc, 0xe0, 0x7, 0xf0, 0x7, 0xb8, 0x7, + 0xf3, 0xc2, 0x0, 0x12, 0x1e, 0x1e, 0x9d, 0xd4, + 0xf0, 0x0, 0x17, 0x72, 0xa0, 0x0, + + /* U+F095 "" */ + 0x0, 0xff, 0xe1, 0xbf, 0x50, 0x7, 0xa4, 0x50, + 0x3, 0xc4, 0x4, 0x1, 0xe8, 0xb, 0x0, 0xe1, + 0x91, 0x70, 0x7d, 0xc4, 0xc2, 0xd0, 0x4, 0x91, + 0xd9, 0xe1, 0x80, 0x10, 0x4e, 0x38, 0xc0, 0x0, + + /* U+F0C4 "" */ + 0x3, 0x0, 0xf6, 0x76, 0x1, 0x6e, 0x1, 0x51, + 0x96, 0x1f, 0x5, 0x60, 0x68, 0x61, 0x2, 0x78, + 0x1, 0x8, 0x1, 0x92, 0xc, 0xb2, 0x0, 0x2a, + 0x19, 0x86, 0x90, 0xad, 0xa0, 0x7b, 0xc0, + + /* U+F0C5 "" */ + 0x0, 0x7f, 0xce, 0x8e, 0x80, 0x11, 0x9a, 0x30, + 0x2, 0xb8, 0x0, 0xff, 0xe5, 0x1c, 0x3b, 0xd0, + 0x9, 0xe, 0xe8, 0x70, + + /* U+F0C7 "" */ + 0x24, 0x4c, 0x21, 0xbf, 0xfc, 0x41, 0x77, 0x87, + 0xc1, 0x13, 0x1, 0x5, 0xda, 0x2c, 0x3, 0x36, + 0x30, 0x6, 0x45, 0x40, 0x3, 0xa3, 0x73, 0x23, + 0x80, + + /* U+F0E7 "" */ + 0x7, 0xff, 0x30, 0x5, 0xa0, 0x4, 0x0, 0x98, + 0x1, 0x4e, 0x0, 0x20, 0x3, 0xe0, 0x2, 0x5c, + 0x42, 0x40, 0xf, 0x2, 0xe4, 0x1, 0x18, 0xc0, + 0x6, 0x5b, 0x0, 0x80, + + /* U+F0EA "" */ + 0x79, 0xb9, 0x70, 0x4, 0x33, 0xb4, 0x0, 0x6a, + 0x77, 0x18, 0x5, 0xce, 0xeb, 0xb0, 0x7, 0x8c, + 0x3, 0x9d, 0xd0, 0xe0, 0x1c, 0xf1, 0xe0, 0x18, + + /* U+F0F3 "" */ + 0x0, 0xb4, 0x3, 0x27, 0x17, 0x18, 0x2, 0x44, + 0x7, 0x80, 0x4, 0x1, 0x10, 0x18, 0x7, 0x1c, + 0x0, 0x74, 0x63, 0xbf, 0x6b, 0xc6, 0x3e, 0x43, + 0x0, + + /* U+F11C "" */ + 0xdf, 0xff, 0xb4, 0xb9, 0xdd, 0xce, 0xee, 0x20, + 0xf2, 0x26, 0x91, 0x3c, 0x3, 0xfe, 0xf2, 0xac, + 0xa2, 0xf0, 0x2e, 0x7f, 0xf9, 0xf8, 0x80, + + /* U+F124 "" */ + 0x0, 0xff, 0xe2, 0x25, 0xe0, 0x7, 0x2e, 0x5a, + 0x38, 0x4, 0xdd, 0x46, 0x0, 0xf0, 0x6, 0xc8, + 0x80, 0x46, 0x80, 0xb, 0x77, 0x18, 0x2, 0x40, + 0x26, 0x88, 0x20, 0xa, 0x80, 0x7e, 0x80, 0xf, + 0xb4, 0x98, 0x3, 0xe5, 0xd0, 0xc, + + /* U+F15B "" */ + 0xff, 0xa2, 0xc0, 0x39, 0x2c, 0x2, 0x47, 0x30, + 0x8, 0xdd, 0xc0, 0x1f, 0xfc, 0xc0, + + /* U+F1EB "" */ + 0x0, 0x91, 0xdc, 0x80, 0x1a, 0x7e, 0xef, 0x7c, + 0x86, 0x25, 0xfe, 0x63, 0xed, 0x33, 0xb4, 0x2f, + 0xfd, 0x61, 0xbc, 0x43, 0x63, 0x54, 0x1b, 0x12, + 0x1, 0xfa, 0x74, 0xaf, 0x10, 0xe, 0xcf, 0x0, + 0xfc, 0xd2, 0x1, 0x80, + + /* U+F240 "" */ + 0x24, 0x4f, 0xc1, 0xbf, 0xff, 0x4d, 0x6, 0x2a, + 0xfa, 0x14, 0x3c, 0x47, 0xce, 0x0, 0xd9, 0x9f, + 0x42, 0x3f, 0x6e, 0xf8, 0x60, + + /* U+F241 "" */ + 0x24, 0x4f, 0xc1, 0xbf, 0xff, 0x4d, 0x6, 0x2a, + 0xec, 0xb8, 0x50, 0xf1, 0x1d, 0xe0, 0xe0, 0xd, + 0x99, 0xda, 0x90, 0x8f, 0xdb, 0xbb, 0xbc, 0x60, + + /* U+F242 "" */ + 0x24, 0x4f, 0xc1, 0xbf, 0xff, 0x4d, 0x6, 0x2a, + 0xd7, 0x74, 0x28, 0x78, 0x8c, 0x1, 0x38, 0x3, + 0x66, 0x64, 0x4a, 0x11, 0xfb, 0x76, 0xff, 0x86, + 0x0, + + /* U+F243 "" */ + 0x24, 0x4f, 0xc1, 0xbf, 0xff, 0x4d, 0x6, 0x2e, + 0x5d, 0xe8, 0x50, 0xf1, 0xf0, 0xc, 0xe0, 0xd, + 0x9d, 0x44, 0xd0, 0x8f, 0xdb, 0xdf, 0xf8, 0x60, + + /* U+F244 "" */ + 0x24, 0x4f, 0xc1, 0xbf, 0xff, 0x4c, 0x5, 0xdf, + 0xd0, 0xe0, 0x1f, 0x9c, 0x0, 0x89, 0xf4, 0x13, + 0xff, 0xfc, 0x3c, + + /* U+F287 "" */ + 0x0, 0xff, 0xe1, 0xbe, 0xc0, 0x7, 0xce, 0x97, + 0x80, 0x1a, 0x6c, 0x78, 0x9d, 0x45, 0xc8, 0x1d, + 0x24, 0x72, 0x66, 0xab, 0xc, 0xd8, 0x85, 0xe0, + 0x7e, 0xc8, 0x11, 0x0, 0xc, 0x4d, 0x60, 0x1f, + 0x9b, 0xb0, 0x2, + + /* U+F293 "" */ + 0x6, 0xdd, 0x61, 0x82, 0x49, 0x71, 0x70, 0x69, + 0xa3, 0x59, 0x14, 0x78, 0x9e, 0xc, 0x0, 0xf0, + 0x10, 0x72, 0x31, 0x7f, 0x1, 0xd3, 0x65, 0x91, + 0x24, 0x92, 0xd0, 0xd0, + + /* U+F2ED "" */ + 0x78, 0xdf, 0xd8, 0x70, 0x2, 0xba, 0x80, 0x3d, + 0xdf, 0xbc, 0xc, 0xce, 0x66, 0x0, 0xff, 0xe5, + 0x69, 0x99, 0xcc, 0xda, + + /* U+F304 "" */ + 0x0, 0xf3, 0xf1, 0x80, 0x72, 0x60, 0xe8, 0x6, + 0x8b, 0x24, 0x90, 0xa, 0x1c, 0x1b, 0xdc, 0x1, + 0xe, 0x0, 0x74, 0x0, 0x3b, 0x80, 0xf, 0x0, + 0x14, 0x80, 0x1e, 0x0, 0x38, 0x62, 0x0, 0x1d, + 0xdc, 0x70, 0xe, + + /* U+F55A "" */ + 0x0, 0x57, 0xff, 0xb0, 0x2d, 0x41, 0x8c, 0xcc, + 0x7, 0x48, 0x0, 0x5d, 0xd2, 0x80, 0x7f, 0xf0, + 0x29, 0x0, 0xb, 0xba, 0x50, 0xa, 0xd4, 0x18, + 0xcc, 0xc0, 0x60, + + /* U+F7C2 "" */ + 0x7, 0xff, 0xb8, 0x5f, 0x27, 0x60, 0x89, 0xb, + 0xb7, 0x84, 0x0, 0x14, 0x64, 0x10, 0xf, 0xfe, + 0x51, 0x80, 0x61, 0x20, + + /* U+F8A2 "" */ + 0x0, 0xf8, 0xc0, 0x4, 0x60, 0x11, 0x60, 0x16, + 0x51, 0x14, 0xe0, 0xf, 0x16, 0xdd, 0xa8, 0x1, + 0xe2, 0xdb, 0xbb, 0x80, 0xb2, 0x88, 0xb0, 0x80 +}; + + +/*--------------------- + * GLYPH DESCRIPTION + *--------------------*/ + +static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { + {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */, + {.bitmap_index = 0, .adv_w = 34, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 0, .adv_w = 34, .box_w = 2, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 6, .adv_w = 50, .box_w = 3, .box_h = 3, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 11, .adv_w = 90, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 26, .adv_w = 79, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 44, .adv_w = 108, .box_w = 7, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 62, .adv_w = 88, .box_w = 6, .box_h = 6, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 80, .adv_w = 27, .box_w = 2, .box_h = 3, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 84, .adv_w = 43, .box_w = 3, .box_h = 7, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 96, .adv_w = 43, .box_w = 2, .box_h = 7, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 103, .adv_w = 51, .box_w = 4, .box_h = 3, .ofs_x = 0, .ofs_y = 3}, + {.bitmap_index = 109, .adv_w = 74, .box_w = 5, .box_h = 4, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 119, .adv_w = 29, .box_w = 2, .box_h = 3, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 123, .adv_w = 49, .box_w = 3, .box_h = 1, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 125, .adv_w = 29, .box_w = 2, .box_h = 2, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 128, .adv_w = 45, .box_w = 5, .box_h = 7, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 145, .adv_w = 85, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 158, .adv_w = 47, .box_w = 3, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 163, .adv_w = 73, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 176, .adv_w = 73, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 189, .adv_w = 86, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 204, .adv_w = 73, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 218, .adv_w = 79, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 231, .adv_w = 77, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 244, .adv_w = 82, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 257, .adv_w = 79, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 270, .adv_w = 29, .box_w = 2, .box_h = 4, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 275, .adv_w = 29, .box_w = 2, .box_h = 6, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 282, .adv_w = 74, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 295, .adv_w = 74, .box_w = 5, .box_h = 3, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 302, .adv_w = 74, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 314, .adv_w = 73, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 327, .adv_w = 132, .box_w = 8, .box_h = 6, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 350, .adv_w = 94, .box_w = 7, .box_h = 5, .ofs_x = -1, .ofs_y = 0}, + {.bitmap_index = 367, .adv_w = 97, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 383, .adv_w = 93, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 398, .adv_w = 106, .box_w = 7, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 415, .adv_w = 86, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 429, .adv_w = 81, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 441, .adv_w = 99, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 457, .adv_w = 104, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 469, .adv_w = 40, .box_w = 2, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 472, .adv_w = 66, .box_w = 5, .box_h = 5, .ofs_x = -1, .ofs_y = 0}, + {.bitmap_index = 483, .adv_w = 92, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 499, .adv_w = 76, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 506, .adv_w = 122, .box_w = 7, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 524, .adv_w = 104, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 538, .adv_w = 108, .box_w = 7, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 556, .adv_w = 92, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 571, .adv_w = 108, .box_w = 7, .box_h = 6, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 592, .adv_w = 93, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 607, .adv_w = 79, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 620, .adv_w = 75, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 629, .adv_w = 101, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 642, .adv_w = 91, .box_w = 7, .box_h = 5, .ofs_x = -1, .ofs_y = 0}, + {.bitmap_index = 660, .adv_w = 144, .box_w = 9, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 683, .adv_w = 86, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 699, .adv_w = 83, .box_w = 7, .box_h = 5, .ofs_x = -1, .ofs_y = 0}, + {.bitmap_index = 716, .adv_w = 84, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 732, .adv_w = 43, .box_w = 3, .box_h = 7, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 740, .adv_w = 45, .box_w = 5, .box_h = 7, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 756, .adv_w = 43, .box_w = 2, .box_h = 7, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 761, .adv_w = 75, .box_w = 5, .box_h = 3, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 769, .adv_w = 64, .box_w = 4, .box_h = 1, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 771, .adv_w = 77, .box_w = 3, .box_h = 1, .ofs_x = 0, .ofs_y = 5}, + {.bitmap_index = 773, .adv_w = 77, .box_w = 5, .box_h = 4, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 783, .adv_w = 87, .box_w = 6, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 796, .adv_w = 73, .box_w = 5, .box_h = 4, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 805, .adv_w = 87, .box_w = 5, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 818, .adv_w = 78, .box_w = 5, .box_h = 4, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 828, .adv_w = 45, .box_w = 4, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 838, .adv_w = 88, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 851, .adv_w = 87, .box_w = 5, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 863, .adv_w = 36, .box_w = 2, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 868, .adv_w = 36, .box_w = 3, .box_h = 7, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 876, .adv_w = 79, .box_w = 5, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 888, .adv_w = 36, .box_w = 2, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 892, .adv_w = 135, .box_w = 8, .box_h = 4, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 907, .adv_w = 87, .box_w = 5, .box_h = 4, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 916, .adv_w = 81, .box_w = 5, .box_h = 4, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 925, .adv_w = 87, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 939, .adv_w = 87, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 951, .adv_w = 52, .box_w = 4, .box_h = 4, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 958, .adv_w = 64, .box_w = 4, .box_h = 4, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 967, .adv_w = 53, .box_w = 4, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 977, .adv_w = 87, .box_w = 5, .box_h = 4, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 986, .adv_w = 72, .box_w = 6, .box_h = 4, .ofs_x = -1, .ofs_y = 0}, + {.bitmap_index = 998, .adv_w = 115, .box_w = 8, .box_h = 4, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1015, .adv_w = 71, .box_w = 5, .box_h = 4, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1026, .adv_w = 72, .box_w = 6, .box_h = 5, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 1041, .adv_w = 67, .box_w = 4, .box_h = 4, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1050, .adv_w = 45, .box_w = 3, .box_h = 7, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1060, .adv_w = 38, .box_w = 2, .box_h = 7, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1065, .adv_w = 45, .box_w = 3, .box_h = 7, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1075, .adv_w = 74, .box_w = 5, .box_h = 2, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 1080, .adv_w = 54, .box_w = 3, .box_h = 3, .ofs_x = 0, .ofs_y = 3}, + {.bitmap_index = 1085, .adv_w = 40, .box_w = 2, .box_h = 3, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 1089, .adv_w = 128, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1118, .adv_w = 128, .box_w = 8, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1138, .adv_w = 128, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1166, .adv_w = 128, .box_w = 8, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1188, .adv_w = 88, .box_w = 6, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1207, .adv_w = 128, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1239, .adv_w = 128, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1271, .adv_w = 144, .box_w = 9, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1306, .adv_w = 128, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1331, .adv_w = 144, .box_w = 9, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1355, .adv_w = 128, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 1395, .adv_w = 64, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1408, .adv_w = 96, .box_w = 6, .box_h = 7, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1428, .adv_w = 144, .box_w = 9, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1461, .adv_w = 128, .box_w = 8, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1482, .adv_w = 112, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1501, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 1527, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1541, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1552, .adv_w = 112, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1571, .adv_w = 112, .box_w = 9, .box_h = 8, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 1600, .adv_w = 80, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1621, .adv_w = 80, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1642, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1666, .adv_w = 112, .box_w = 7, .box_h = 2, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 1671, .adv_w = 144, .box_w = 9, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1698, .adv_w = 160, .box_w = 11, .box_h = 8, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 1741, .adv_w = 144, .box_w = 11, .box_h = 8, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 1779, .adv_w = 128, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1810, .adv_w = 112, .box_w = 7, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1828, .adv_w = 112, .box_w = 7, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1847, .adv_w = 160, .box_w = 11, .box_h = 7, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 1885, .adv_w = 128, .box_w = 8, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1901, .adv_w = 128, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1931, .adv_w = 128, .box_w = 9, .box_h = 9, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 1963, .adv_w = 112, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1994, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2014, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2039, .adv_w = 80, .box_w = 7, .box_h = 8, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 2067, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2091, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2116, .adv_w = 144, .box_w = 9, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2139, .adv_w = 128, .box_w = 10, .box_h = 10, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 2177, .adv_w = 96, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2191, .adv_w = 160, .box_w = 10, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2227, .adv_w = 160, .box_w = 10, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2248, .adv_w = 160, .box_w = 10, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2272, .adv_w = 160, .box_w = 10, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2297, .adv_w = 160, .box_w = 10, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2321, .adv_w = 160, .box_w = 10, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2340, .adv_w = 160, .box_w = 11, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2375, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2403, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2423, .adv_w = 128, .box_w = 9, .box_h = 9, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 2458, .adv_w = 160, .box_w = 10, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2485, .adv_w = 96, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2505, .adv_w = 129, .box_w = 9, .box_h = 6, .ofs_x = 0, .ofs_y = 0} +}; + +/*--------------------- + * CHARACTER MAPPING + *--------------------*/ + +static const uint16_t unicode_list_1[] = { + 0x0, 0x1f72, 0xef51, 0xef58, 0xef5b, 0xef5c, 0xef5d, 0xef61, + 0xef63, 0xef65, 0xef69, 0xef6c, 0xef71, 0xef76, 0xef77, 0xef78, + 0xef8e, 0xef98, 0xef9b, 0xef9c, 0xef9d, 0xefa1, 0xefa2, 0xefa3, + 0xefa4, 0xefb7, 0xefb8, 0xefbe, 0xefc0, 0xefc1, 0xefc4, 0xefc7, + 0xefc8, 0xefc9, 0xefcb, 0xefe3, 0xefe5, 0xf014, 0xf015, 0xf017, + 0xf037, 0xf03a, 0xf043, 0xf06c, 0xf074, 0xf0ab, 0xf13b, 0xf190, + 0xf191, 0xf192, 0xf193, 0xf194, 0xf1d7, 0xf1e3, 0xf23d, 0xf254, + 0xf4aa, 0xf712, 0xf7f2 +}; + +/*Collect the unicode lists and glyph_id offsets*/ +static const lv_font_fmt_txt_cmap_t cmaps[] = +{ + { + .range_start = 32, .range_length = 95, .glyph_id_start = 1, + .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY + }, + { + .range_start = 176, .range_length = 63475, .glyph_id_start = 96, + .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 59, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + } +}; + +/*----------------- + * KERNING + *----------------*/ + + +/*Map glyph_ids to kern left classes*/ +static const uint8_t kern_left_class_mapping[] = +{ + 0, 0, 1, 2, 0, 3, 4, 5, + 2, 6, 7, 8, 9, 10, 9, 10, + 11, 12, 0, 13, 14, 15, 16, 17, + 18, 19, 12, 20, 20, 0, 0, 0, + 21, 22, 23, 24, 25, 22, 26, 27, + 28, 29, 29, 30, 31, 32, 29, 29, + 22, 33, 34, 35, 3, 36, 30, 37, + 37, 38, 39, 40, 41, 42, 43, 0, + 44, 0, 45, 46, 47, 48, 49, 50, + 51, 45, 52, 52, 53, 48, 45, 45, + 46, 46, 54, 55, 56, 57, 51, 58, + 58, 59, 58, 60, 41, 0, 0, 9, + 61, 9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0 +}; + +/*Map glyph_ids to kern right classes*/ +static const uint8_t kern_right_class_mapping[] = +{ + 0, 0, 1, 2, 0, 3, 4, 5, + 2, 6, 7, 8, 9, 10, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 12, + 18, 19, 20, 21, 21, 0, 0, 0, + 22, 23, 24, 25, 23, 25, 25, 25, + 23, 25, 25, 26, 25, 25, 25, 25, + 23, 25, 23, 25, 3, 27, 28, 29, + 29, 30, 31, 32, 33, 34, 35, 0, + 36, 0, 37, 38, 39, 39, 39, 0, + 39, 38, 40, 41, 38, 38, 42, 42, + 39, 42, 39, 42, 43, 44, 45, 46, + 46, 47, 46, 48, 0, 0, 35, 9, + 49, 9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0 +}; + +/*Kern values between classes*/ +static const int8_t kern_class_values[] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 3, -3, 0, 0, + 0, 0, -7, -8, 1, 6, 3, 2, + -5, 1, 6, 0, 5, 1, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 8, 1, -1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, -4, 0, 0, 0, 0, + 0, -3, 2, 3, 0, 0, -1, 0, + -1, 1, 0, -1, 0, -1, -1, -3, + 0, 0, 0, 0, -1, 0, 0, -2, + -2, 0, 0, -1, 0, -3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -1, + -1, 0, -2, 0, -3, 0, -15, 0, + 0, -3, 0, 3, 4, 0, 0, -3, + 1, 1, 4, 3, -2, 3, 0, 0, + -7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -3, -2, -6, 0, -5, + -1, 0, 0, 0, 0, 0, 5, 0, + -4, -1, 0, 0, 0, -2, 0, 0, + -1, -9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -10, -1, 5, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 4, + 0, 1, 0, 0, -3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, + 3, 1, 4, -1, 0, 0, 3, -1, + -4, -18, 1, 3, 3, 0, -2, 0, + 5, 0, 4, 0, 4, 0, -12, 0, + -2, 4, 0, 4, -1, 3, 1, 0, + 0, 0, -1, 0, 0, -2, 10, 0, + 10, 0, 4, 0, 5, 2, 2, 4, + 0, 0, 0, -5, 0, 0, 0, 0, + 0, -1, 0, 1, -2, -2, -3, 1, + 0, -1, 0, 0, 0, -5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -8, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -7, 0, -8, 0, 0, 0, + 0, -1, 0, 13, -2, -2, 1, 1, + -1, 0, -2, 1, 0, 0, -7, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -12, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -8, 0, 8, 0, 0, -5, 0, + 4, 0, -9, -12, -9, -3, 4, 0, + 0, -9, 0, 2, -3, 0, -2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 4, -16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 1, 0, 0, 0, + 0, 0, 1, 1, -2, -3, 0, 0, + 0, -1, 0, 0, -1, 0, 0, 0, + -3, 0, -1, 0, -3, -3, 0, -3, + -4, -4, -2, 0, -3, 0, -3, 0, + 0, 0, 0, -1, 0, 0, 1, 0, + 1, -1, 0, 0, 0, 0, 0, 1, + -1, 0, 0, 0, -1, 1, 1, 0, + 0, 0, 0, -2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, -1, 0, + -2, 0, -2, 0, 0, -1, 0, 4, + 0, 0, -1, 0, 0, 0, 0, 0, + 0, 0, -1, -1, 0, 0, -1, 0, + -1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -1, -1, 0, -1, -2, 0, + 0, 0, 0, 0, 0, 0, 0, -1, + 0, -1, -1, -1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -1, 0, 0, + 0, 0, -1, -2, 0, -2, 0, -4, + -1, -4, 3, 0, 0, -3, 1, 3, + 3, 0, -3, 0, -2, 0, 0, -6, + 1, -1, 1, -7, 1, 0, 0, 0, + -7, 0, -7, -1, -11, -1, 0, -6, + 0, 3, 4, 0, 2, 0, 0, 0, + 0, 0, 0, -2, -2, 0, -4, 0, + 0, 0, -1, 0, 0, 0, -1, 0, + 0, 0, 0, 0, -1, -1, 0, -1, + -2, 0, 0, 0, 0, 0, 0, 0, + -1, -1, 0, -1, -2, -1, 0, 0, + -1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -1, -1, 0, -2, + 0, -1, 0, -3, 1, 0, 0, -2, + 1, 1, 1, 0, 0, 0, 0, 0, + 0, -1, 0, 0, 0, 0, 0, 1, + 0, 0, -1, 0, -1, -1, -2, 0, + 0, 0, 0, 0, 0, 0, 1, 0, + -1, 0, 0, 0, 0, -1, -2, 0, + -2, 0, 4, -1, 0, -4, 0, 0, + 3, -6, -7, -5, -3, 1, 0, -1, + -8, -2, 0, -2, 0, -3, 2, -2, + -8, 0, -3, 0, 0, 1, 0, 1, + -1, 0, 1, 0, -4, -5, 0, -6, + -3, -3, -3, -4, -2, -3, 0, -2, + -3, 1, 0, 0, 0, -1, 0, 0, + 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -1, + 0, -1, 0, 0, -1, 0, -2, -3, + -3, 0, 0, -4, 0, 0, 0, 0, + 0, 0, -1, 0, 0, 0, 0, 1, + -1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, + -1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -2, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -1, 0, 0, 0, + -2, 0, 0, 0, 0, -6, -4, 0, + 0, 0, -2, -6, 0, 0, -1, 1, + 0, -3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -2, 0, 0, -2, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, -2, 0, + 0, 0, 0, 2, 0, 1, -3, -3, + 0, -1, -1, -2, 0, 0, 0, 0, + 0, 0, -4, 0, -1, 0, -2, -1, + 0, -3, -3, -4, -1, 0, -3, 0, + -4, 0, 0, 0, 0, 10, 0, 0, + 1, 0, 0, -2, 0, 1, 0, -6, + 0, 0, 0, 0, 0, -12, -2, 4, + 4, -1, -5, 0, 1, -2, 0, -6, + -1, -2, 1, -9, -1, 2, 0, 2, + -4, -2, -5, -4, -5, 0, 0, -8, + 0, 7, 0, 0, -1, 0, 0, 0, + -1, -1, -1, -3, -4, 0, -12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -1, 0, -1, -1, -2, 0, 0, + -3, 0, -1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -3, 0, 0, 3, + 0, 2, 0, -3, 1, -1, 0, -3, + -1, 0, -2, -1, -1, 0, -2, -2, + 0, 0, -1, 0, -1, -2, -2, 0, + 0, -1, 0, 1, -1, 0, -3, 0, + 0, 0, -3, 0, -2, 0, -2, -2, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, -3, 1, 0, -2, 0, -1, -2, + -4, -1, -1, -1, 0, -1, -2, 0, + 0, 0, 0, 0, 0, -1, -1, -1, + 0, 0, 0, 0, 2, -1, 0, -1, + 0, 0, 0, -1, -2, -1, -1, -2, + -1, 0, 1, 5, 0, 0, -3, 0, + -1, 3, 0, -1, -5, -2, 2, 0, + 0, -6, -2, 1, -2, 1, 0, -1, + -1, -4, 0, -2, 1, 0, 0, -2, + 0, 0, 0, 1, 1, -3, -2, 0, + -2, -1, -2, -1, -1, 0, -2, 1, + -2, -2, 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -1, -1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -2, 0, 0, -2, + 0, 0, -1, -1, 0, 0, 0, 0, + -1, 0, 0, 0, 0, -1, 0, 0, + 0, 0, 0, -1, 0, 0, 0, 0, + -2, 0, -3, 0, 0, 0, -4, 0, + 1, -3, 3, 0, -1, -6, 0, 0, + -3, -1, 0, -5, -3, -4, 0, 0, + -6, -1, -5, -5, -6, 0, -3, 0, + 1, 9, -2, 0, -3, -1, 0, -1, + -2, -3, -2, -5, -5, -3, -1, 0, + 0, -1, 0, 0, 0, 0, -9, -1, + 4, 3, -3, -5, 0, 0, -4, 0, + -6, -1, -1, 3, -12, -2, 0, 0, + 0, -8, -2, -7, -1, -9, 0, 0, + -9, 0, 8, 0, 0, -1, 0, 0, + 0, 0, -1, -1, -5, -1, 0, -8, + 0, 0, 0, 0, -4, 0, -1, 0, + 0, -4, -6, 0, 0, -1, -2, -4, + -1, 0, -1, 0, 0, 0, 0, -6, + -1, -4, -4, -1, -2, -3, -1, -2, + 0, -3, -1, -4, -2, 0, -2, -2, + -1, -2, 0, 1, 0, -1, -4, 0, + 3, 0, -2, 0, 0, 0, 0, 2, + 0, 1, -3, 5, 0, -1, -1, -2, + 0, 0, 0, 0, 0, 0, -4, 0, + -1, 0, -2, -1, 0, -3, -3, -4, + -1, 0, -3, 1, 5, 0, 0, 0, + 0, 10, 0, 0, 1, 0, 0, -2, + 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -1, -3, 0, 0, 0, 0, 0, -1, + 0, 0, 0, -1, -1, 0, 0, -3, + -1, 0, 0, -3, 0, 2, -1, 0, + 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 2, 3, 1, -1, 0, -4, + -2, 0, 4, -4, -4, -3, -3, 5, + 2, 1, -11, -1, 3, -1, 0, -1, + 1, -1, -4, 0, -1, 1, -2, -1, + -4, -1, 0, 0, 4, 3, 0, -4, + 0, -7, -2, 4, -2, -5, 0, -2, + -4, -4, -1, 5, 1, 0, -2, 0, + -3, 0, 1, 4, -3, -5, -5, -3, + 4, 0, 0, -9, -1, 1, -2, -1, + -3, 0, -3, -5, -2, -2, -1, 0, + 0, -3, -3, -1, 0, 4, 3, -1, + -7, 0, -7, -2, 0, -4, -7, 0, + -4, -2, -4, -4, 3, 0, 0, -2, + 0, -3, -1, 0, -1, -2, 0, 2, + -4, 1, 0, 0, -7, 0, -1, -3, + -2, -1, -4, -3, -4, -3, 0, -4, + -1, -3, -2, -4, -1, 0, 0, 0, + 6, -2, 0, -4, -1, 0, -1, -3, + -3, -3, -4, -5, -2, -3, 3, 0, + -2, 0, -6, -2, 1, 3, -4, -5, + -3, -4, 4, -1, 1, -12, -2, 3, + -3, -2, -5, 0, -4, -5, -2, -1, + -1, -1, -3, -4, 0, 0, 0, 4, + 4, -1, -8, 0, -8, -3, 3, -5, + -9, -3, -4, -5, -6, -4, 3, 0, + 0, 0, 0, -2, 0, 0, 1, -2, + 3, 1, -2, 3, 0, 0, -4, 0, + 0, 0, 0, 0, 0, -1, 0, 0, + 0, 0, 0, 0, -1, 0, 0, 0, + 0, 1, 4, 0, 0, -2, 0, 0, + 0, 0, -1, -1, -2, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 1, 0, + -1, 0, 5, 0, 2, 0, 0, -2, + 0, 3, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4, 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -8, 0, -1, 2, 0, 4, + 0, 0, 13, 2, -3, -3, 1, 1, + -1, 0, -6, 0, 0, 6, -8, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -9, 5, 18, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -8, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -2, 0, 0, -2, + -1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -1, 0, -3, 0, + 0, 0, 0, 0, 1, 17, -3, -1, + 4, 3, -3, 1, 0, 0, 1, 1, + -2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -17, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -4, + 0, 0, 0, -3, 0, 0, 0, 0, + -3, -1, 0, 0, 0, -3, 0, -2, + 0, -6, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -1, 0, 0, -2, 0, -2, 0, + -3, 0, 0, 0, -2, 1, -2, 0, + 0, -3, -1, -3, 0, 0, -3, 0, + -1, 0, -6, 0, -1, 0, 0, -10, + -2, -5, -1, -5, 0, 0, -9, 0, + -3, -1, 0, 0, 0, 0, 0, 0, + 0, 0, -2, -2, -1, -2, 0, 0, + 0, 0, -3, 0, -3, 2, -1, 3, + 0, -1, -3, -1, -2, -2, 0, -2, + -1, -1, 1, -3, 0, 0, 0, 0, + -11, -1, -2, 0, -3, 0, -1, -6, + -1, 0, 0, -1, -1, 0, 0, 0, + 0, 1, 0, -1, -2, -1, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 0, + 0, -3, 0, -1, 0, 0, 0, -3, + 1, 0, 0, 0, -3, -1, -3, 0, + 0, -4, 0, -1, 0, -6, 0, 0, + 0, 0, -12, 0, -3, -5, -6, 0, + 0, -9, 0, -1, -2, 0, 0, 0, + 0, 0, 0, 0, 0, -1, -2, -1, + -2, 0, 0, 0, 2, -2, 0, 4, + 6, -1, -1, -4, 2, 6, 2, 3, + -3, 2, 5, 2, 4, 3, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 8, 6, -2, -1, 0, -1, + 10, 6, 10, 0, 0, 0, 1, 0, + 0, 5, 0, 0, -2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -1, 0, + 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, -11, -2, -1, -5, + -6, 0, 0, -9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -1, + 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, -11, -2, -1, + -5, -6, 0, 0, -5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -1, 0, 0, 0, -3, 1, 0, -1, + 1, 2, 1, -4, 0, 0, -1, 1, + 0, 1, 0, 0, 0, 0, -3, 0, + -1, -1, -3, 0, -1, -5, 0, 8, + -1, 0, -3, -1, 0, -1, -2, 0, + -1, -4, -3, -2, 0, 0, 0, -2, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -1, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, -11, + -2, -1, -5, -6, 0, 0, -9, 0, + 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -2, 0, -4, -2, -1, 4, -1, -1, + -5, 0, -1, 0, -1, -3, 0, 3, + 0, 1, 0, 1, -3, -5, -2, 0, + -5, -2, -3, -5, -5, 0, -2, -3, + -2, -2, -1, -1, -2, -1, 0, -1, + 0, 2, 0, 2, -1, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -1, -1, -1, 0, 0, + -3, 0, -1, 0, -2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -1, -1, 0, -2, + 0, 0, 0, 0, -1, 0, 0, -2, + -1, 1, 0, -2, -2, -1, 0, -4, + -1, -3, -1, -2, 0, -2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -9, 0, 4, 0, 0, -2, 0, + 0, 0, 0, -2, 0, -1, 0, 0, + -1, 0, 0, -1, 0, -3, 0, 0, + 5, -2, -4, -4, 1, 1, 1, 0, + -4, 1, 2, 1, 4, 1, 4, -1, + -3, 0, 0, -5, 0, 0, -4, -3, + 0, 0, -3, 0, -2, -2, 0, -2, + 0, -2, 0, -1, 2, 0, -1, -4, + -1, 5, 0, 0, -1, 0, -3, 0, + 0, 2, -3, 0, 1, -1, 1, 0, + 0, -4, 0, -1, 0, 0, -1, 1, + -1, 0, 0, 0, -5, -2, -3, 0, + -4, 0, 0, -6, 0, 5, -1, 0, + -2, 0, 1, 0, -1, 0, -1, -4, + 0, -1, 1, 0, 0, 0, 0, -1, + 0, 0, 1, -2, 0, 0, 0, -2, + -1, 0, -2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -8, 0, 3, 0, + 0, -1, 0, 0, 0, 0, 0, 0, + -1, -1, 0, 0, 0, 3, 0, 3, + 0, 0, 0, 0, 0, -8, -7, 0, + 6, 4, 2, -5, 1, 5, 0, 5, + 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 +}; + + +/*Collect the kern class' data in one place*/ +static const lv_font_fmt_txt_kern_classes_t kern_classes = +{ + .class_pair_values = kern_class_values, + .left_class_mapping = kern_left_class_mapping, + .right_class_mapping = kern_right_class_mapping, + .left_class_cnt = 61, + .right_class_cnt = 49, +}; + +/*-------------------- + * ALL CUSTOM DATA + *--------------------*/ + +/*Store all the custom data of the font*/ +static lv_font_fmt_txt_dsc_t font_dsc = { + .glyph_bitmap = gylph_bitmap, + .glyph_dsc = glyph_dsc, + .cmaps = cmaps, + .kern_dsc = &kern_classes, + .kern_scale = 16, + .cmap_num = 2, + .bpp = 4, + .kern_classes = 1, + .bitmap_format = 1 +}; + + +/*----------------- + * PUBLIC FONT + *----------------*/ + +/*Initialize a public general font descriptor*/ +lv_font_t font_1 = { + .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ + .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ + .line_height = 10, /*The maximum line height required by the font*/ + .base_line = 2, /*Baseline measured from the bottom of the line*/ +#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) + .subpx = LV_FONT_SUBPX_NONE, +#endif + .dsc = &font_dsc /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ +}; + +#endif /*#if FONT_1*/ + diff --git a/tests/lv_test_fonts/font_2.c b/tests/lv_test_fonts/font_2.c new file mode 100644 index 000000000..cf2a7b70b --- /dev/null +++ b/tests/lv_test_fonts/font_2.c @@ -0,0 +1,1413 @@ +#include "lvgl/lvgl.h" + +/******************************************************************************* + * Size: 8 px + * Bpp: 4 + * Opts: --bpp 4 --size 8 --font ../Montserrat-Medium.ttf -r 0x20-0x7F,0xB0,0x2022 --font ../FontAwesome5-Solid+Brands+Regular.woff -r 61441,61448,61451,61452,61452,61453,61457,61459,61461,61465,61468,61473,61478,61479,61480,61502,61512,61515,61516,61517,61521,61522,61523,61524,61543,61544,61550,61552,61553,61556,61559,61560,61561,61563,61587,61589,61636,61637,61639,61671,61674,61683,61724,61732,61787,61931,62016,62017,62018,62019,62020,62087,62099,62212,62189,62810,63426,63650 --no-compress --no-prefilter --force-fast-kern-format --format lvgl -o ..\generated_fonts/font_2.c + ******************************************************************************/ + +#ifndef FONT_2 +#define FONT_2 1 +#endif + +#if FONT_2 + +/*----------------- + * BITMAPS + *----------------*/ + +/*Store the image of the glyphs*/ +static LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = { + /* U+20 " " */ + + /* U+21 "!" */ + 0x58, 0x57, 0x46, 0x23, 0x46, + + /* U+22 "\"" */ + 0x73, 0x97, 0x29, 0x0, 0x0, + + /* U+23 "#" */ + 0x4, 0x52, 0x60, 0x4b, 0x9b, 0xa3, 0x8, 0x7, + 0x20, 0x6c, 0x8c, 0x81, 0x9, 0x9, 0x0, + + /* U+24 "$" */ + 0x0, 0x80, 0x2, 0xbd, 0xa2, 0x76, 0x80, 0x0, + 0x8d, 0x81, 0x0, 0x84, 0x95, 0xad, 0xb3, 0x0, + 0x80, 0x0, + + /* U+25 "%" */ + 0x58, 0x70, 0x63, 0x8, 0x8, 0x36, 0x0, 0x27, + 0x58, 0x67, 0x10, 0x8, 0x27, 0x26, 0x6, 0x20, + 0x88, 0x20, + + /* U+26 "&" */ + 0x9, 0x99, 0x0, 0xb, 0x3a, 0x0, 0x19, 0xc2, + 0x20, 0x83, 0x1a, 0xa0, 0x3a, 0x99, 0x92, 0x0, + 0x0, 0x0, + + /* U+27 "'" */ + 0x72, 0x72, 0x0, + + /* U+28 "(" */ + 0x8, 0x20, 0xb0, 0x1a, 0x3, 0x80, 0x1a, 0x0, + 0xb0, 0x8, 0x20, + + /* U+29 ")" */ + 0x73, 0x19, 0xb, 0xc, 0xb, 0x19, 0x73, + + /* U+2A "*" */ + 0x48, 0x40, 0x6e, 0x80, 0x15, 0x10, + + /* U+2B "+" */ + 0x0, 0x20, 0x0, 0xa, 0x0, 0x49, 0xd9, 0x10, + 0xa, 0x0, + + /* U+2C "," */ + 0x0, 0x75, 0x71, + + /* U+2D "-" */ + 0x5a, 0x60, + + /* U+2E "." */ + 0x0, 0x74, + + /* U+2F "/" */ + 0x0, 0xa, 0x0, 0x2, 0x80, 0x0, 0x82, 0x0, + 0xa, 0x0, 0x4, 0x60, 0x0, 0x91, 0x0, 0x19, + 0x0, 0x0, + + /* U+30 "0" */ + 0xa, 0xbb, 0x26, 0x60, 0x1b, 0x93, 0x0, 0xc6, + 0x60, 0x1b, 0xa, 0xbb, 0x20, + + /* U+31 "1" */ + 0x9e, 0x20, 0xa2, 0xa, 0x20, 0xa2, 0xa, 0x20, + + /* U+32 "2" */ + 0x6a, 0xb9, 0x0, 0x0, 0xc0, 0x0, 0x58, 0x0, + 0x87, 0x0, 0x9e, 0xaa, 0x30, + + /* U+33 "3" */ + 0x7a, 0xbe, 0x0, 0xa, 0x20, 0x4, 0xa9, 0x0, + 0x0, 0xa2, 0x8a, 0xa9, 0x0, + + /* U+34 "4" */ + 0x0, 0x49, 0x0, 0x3, 0xa0, 0x0, 0x1b, 0x8, + 0x20, 0x8b, 0xad, 0xb2, 0x0, 0x9, 0x30, + + /* U+35 "5" */ + 0x3d, 0xaa, 0x5, 0x60, 0x0, 0x5b, 0xa8, 0x0, + 0x0, 0x93, 0x7a, 0xaa, 0x0, + + /* U+36 "6" */ + 0x9, 0xaa, 0x36, 0x70, 0x0, 0x98, 0x9a, 0x26, + 0x80, 0x2a, 0x9, 0x9a, 0x40, + + /* U+37 "7" */ + 0xca, 0xad, 0x67, 0x0, 0xc0, 0x0, 0x67, 0x0, + 0xc, 0x0, 0x6, 0x70, 0x0, + + /* U+38 "8" */ + 0x1a, 0xab, 0x25, 0x60, 0x48, 0x1d, 0xad, 0x38, + 0x40, 0x1b, 0x3a, 0x9a, 0x40, + + /* U+39 "9" */ + 0x4a, 0x99, 0xb, 0x10, 0x95, 0x3a, 0x99, 0x80, + 0x0, 0x95, 0x3a, 0xb8, 0x0, + + /* U+3A ":" */ + 0x74, 0x0, 0x0, 0x74, + + /* U+3B ";" */ + 0x74, 0x0, 0x0, 0x75, 0x62, 0x0, + + /* U+3C "<" */ + 0x0, 0x1, 0x0, 0x49, 0x80, 0x5c, 0x30, 0x0, + 0x16, 0x91, 0x0, 0x0, 0x0, + + /* U+3D "=" */ + 0x49, 0x99, 0x10, 0x0, 0x0, 0x49, 0x99, 0x10, + + /* U+3E ">" */ + 0x10, 0x0, 0x3, 0x98, 0x20, 0x0, 0x6d, 0x14, + 0x94, 0x0, 0x0, 0x0, 0x0, + + /* U+3F "?" */ + 0x6a, 0xb9, 0x0, 0x0, 0xc0, 0x0, 0xa4, 0x0, + 0x3, 0x0, 0x2, 0x80, 0x0, + + /* U+40 "@" */ + 0x3, 0x87, 0x78, 0x50, 0x28, 0x4a, 0x9c, 0x75, + 0x80, 0xb0, 0xa, 0x28, 0x80, 0xb0, 0xa, 0x28, + 0x28, 0x49, 0x99, 0xa6, 0x3, 0x88, 0x75, 0x0, + + /* U+41 "A" */ + 0x0, 0xb, 0x90, 0x0, 0x3, 0x8a, 0x10, 0x0, + 0xb1, 0x39, 0x0, 0x4d, 0x99, 0xd1, 0xb, 0x10, + 0x3, 0x90, + + /* U+42 "B" */ + 0x2d, 0x99, 0xb1, 0x2a, 0x0, 0x84, 0x2d, 0x9a, + 0xd1, 0x2a, 0x0, 0x39, 0x2d, 0x99, 0xb4, + + /* U+43 "C" */ + 0x7, 0xba, 0xa2, 0x59, 0x0, 0x0, 0x93, 0x0, + 0x0, 0x59, 0x0, 0x0, 0x7, 0xba, 0xa2, + + /* U+44 "D" */ + 0x2e, 0xab, 0xb3, 0x2, 0xa0, 0x1, 0xc0, 0x2a, + 0x0, 0x9, 0x22, 0xa0, 0x1, 0xc0, 0x2e, 0xab, + 0xb3, 0x0, + + /* U+45 "E" */ + 0x2e, 0xaa, 0x82, 0xa0, 0x0, 0x2d, 0xaa, 0x42, + 0xa0, 0x0, 0x2e, 0xaa, 0x90, + + /* U+46 "F" */ + 0x2e, 0xaa, 0x82, 0xa0, 0x0, 0x2e, 0xaa, 0x42, + 0xa0, 0x0, 0x2a, 0x0, 0x0, + + /* U+47 "G" */ + 0x7, 0xba, 0xa2, 0x59, 0x0, 0x0, 0x93, 0x0, + 0x23, 0x59, 0x0, 0x47, 0x7, 0xba, 0xa3, + + /* U+48 "H" */ + 0x2a, 0x0, 0x2a, 0x2a, 0x0, 0x2a, 0x2e, 0xaa, + 0xba, 0x2a, 0x0, 0x2a, 0x2a, 0x0, 0x2a, + + /* U+49 "I" */ + 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, + + /* U+4A "J" */ + 0x5, 0xad, 0x50, 0x0, 0x75, 0x0, 0x7, 0x50, + 0x0, 0x84, 0x9, 0xab, 0x0, + + /* U+4B "K" */ + 0x2a, 0x1, 0xa2, 0x2a, 0x1b, 0x20, 0x2c, 0xc7, + 0x0, 0x2d, 0x19, 0x50, 0x2a, 0x0, 0xa4, + + /* U+4C "L" */ + 0x2a, 0x0, 0x2, 0xa0, 0x0, 0x2a, 0x0, 0x2, + 0xa0, 0x0, 0x2e, 0xaa, 0x70, + + /* U+4D "M" */ + 0x2c, 0x0, 0x3, 0xc2, 0xd7, 0x0, 0xbc, 0x29, + 0x92, 0x84, 0xc2, 0x91, 0xb9, 0xc, 0x29, 0x3, + 0x0, 0xc0, + + /* U+4E "N" */ + 0x2d, 0x10, 0x2a, 0x2c, 0xb0, 0x2a, 0x2a, 0x4b, + 0x2a, 0x2a, 0x5, 0xca, 0x2a, 0x0, 0x7a, + + /* U+4F "O" */ + 0x7, 0xbb, 0xb3, 0x5, 0x90, 0x1, 0xc1, 0x93, + 0x0, 0x8, 0x45, 0x90, 0x1, 0xc1, 0x7, 0xbb, + 0xb3, 0x0, + + /* U+50 "P" */ + 0x2e, 0xaa, 0x90, 0x2a, 0x0, 0x84, 0x2a, 0x0, + 0xa3, 0x2e, 0xaa, 0x60, 0x2a, 0x0, 0x0, + + /* U+51 "Q" */ + 0x7, 0xbb, 0xb3, 0x5, 0x90, 0x1, 0xc1, 0x93, + 0x0, 0x8, 0x45, 0x90, 0x0, 0xc1, 0x7, 0xbb, + 0xb3, 0x0, 0x0, 0x39, 0x93, + + /* U+52 "R" */ + 0x2e, 0xaa, 0x90, 0x2a, 0x0, 0x84, 0x2a, 0x0, + 0xa3, 0x2d, 0xac, 0x80, 0x2a, 0x1, 0xa1, + + /* U+53 "S" */ + 0x2a, 0xaa, 0x27, 0x60, 0x0, 0x8, 0x98, 0x10, + 0x0, 0x49, 0x5a, 0xaa, 0x30, + + /* U+54 "T" */ + 0xaa, 0xea, 0x60, 0xc, 0x0, 0x0, 0xc0, 0x0, + 0xc, 0x0, 0x0, 0xc0, 0x0, + + /* U+55 "U" */ + 0x39, 0x0, 0x48, 0x39, 0x0, 0x48, 0x39, 0x0, + 0x48, 0x1c, 0x0, 0x66, 0x6, 0xba, 0xa0, + + /* U+56 "V" */ + 0xb, 0x10, 0x5, 0x70, 0x49, 0x0, 0xb0, 0x0, + 0xc1, 0x57, 0x0, 0x4, 0x9c, 0x0, 0x0, 0xc, + 0x70, 0x0, + + /* U+57 "W" */ + 0x94, 0x0, 0xf1, 0x3, 0x93, 0xa0, 0x69, 0x70, + 0x93, 0xc, 0xb, 0xb, 0xb, 0x0, 0x79, 0x80, + 0x89, 0x70, 0x1, 0xf2, 0x2, 0xf1, 0x0, + + /* U+58 "X" */ + 0x58, 0x2, 0xa0, 0x8, 0x7b, 0x10, 0x0, 0xf5, + 0x0, 0xa, 0x4b, 0x10, 0x76, 0x2, 0xb0, + + /* U+59 "Y" */ + 0xa, 0x20, 0xb, 0x0, 0x1b, 0x9, 0x30, 0x0, + 0x5b, 0x80, 0x0, 0x0, 0xd0, 0x0, 0x0, 0xc, + 0x0, 0x0, + + /* U+5A "Z" */ + 0x6a, 0xac, 0xd0, 0x0, 0x1b, 0x10, 0x0, 0xb2, + 0x0, 0xb, 0x30, 0x0, 0x8d, 0xaa, 0xa0, + + /* U+5B "[" */ + 0x2d, 0x42, 0x90, 0x29, 0x2, 0x90, 0x29, 0x2, + 0x90, 0x2d, 0x40, + + /* U+5C "\\" */ + 0x19, 0x0, 0x0, 0xa0, 0x0, 0x5, 0x50, 0x0, + 0xa, 0x0, 0x0, 0x91, 0x0, 0x3, 0x70, 0x0, + 0xa, 0x0, + + /* U+5D "]" */ + 0x8c, 0xc, 0xc, 0xc, 0xc, 0xc, 0x8c, + + /* U+5E "^" */ + 0x3, 0xc0, 0x0, 0x94, 0x50, 0x27, 0x9, 0x0, + + /* U+5F "_" */ + 0x77, 0x77, + + /* U+60 "`" */ + 0x6, 0x60, + + /* U+61 "a" */ + 0x29, 0x98, 0x2, 0x98, 0xd0, 0x84, 0xc, 0x13, + 0xb9, 0xd1, + + /* U+62 "b" */ + 0x48, 0x0, 0x0, 0x48, 0x0, 0x0, 0x4c, 0xab, + 0x50, 0x4a, 0x0, 0xc0, 0x4a, 0x0, 0xc0, 0x4c, + 0xaa, 0x50, + + /* U+63 "c" */ + 0x1a, 0xaa, 0x18, 0x40, 0x0, 0x84, 0x0, 0x1, + 0xaa, 0xa1, + + /* U+64 "d" */ + 0x0, 0x0, 0xb0, 0x0, 0xb, 0x1a, 0xaa, 0xb9, + 0x40, 0x3b, 0x94, 0x2, 0xb1, 0xa9, 0x9b, + + /* U+65 "e" */ + 0x19, 0x99, 0x19, 0x98, 0x86, 0x85, 0x1, 0x1, + 0xaa, 0xb1, + + /* U+66 "f" */ + 0xa, 0xa0, 0x2a, 0x0, 0x9d, 0x70, 0x29, 0x0, + 0x29, 0x0, 0x29, 0x0, + + /* U+67 "g" */ + 0x1a, 0x99, 0xb9, 0x40, 0x1c, 0x94, 0x2, 0xc1, + 0xaa, 0xab, 0x18, 0x9a, 0x30, + + /* U+68 "h" */ + 0x48, 0x0, 0x4, 0x80, 0x0, 0x4c, 0x9b, 0x44, + 0x90, 0x1b, 0x48, 0x0, 0xc4, 0x80, 0xc, + + /* U+69 "i" */ + 0x37, 0x0, 0x48, 0x48, 0x48, 0x48, + + /* U+6A "j" */ + 0x3, 0x70, 0x0, 0x3, 0x80, 0x38, 0x3, 0x80, + 0x38, 0x6b, 0x40, + + /* U+6B "k" */ + 0x48, 0x0, 0x4, 0x80, 0x0, 0x48, 0xa, 0x44, + 0x9c, 0x30, 0x4d, 0x6a, 0x4, 0x80, 0x77, + + /* U+6C "l" */ + 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, + + /* U+6D "m" */ + 0x4c, 0x9b, 0x89, 0xb4, 0x49, 0x3, 0xb0, 0xb, + 0x48, 0x2, 0xa0, 0xc, 0x48, 0x2, 0xa0, 0xc, + + /* U+6E "n" */ + 0x4c, 0x9b, 0x44, 0x90, 0x1b, 0x48, 0x0, 0xc4, + 0x80, 0xc, + + /* U+6F "o" */ + 0x1a, 0xaa, 0x18, 0x40, 0x3a, 0x84, 0x3, 0xa1, + 0xaa, 0xa1, + + /* U+70 "p" */ + 0x4c, 0xab, 0x50, 0x4a, 0x0, 0xc0, 0x4a, 0x0, + 0xc0, 0x4c, 0xaa, 0x50, 0x48, 0x0, 0x0, + + /* U+71 "q" */ + 0x1a, 0xa9, 0xb9, 0x40, 0x3b, 0x94, 0x3, 0xb1, + 0xaa, 0x9b, 0x0, 0x0, 0xb0, + + /* U+72 "r" */ + 0x4b, 0xa0, 0x4a, 0x0, 0x48, 0x0, 0x48, 0x0, + + /* U+73 "s" */ + 0x5b, 0x95, 0x87, 0x30, 0x3, 0x79, 0x7a, 0xa6, + + /* U+74 "t" */ + 0x29, 0x0, 0x9d, 0x70, 0x29, 0x0, 0x29, 0x0, + 0xb, 0x90, + + /* U+75 "u" */ + 0x57, 0x1, 0xb5, 0x70, 0x1b, 0x48, 0x3, 0xb0, + 0xa9, 0x9b, + + /* U+76 "v" */ + 0xb, 0x0, 0x84, 0x5, 0x70, 0xb0, 0x0, 0xb7, + 0x50, 0x0, 0x6d, 0x0, + + /* U+77 "w" */ + 0xb0, 0xe, 0x20, 0xa0, 0x55, 0x59, 0x82, 0x80, + 0xa, 0xa0, 0xa8, 0x20, 0x9, 0x80, 0x6b, 0x0, + + /* U+78 "x" */ + 0x67, 0x1b, 0x0, 0x9b, 0x10, 0xa, 0xb2, 0x7, + 0x51, 0xb0, + + /* U+79 "y" */ + 0xb, 0x10, 0x83, 0x3, 0x81, 0xa0, 0x0, 0xaa, + 0x30, 0x0, 0x4a, 0x0, 0xa, 0xb2, 0x0, + + /* U+7A "z" */ + 0x59, 0xbb, 0x1, 0xb1, 0xb, 0x20, 0x9c, 0x98, + + /* U+7B "{" */ + 0xa, 0x60, 0xc0, 0xc, 0x5, 0xb0, 0xc, 0x0, + 0xc0, 0xa, 0x60, + + /* U+7C "|" */ + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + + /* U+7D "}" */ + 0x97, 0x0, 0xb0, 0xb, 0x0, 0xd3, 0xb, 0x0, + 0xb0, 0x97, 0x0, + + /* U+7E "~" */ + 0x29, 0x35, 0x15, 0x6, 0x80, + + /* U+B0 "°" */ + 0x26, 0x47, 0x7, 0x27, 0x50, + + /* U+2022 "•" */ + 0x0, 0x5d, 0x2, + + /* U+F001 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x26, 0xbe, + 0x0, 0x8d, 0xff, 0xff, 0x0, 0xff, 0xe9, 0x5f, + 0x0, 0xf3, 0x0, 0xf, 0x0, 0xf0, 0x0, 0xf, + 0x0, 0xf0, 0xa, 0xff, 0xaf, 0xf0, 0xa, 0xfa, + 0xaf, 0xa0, 0x0, 0x0, + + /* U+F008 "" */ + 0xbd, 0xcc, 0xce, 0xab, 0x8b, 0x0, 0x7, 0x58, + 0xcd, 0x66, 0x6a, 0xac, 0xcd, 0x66, 0x6a, 0xac, + 0x8b, 0x0, 0x7, 0x58, 0xbd, 0xcc, 0xce, 0xab, + + /* U+F00B "" */ + 0x34, 0x14, 0x44, 0x43, 0xff, 0x7f, 0xff, 0xff, + 0xab, 0x4b, 0xbb, 0xba, 0xbc, 0x5c, 0xcc, 0xcb, + 0xff, 0x7f, 0xff, 0xff, 0x67, 0x17, 0x88, 0x86, + 0xff, 0x7f, 0xff, 0xff, 0xab, 0x4b, 0xbb, 0xba, + + /* U+F00C "" */ + 0x0, 0x0, 0x0, 0x9a, 0x0, 0x0, 0x9, 0xfa, + 0xa9, 0x0, 0x9f, 0xa0, 0xaf, 0x99, 0xfa, 0x0, + 0xa, 0xff, 0xa0, 0x0, 0x0, 0x99, 0x0, 0x0, + + /* U+F00D "" */ + 0x63, 0x0, 0x82, 0xcf, 0x4a, 0xf4, 0x1d, 0xff, + 0x60, 0xa, 0xff, 0x30, 0xaf, 0x7d, 0xf3, 0xa6, + 0x1, 0xb3, + + /* U+F011 "" */ + 0x0, 0xc, 0x51, 0x0, 0x1d, 0x7d, 0x6e, 0x70, + 0x8d, 0xd, 0x65, 0xf1, 0xc7, 0xd, 0x60, 0xe6, + 0xd7, 0x6, 0x20, 0xe6, 0x9d, 0x0, 0x4, 0xf2, + 0x1e, 0xc7, 0x8f, 0x80, 0x1, 0x9d, 0xc6, 0x0, + + /* U+F013 "" */ + 0x0, 0xc, 0xc0, 0x0, 0x18, 0x8f, 0xf8, 0x81, + 0x8f, 0xfe, 0xef, 0xf8, 0x2f, 0xe0, 0xe, 0xf2, + 0x2f, 0xe0, 0xe, 0xf2, 0x8f, 0xfe, 0xef, 0xf8, + 0x18, 0x8f, 0xf8, 0x81, 0x0, 0xc, 0xc0, 0x0, + + /* U+F015 "" */ + 0x0, 0x0, 0x30, 0x22, 0x0, 0x0, 0xaf, 0xaa, + 0xa0, 0x1, 0xda, 0x6a, 0xfa, 0x3, 0xe8, 0xbf, + 0xb8, 0xe3, 0xb6, 0xdf, 0xff, 0xd6, 0xb0, 0x8f, + 0xfb, 0xff, 0x80, 0x8, 0xfc, 0xc, 0xf8, 0x0, + 0x5b, 0x80, 0x8b, 0x50, + + /* U+F019 "" */ + 0x0, 0xf, 0xf0, 0x0, 0x0, 0xf, 0xf0, 0x0, + 0x0, 0xf, 0xf0, 0x0, 0x7, 0xff, 0xff, 0x70, + 0x0, 0x9f, 0xf9, 0x0, 0x78, 0x7a, 0xa7, 0x87, + 0xff, 0xfb, 0xbf, 0xff, 0xff, 0xff, 0xfb, 0xbf, + + /* U+F01C "" */ + 0x5, 0xff, 0xff, 0xf5, 0x1, 0xe3, 0x0, 0x3, + 0xe1, 0xa8, 0x0, 0x0, 0x8, 0xaf, 0xff, 0x60, + 0x6f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, + 0xff, 0xff, 0xfd, + + /* U+F021 "" */ + 0x0, 0x0, 0x0, 0x3, 0x2, 0xbf, 0xfb, 0x3f, + 0x2e, 0x91, 0x18, 0xff, 0x9a, 0x0, 0x6c, 0xff, + 0x31, 0x0, 0x24, 0x44, 0x44, 0x42, 0x0, 0x13, + 0xff, 0xc6, 0x0, 0xb9, 0xfe, 0xa5, 0x5b, 0xd1, + 0xf2, 0x8c, 0xc8, 0x10, 0x30, 0x0, 0x0, 0x0, + + /* U+F026 "" */ + 0x0, 0x9, 0x34, 0xcf, 0xff, 0xff, 0xff, 0xff, + 0xab, 0xff, 0x0, 0x4f, 0x0, 0x1, + + /* U+F027 "" */ + 0x0, 0x9, 0x0, 0x34, 0xcf, 0x1, 0xff, 0xff, + 0x1b, 0xff, 0xff, 0x1b, 0xbb, 0xff, 0x1, 0x0, + 0x4f, 0x0, 0x0, 0x1, 0x0, + + /* U+F028 "" */ + 0x0, 0x0, 0x0, 0x54, 0x0, 0x0, 0x90, 0x23, + 0xb3, 0x34, 0xcf, 0x2, 0xc3, 0xbf, 0xff, 0xf1, + 0xb5, 0x6c, 0xff, 0xff, 0x1b, 0x56, 0xca, 0xbf, + 0xf0, 0x2c, 0x3a, 0x0, 0x4f, 0x2, 0x3b, 0x30, + 0x0, 0x10, 0x5, 0x40, + + /* U+F03E "" */ + 0xdf, 0xff, 0xff, 0xfd, 0xf0, 0x7f, 0xff, 0xff, + 0xf8, 0xcf, 0xb1, 0xbf, 0xfb, 0x5b, 0x0, 0xf, + 0xf0, 0x0, 0x0, 0xf, 0xdf, 0xff, 0xff, 0xfd, + + /* U+F048 "" */ + 0x40, 0x0, 0x2f, 0x20, 0x8f, 0xf2, 0x9f, 0xff, + 0xcf, 0xff, 0xff, 0xff, 0xff, 0x5e, 0xff, 0xf2, + 0x2e, 0xfb, 0x10, 0x19, + + /* U+F04B "" */ + 0x0, 0x0, 0x0, 0xd, 0xa1, 0x0, 0x0, 0xff, + 0xf7, 0x0, 0xf, 0xff, 0xfd, 0x40, 0xff, 0xff, + 0xff, 0xaf, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xd4, + 0xf, 0xff, 0x70, 0x0, 0xda, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, + + /* U+F04C "" */ + 0x9b, 0x90, 0x9b, 0x9f, 0xff, 0xf, 0xff, 0xff, + 0xf0, 0xff, 0xff, 0xff, 0xf, 0xff, 0xff, 0xf0, + 0xff, 0xff, 0xff, 0xf, 0xff, 0xff, 0xf0, 0xff, + 0xf2, 0x42, 0x2, 0x42, + + /* U+F04D "" */ + 0x24, 0x44, 0x44, 0x2f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf8, 0xbb, 0xbb, 0xb8, + + /* U+F051 "" */ + 0x20, 0x0, 0x4f, 0x80, 0x2f, 0xff, 0x92, 0xff, + 0xff, 0xcf, 0xff, 0xff, 0xff, 0xfe, 0x5f, 0xfd, + 0x22, 0xf9, 0x10, 0x1b, + + /* U+F052 "" */ + 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x8f, 0x80, + 0x0, 0x0, 0x7f, 0xff, 0x70, 0x0, 0x5f, 0xff, + 0xff, 0x50, 0xe, 0xff, 0xff, 0xfe, 0x0, 0x58, + 0x88, 0x88, 0x50, 0xf, 0xff, 0xff, 0xff, 0x0, + 0xab, 0xbb, 0xbb, 0xa0, + + /* U+F053 "" */ + 0x0, 0x6, 0x20, 0x7, 0xf4, 0x7, 0xf5, 0x5, + 0xf6, 0x0, 0x1e, 0xb0, 0x0, 0x2e, 0xb0, 0x0, + 0x2e, 0x60, 0x0, 0x10, + + /* U+F054 "" */ + 0x26, 0x0, 0x4, 0xf7, 0x0, 0x5, 0xf7, 0x0, + 0x6, 0xf5, 0x0, 0xbe, 0x10, 0xbe, 0x20, 0x6e, + 0x20, 0x0, 0x10, 0x0, + + /* U+F067 "" */ + 0x0, 0x4, 0x0, 0x0, 0x3, 0xf3, 0x0, 0x0, + 0x4f, 0x40, 0x7, 0x8a, 0xfa, 0x87, 0xef, 0xff, + 0xff, 0xe0, 0x4, 0xf4, 0x0, 0x0, 0x4f, 0x40, + 0x0, 0x1, 0xb1, 0x0, + + /* U+F068 "" */ + 0x78, 0x88, 0x88, 0x7e, 0xff, 0xff, 0xfe, + + /* U+F06E "" */ + 0x0, 0x8c, 0xcc, 0x80, 0x1, 0xdd, 0x16, 0x3d, + 0xd1, 0xcf, 0x55, 0xed, 0x5f, 0xcb, 0xf5, 0xdf, + 0xd5, 0xfc, 0x1d, 0xd3, 0x73, 0xdd, 0x10, 0x8, + 0xdc, 0xc8, 0x10, + + /* U+F070 "" */ + 0x1d, 0x30, 0x0, 0x0, 0x0, 0x0, 0x5e, 0x8c, + 0xcc, 0xa2, 0x0, 0x0, 0x2d, 0xb4, 0x49, 0xf4, + 0x0, 0x7a, 0x1a, 0xff, 0x3f, 0xe1, 0x7, 0xfa, + 0x6, 0xf7, 0xff, 0x10, 0xa, 0xf3, 0x3, 0xef, + 0x40, 0x0, 0x6, 0xcc, 0x71, 0xbb, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x89, + + /* U+F071 "" */ + 0x0, 0x0, 0x3e, 0x30, 0x0, 0x0, 0x0, 0xc, + 0xfc, 0x0, 0x0, 0x0, 0x6, 0xfc, 0xf6, 0x0, + 0x0, 0x0, 0xed, 0xd, 0xe0, 0x0, 0x0, 0x8f, + 0xe0, 0xef, 0x80, 0x0, 0x2f, 0xff, 0x6f, 0xff, + 0x20, 0xb, 0xff, 0xe2, 0xef, 0xfa, 0x0, 0xdf, + 0xff, 0xff, 0xff, 0xd0, + + /* U+F074 "" */ + 0x0, 0x0, 0x0, 0x20, 0x44, 0x0, 0x4, 0xf5, + 0xef, 0xb1, 0xcf, 0xfd, 0x1, 0x8c, 0xd1, 0xc1, + 0x1, 0xdc, 0x81, 0xc1, 0xef, 0xc1, 0xbf, 0xfd, + 0x44, 0x0, 0x4, 0xf5, 0x0, 0x0, 0x0, 0x20, + + /* U+F077 "" */ + 0x0, 0x0, 0x0, 0x0, 0x4, 0xe4, 0x0, 0x4, + 0xfc, 0xf4, 0x4, 0xf8, 0x8, 0xf4, 0xb8, 0x0, + 0x8, 0xb0, 0x0, 0x0, 0x0, + + /* U+F078 "" */ + 0x0, 0x0, 0x0, 0xb, 0x80, 0x0, 0x8b, 0x4f, + 0x80, 0x8f, 0x40, 0x4f, 0xcf, 0x40, 0x0, 0x4e, + 0x40, 0x0, 0x0, 0x0, 0x0, + + /* U+F079 "" */ + 0x0, 0x94, 0x14, 0x44, 0x40, 0x0, 0xbf, 0xf8, + 0xbb, 0xbf, 0x10, 0x8, 0xb7, 0x60, 0x0, 0xe1, + 0x0, 0xb, 0x40, 0x0, 0x1e, 0x20, 0x0, 0xb7, + 0x44, 0x5e, 0xfd, 0x50, 0x7, 0xbb, 0xb8, 0x5f, + 0x80, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, + + /* U+F07B "" */ + 0xdf, 0xfb, 0x0, 0x0, 0xff, 0xff, 0xff, 0xfd, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xfd, + + /* U+F093 "" */ + 0x0, 0x9, 0x90, 0x0, 0x0, 0x9f, 0xf9, 0x0, + 0x7, 0xff, 0xff, 0x70, 0x0, 0xf, 0xf0, 0x0, + 0x0, 0xf, 0xf0, 0x0, 0x78, 0x4f, 0xf4, 0x87, + 0xff, 0xe8, 0x8e, 0xff, 0xff, 0xff, 0xfb, 0xbf, + + /* U+F095 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, + 0xea, 0x0, 0x0, 0x0, 0xef, 0xe0, 0x0, 0x0, + 0xc, 0xfc, 0x0, 0x0, 0x0, 0x4f, 0x70, 0x0, + 0x0, 0x1d, 0xe0, 0x7, 0xdc, 0x4d, 0xf3, 0x0, + 0xef, 0xff, 0xe3, 0x0, 0xa, 0xec, 0x70, 0x0, + 0x0, + + /* U+F0C4 "" */ + 0x3, 0x0, 0x0, 0x0, 0xcd, 0xc0, 0x2d, 0xc0, + 0xe7, 0xf2, 0xee, 0x20, 0x4b, 0xff, 0xe2, 0x0, + 0x4, 0xff, 0xa0, 0x0, 0xcd, 0xf9, 0xf9, 0x0, + 0xe7, 0xe0, 0x7f, 0x90, 0x4a, 0x40, 0x4, 0x50, + + /* U+F0C5 "" */ + 0x0, 0xff, 0xf7, 0x47, 0x4f, 0xff, 0x47, 0xf8, + 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xf8, 0xff, + 0xff, 0xff, 0x8f, 0xff, 0xff, 0xfb, 0x78, 0x88, + 0x7f, 0xff, 0xff, 0x0, + + /* U+F0C7 "" */ + 0x24, 0x44, 0x41, 0xf, 0xbb, 0xbb, 0xe2, 0xf0, + 0x0, 0xf, 0xdf, 0x44, 0x44, 0xff, 0xff, 0xfc, + 0xff, 0xff, 0xf9, 0x9, 0xff, 0xff, 0xd5, 0xdf, + 0xf8, 0xbb, 0xbb, 0xb8, + + /* U+F0E7 "" */ + 0x7, 0xff, 0x60, 0x0, 0xaf, 0xf2, 0x0, 0xc, + 0xff, 0x87, 0x0, 0xef, 0xff, 0xb0, 0x7, 0x8e, + 0xf2, 0x0, 0x0, 0xf8, 0x0, 0x0, 0x3e, 0x0, + 0x0, 0x6, 0x50, 0x0, + + /* U+F0EA "" */ + 0x79, 0xb9, 0x70, 0xf, 0xfc, 0xff, 0x0, 0xff, + 0x68, 0x83, 0xf, 0xf8, 0xff, 0x8b, 0xff, 0x8f, + 0xf8, 0x8f, 0xf8, 0xff, 0xff, 0x78, 0x8f, 0xff, + 0xf0, 0x7, 0xff, 0xff, + + /* U+F0F3 "" */ + 0x0, 0xd, 0x0, 0x0, 0x4e, 0xfe, 0x30, 0xd, + 0xff, 0xfd, 0x0, 0xff, 0xff, 0xf0, 0x3f, 0xff, + 0xff, 0x3b, 0xff, 0xff, 0xfb, 0x78, 0x88, 0x88, + 0x60, 0x4, 0xf4, 0x0, + + /* U+F11C "" */ + 0xdf, 0xff, 0xff, 0xff, 0xdf, 0x18, 0x81, 0x88, + 0x1f, 0xfe, 0xaa, 0xca, 0xae, 0xff, 0xea, 0xac, + 0xaa, 0xef, 0xf1, 0x80, 0x0, 0x81, 0xfd, 0xff, + 0xff, 0xff, 0xfd, + + /* U+F124 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4b, 0xc0, 0x0, 0x0, 0x5c, 0xff, 0xb0, 0x0, + 0x6e, 0xff, 0xff, 0x40, 0xd, 0xff, 0xff, 0xfc, + 0x0, 0x6, 0x88, 0xcf, 0xf5, 0x0, 0x0, 0x0, + 0x8f, 0xe0, 0x0, 0x0, 0x0, 0x8f, 0x60, 0x0, + 0x0, 0x0, 0x5d, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+F15B "" */ + 0xff, 0xf8, 0xb0, 0xff, 0xf8, 0xfb, 0xff, 0xfc, + 0x88, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + + /* U+F1EB "" */ + 0x0, 0x4, 0x77, 0x40, 0x0, 0x9, 0xff, 0xcc, + 0xff, 0x90, 0xcd, 0x40, 0x0, 0x4, 0xdc, 0x20, + 0x4b, 0xff, 0xb4, 0x2, 0x1, 0xfa, 0x55, 0xaf, + 0x10, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, 0x0, + 0xee, 0x0, 0x0, 0x0, 0x0, 0x87, 0x0, 0x0, + + /* U+F240 "" */ + 0x24, 0x44, 0x44, 0x44, 0x40, 0xfb, 0xbb, 0xbb, + 0xbb, 0xda, 0xf7, 0xee, 0xee, 0xee, 0x5f, 0xf8, + 0xff, 0xff, 0xff, 0x2f, 0xf5, 0x66, 0x66, 0x66, + 0xab, 0x8b, 0xbb, 0xbb, 0xbb, 0xb3, + + /* U+F241 "" */ + 0x24, 0x44, 0x44, 0x44, 0x40, 0xfb, 0xbb, 0xbb, + 0xbb, 0xda, 0xf7, 0xee, 0xee, 0x70, 0x5f, 0xf8, + 0xff, 0xff, 0x80, 0x2f, 0xf5, 0x66, 0x66, 0x54, + 0xab, 0x8b, 0xbb, 0xbb, 0xbb, 0xb3, + + /* U+F242 "" */ + 0x24, 0x44, 0x44, 0x44, 0x40, 0xfb, 0xbb, 0xbb, + 0xbb, 0xda, 0xf7, 0xee, 0xe0, 0x0, 0x5f, 0xf8, + 0xff, 0xf0, 0x0, 0x2f, 0xf5, 0x66, 0x64, 0x44, + 0xab, 0x8b, 0xbb, 0xbb, 0xbb, 0xb3, + + /* U+F243 "" */ + 0x24, 0x44, 0x44, 0x44, 0x40, 0xfb, 0xbb, 0xbb, + 0xbb, 0xda, 0xf7, 0xe7, 0x0, 0x0, 0x5f, 0xf8, + 0xf8, 0x0, 0x0, 0x2f, 0xf5, 0x65, 0x44, 0x44, + 0xab, 0x8b, 0xbb, 0xbb, 0xbb, 0xb3, + + /* U+F244 "" */ + 0x24, 0x44, 0x44, 0x44, 0x40, 0xfb, 0xbb, 0xbb, + 0xbb, 0xd8, 0xf0, 0x0, 0x0, 0x0, 0x5f, 0xf0, + 0x0, 0x0, 0x0, 0x2f, 0xf4, 0x44, 0x44, 0x44, + 0xad, 0x8b, 0xbb, 0xbb, 0xbb, 0xb3, + + /* U+F287 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, + 0xd8, 0x0, 0x0, 0x0, 0x7, 0x36, 0x40, 0x0, + 0x9, 0xb1, 0x91, 0x11, 0x17, 0x20, 0xef, 0x88, + 0xd8, 0x88, 0xd9, 0x2, 0x20, 0x6, 0x48, 0x70, + 0x0, 0x0, 0x0, 0x6, 0xec, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+F293 "" */ + 0x6, 0xdd, 0xc3, 0x4, 0xff, 0x3e, 0xd0, 0x9c, + 0xb5, 0x5f, 0x2b, 0xf7, 0x1a, 0xf4, 0xbf, 0x81, + 0xbf, 0x39, 0xc9, 0x64, 0xf2, 0x4f, 0xf3, 0xde, + 0x0, 0x6d, 0xed, 0x30, + + /* U+F2ED "" */ + 0x78, 0xdf, 0xd8, 0x77, 0x88, 0x88, 0x87, 0x8f, + 0xff, 0xff, 0x88, 0xcc, 0x8c, 0xc8, 0x8c, 0xc8, + 0xcc, 0x88, 0xcc, 0x8c, 0xc8, 0x8c, 0xc8, 0xcc, + 0x85, 0xff, 0xff, 0xf5, + + /* U+F304 "" */ + 0x0, 0x0, 0x0, 0x7e, 0x30, 0x0, 0x0, 0x4b, + 0xfe, 0x0, 0x0, 0x8f, 0x9b, 0x70, 0x0, 0x8f, + 0xff, 0x40, 0x0, 0x8f, 0xff, 0x80, 0x0, 0x7f, + 0xff, 0x80, 0x0, 0xe, 0xff, 0x80, 0x0, 0x0, + 0xee, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+F55A "" */ + 0x0, 0xaf, 0xff, 0xff, 0xfc, 0xb, 0xff, 0x9c, + 0xc9, 0xff, 0xaf, 0xff, 0xc1, 0x1c, 0xff, 0xaf, + 0xff, 0xc1, 0x1c, 0xff, 0xb, 0xff, 0x9c, 0xc9, + 0xff, 0x0, 0xaf, 0xff, 0xff, 0xfc, + + /* U+F7C2 "" */ + 0x7, 0xff, 0xfe, 0x17, 0xb6, 0x27, 0xc3, 0xfe, + 0xb9, 0xbe, 0x3f, 0xff, 0xff, 0xf3, 0xff, 0xff, + 0xff, 0x3f, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, + 0x3c, 0xff, 0xff, 0xe1, + + /* U+F8A2 "" */ + 0x0, 0x0, 0x0, 0x3, 0x0, 0x23, 0x0, 0x2, + 0xf0, 0x2e, 0x92, 0x22, 0x5f, 0xd, 0xff, 0xff, + 0xff, 0xf0, 0x2e, 0x92, 0x22, 0x21, 0x0, 0x23, + 0x0, 0x0, 0x0 +}; + + +/*--------------------- + * GLYPH DESCRIPTION + *--------------------*/ + +static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { + {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */, + {.bitmap_index = 0, .adv_w = 34, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 0, .adv_w = 34, .box_w = 2, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 5, .adv_w = 50, .box_w = 3, .box_h = 3, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 10, .adv_w = 90, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 25, .adv_w = 79, .box_w = 5, .box_h = 7, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 43, .adv_w = 108, .box_w = 7, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 61, .adv_w = 88, .box_w = 6, .box_h = 6, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 79, .adv_w = 27, .box_w = 2, .box_h = 3, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 82, .adv_w = 43, .box_w = 3, .box_h = 7, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 93, .adv_w = 43, .box_w = 2, .box_h = 7, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 100, .adv_w = 51, .box_w = 4, .box_h = 3, .ofs_x = 0, .ofs_y = 3}, + {.bitmap_index = 106, .adv_w = 74, .box_w = 5, .box_h = 4, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 116, .adv_w = 29, .box_w = 2, .box_h = 3, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 119, .adv_w = 49, .box_w = 3, .box_h = 1, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 121, .adv_w = 29, .box_w = 2, .box_h = 2, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 123, .adv_w = 45, .box_w = 5, .box_h = 7, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 141, .adv_w = 85, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 154, .adv_w = 47, .box_w = 3, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 162, .adv_w = 73, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 175, .adv_w = 73, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 188, .adv_w = 86, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 203, .adv_w = 73, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 216, .adv_w = 79, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 229, .adv_w = 77, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 242, .adv_w = 82, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 255, .adv_w = 79, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 268, .adv_w = 29, .box_w = 2, .box_h = 4, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 272, .adv_w = 29, .box_w = 2, .box_h = 6, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 278, .adv_w = 74, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 291, .adv_w = 74, .box_w = 5, .box_h = 3, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 299, .adv_w = 74, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 312, .adv_w = 73, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 325, .adv_w = 132, .box_w = 8, .box_h = 6, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 349, .adv_w = 94, .box_w = 7, .box_h = 5, .ofs_x = -1, .ofs_y = 0}, + {.bitmap_index = 367, .adv_w = 97, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 382, .adv_w = 93, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 397, .adv_w = 106, .box_w = 7, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 415, .adv_w = 86, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 428, .adv_w = 81, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 441, .adv_w = 99, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 456, .adv_w = 104, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 471, .adv_w = 40, .box_w = 2, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 476, .adv_w = 66, .box_w = 5, .box_h = 5, .ofs_x = -1, .ofs_y = 0}, + {.bitmap_index = 489, .adv_w = 92, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 504, .adv_w = 76, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 517, .adv_w = 122, .box_w = 7, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 535, .adv_w = 104, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 550, .adv_w = 108, .box_w = 7, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 568, .adv_w = 92, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 583, .adv_w = 108, .box_w = 7, .box_h = 6, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 604, .adv_w = 93, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 619, .adv_w = 79, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 632, .adv_w = 75, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 645, .adv_w = 101, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 660, .adv_w = 91, .box_w = 7, .box_h = 5, .ofs_x = -1, .ofs_y = 0}, + {.bitmap_index = 678, .adv_w = 144, .box_w = 9, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 701, .adv_w = 86, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 716, .adv_w = 83, .box_w = 7, .box_h = 5, .ofs_x = -1, .ofs_y = 0}, + {.bitmap_index = 734, .adv_w = 84, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 749, .adv_w = 43, .box_w = 3, .box_h = 7, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 760, .adv_w = 45, .box_w = 5, .box_h = 7, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 778, .adv_w = 43, .box_w = 2, .box_h = 7, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 785, .adv_w = 75, .box_w = 5, .box_h = 3, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 793, .adv_w = 64, .box_w = 4, .box_h = 1, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 795, .adv_w = 77, .box_w = 3, .box_h = 1, .ofs_x = 0, .ofs_y = 5}, + {.bitmap_index = 797, .adv_w = 77, .box_w = 5, .box_h = 4, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 807, .adv_w = 87, .box_w = 6, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 825, .adv_w = 73, .box_w = 5, .box_h = 4, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 835, .adv_w = 87, .box_w = 5, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 850, .adv_w = 78, .box_w = 5, .box_h = 4, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 860, .adv_w = 45, .box_w = 4, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 872, .adv_w = 88, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 885, .adv_w = 87, .box_w = 5, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 900, .adv_w = 36, .box_w = 2, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 906, .adv_w = 36, .box_w = 3, .box_h = 7, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 917, .adv_w = 79, .box_w = 5, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 932, .adv_w = 36, .box_w = 2, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 938, .adv_w = 135, .box_w = 8, .box_h = 4, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 954, .adv_w = 87, .box_w = 5, .box_h = 4, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 964, .adv_w = 81, .box_w = 5, .box_h = 4, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 974, .adv_w = 87, .box_w = 6, .box_h = 5, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 989, .adv_w = 87, .box_w = 5, .box_h = 5, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1002, .adv_w = 52, .box_w = 4, .box_h = 4, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1010, .adv_w = 64, .box_w = 4, .box_h = 4, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1018, .adv_w = 53, .box_w = 4, .box_h = 5, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1028, .adv_w = 87, .box_w = 5, .box_h = 4, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1038, .adv_w = 72, .box_w = 6, .box_h = 4, .ofs_x = -1, .ofs_y = 0}, + {.bitmap_index = 1050, .adv_w = 115, .box_w = 8, .box_h = 4, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1066, .adv_w = 71, .box_w = 5, .box_h = 4, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1076, .adv_w = 72, .box_w = 6, .box_h = 5, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 1091, .adv_w = 67, .box_w = 4, .box_h = 4, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1099, .adv_w = 45, .box_w = 3, .box_h = 7, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1110, .adv_w = 38, .box_w = 2, .box_h = 7, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1117, .adv_w = 45, .box_w = 3, .box_h = 7, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1128, .adv_w = 74, .box_w = 5, .box_h = 2, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 1133, .adv_w = 54, .box_w = 3, .box_h = 3, .ofs_x = 0, .ofs_y = 3}, + {.bitmap_index = 1138, .adv_w = 40, .box_w = 2, .box_h = 3, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 1141, .adv_w = 128, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1177, .adv_w = 128, .box_w = 8, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1201, .adv_w = 128, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1233, .adv_w = 128, .box_w = 8, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1257, .adv_w = 88, .box_w = 6, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1275, .adv_w = 128, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1307, .adv_w = 128, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1339, .adv_w = 144, .box_w = 9, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1375, .adv_w = 128, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1407, .adv_w = 144, .box_w = 9, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1434, .adv_w = 128, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 1474, .adv_w = 64, .box_w = 4, .box_h = 7, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1488, .adv_w = 96, .box_w = 6, .box_h = 7, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1509, .adv_w = 144, .box_w = 9, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1545, .adv_w = 128, .box_w = 8, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1569, .adv_w = 112, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1589, .adv_w = 112, .box_w = 7, .box_h = 10, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 1624, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1652, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1680, .adv_w = 112, .box_w = 5, .box_h = 8, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 1700, .adv_w = 112, .box_w = 9, .box_h = 8, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 1736, .adv_w = 80, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1756, .adv_w = 80, .box_w = 5, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1776, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1804, .adv_w = 112, .box_w = 7, .box_h = 2, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 1811, .adv_w = 144, .box_w = 9, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1838, .adv_w = 160, .box_w = 11, .box_h = 8, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 1882, .adv_w = 144, .box_w = 11, .box_h = 8, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 1926, .adv_w = 128, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1958, .adv_w = 112, .box_w = 7, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1979, .adv_w = 112, .box_w = 7, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2000, .adv_w = 160, .box_w = 11, .box_h = 7, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 2039, .adv_w = 128, .box_w = 8, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2063, .adv_w = 128, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2095, .adv_w = 128, .box_w = 9, .box_h = 9, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 2136, .adv_w = 112, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2168, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2196, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2224, .adv_w = 80, .box_w = 7, .box_h = 8, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 2252, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2280, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2308, .adv_w = 144, .box_w = 9, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2335, .adv_w = 128, .box_w = 10, .box_h = 10, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 2385, .adv_w = 96, .box_w = 6, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2409, .adv_w = 160, .box_w = 10, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2449, .adv_w = 160, .box_w = 10, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2479, .adv_w = 160, .box_w = 10, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2509, .adv_w = 160, .box_w = 10, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2539, .adv_w = 160, .box_w = 10, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2569, .adv_w = 160, .box_w = 10, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2599, .adv_w = 160, .box_w = 11, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2643, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2671, .adv_w = 112, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2699, .adv_w = 128, .box_w = 9, .box_h = 9, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 2740, .adv_w = 160, .box_w = 10, .box_h = 6, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2770, .adv_w = 96, .box_w = 7, .box_h = 8, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 2798, .adv_w = 129, .box_w = 9, .box_h = 6, .ofs_x = 0, .ofs_y = 0} +}; + +/*--------------------- + * CHARACTER MAPPING + *--------------------*/ + +static const uint16_t unicode_list_1[] = { + 0x0, 0x1f72, 0xef51, 0xef58, 0xef5b, 0xef5c, 0xef5d, 0xef61, + 0xef63, 0xef65, 0xef69, 0xef6c, 0xef71, 0xef76, 0xef77, 0xef78, + 0xef8e, 0xef98, 0xef9b, 0xef9c, 0xef9d, 0xefa1, 0xefa2, 0xefa3, + 0xefa4, 0xefb7, 0xefb8, 0xefbe, 0xefc0, 0xefc1, 0xefc4, 0xefc7, + 0xefc8, 0xefc9, 0xefcb, 0xefe3, 0xefe5, 0xf014, 0xf015, 0xf017, + 0xf037, 0xf03a, 0xf043, 0xf06c, 0xf074, 0xf0ab, 0xf13b, 0xf190, + 0xf191, 0xf192, 0xf193, 0xf194, 0xf1d7, 0xf1e3, 0xf23d, 0xf254, + 0xf4aa, 0xf712, 0xf7f2 +}; + +/*Collect the unicode lists and glyph_id offsets*/ +static const lv_font_fmt_txt_cmap_t cmaps[] = +{ + { + .range_start = 32, .range_length = 95, .glyph_id_start = 1, + .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY + }, + { + .range_start = 176, .range_length = 63475, .glyph_id_start = 96, + .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 59, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + } +}; + +/*----------------- + * KERNING + *----------------*/ + + +/*Map glyph_ids to kern left classes*/ +static const uint8_t kern_left_class_mapping[] = +{ + 0, 0, 1, 2, 0, 3, 4, 5, + 2, 6, 7, 8, 9, 10, 9, 10, + 11, 12, 0, 13, 14, 15, 16, 17, + 18, 19, 12, 20, 20, 0, 0, 0, + 21, 22, 23, 24, 25, 22, 26, 27, + 28, 29, 29, 30, 31, 32, 29, 29, + 22, 33, 34, 35, 3, 36, 30, 37, + 37, 38, 39, 40, 41, 42, 43, 0, + 44, 0, 45, 46, 47, 48, 49, 50, + 51, 45, 52, 52, 53, 48, 45, 45, + 46, 46, 54, 55, 56, 57, 51, 58, + 58, 59, 58, 60, 41, 0, 0, 9, + 61, 9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0 +}; + +/*Map glyph_ids to kern right classes*/ +static const uint8_t kern_right_class_mapping[] = +{ + 0, 0, 1, 2, 0, 3, 4, 5, + 2, 6, 7, 8, 9, 10, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 12, + 18, 19, 20, 21, 21, 0, 0, 0, + 22, 23, 24, 25, 23, 25, 25, 25, + 23, 25, 25, 26, 25, 25, 25, 25, + 23, 25, 23, 25, 3, 27, 28, 29, + 29, 30, 31, 32, 33, 34, 35, 0, + 36, 0, 37, 38, 39, 39, 39, 0, + 39, 38, 40, 41, 38, 38, 42, 42, + 39, 42, 39, 42, 43, 44, 45, 46, + 46, 47, 46, 48, 0, 0, 35, 9, + 49, 9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0 +}; + +/*Kern values between classes*/ +static const int8_t kern_class_values[] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 3, -3, 0, 0, + 0, 0, -7, -8, 1, 6, 3, 2, + -5, 1, 6, 0, 5, 1, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 8, 1, -1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, -4, 0, 0, 0, 0, + 0, -3, 2, 3, 0, 0, -1, 0, + -1, 1, 0, -1, 0, -1, -1, -3, + 0, 0, 0, 0, -1, 0, 0, -2, + -2, 0, 0, -1, 0, -3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -1, + -1, 0, -2, 0, -3, 0, -15, 0, + 0, -3, 0, 3, 4, 0, 0, -3, + 1, 1, 4, 3, -2, 3, 0, 0, + -7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -3, -2, -6, 0, -5, + -1, 0, 0, 0, 0, 0, 5, 0, + -4, -1, 0, 0, 0, -2, 0, 0, + -1, -9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -10, -1, 5, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 4, + 0, 1, 0, 0, -3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, + 3, 1, 4, -1, 0, 0, 3, -1, + -4, -18, 1, 3, 3, 0, -2, 0, + 5, 0, 4, 0, 4, 0, -12, 0, + -2, 4, 0, 4, -1, 3, 1, 0, + 0, 0, -1, 0, 0, -2, 10, 0, + 10, 0, 4, 0, 5, 2, 2, 4, + 0, 0, 0, -5, 0, 0, 0, 0, + 0, -1, 0, 1, -2, -2, -3, 1, + 0, -1, 0, 0, 0, -5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -8, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -7, 0, -8, 0, 0, 0, + 0, -1, 0, 13, -2, -2, 1, 1, + -1, 0, -2, 1, 0, 0, -7, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -12, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -8, 0, 8, 0, 0, -5, 0, + 4, 0, -9, -12, -9, -3, 4, 0, + 0, -9, 0, 2, -3, 0, -2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3, 4, -16, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 1, 0, 0, 0, + 0, 0, 1, 1, -2, -3, 0, 0, + 0, -1, 0, 0, -1, 0, 0, 0, + -3, 0, -1, 0, -3, -3, 0, -3, + -4, -4, -2, 0, -3, 0, -3, 0, + 0, 0, 0, -1, 0, 0, 1, 0, + 1, -1, 0, 0, 0, 0, 0, 1, + -1, 0, 0, 0, -1, 1, 1, 0, + 0, 0, 0, -2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, -1, 0, + -2, 0, -2, 0, 0, -1, 0, 4, + 0, 0, -1, 0, 0, 0, 0, 0, + 0, 0, -1, -1, 0, 0, -1, 0, + -1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -1, -1, 0, -1, -2, 0, + 0, 0, 0, 0, 0, 0, 0, -1, + 0, -1, -1, -1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -1, 0, 0, + 0, 0, -1, -2, 0, -2, 0, -4, + -1, -4, 3, 0, 0, -3, 1, 3, + 3, 0, -3, 0, -2, 0, 0, -6, + 1, -1, 1, -7, 1, 0, 0, 0, + -7, 0, -7, -1, -11, -1, 0, -6, + 0, 3, 4, 0, 2, 0, 0, 0, + 0, 0, 0, -2, -2, 0, -4, 0, + 0, 0, -1, 0, 0, 0, -1, 0, + 0, 0, 0, 0, -1, -1, 0, -1, + -2, 0, 0, 0, 0, 0, 0, 0, + -1, -1, 0, -1, -2, -1, 0, 0, + -1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -1, -1, 0, -2, + 0, -1, 0, -3, 1, 0, 0, -2, + 1, 1, 1, 0, 0, 0, 0, 0, + 0, -1, 0, 0, 0, 0, 0, 1, + 0, 0, -1, 0, -1, -1, -2, 0, + 0, 0, 0, 0, 0, 0, 1, 0, + -1, 0, 0, 0, 0, -1, -2, 0, + -2, 0, 4, -1, 0, -4, 0, 0, + 3, -6, -7, -5, -3, 1, 0, -1, + -8, -2, 0, -2, 0, -3, 2, -2, + -8, 0, -3, 0, 0, 1, 0, 1, + -1, 0, 1, 0, -4, -5, 0, -6, + -3, -3, -3, -4, -2, -3, 0, -2, + -3, 1, 0, 0, 0, -1, 0, 0, + 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -1, + 0, -1, 0, 0, -1, 0, -2, -3, + -3, 0, 0, -4, 0, 0, 0, 0, + 0, 0, -1, 0, 0, 0, 0, 1, + -1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, + -1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -2, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -1, 0, 0, 0, + -2, 0, 0, 0, 0, -6, -4, 0, + 0, 0, -2, -6, 0, 0, -1, 1, + 0, -3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -2, 0, 0, -2, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, -2, 0, + 0, 0, 0, 2, 0, 1, -3, -3, + 0, -1, -1, -2, 0, 0, 0, 0, + 0, 0, -4, 0, -1, 0, -2, -1, + 0, -3, -3, -4, -1, 0, -3, 0, + -4, 0, 0, 0, 0, 10, 0, 0, + 1, 0, 0, -2, 0, 1, 0, -6, + 0, 0, 0, 0, 0, -12, -2, 4, + 4, -1, -5, 0, 1, -2, 0, -6, + -1, -2, 1, -9, -1, 2, 0, 2, + -4, -2, -5, -4, -5, 0, 0, -8, + 0, 7, 0, 0, -1, 0, 0, 0, + -1, -1, -1, -3, -4, 0, -12, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -1, 0, -1, -1, -2, 0, 0, + -3, 0, -1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -3, 0, 0, 3, + 0, 2, 0, -3, 1, -1, 0, -3, + -1, 0, -2, -1, -1, 0, -2, -2, + 0, 0, -1, 0, -1, -2, -2, 0, + 0, -1, 0, 1, -1, 0, -3, 0, + 0, 0, -3, 0, -2, 0, -2, -2, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, -3, 1, 0, -2, 0, -1, -2, + -4, -1, -1, -1, 0, -1, -2, 0, + 0, 0, 0, 0, 0, -1, -1, -1, + 0, 0, 0, 0, 2, -1, 0, -1, + 0, 0, 0, -1, -2, -1, -1, -2, + -1, 0, 1, 5, 0, 0, -3, 0, + -1, 3, 0, -1, -5, -2, 2, 0, + 0, -6, -2, 1, -2, 1, 0, -1, + -1, -4, 0, -2, 1, 0, 0, -2, + 0, 0, 0, 1, 1, -3, -2, 0, + -2, -1, -2, -1, -1, 0, -2, 1, + -2, -2, 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -1, -1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -2, 0, 0, -2, + 0, 0, -1, -1, 0, 0, 0, 0, + -1, 0, 0, 0, 0, -1, 0, 0, + 0, 0, 0, -1, 0, 0, 0, 0, + -2, 0, -3, 0, 0, 0, -4, 0, + 1, -3, 3, 0, -1, -6, 0, 0, + -3, -1, 0, -5, -3, -4, 0, 0, + -6, -1, -5, -5, -6, 0, -3, 0, + 1, 9, -2, 0, -3, -1, 0, -1, + -2, -3, -2, -5, -5, -3, -1, 0, + 0, -1, 0, 0, 0, 0, -9, -1, + 4, 3, -3, -5, 0, 0, -4, 0, + -6, -1, -1, 3, -12, -2, 0, 0, + 0, -8, -2, -7, -1, -9, 0, 0, + -9, 0, 8, 0, 0, -1, 0, 0, + 0, 0, -1, -1, -5, -1, 0, -8, + 0, 0, 0, 0, -4, 0, -1, 0, + 0, -4, -6, 0, 0, -1, -2, -4, + -1, 0, -1, 0, 0, 0, 0, -6, + -1, -4, -4, -1, -2, -3, -1, -2, + 0, -3, -1, -4, -2, 0, -2, -2, + -1, -2, 0, 1, 0, -1, -4, 0, + 3, 0, -2, 0, 0, 0, 0, 2, + 0, 1, -3, 5, 0, -1, -1, -2, + 0, 0, 0, 0, 0, 0, -4, 0, + -1, 0, -2, -1, 0, -3, -3, -4, + -1, 0, -3, 1, 5, 0, 0, 0, + 0, 10, 0, 0, 1, 0, 0, -2, + 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -1, -3, 0, 0, 0, 0, 0, -1, + 0, 0, 0, -1, -1, 0, 0, -3, + -1, 0, 0, -3, 0, 2, -1, 0, + 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 2, 3, 1, -1, 0, -4, + -2, 0, 4, -4, -4, -3, -3, 5, + 2, 1, -11, -1, 3, -1, 0, -1, + 1, -1, -4, 0, -1, 1, -2, -1, + -4, -1, 0, 0, 4, 3, 0, -4, + 0, -7, -2, 4, -2, -5, 0, -2, + -4, -4, -1, 5, 1, 0, -2, 0, + -3, 0, 1, 4, -3, -5, -5, -3, + 4, 0, 0, -9, -1, 1, -2, -1, + -3, 0, -3, -5, -2, -2, -1, 0, + 0, -3, -3, -1, 0, 4, 3, -1, + -7, 0, -7, -2, 0, -4, -7, 0, + -4, -2, -4, -4, 3, 0, 0, -2, + 0, -3, -1, 0, -1, -2, 0, 2, + -4, 1, 0, 0, -7, 0, -1, -3, + -2, -1, -4, -3, -4, -3, 0, -4, + -1, -3, -2, -4, -1, 0, 0, 0, + 6, -2, 0, -4, -1, 0, -1, -3, + -3, -3, -4, -5, -2, -3, 3, 0, + -2, 0, -6, -2, 1, 3, -4, -5, + -3, -4, 4, -1, 1, -12, -2, 3, + -3, -2, -5, 0, -4, -5, -2, -1, + -1, -1, -3, -4, 0, 0, 0, 4, + 4, -1, -8, 0, -8, -3, 3, -5, + -9, -3, -4, -5, -6, -4, 3, 0, + 0, 0, 0, -2, 0, 0, 1, -2, + 3, 1, -2, 3, 0, 0, -4, 0, + 0, 0, 0, 0, 0, -1, 0, 0, + 0, 0, 0, 0, -1, 0, 0, 0, + 0, 1, 4, 0, 0, -2, 0, 0, + 0, 0, -1, -1, -2, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 1, 0, + -1, 0, 5, 0, 2, 0, 0, -2, + 0, 3, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4, 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -8, 0, -1, 2, 0, 4, + 0, 0, 13, 2, -3, -3, 1, 1, + -1, 0, -6, 0, 0, 6, -8, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -9, 5, 18, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -8, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -2, 0, 0, -2, + -1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -1, 0, -3, 0, + 0, 0, 0, 0, 1, 17, -3, -1, + 4, 3, -3, 1, 0, 0, 1, 1, + -2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -17, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -4, + 0, 0, 0, -3, 0, 0, 0, 0, + -3, -1, 0, 0, 0, -3, 0, -2, + 0, -6, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -1, 0, 0, -2, 0, -2, 0, + -3, 0, 0, 0, -2, 1, -2, 0, + 0, -3, -1, -3, 0, 0, -3, 0, + -1, 0, -6, 0, -1, 0, 0, -10, + -2, -5, -1, -5, 0, 0, -9, 0, + -3, -1, 0, 0, 0, 0, 0, 0, + 0, 0, -2, -2, -1, -2, 0, 0, + 0, 0, -3, 0, -3, 2, -1, 3, + 0, -1, -3, -1, -2, -2, 0, -2, + -1, -1, 1, -3, 0, 0, 0, 0, + -11, -1, -2, 0, -3, 0, -1, -6, + -1, 0, 0, -1, -1, 0, 0, 0, + 0, 1, 0, -1, -2, -1, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 0, + 0, -3, 0, -1, 0, 0, 0, -3, + 1, 0, 0, 0, -3, -1, -3, 0, + 0, -4, 0, -1, 0, -6, 0, 0, + 0, 0, -12, 0, -3, -5, -6, 0, + 0, -9, 0, -1, -2, 0, 0, 0, + 0, 0, 0, 0, 0, -1, -2, -1, + -2, 0, 0, 0, 2, -2, 0, 4, + 6, -1, -1, -4, 2, 6, 2, 3, + -3, 2, 5, 2, 4, 3, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 8, 6, -2, -1, 0, -1, + 10, 6, 10, 0, 0, 0, 1, 0, + 0, 5, 0, 0, -2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -1, 0, + 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, -11, -2, -1, -5, + -6, 0, 0, -9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -1, + 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, -11, -2, -1, + -5, -6, 0, 0, -5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -1, 0, 0, 0, -3, 1, 0, -1, + 1, 2, 1, -4, 0, 0, -1, 1, + 0, 1, 0, 0, 0, 0, -3, 0, + -1, -1, -3, 0, -1, -5, 0, 8, + -1, 0, -3, -1, 0, -1, -2, 0, + -1, -4, -3, -2, 0, 0, 0, -2, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -1, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, -11, + -2, -1, -5, -6, 0, 0, -9, 0, + 0, 0, 0, 0, 0, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -2, 0, -4, -2, -1, 4, -1, -1, + -5, 0, -1, 0, -1, -3, 0, 3, + 0, 1, 0, 1, -3, -5, -2, 0, + -5, -2, -3, -5, -5, 0, -2, -3, + -2, -2, -1, -1, -2, -1, 0, -1, + 0, 2, 0, 2, -1, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -1, -1, -1, 0, 0, + -3, 0, -1, 0, -2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -8, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -1, -1, 0, -2, + 0, 0, 0, 0, -1, 0, 0, -2, + -1, 1, 0, -2, -2, -1, 0, -4, + -1, -3, -1, -2, 0, -2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, -9, 0, 4, 0, 0, -2, 0, + 0, 0, 0, -2, 0, -1, 0, 0, + -1, 0, 0, -1, 0, -3, 0, 0, + 5, -2, -4, -4, 1, 1, 1, 0, + -4, 1, 2, 1, 4, 1, 4, -1, + -3, 0, 0, -5, 0, 0, -4, -3, + 0, 0, -3, 0, -2, -2, 0, -2, + 0, -2, 0, -1, 2, 0, -1, -4, + -1, 5, 0, 0, -1, 0, -3, 0, + 0, 2, -3, 0, 1, -1, 1, 0, + 0, -4, 0, -1, 0, 0, -1, 1, + -1, 0, 0, 0, -5, -2, -3, 0, + -4, 0, 0, -6, 0, 5, -1, 0, + -2, 0, 1, 0, -1, 0, -1, -4, + 0, -1, 1, 0, 0, 0, 0, -1, + 0, 0, 1, -2, 0, 0, 0, -2, + -1, 0, -2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -8, 0, 3, 0, + 0, -1, 0, 0, 0, 0, 0, 0, + -1, -1, 0, 0, 0, 3, 0, 3, + 0, 0, 0, 0, 0, -8, -7, 0, + 6, 4, 2, -5, 1, 5, 0, 5, + 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 +}; + + +/*Collect the kern class' data in one place*/ +static const lv_font_fmt_txt_kern_classes_t kern_classes = +{ + .class_pair_values = kern_class_values, + .left_class_mapping = kern_left_class_mapping, + .right_class_mapping = kern_right_class_mapping, + .left_class_cnt = 61, + .right_class_cnt = 49, +}; + +/*-------------------- + * ALL CUSTOM DATA + *--------------------*/ + +/*Store all the custom data of the font*/ +static lv_font_fmt_txt_dsc_t font_dsc = { + .glyph_bitmap = gylph_bitmap, + .glyph_dsc = glyph_dsc, + .cmaps = cmaps, + .kern_dsc = &kern_classes, + .kern_scale = 16, + .cmap_num = 2, + .bpp = 4, + .kern_classes = 1, + .bitmap_format = 0 +}; + + +/*----------------- + * PUBLIC FONT + *----------------*/ + +/*Initialize a public general font descriptor*/ +lv_font_t font_2 = { + .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ + .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ + .line_height = 10, /*The maximum line height required by the font*/ + .base_line = 2, /*Baseline measured from the bottom of the line*/ +#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) + .subpx = LV_FONT_SUBPX_NONE, +#endif + .dsc = &font_dsc /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ +}; + +#endif /*#if FONT_2*/ + diff --git a/tests/lv_test_fonts/font_3.c b/tests/lv_test_fonts/font_3.c new file mode 100644 index 000000000..923affa1d --- /dev/null +++ b/tests/lv_test_fonts/font_3.c @@ -0,0 +1,953 @@ +#include "lvgl/lvgl.h" + +/******************************************************************************* + * Size: 20 px + * Bpp: 4 + * Opts: --bpp 4 --size 20 --font ../RobotoMono-Regular.ttf -r 0x20-0x7f --format lvgl -o ..\generated_fonts/font_3.c + ******************************************************************************/ + +#ifndef FONT_3 +#define FONT_3 1 +#endif + +#if FONT_3 + +/*----------------- + * BITMAPS + *----------------*/ + +/*Store the image of the glyphs*/ +static LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = { + /* U+20 " " */ + + /* U+21 "!" */ + 0x1f, 0xb0, 0xf, 0xfe, 0x69, 0x10, 0x76, 0x40, + 0x30, 0x81, 0x76, 0x98, 0xb0, + + /* U+22 "\"" */ + 0x8e, 0x0, 0x7b, 0x0, 0x7c, 0x60, 0x11, 0x80, + 0x80, 0x43, 0xca, 0x0, 0x37, + + /* U+23 "#" */ + 0x0, 0xc5, 0xe6, 0x7, 0xe6, 0x1, 0xc8, 0x6, + 0xa, 0x6, 0x1, 0xde, 0x40, 0xf, 0x30, 0xf, + 0x2a, 0x0, 0x15, 0x40, 0x15, 0x7f, 0x8d, 0xbf, + 0xc6, 0xde, 0xe1, 0xd2, 0xe0, 0xf2, 0xe0, 0xf2, + 0x80, 0x8d, 0x81, 0x2d, 0xa1, 0x2c, 0x60, 0x11, + 0x88, 0x80, 0x84, 0x40, 0x1d, 0xc4, 0x0, 0xd2, + 0x0, 0xc2, 0x25, 0x61, 0x13, 0x30, 0x40, 0xd, + 0xdc, 0x35, 0xee, 0x1a, 0xf6, 0x3, 0xdd, 0x4, + 0x5c, 0x84, 0xdf, 0x80, 0xa0, 0x1, 0x90, 0xc1, + 0x90, 0xc0, 0x2d, 0x21, 0xd, 0x20, 0xf, 0x1b, + 0x80, 0x11, 0x0, 0x18, + + /* U+24 "$" */ + 0x0, 0xcb, 0xe2, 0x1, 0xff, 0xc4, 0x78, 0xb, + 0x40, 0xd, 0xb0, 0x64, 0xb6, 0xe0, 0x8, 0x27, + 0xed, 0xd0, 0xc0, 0x82, 0x4, 0x0, 0xa, 0x41, + 0xc0, 0x40, 0x38, 0xc8, 0x0, 0xe0, 0xe0, 0x12, + 0x6b, 0x5, 0x84, 0x5a, 0x0, 0x70, 0xe9, 0xa5, + 0xea, 0x80, 0x62, 0xcc, 0x29, 0x54, 0x80, 0x71, + 0xd6, 0x93, 0x21, 0x29, 0x0, 0x45, 0x21, 0xaf, + 0x4a, 0x1, 0x9c, 0xd, 0x2, 0x44, 0x2, 0xa0, + 0xd1, 0x71, 0xf8, 0x86, 0x31, 0x38, 0x44, 0x9b, + 0xb8, 0x97, 0x0, 0x26, 0xd6, 0x1e, 0xa1, 0x0, + 0xe1, 0x0, 0xe0, + + /* U+25 "%" */ + 0x7, 0xee, 0x40, 0x7, 0xc9, 0x10, 0xb7, 0x50, + 0xf, 0x61, 0x32, 0xa7, 0x80, 0xf1, 0x80, 0x42, + 0x1, 0xd2, 0x66, 0x0, 0x69, 0x98, 0x97, 0x45, + 0xe0, 0x2, 0x55, 0x66, 0xab, 0xc1, 0x28, 0x6, + 0xae, 0xe5, 0x8b, 0x48, 0x7, 0x84, 0x41, 0x6, + 0x80, 0x1f, 0x89, 0xa0, 0x3, 0xfa, 0x11, 0x13, + 0xdc, 0x70, 0xc, 0x6b, 0xc, 0xca, 0x88, 0x20, + 0x5, 0x8, 0x78, 0xa8, 0xc5, 0x80, 0x13, 0x40, + 0x7, 0xfb, 0x4c, 0x31, 0x51, 0x8b, 0x0, 0x3c, + 0xcc, 0xa8, 0x82, 0x0, + + /* U+26 "&" */ + 0x0, 0x26, 0x7e, 0xb0, 0x7, 0x15, 0x9b, 0xc, + 0xa8, 0x6, 0xa0, 0xa9, 0xc1, 0xe0, 0xc, 0x40, + 0xe0, 0x13, 0x80, 0x63, 0x7, 0x6, 0x1b, 0x0, + 0xd4, 0x12, 0xf2, 0xae, 0x1, 0x8d, 0x8e, 0x1a, + 0x80, 0x38, 0x90, 0x1, 0x40, 0x1c, 0x38, 0x50, + 0x1a, 0x20, 0xbc, 0x70, 0x32, 0xf2, 0x34, 0x1a, + 0x22, 0x40, 0x60, 0x65, 0x47, 0x51, 0x23, 0x10, + 0xa, 0x8a, 0xa, 0x41, 0x5, 0x0, 0x2a, 0x0, + 0x30, 0x40, 0x5d, 0x45, 0xc0, 0x84, 0x1, 0x6a, + 0xa3, 0xb4, 0x71, 0xb2, 0x0, + + /* U+27 "'" */ + 0x2f, 0x50, 0xe, 0x10, 0x3, 0x81, 0x88, + + /* U+28 "(" */ + 0x0, 0xe1, 0x0, 0xd9, 0x20, 0x15, 0x8c, 0x80, + 0x1d, 0x38, 0x40, 0x10, 0xa6, 0x0, 0x70, 0x90, + 0xa, 0xc4, 0xc0, 0x2, 0x68, 0x1, 0x28, 0x68, + 0x4, 0x40, 0x20, 0x10, 0x81, 0x80, 0x70, 0x80, + 0x42, 0x2, 0x1, 0x18, 0x18, 0x4, 0xe1, 0xe0, + 0x11, 0xa, 0x80, 0x67, 0x31, 0x0, 0xac, 0x24, + 0x2, 0x25, 0x60, 0xd, 0x61, 0x40, 0x10, 0xea, + 0xb8, 0x4, 0x7a, 0x80, + + /* U+29 ")" */ + 0x20, 0xe, 0xe9, 0x0, 0xde, 0xd0, 0x1, 0x1c, + 0x39, 0x80, 0x4e, 0x5e, 0x1, 0xa8, 0xcc, 0x1, + 0x28, 0x50, 0x4, 0x42, 0x80, 0x19, 0x48, 0x40, + 0x21, 0x2, 0x0, 0x8c, 0x1c, 0x2, 0x10, 0xe, + 0x10, 0x70, 0x8, 0xc0, 0x80, 0x27, 0x11, 0x0, + 0x44, 0x80, 0x12, 0x87, 0x80, 0x5c, 0x2a, 0x0, + 0x34, 0x80, 0xb, 0x8d, 0x80, 0x14, 0x1a, 0x1, + 0x7e, 0x8, 0x4, + + /* U+2A "*" */ + 0x0, 0xd3, 0xe2, 0x1, 0xf0, 0x80, 0x80, 0x61, + 0x0, 0x78, 0x6, 0x12, 0xeb, 0x41, 0x10, 0x36, + 0xc0, 0xaa, 0xae, 0x47, 0xe4, 0xc0, 0xeb, 0xb0, + 0x0, 0xdb, 0xd2, 0x1, 0x50, 0xab, 0x98, 0x6, + 0x66, 0x45, 0x8d, 0x0, 0x43, 0x24, 0xc3, 0x8, + 0xe0, 0x1, 0xbe, 0x0, 0x3b, 0xc0, + + /* U+2B "+" */ + 0x0, 0xd1, 0x0, 0xf, 0xca, 0xc0, 0x1f, 0xfd, + 0x6d, 0xff, 0x88, 0x7f, 0xee, 0x62, 0x28, 0x0, + 0x45, 0xaf, 0x76, 0x21, 0xdd, 0xb0, 0x3, 0xff, + 0xa4, + + /* U+2C "," */ + 0xa, 0xf4, 0x1, 0x0, 0x9c, 0x18, 0x8, 0x49, + 0x46, 0x1, 0x69, 0x80, + + /* U+2D "-" */ + 0x78, 0x8f, 0x25, 0x3b, 0xfb, 0x40, + + /* U+2E "." */ + 0x8, 0xc3, 0x17, 0x39, 0x14, 0xf, + + /* U+2F "/" */ + 0x0, 0xf6, 0x68, 0x7, 0x88, 0xe8, 0x3, 0xd4, + 0xc, 0x1, 0xe6, 0x41, 0x0, 0xe4, 0x1e, 0x0, + 0xf7, 0x2, 0x80, 0x79, 0x58, 0x3, 0xcc, 0x14, + 0x1, 0xed, 0x23, 0x0, 0xe1, 0x4a, 0x0, 0xf3, + 0x2, 0x80, 0x7a, 0x90, 0x80, 0x38, 0xcb, 0x40, + 0x3d, 0x40, 0xc0, 0x1e, 0x65, 0x0, 0xf2, 0x87, + 0x0, 0x78, + + /* U+30 "0" */ + 0x0, 0x25, 0xff, 0xb1, 0x0, 0x25, 0xb5, 0x66, + 0x15, 0xa8, 0x2, 0xc7, 0xe6, 0x5e, 0x34, 0x8, + 0x32, 0x20, 0x1, 0x90, 0x53, 0x2, 0x0, 0xc2, + 0x1b, 0xe0, 0xc0, 0x14, 0x48, 0x8, 0x80, 0x21, + 0xb7, 0x50, 0xe, 0x3c, 0x4b, 0x80, 0xd, 0x58, + 0x1a, 0x80, 0x10, 0x83, 0x2e, 0x90, 0x8, 0x3, + 0xc1, 0xe8, 0x3, 0x84, 0xc3, 0xc0, 0x32, 0x86, + 0xa0, 0xc8, 0x80, 0x56, 0xa, 0x16, 0x3f, 0x32, + 0xe2, 0x90, 0x2, 0xda, 0xb3, 0xa, 0xd8, 0x0, + + /* U+31 "1" */ + 0x0, 0xc4, 0x80, 0x6, 0xcd, 0xc9, 0xf9, 0x30, + 0x3, 0x25, 0xd8, 0x1, 0xd6, 0x8e, 0x0, 0x10, + 0xf, 0xff, 0x78, + + /* U+32 "2" */ + 0x0, 0xc, 0xf7, 0xf4, 0x0, 0x62, 0xf6, 0x56, + 0x27, 0xd0, 0xa, 0x46, 0xed, 0x38, 0xa4, 0xe0, + 0x4, 0x34, 0x0, 0xa0, 0x30, 0x5, 0xe4, 0x3, + 0x18, 0x4, 0x30, 0xa0, 0x19, 0x3, 0x0, 0x3f, + 0x40, 0x30, 0x7, 0xd2, 0x52, 0x20, 0x1e, 0x76, + 0x56, 0x0, 0xf2, 0x41, 0xd0, 0x7, 0x8e, 0xcb, + 0x40, 0x3c, 0x3a, 0x3e, 0x20, 0x1e, 0xc1, 0xd2, + 0x0, 0xf5, 0x91, 0xa3, 0xbf, 0x18, 0x28, 0x1c, + 0x47, 0x94, + + /* U+33 "3" */ + 0x0, 0xc, 0xf7, 0xf4, 0x0, 0x43, 0xec, 0xae, + 0xaf, 0xa0, 0xb, 0x1a, 0xb8, 0xb7, 0x26, 0x4, + 0x15, 0x0, 0xa8, 0x30, 0x3b, 0x80, 0x1f, 0xfc, + 0x2b, 0xf, 0x0, 0x85, 0xe7, 0x59, 0xd4, 0x2, + 0x38, 0x62, 0x1c, 0x0, 0xc5, 0xfe, 0xb3, 0xb4, + 0x0, 0xf2, 0x78, 0x78, 0x8, 0x80, 0x31, 0xa, + 0x87, 0x60, 0x7, 0x9, 0x81, 0x92, 0x0, 0x4c, + 0x8, 0x1c, 0x17, 0x68, 0xb9, 0x28, 0x2, 0xe6, + 0x57, 0x57, 0xd1, + + /* U+34 "4" */ + 0x0, 0xf1, 0xff, 0x80, 0x3f, 0x78, 0x7, 0xf3, + 0x18, 0x7, 0xe1, 0x94, 0x30, 0xf, 0xac, 0x28, + 0x3, 0xe4, 0x58, 0x10, 0xf, 0xa4, 0x9c, 0x3, + 0xe7, 0x29, 0x0, 0xf8, 0xa1, 0x50, 0x3, 0xe9, + 0xb, 0x0, 0xf8, 0xd0, 0x3b, 0xfe, 0x30, 0xff, + 0xc, 0x47, 0x84, 0x1e, 0x9, 0xdf, 0xc4, 0x10, + 0xe0, 0x1f, 0xfc, 0xa0, + + /* U+35 "5" */ + 0x0, 0x7f, 0xfc, 0xa0, 0x20, 0x26, 0x7c, 0x20, + 0x60, 0xd9, 0x9c, 0x80, 0xc1, 0xc0, 0x1f, 0x8, + 0x18, 0x7, 0xc4, 0x7, 0x15, 0x6, 0x1, 0x78, + 0x4b, 0xab, 0xe3, 0x80, 0x38, 0xa7, 0xb9, 0x21, + 0x4, 0xd, 0xac, 0x22, 0x68, 0xa, 0x0, 0xf9, + 0x40, 0xc0, 0x3e, 0x30, 0x0, 0xfd, 0x80, 0x62, + 0x2, 0x13, 0x43, 0x0, 0xa0, 0x30, 0x38, 0x32, + 0xa7, 0x51, 0xa, 0x5, 0xaa, 0x8c, 0xf, 0x60, + + /* U+36 "6" */ + 0x0, 0x86, 0x37, 0xd4, 0x3, 0x27, 0x39, 0xa3, + 0x0, 0x45, 0x61, 0x5d, 0x66, 0x1, 0x48, 0x52, + 0x80, 0x70, 0xa1, 0xa8, 0x7, 0x90, 0x2c, 0x59, + 0xd4, 0x2, 0x20, 0xde, 0x98, 0xad, 0x10, 0xe0, + 0x58, 0xee, 0x31, 0x50, 0x5, 0xe, 0x22, 0x92, + 0x41, 0x0, 0x20, 0x6, 0x50, 0x51, 0x6, 0x0, + 0xde, 0x3, 0x81, 0xa0, 0x1b, 0x41, 0x90, 0x9c, + 0x80, 0x4, 0xa2, 0x61, 0xc1, 0xb5, 0x4d, 0xa, + 0x0, 0x1e, 0x22, 0xa9, 0x31, 0x0, + + /* U+37 "7" */ + 0xef, 0xff, 0xd6, 0xec, 0xde, 0x40, 0x39, 0x9f, + 0x88, 0x24, 0x3, 0xc2, 0xca, 0x20, 0x1e, 0x60, + 0x90, 0xf, 0xa4, 0x8c, 0x3, 0xca, 0x36, 0x1, + 0xf4, 0x8b, 0x0, 0x78, 0xcc, 0xc0, 0x1f, 0x48, + 0x50, 0x7, 0x85, 0x50, 0x80, 0x3d, 0x21, 0xe0, + 0x1f, 0x31, 0x20, 0x7, 0x98, 0x68, 0x3, 0xeb, + 0x6, 0x0, 0xe0, + + /* U+38 "8" */ + 0x0, 0x15, 0x77, 0xea, 0x80, 0x43, 0xaa, 0x8c, + 0x15, 0x20, 0xb, 0xa, 0xa4, 0xe9, 0x31, 0x2, + 0x2, 0x80, 0x54, 0x8, 0x6, 0x1, 0xf1, 0x82, + 0x2, 0x80, 0x54, 0x8, 0x12, 0x75, 0x49, 0xd2, + 0xa1, 0x0, 0x50, 0x2b, 0x11, 0xa0, 0x1, 0xe5, + 0x77, 0xe8, 0xb0, 0x42, 0xa, 0x88, 0x16, 0xc9, + 0x8c, 0x10, 0x3, 0x20, 0x60, 0x0, 0xc0, 0x31, + 0x80, 0xc, 0x54, 0x80, 0x2b, 0xd, 0xa, 0xd, + 0xa8, 0xc6, 0x36, 0x4, 0xc4, 0x57, 0x17, 0xc0, + + /* U+39 "9" */ + 0x0, 0x26, 0x7f, 0x51, 0x0, 0x4d, 0x64, 0xca, + 0xac, 0x10, 0x4, 0x8f, 0xcd, 0xc8, 0xd8, 0x28, + 0x48, 0x80, 0x18, 0x94, 0x34, 0xc, 0x3, 0x28, + 0x27, 0x80, 0x7b, 0x80, 0x48, 0xc, 0x3, 0x70, + 0x1a, 0x4, 0x88, 0x0, 0xdc, 0xc, 0x5c, 0x7e, + 0x6b, 0x4, 0x4, 0x22, 0x4d, 0x9e, 0x1c, 0x18, + 0x0, 0xdb, 0xfa, 0xea, 0x24, 0x1, 0xe3, 0x33, + 0x80, 0x79, 0x34, 0x60, 0x2, 0x5b, 0xeb, 0xd, + 0x10, 0xb, 0x54, 0x9f, 0xcc, 0x0, + + /* U+3A ":" */ + 0x5f, 0xb0, 0xf0, 0x42, 0x93, 0x62, 0x3c, 0x90, + 0xf, 0xfe, 0x29, 0xe4, 0x4, 0x9b, 0x97, 0x81, + 0x90, + + /* U+3B ";" */ + 0x6, 0xfa, 0x0, 0x68, 0x28, 0x3, 0xcd, 0xc0, + 0x9, 0x90, 0x1, 0xff, 0xcf, 0x4a, 0x60, 0x1, + 0x2f, 0x0, 0x4, 0x3, 0x70, 0x60, 0x1, 0x9, + 0x0, 0xf, 0xc0, 0x0, + + /* U+3C "<" */ + 0x0, 0xf9, 0x2c, 0x3, 0x9b, 0x6d, 0x40, 0x2, + 0xfd, 0x26, 0xd8, 0x33, 0xd0, 0x55, 0xd2, 0x48, + 0xc3, 0x78, 0xa0, 0x12, 0x28, 0xdd, 0x20, 0x4, + 0x35, 0xac, 0xb7, 0xae, 0x20, 0x2, 0x9e, 0x83, + 0x8f, 0x0, 0xc2, 0xfd, 0x24, 0x1, 0xf3, 0x60, + + /* U+3D "=" */ + 0x39, 0x9f, 0xc6, 0xec, 0xdf, 0x95, 0x3f, 0xff, + 0x30, 0x7, 0xf8, 0xa6, 0x7f, 0x1b, 0x37, 0xf2, + 0x80, + + /* U+3E ">" */ + 0x3a, 0x30, 0xf, 0x9d, 0x73, 0xa, 0x1, 0xc9, + 0x8c, 0x75, 0xae, 0x1, 0x8e, 0x7e, 0x9a, 0x3e, + 0x44, 0x3, 0x2d, 0xe1, 0x32, 0x0, 0x65, 0xbc, + 0x25, 0x40, 0x28, 0xea, 0x57, 0xea, 0x13, 0xd7, + 0x39, 0xe8, 0x10, 0x3, 0xa5, 0xeb, 0x0, 0x72, + 0x5a, 0x0, 0x7c, + + /* U+3F "?" */ + 0x0, 0x1d, 0xf7, 0xea, 0x80, 0x4b, 0x88, 0xaa, + 0x3a, 0x80, 0x5, 0x86, 0xdd, 0x78, 0xb8, 0x89, + 0xe0, 0x80, 0x2, 0xe0, 0x43, 0x2e, 0x1, 0x8c, + 0x4, 0x3, 0xc4, 0xa4, 0x40, 0xf, 0x70, 0x48, + 0x7, 0xb0, 0xe1, 0x0, 0x3a, 0x4d, 0xdc, 0x1, + 0xe7, 0x18, 0x0, 0xf8, 0x9c, 0x3, 0xf6, 0x48, + 0x7, 0xe1, 0x10, 0x7, 0xc3, 0xde, 0x1, 0xf8, + 0x48, 0x3, 0x0, + + /* U+40 "@" */ + 0x0, 0xd1, 0xbf, 0xae, 0x1, 0xc3, 0xab, 0x76, + 0xa9, 0xb0, 0xd, 0x4d, 0xac, 0x8f, 0xea, 0xc0, + 0x4, 0x5b, 0x9, 0xfd, 0x3b, 0xb0, 0x3, 0xe4, + 0x25, 0x2d, 0x95, 0x44, 0x20, 0x8a, 0x2d, 0xc8, + 0x2, 0x4, 0x43, 0x2, 0x41, 0x30, 0x72, 0x1, + 0x77, 0x8, 0x12, 0x80, 0x5, 0xc0, 0x21, 0x30, + 0xe2, 0x0, 0x10, 0x80, 0xb0, 0x98, 0x0, 0xc0, + 0x40, 0xc4, 0xc9, 0x44, 0x5e, 0x88, 0xa0, 0x29, + 0x40, 0x12, 0x67, 0xb, 0x26, 0xc5, 0xb0, 0x5, + 0xc9, 0xf7, 0x26, 0x5d, 0xa2, 0x0, 0x64, 0xd8, + 0x44, 0x3a, 0x80, 0x75, 0x4a, 0x55, 0xd9, 0xc0, + 0x20, + + /* U+41 "A" */ + 0x0, 0xec, 0xf0, 0xf, 0xe1, 0x30, 0x50, 0xf, + 0xce, 0x0, 0xf0, 0xf, 0xda, 0x8, 0x80, 0xf, + 0xc8, 0xba, 0x26, 0x1, 0xe4, 0xc, 0x70, 0xb0, + 0xf, 0x68, 0x38, 0x92, 0x80, 0x79, 0xcc, 0x41, + 0x48, 0x80, 0x18, 0xc6, 0xc0, 0x16, 0xa, 0x1, + 0xac, 0x32, 0x66, 0xc, 0x0, 0xca, 0x8, 0xcc, + 0x50, 0x41, 0x0, 0x11, 0x1b, 0xff, 0x50, 0x20, + 0x1, 0x43, 0x40, 0x32, 0x7, 0x80, 0x30, 0x10, + 0x3, 0x9, 0xa0, 0xa, 0x20, 0x3, 0xc8, 0x28, + + /* U+42 "B" */ + 0x4f, 0xfd, 0xd8, 0xa0, 0x18, 0xd9, 0x88, 0x55, + 0x40, 0xa, 0xe6, 0x55, 0xc6, 0xa8, 0x1, 0xf4, + 0x86, 0x0, 0x7c, 0x61, 0xe0, 0x1e, 0x1b, 0x5, + 0x0, 0x5c, 0x42, 0x7c, 0xa8, 0x80, 0x6, 0xee, + 0x61, 0x36, 0x0, 0xa3, 0xfe, 0xb1, 0xc3, 0x0, + 0xf2, 0x70, 0x40, 0x7, 0xc6, 0xa, 0x1, 0xf0, + 0x81, 0x80, 0x7d, 0x0, 0xa0, 0xb, 0x88, 0x4e, + 0xb1, 0xc0, 0x0, 0xdd, 0xcc, 0x11, 0x80, + + /* U+43 "C" */ + 0x0, 0x15, 0xff, 0xb1, 0x80, 0x24, 0xd5, 0x53, + 0x14, 0xc8, 0x1, 0x43, 0xf5, 0x3c, 0x6c, 0x6c, + 0x30, 0x20, 0x17, 0x84, 0xe8, 0x38, 0x6, 0x35, + 0x36, 0x11, 0x0, 0x75, 0x49, 0x18, 0x7, 0xff, + 0x40, 0x8c, 0x3, 0xf3, 0x8, 0x80, 0x3a, 0x63, + 0x41, 0xc0, 0x31, 0xb1, 0x30, 0xc0, 0x80, 0x50, + 0x12, 0x14, 0x3f, 0x32, 0xd4, 0x73, 0x4, 0xc5, + 0x76, 0x19, 0x80, + + /* U+44 "D" */ + 0x7f, 0xfb, 0xb1, 0x80, 0x3c, 0xae, 0xe1, 0x9d, + 0x10, 0xd, 0xf1, 0x3b, 0x25, 0x80, 0x1f, 0x99, + 0x84, 0xc0, 0x1f, 0xa0, 0x34, 0x3, 0xf0, 0x92, + 0x0, 0x7f, 0x8, 0x7, 0xf9, 0xc0, 0x40, 0x3f, + 0x38, 0x8, 0x7, 0xe1, 0x0, 0xfe, 0x12, 0x40, + 0xf, 0xd0, 0x1a, 0x1, 0xf3, 0xb1, 0xb0, 0x5, + 0xf1, 0x3b, 0x5, 0xa0, 0x19, 0x5d, 0xc3, 0x3a, + 0x20, 0x0, + + /* U+45 "E" */ + 0x3f, 0xff, 0xcc, 0x0, 0x26, 0x6f, 0x28, 0x1, + 0x26, 0x7c, 0x60, 0x1f, 0xfd, 0xe6, 0xff, 0xe8, + 0x0, 0x89, 0xdf, 0xb0, 0x2, 0x48, 0x8e, 0x40, + 0xf, 0xfe, 0xaa, 0x44, 0x79, 0x0, 0x4, 0xef, + 0xec, + + /* U+46 "F" */ + 0x2f, 0xff, 0xd2, 0x0, 0x26, 0x6f, 0x60, 0x1, + 0xe6, 0x7c, 0xa0, 0x1f, 0xfd, 0xe5, 0xff, 0xe9, + 0x0, 0x89, 0xdf, 0xb0, 0x2, 0x78, 0x8e, 0x50, + 0xf, 0xff, 0x38, + + /* U+47 "G" */ + 0x0, 0x8a, 0xff, 0xd8, 0xa0, 0x19, 0x35, 0x10, + 0xa5, 0x52, 0x1, 0x50, 0xed, 0xd7, 0x1b, 0x20, + 0x38, 0xc1, 0x0, 0x5e, 0x1e, 0x18, 0xe, 0x1, + 0x8e, 0x78, 0x14, 0x44, 0x1, 0xcc, 0xa0, 0x24, + 0x1, 0xff, 0xc2, 0x68, 0x89, 0xc0, 0x3d, 0xae, + 0xf4, 0x80, 0x90, 0x5, 0x7f, 0xe2, 0x0, 0x28, + 0x88, 0x3, 0xf6, 0x84, 0x80, 0x7e, 0x62, 0x74, + 0x0, 0x88, 0x80, 0x17, 0x8d, 0xda, 0x6f, 0x42, + 0x80, 0x5, 0xec, 0xac, 0xc7, 0xd4, + + /* U+48 "H" */ + 0x9f, 0x10, 0xc, 0x3f, 0x20, 0x1f, 0xff, 0x2e, + 0xff, 0xdc, 0x1, 0x99, 0xdf, 0x30, 0x6, 0x88, + 0xf0, 0x7, 0xff, 0xa0, + + /* U+49 "I" */ + 0x4f, 0xff, 0xc8, 0xcd, 0x80, 0xc, 0xd8, 0xa6, + 0x60, 0x19, 0x98, 0x80, 0x3f, 0xff, 0xe0, 0x1f, + 0xfc, 0xd2, 0x99, 0x80, 0x66, 0x62, 0x66, 0xc0, + 0x6, 0x6c, + + /* U+4A "J" */ + 0x0, 0xfd, 0x3e, 0x60, 0x1f, 0xff, 0xf0, 0xf, + 0xfe, 0x6b, 0xb0, 0x7, 0x18, 0x5, 0x52, 0x1, + 0xce, 0x6, 0x14, 0x12, 0x1, 0x39, 0x28, 0x1, + 0xcd, 0xb6, 0x72, 0xa, 0xc0, 0x2c, 0x80, 0x62, + 0x6c, 0x10, + + /* U+4B "K" */ + 0x4f, 0x80, 0xc, 0x9f, 0xa0, 0x1f, 0x15, 0x7, + 0x80, 0x7d, 0xc3, 0x44, 0x1, 0xe9, 0x36, 0x50, + 0xf, 0x2b, 0x14, 0x80, 0x78, 0xa8, 0x3c, 0x3, + 0xc3, 0xc1, 0x4, 0x1, 0xe6, 0x30, 0xa0, 0xf, + 0xc8, 0xa5, 0x0, 0x1e, 0x2a, 0xb1, 0x72, 0x0, + 0xe5, 0x11, 0x40, 0x70, 0x7, 0xe6, 0x33, 0x30, + 0x7, 0xee, 0x8, 0x10, 0xf, 0x89, 0xc6, 0xc0, + 0x3f, 0x41, 0x2a, 0x0, + + /* U+4C "L" */ + 0xf, 0xb0, 0xf, 0xff, 0xf8, 0x7, 0xff, 0xa9, + 0x62, 0x3c, 0xc0, 0x1, 0x77, 0xf6, 0x0, + + /* U+4D "M" */ + 0x8f, 0xd0, 0xd, 0x5f, 0x60, 0x2, 0x20, 0x4, + 0xa0, 0x1c, 0xa0, 0x5, 0x0, 0xe2, 0xb0, 0x7, + 0x88, 0x80, 0x24, 0x31, 0x5, 0x60, 0xd, 0xa0, + 0xea, 0x16, 0x1, 0x98, 0xb7, 0xc4, 0xc4, 0x3, + 0x2a, 0x2b, 0x80, 0x7a, 0xc0, 0x1a, 0x1, 0xc2, + 0x62, 0x24, 0x0, 0xf9, 0x98, 0x1, 0xfa, 0x20, + 0x1, 0xff, 0xd6, + + /* U+4E "N" */ + 0x9f, 0x70, 0xc, 0x7f, 0x20, 0x9, 0x0, 0xfe, + 0x17, 0x0, 0xfe, 0x90, 0xf, 0xca, 0x2e, 0x1, + 0xf7, 0xc, 0x80, 0x7c, 0xf0, 0x2c, 0x1, 0xf3, + 0xc, 0x0, 0x7e, 0x81, 0x60, 0xf, 0x98, 0x61, + 0xc0, 0x3e, 0x91, 0xe0, 0xf, 0x9c, 0x54, 0x3, + 0xf4, 0x80, 0x7f, 0x38, 0x80, 0x7f, 0x48, 0x0, + + /* U+4F "O" */ + 0x0, 0x1d, 0xff, 0xac, 0x80, 0x24, 0xc4, 0x33, + 0x26, 0x98, 0x2, 0x87, 0x73, 0x20, 0xd0, 0x61, + 0x92, 0x0, 0x1c, 0xb, 0x60, 0x30, 0x6, 0x60, + 0xc7, 0x11, 0x0, 0x61, 0x13, 0x91, 0x80, 0x78, + 0xcc, 0x2, 0x1, 0xf0, 0x80, 0x80, 0x7c, 0x24, + 0x60, 0x1e, 0x33, 0x38, 0x88, 0x3, 0x8, 0x9f, + 0x1, 0x80, 0x33, 0x6, 0x30, 0xc1, 0x80, 0xa, + 0x45, 0x82, 0x83, 0x2e, 0xda, 0x34, 0x0, 0x4d, + 0x44, 0xd8, 0x80, + + /* U+50 "P" */ + 0x2f, 0xfe, 0xe9, 0x10, 0xc, 0x4e, 0xf2, 0xb7, + 0x90, 0x4, 0xf1, 0x15, 0xc8, 0xc8, 0x7, 0xe6, + 0x24, 0x10, 0xf, 0xce, 0x6, 0x1, 0xf9, 0x80, + 0xc0, 0x3e, 0x53, 0x41, 0x0, 0x3c, 0x45, 0x74, + 0x32, 0x1, 0x13, 0xbc, 0xad, 0xe4, 0x1, 0x2f, + 0xfd, 0xd2, 0x20, 0x1f, 0xfe, 0xd0, + + /* U+51 "Q" */ + 0x0, 0x8e, 0xff, 0xd6, 0x60, 0x1c, 0x98, 0x86, + 0x64, 0xc4, 0x0, 0x86, 0xc7, 0x73, 0x1a, 0x36, + 0x20, 0x6, 0x8, 0x20, 0x1, 0x58, 0x30, 0x2, + 0xc1, 0x80, 0x32, 0x85, 0x80, 0xc, 0x80, 0x3c, + 0x46, 0x1, 0x30, 0x7, 0x98, 0x0, 0x20, 0x1f, + 0xe1, 0x10, 0x7, 0xf8, 0x40, 0xc, 0x1, 0xe6, + 0x0, 0x8c, 0x80, 0x3c, 0x46, 0x0, 0xb0, 0x50, + 0xc, 0xa1, 0x60, 0x6, 0xb, 0x20, 0x1, 0x58, + 0x30, 0x0, 0x6c, 0x76, 0xed, 0xa3, 0x42, 0x1, + 0x26, 0x22, 0x42, 0x1a, 0x1, 0xc7, 0x7f, 0xf1, + 0xbd, 0x0, 0x7e, 0x1c, 0x47, 0x10, 0xf, 0xeb, + 0xd1, + + /* U+52 "R" */ + 0x3f, 0xfe, 0xc6, 0x0, 0xe3, 0x77, 0x31, 0x4d, + 0x0, 0x64, 0x88, 0x4f, 0x1a, 0xa8, 0x3, 0xf7, + 0x87, 0x80, 0x7e, 0x20, 0x10, 0xf, 0xc4, 0x2, + 0x1, 0xfb, 0xc3, 0x80, 0x24, 0x88, 0x4f, 0x1b, + 0x20, 0x4, 0x6e, 0xe6, 0x19, 0x90, 0x6, 0x7f, + 0xf5, 0x7, 0x0, 0x7e, 0x51, 0x71, 0x0, 0xfd, + 0x0, 0xc0, 0x1f, 0x98, 0x64, 0x3, 0xfa, 0x45, + 0xc0, 0x3f, 0x30, 0x48, 0x0, + + /* U+53 "S" */ + 0x0, 0x1d, 0xf7, 0xe2, 0x80, 0x65, 0xc4, 0x55, + 0x15, 0x58, 0x0, 0x68, 0x76, 0xeb, 0x91, 0xe, + 0x8, 0xc, 0x40, 0x14, 0x85, 0x0, 0x42, 0x1, + 0x8a, 0x6c, 0x10, 0x19, 0x40, 0x33, 0x30, 0x6, + 0xc2, 0xb1, 0x84, 0x3, 0x93, 0x50, 0xe7, 0xa0, + 0x3, 0x8a, 0xfa, 0x5, 0xf4, 0x3, 0xc2, 0xfc, + 0xa5, 0x40, 0xac, 0x1, 0xd4, 0xa, 0x1d, 0x28, + 0x1, 0xfb, 0xc2, 0x44, 0x2, 0x70, 0x40, 0x47, + 0x2e, 0xa9, 0xc8, 0x19, 0x0, 0x45, 0xa2, 0x18, + 0x63, 0xc8, 0x0, + + /* U+54 "T" */ + 0x3f, 0xff, 0xf2, 0xb, 0x36, 0x0, 0x33, 0x71, + 0x4c, 0xe2, 0x19, 0x9c, 0x40, 0x1f, 0xff, 0xf0, + 0xf, 0xff, 0xc8, + + /* U+55 "U" */ + 0xaf, 0x10, 0xc, 0x5f, 0x20, 0x1f, 0xfc, 0x73, + 0x0, 0xff, 0xef, 0x18, 0x7, 0xff, 0x3c, 0xc0, + 0x40, 0x30, 0x81, 0xf8, 0x20, 0x6, 0x40, 0xf7, + 0x9, 0x20, 0x1, 0x48, 0x38, 0xd0, 0xed, 0x53, + 0x46, 0x84, 0x17, 0x11, 0x54, 0x98, 0xa0, + + /* U+56 "V" */ + 0x2f, 0xc0, 0xf, 0x6f, 0x89, 0x10, 0xc0, 0x38, + 0x48, 0xc4, 0x10, 0x14, 0x3, 0x38, 0x58, 0x3, + 0x43, 0x0, 0x36, 0x2, 0x0, 0x10, 0x1c, 0x3, + 0x20, 0x98, 0x4, 0xa2, 0x40, 0x3, 0x17, 0x0, + 0xde, 0x8, 0x0, 0xb0, 0xd0, 0xc, 0x81, 0xa0, + 0x4, 0x4, 0x0, 0xc2, 0x68, 0x2, 0x68, 0x1, + 0xeb, 0x4, 0x40, 0x68, 0x7, 0x94, 0x33, 0xc1, + 0xc0, 0x3c, 0x44, 0x54, 0x31, 0x0, 0xf9, 0x8, + 0x50, 0x3, 0xf6, 0x80, 0x2c, 0x3, 0xf2, 0x0, + 0x98, 0x6, + + /* U+57 "W" */ + 0x3f, 0x70, 0x5, 0xf8, 0x0, 0xfd, 0xc8, 0x38, + 0x0, 0xa0, 0x40, 0xc0, 0x42, 0x6, 0x2, 0x20, + 0x70, 0x30, 0x10, 0x16, 0x2, 0x0, 0x68, 0x70, + 0x30, 0x11, 0x1, 0x40, 0xc8, 0x4, 0x8, 0x18, + 0x43, 0xc9, 0x5c, 0x8, 0x40, 0x4, 0x2, 0x4f, + 0xe4, 0xc, 0x40, 0xe, 0x3, 0x52, 0x20, 0x11, + 0xb0, 0x0, 0x81, 0xc7, 0x54, 0x1c, 0x48, 0x0, + 0xe1, 0x80, 0xc2, 0x2c, 0xf, 0x0, 0x10, 0x38, + 0x18, 0x13, 0x81, 0x0, 0x4, 0x4, 0x80, 0xa, + 0x20, 0xc0, 0x11, 0x3, 0x0, 0x38, 0x0, 0x40, + 0x13, 0x1, 0x80, 0xc, 0x0, 0x20, 0x11, 0x7, + 0x0, 0x14, 0x8, 0x0, + + /* U+58 "X" */ + 0xc, 0xf5, 0x0, 0xc3, 0xfe, 0x10, 0xf0, 0x80, + 0xd, 0x61, 0x2, 0x6, 0xa4, 0xc0, 0x2, 0x51, + 0x70, 0xa, 0x2, 0x0, 0x12, 0x16, 0x1, 0x89, + 0xc5, 0xcd, 0xd, 0x40, 0x3a, 0x46, 0x7c, 0x3c, + 0x3, 0xc3, 0x2, 0x68, 0x60, 0x1f, 0x38, 0x3, + 0x80, 0x3f, 0x48, 0x2, 0x40, 0x3e, 0x17, 0x26, + 0x35, 0x0, 0xf5, 0x84, 0x40, 0x20, 0x3, 0x8d, + 0x49, 0x45, 0xc9, 0x80, 0x37, 0x84, 0x80, 0x24, + 0x20, 0x40, 0xa, 0x66, 0x40, 0x0, 0xb8, 0xc8, + 0x2, 0x3, 0xc0, 0x34, 0xb, 0x90, + + /* U+59 "Y" */ + 0x2f, 0xd0, 0xe, 0x1f, 0xe0, 0x24, 0x25, 0x0, + 0xd2, 0x12, 0x0, 0x80, 0x90, 0xc, 0xc0, 0xc0, + 0x3, 0x3c, 0x0, 0x61, 0x71, 0x0, 0xa0, 0x24, + 0x1, 0x61, 0x20, 0x19, 0x9, 0x45, 0x49, 0x84, + 0x3, 0xa0, 0x26, 0x41, 0x60, 0x1e, 0x52, 0x73, + 0x52, 0x0, 0xfa, 0xc0, 0x12, 0x1, 0xf9, 0x80, + 0xcc, 0x1, 0xff, 0xd6, 0x70, 0xf, 0xfe, 0x88, + + /* U+5A "Z" */ + 0xcf, 0xff, 0xc9, 0x6c, 0xde, 0x0, 0x33, 0xcc, + 0xf6, 0x2, 0x90, 0x7, 0xac, 0x2c, 0x3, 0xd0, + 0x30, 0x20, 0x1c, 0x4e, 0x4e, 0x1, 0xe9, 0x9, + 0x0, 0xf2, 0x21, 0x50, 0x3, 0xd2, 0x16, 0x1, + 0xe7, 0x28, 0x10, 0xe, 0x18, 0x27, 0x0, 0xf5, + 0x84, 0x0, 0x79, 0x15, 0x14, 0x3, 0xd0, 0x0, + 0x88, 0xf2, 0x8, 0x23, 0xbf, 0xb0, + + /* U+5B "[" */ + 0x68, 0x88, 0x2d, 0xde, 0x0, 0x17, 0xf8, 0x3, + 0xff, 0xfe, 0x0, 0x28, 0x80, 0x4, 0xee, 0x0, + + /* U+5C "\\" */ + 0x9f, 0x10, 0xe, 0xa0, 0x60, 0xe, 0x32, 0xa0, + 0xf, 0x51, 0x18, 0x7, 0x30, 0x58, 0x7, 0xa, + 0x30, 0x7, 0xb8, 0x50, 0x3, 0x94, 0x78, 0x3, + 0xce, 0xa2, 0x1, 0xd4, 0xe, 0x1, 0xc6, 0x54, + 0x1, 0xea, 0x32, 0x0, 0xe6, 0xa, 0x0, 0xe1, + 0x46, 0x0, 0xf7, 0xa, 0x0, 0x72, 0x87, 0x0, + + /* U+5D "]" */ + 0x8, 0x89, 0x81, 0xde, 0xb0, 0xff, 0x10, 0x7, + 0xff, 0xfc, 0x1, 0x10, 0x20, 0x3, 0xb8, 0x0, + + /* U+5E "^" */ + 0x0, 0xb7, 0x40, 0x1c, 0x64, 0x43, 0x0, 0xd4, + 0x0, 0xa0, 0xc, 0xca, 0xa6, 0x0, 0x98, 0x3b, + 0x80, 0xa0, 0xa, 0x14, 0x40, 0xc8, 0x11, 0xb0, + 0x1, 0x8c, 0xa8, 0x28, 0x1, 0x41, 0x40, + + /* U+5F "_" */ + 0x37, 0x7f, 0xc6, 0x91, 0x1f, 0x90, + + /* U+60 "`" */ + 0x57, 0x30, 0x4a, 0xe0, 0x1f, 0x39, + + /* U+61 "a" */ + 0x0, 0x26, 0x7f, 0x62, 0x80, 0x4d, 0x62, 0xee, + 0x3a, 0x60, 0x19, 0x2d, 0x89, 0xd0, 0x90, 0x4, + 0x48, 0x4, 0x48, 0x4, 0x2e, 0x80, 0x18, 0x40, + 0x21, 0x9d, 0xff, 0x94, 0x2, 0xc6, 0x4a, 0xbc, + 0x40, 0x3, 0x14, 0x4a, 0xa1, 0x88, 0x7, 0xe1, + 0x70, 0x3, 0x8c, 0x4b, 0xcf, 0x90, 0x8, 0xb1, + 0x5e, 0x16, 0x1c, 0x14, + + /* U+62 "b" */ + 0x4f, 0x80, 0xf, 0xfe, 0xe3, 0xef, 0xeb, 0x0, + 0x67, 0x87, 0x53, 0x97, 0x0, 0x87, 0x6a, 0x98, + 0x30, 0x20, 0x6, 0x20, 0x1, 0x48, 0x38, 0x7, + 0xc8, 0x1e, 0x1, 0xf0, 0x81, 0x80, 0x7c, 0x20, + 0x60, 0x1f, 0x28, 0x78, 0x1, 0x40, 0x35, 0x83, + 0x80, 0xb, 0x5d, 0xb0, 0xa0, 0x40, 0x10, 0xb3, + 0x21, 0x97, 0x0, + + /* U+63 "c" */ + 0x0, 0x1d, 0xf7, 0xea, 0x80, 0x49, 0x88, 0xec, + 0x15, 0x20, 0xa, 0xc, 0x99, 0x6a, 0x31, 0xa8, + 0xb9, 0x80, 0x5e, 0x4b, 0xa1, 0x80, 0x19, 0x35, + 0x84, 0x1c, 0x3, 0xe1, 0x7, 0x0, 0xfb, 0x43, + 0x0, 0x31, 0x42, 0x28, 0xb9, 0x0, 0x50, 0xee, + 0xa, 0xd, 0x98, 0xd5, 0x73, 0x4, 0xc4, 0x77, + 0xd, 0xc0, 0x0, + + /* U+64 "d" */ + 0x0, 0xfa, 0x3d, 0x0, 0x3f, 0xfa, 0x8b, 0xbf, + 0xce, 0x1, 0x9a, 0x89, 0x52, 0x1c, 0x0, 0x32, + 0x3b, 0x54, 0xd1, 0x0, 0x38, 0x31, 0x0, 0x9, + 0x80, 0x1e, 0x18, 0x1, 0xf1, 0x83, 0x80, 0x7c, + 0x60, 0xe0, 0x1f, 0x78, 0x60, 0x7, 0xce, 0xc, + 0x40, 0x1, 0x50, 0x0, 0xc8, 0xed, 0x53, 0xc8, + 0x2, 0x6a, 0x25, 0x46, 0x80, 0x0, + + /* U+65 "e" */ + 0x0, 0x15, 0x77, 0xe2, 0x80, 0x47, 0xaa, 0x8e, + 0x55, 0x0, 0xd, 0x1d, 0xa8, 0xe3, 0x72, 0x61, + 0x92, 0x0, 0xa4, 0x17, 0xc3, 0x26, 0x77, 0x87, + 0x18, 0x23, 0x36, 0x50, 0x30, 0x6, 0x7f, 0xfa, + 0xb4, 0x2c, 0x3, 0xe6, 0x7, 0x40, 0x8, 0xac, + 0x86, 0xc2, 0xea, 0x2b, 0x54, 0xc1, 0x35, 0x51, + 0xde, 0xf1, + + /* U+66 "f" */ + 0x0, 0xe2, 0x68, 0x74, 0x0, 0xe7, 0xd9, 0x78, + 0xb0, 0xc, 0x70, 0x57, 0xfe, 0xd0, 0xd, 0x61, + 0x8, 0x0, 0x20, 0xc, 0x20, 0xc0, 0x1d, 0x1f, + 0xe6, 0xc, 0xff, 0x90, 0x2e, 0x64, 0x60, 0xf3, + 0x32, 0x81, 0xb3, 0x14, 0x2d, 0x9a, 0x10, 0xf, + 0xff, 0xf8, 0x7, 0xff, 0x8, + + /* U+67 "g" */ + 0x0, 0x36, 0xff, 0x43, 0xfa, 0x3, 0xc8, 0x44, + 0xa4, 0x0, 0x6, 0x7, 0x1d, 0xd8, 0x60, 0x7, + 0x9, 0x10, 0x9, 0x0, 0x1e, 0x6, 0x1, 0xfc, + 0xe0, 0x1f, 0xce, 0x1, 0xf7, 0x86, 0x0, 0x7c, + 0xe0, 0xc4, 0x0, 0x16, 0x0, 0xc, 0x8e, 0xd5, + 0x3c, 0x40, 0x26, 0xa2, 0x57, 0x67, 0x0, 0xcb, + 0xbf, 0xb0, 0x40, 0xc1, 0xa, 0x1, 0x12, 0x91, + 0x0, 0xea, 0xe2, 0xb4, 0x24, 0x1, 0x72, 0xee, + 0x54, 0xc4, 0x0, + + /* U+68 "h" */ + 0x4f, 0x70, 0xf, 0xfe, 0xe1, 0xdf, 0xf4, 0x88, + 0x5, 0x78, 0xc, 0x6d, 0xa0, 0x11, 0x6d, 0xce, + 0x91, 0x98, 0x0, 0xc4, 0x1, 0x50, 0x28, 0x3, + 0xc0, 0x30, 0x80, 0x7f, 0x18, 0x7, 0xff, 0xa0, + + /* U+69 "i" */ + 0x0, 0xcd, 0xe8, 0x1, 0xf7, 0x1, 0x0, 0x7d, + 0x1c, 0xc0, 0x1f, 0x84, 0x3, 0xbf, 0xf9, 0x80, + 0x33, 0x34, 0x60, 0x1e, 0x99, 0xa8, 0x3, 0xff, + 0xed, 0x33, 0x50, 0x54, 0xc9, 0xc1, 0x9a, 0x30, + 0x36, 0x65, 0x0, + + /* U+6A "j" */ + 0x0, 0xd3, 0xc4, 0x1, 0x8c, 0x44, 0x1, 0xab, + 0x8c, 0x3, 0x84, 0x7, 0xff, 0x8c, 0x59, 0xa2, + 0x0, 0xa6, 0x65, 0x0, 0xff, 0xf9, 0x10, 0x7, + 0xa, 0x81, 0xc4, 0x27, 0xc2, 0x1, 0x5d, 0x8a, + 0x9c, 0x0, + + /* U+6B "k" */ + 0x4f, 0x80, 0xf, 0xff, 0x1a, 0xfe, 0x88, 0x7, + 0x92, 0x8b, 0x4, 0x3, 0x92, 0xc7, 0xc4, 0x3, + 0x8e, 0xc7, 0x8, 0x3, 0x8b, 0x42, 0xc8, 0x3, + 0xca, 0x21, 0x20, 0x1f, 0xad, 0x4e, 0x40, 0x3c, + 0xe9, 0x64, 0xca, 0x1, 0xf0, 0xf0, 0x51, 0x0, + 0x7c, 0x72, 0x1e, 0x1, 0xf9, 0x94, 0xa8, 0x0, + + /* U+6C "l" */ + 0xf, 0xfe, 0x60, 0xc, 0xcd, 0x18, 0x7, 0xa6, + 0x6a, 0x0, 0xff, 0xff, 0x80, 0x7f, 0xf4, 0xe6, + 0x6a, 0xa, 0x99, 0x38, 0x33, 0x46, 0x6, 0xcc, + 0xa0, + + /* U+6D "m" */ + 0x1f, 0x9b, 0xfd, 0x5b, 0xfd, 0x30, 0x9, 0xb1, + 0xca, 0x8a, 0xb, 0x80, 0x25, 0x78, 0x11, 0x4b, + 0xa9, 0x0, 0x46, 0x0, 0x33, 0x0, 0xc, 0x4, + 0x3, 0xff, 0xfe, 0x1, 0xfc, + + /* U+6E "n" */ + 0x4f, 0x54, 0xcf, 0xd9, 0x10, 0xb, 0xad, 0x98, + 0xd, 0xa0, 0x12, 0xed, 0x4e, 0x99, 0x88, 0x0, + 0xc4, 0x1, 0x58, 0x38, 0x3, 0xc0, 0x30, 0x81, + 0x80, 0x7f, 0xfc, 0x0, + + /* U+6F "o" */ + 0x0, 0x25, 0xff, 0xad, 0x0, 0x26, 0xb5, 0x66, + 0x2d, 0xb0, 0x14, 0x97, 0xcc, 0xbc, 0xa4, 0xa8, + 0x2c, 0x40, 0x3, 0x61, 0x46, 0xe, 0x1, 0x90, + 0xd, 0xc0, 0x40, 0x31, 0x3, 0xb8, 0x4, 0x3, + 0x8, 0x39, 0x82, 0x0, 0x64, 0x3, 0xa0, 0x81, + 0x0, 0xc, 0x5, 0x14, 0x97, 0xcc, 0xbc, 0xa4, + 0x81, 0xac, 0x99, 0x85, 0x6c, 0x0, + + /* U+70 "p" */ + 0x4f, 0x67, 0xdf, 0xd6, 0x0, 0xd1, 0x2e, 0xa5, + 0x2e, 0x1, 0x1f, 0xd5, 0x30, 0x20, 0x40, 0xa, + 0x20, 0x3, 0x70, 0x70, 0x7, 0x80, 0x6c, 0xe, + 0x0, 0xf9, 0xc0, 0x40, 0x3e, 0x70, 0x10, 0xf, + 0xb0, 0x34, 0x1, 0x60, 0x11, 0x30, 0x20, 0x0, + 0xf6, 0x65, 0xa3, 0x2, 0x0, 0x75, 0x76, 0x29, + 0x70, 0xb, 0xe3, 0xbf, 0x58, 0x3, 0xff, 0xa8, + + /* U+71 "q" */ + 0x0, 0x2e, 0xff, 0x4c, 0x7a, 0x3, 0xd0, 0x4c, + 0x2b, 0x80, 0x6, 0x7, 0x19, 0x98, 0x80, 0x7, + 0x9, 0x10, 0x8, 0xc0, 0x1e, 0x6, 0x1, 0xfc, + 0xe0, 0x1f, 0xce, 0x1, 0xf7, 0x86, 0x0, 0x7c, + 0xe0, 0xc4, 0x0, 0x15, 0x0, 0xc, 0xe, 0x4c, + 0xbc, 0x80, 0x27, 0xa3, 0x67, 0x67, 0x0, 0xcb, + 0xbf, 0xd0, 0x1, 0xff, 0xd5, + + /* U+72 "r" */ + 0xcf, 0x6, 0xdf, 0xe5, 0x0, 0x4c, 0x88, 0x82, + 0x20, 0x3, 0xdf, 0xef, 0xa0, 0x2, 0xd0, 0x3, + 0xca, 0x1, 0xff, 0xe9, + + /* U+73 "s" */ + 0x0, 0x1d, 0xf7, 0xeb, 0x80, 0x49, 0x8a, 0xec, + 0x11, 0x60, 0x9, 0xf, 0x99, 0x6a, 0x24, 0x1, + 0x8, 0x5, 0x34, 0xc1, 0x61, 0xce, 0x60, 0x4a, + 0x40, 0xd6, 0xb1, 0x9f, 0x44, 0x1, 0x25, 0xfd, + 0xb2, 0xe0, 0x93, 0xa0, 0x1, 0x26, 0x42, 0xc7, + 0x12, 0x20, 0x10, 0x80, 0x8a, 0xb, 0xe6, 0x2e, + 0x9, 0x81, 0xe9, 0x59, 0xd9, 0xf0, 0x0, + + /* U+74 "t" */ + 0x0, 0x99, 0xc0, 0x3f, 0x5c, 0x0, 0x7f, 0xf0, + 0xe7, 0xfc, 0x41, 0xff, 0x83, 0x66, 0x42, 0x13, + 0x38, 0x11, 0x98, 0x60, 0xcd, 0x80, 0x3f, 0xfd, + 0x4c, 0x8, 0x1, 0xf7, 0x5, 0xd4, 0xd9, 0x80, + 0x4b, 0x44, 0xac, 0xe0, + + /* U+75 "u" */ + 0x3f, 0x80, 0xd, 0x1e, 0x80, 0x1f, 0xfe, 0x81, + 0x0, 0xf8, 0x40, 0x3f, 0x88, 0x1c, 0x3, 0x28, + 0x4, 0xe3, 0x6c, 0xfa, 0x60, 0x14, 0x41, 0x66, + 0xae, 0x0, 0x0, + + /* U+76 "v" */ + 0xd, 0xf0, 0xe, 0x1f, 0xc0, 0xa0, 0x50, 0xc, + 0xe1, 0x40, 0xc1, 0xc0, 0x1a, 0x81, 0x80, 0x55, + 0x4, 0x0, 0x26, 0xc0, 0x17, 0x3, 0x0, 0x18, + 0x28, 0x2, 0x42, 0xa0, 0x5, 0x11, 0x80, 0x6a, + 0x22, 0xd4, 0x1, 0xcc, 0x15, 0x40, 0x60, 0xe, + 0x14, 0x65, 0x50, 0x80, 0x7b, 0xc4, 0xb8, 0x3, + 0xe4, 0x11, 0x20, 0x4, + + /* U+77 "w" */ + 0x6f, 0x20, 0x5, 0x58, 0x5, 0xf0, 0xa0, 0xe0, + 0x4, 0x40, 0x0, 0xc3, 0x4c, 0x34, 0x8, 0x40, + 0xc1, 0x41, 0x0, 0x88, 0xe, 0x24, 0x81, 0xc2, + 0x20, 0x47, 0xc, 0x57, 0xc0, 0x35, 0x0, 0x79, + 0x2, 0x66, 0x14, 0x14, 0xc0, 0xa, 0x8, 0x48, + 0x81, 0x31, 0xc0, 0x1, 0x87, 0x1, 0x90, 0xd0, + 0x28, 0x4, 0x6a, 0x80, 0x4, 0x71, 0x10, 0x4, + 0xa1, 0x80, 0xc, 0x15, 0x0, 0xde, 0x6, 0x0, + 0x40, 0xc0, 0x0, + + /* U+78 "x" */ + 0x7f, 0x90, 0xc, 0xff, 0x40, 0xe8, 0xca, 0x0, + 0x38, 0x2a, 0x0, 0x50, 0xd8, 0x87, 0x7, 0x0, + 0x43, 0x43, 0x52, 0x50, 0x60, 0x19, 0x1d, 0x19, + 0x1c, 0x3, 0xd2, 0x0, 0xf0, 0xf, 0xac, 0x1, + 0x20, 0x1e, 0x65, 0x54, 0x94, 0x80, 0x62, 0x91, + 0xa6, 0x46, 0x40, 0xb, 0x83, 0x40, 0x14, 0x34, + 0x21, 0x6, 0xe6, 0x0, 0x1b, 0x1a, 0x0, + + /* U+79 "y" */ + 0x1f, 0xe0, 0xf, 0x77, 0x88, 0x94, 0x54, 0x3, + 0x28, 0xa8, 0x84, 0x87, 0x0, 0x6e, 0x9, 0x0, + 0x19, 0x90, 0x80, 0x2, 0x86, 0x60, 0xa, 0x42, + 0xc0, 0xc, 0x12, 0x1, 0x94, 0x98, 0x1, 0x22, + 0xa0, 0x1d, 0x60, 0xc8, 0x32, 0x1, 0xe6, 0x1b, + 0xe0, 0x60, 0xf, 0x98, 0x95, 0x84, 0x3, 0xe9, + 0x0, 0x58, 0x7, 0xe1, 0x12, 0x10, 0x7, 0xe7, + 0x1f, 0x0, 0xfc, 0x50, 0x48, 0x1, 0xe3, 0xac, + 0xe, 0x0, 0xf9, 0x54, 0x76, 0x60, 0x1e, + + /* U+7A "z" */ + 0x5f, 0xff, 0xc6, 0xef, 0xe5, 0x0, 0x11, 0x22, + 0x39, 0xc2, 0x84, 0x3, 0xa8, 0x9d, 0x40, 0x39, + 0x94, 0xe0, 0x3, 0x8e, 0x47, 0x40, 0x38, 0x74, + 0x34, 0x40, 0x3a, 0x86, 0x4c, 0x3, 0xa1, 0x15, + 0x80, 0x39, 0x1c, 0x9, 0xdf, 0x90, 0x80, 0xf, + 0x11, 0xda, + + /* U+7B "{" */ + 0x0, 0xc9, 0x92, 0x1, 0x1d, 0xb5, 0x80, 0x50, + 0x14, 0x40, 0x12, 0x20, 0x3, 0x8, 0x7, 0xe1, + 0x0, 0xc6, 0x1, 0xe4, 0xd, 0x0, 0x13, 0x41, + 0x30, 0x3, 0xe4, 0xf0, 0x40, 0x12, 0xc5, 0x40, + 0x12, 0x4c, 0x22, 0x80, 0x64, 0xc, 0x0, 0xc4, + 0x6, 0x1, 0xe1, 0x0, 0xc2, 0xe, 0x1, 0xc6, + 0x60, 0xe, 0x80, 0x90, 0xc, 0x94, 0xd4, 0x1, + 0x97, 0xec, + + /* U+7C "|" */ + 0xbb, 0x0, 0x7f, 0xf6, 0x0, + + /* U+7D "}" */ + 0xac, 0x30, 0xd, 0xf, 0x86, 0x1, 0x15, 0x4, + 0x80, 0x61, 0x24, 0x0, 0xe1, 0x10, 0x7, 0xff, + 0x1, 0xc0, 0x40, 0x31, 0x82, 0x80, 0x69, 0x1a, + 0x52, 0x0, 0xe, 0x5, 0x48, 0x5, 0xc2, 0xfe, + 0x0, 0x73, 0x98, 0x40, 0x6, 0x3, 0x80, 0x67, + 0x1, 0x0, 0xff, 0x84, 0x40, 0x18, 0x49, 0x40, + 0x35, 0x4, 0x0, 0x58, 0xb6, 0x60, 0x16, 0xf2, + 0x0, 0x60, + + /* U+7E "~" */ + 0x3, 0xdf, 0xd5, 0x0, 0xcc, 0x63, 0xa6, 0xa7, + 0x52, 0x0, 0x29, 0x57, 0x1f, 0xae, 0x56, 0xea, + 0xc1, 0x64, 0xa1, 0x0, 0x54, 0x9a, 0x96, 0x0 +}; + + +/*--------------------- + * GLYPH DESCRIPTION + *--------------------*/ + +static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { + {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */, + {.bitmap_index = 0, .adv_w = 192, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 0, .adv_w = 192, .box_w = 3, .box_h = 15, .ofs_x = 4, .ofs_y = 0}, + {.bitmap_index = 13, .adv_w = 192, .box_w = 6, .box_h = 5, .ofs_x = 3, .ofs_y = 10}, + {.bitmap_index = 26, .adv_w = 192, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 110, .adv_w = 192, .box_w = 10, .box_h = 19, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 193, .adv_w = 192, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 269, .adv_w = 192, .box_w = 11, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 346, .adv_w = 192, .box_w = 3, .box_h = 5, .ofs_x = 4, .ofs_y = 10}, + {.bitmap_index = 353, .adv_w = 192, .box_w = 6, .box_h = 22, .ofs_x = 3, .ofs_y = -5}, + {.bitmap_index = 413, .adv_w = 192, .box_w = 6, .box_h = 22, .ofs_x = 3, .ofs_y = -5}, + {.bitmap_index = 472, .adv_w = 192, .box_w = 10, .box_h = 10, .ofs_x = 1, .ofs_y = 5}, + {.bitmap_index = 518, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 543, .adv_w = 192, .box_w = 4, .box_h = 6, .ofs_x = 3, .ofs_y = -4}, + {.bitmap_index = 555, .adv_w = 192, .box_w = 8, .box_h = 2, .ofs_x = 2, .ofs_y = 6}, + {.bitmap_index = 561, .adv_w = 192, .box_w = 4, .box_h = 3, .ofs_x = 4, .ofs_y = 0}, + {.bitmap_index = 567, .adv_w = 192, .box_w = 9, .box_h = 16, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 617, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 689, .adv_w = 192, .box_w = 6, .box_h = 15, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 708, .adv_w = 192, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 774, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 841, .adv_w = 192, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 893, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 957, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1027, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1078, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1150, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1220, .adv_w = 192, .box_w = 4, .box_h = 11, .ofs_x = 5, .ofs_y = 0}, + {.bitmap_index = 1237, .adv_w = 192, .box_w = 5, .box_h = 15, .ofs_x = 4, .ofs_y = -4}, + {.bitmap_index = 1265, .adv_w = 192, .box_w = 9, .box_h = 10, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 1305, .adv_w = 192, .box_w = 10, .box_h = 6, .ofs_x = 1, .ofs_y = 4}, + {.bitmap_index = 1322, .adv_w = 192, .box_w = 10, .box_h = 10, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 1365, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1424, .adv_w = 192, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1513, .adv_w = 192, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1585, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1648, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1707, .adv_w = 192, .box_w = 11, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1765, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1798, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1825, .adv_w = 192, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1895, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1915, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1941, .adv_w = 192, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1975, .adv_w = 192, .box_w = 11, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2035, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2050, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2101, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2149, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2216, .adv_w = 192, .box_w = 11, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2262, .adv_w = 192, .box_w = 12, .box_h = 18, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 2351, .adv_w = 192, .box_w = 11, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2412, .adv_w = 192, .box_w = 11, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2487, .adv_w = 192, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2506, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2545, .adv_w = 192, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2619, .adv_w = 192, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2711, .adv_w = 192, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2789, .adv_w = 192, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2845, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2899, .adv_w = 192, .box_w = 5, .box_h = 20, .ofs_x = 4, .ofs_y = -3}, + {.bitmap_index = 2915, .adv_w = 192, .box_w = 8, .box_h = 16, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 2963, .adv_w = 192, .box_w = 5, .box_h = 20, .ofs_x = 3, .ofs_y = -3}, + {.bitmap_index = 2979, .adv_w = 192, .box_w = 8, .box_h = 8, .ofs_x = 2, .ofs_y = 7}, + {.bitmap_index = 3010, .adv_w = 192, .box_w = 10, .box_h = 2, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 3016, .adv_w = 192, .box_w = 4, .box_h = 3, .ofs_x = 4, .ofs_y = 12}, + {.bitmap_index = 3022, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3074, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3125, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3176, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3230, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3280, .adv_w = 192, .box_w = 11, .box_h = 16, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3325, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = -4}, + {.bitmap_index = 3392, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3424, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3459, .adv_w = 192, .box_w = 7, .box_h = 19, .ofs_x = 2, .ofs_y = -4}, + {.bitmap_index = 3493, .adv_w = 192, .box_w = 11, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3541, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3566, .adv_w = 192, .box_w = 12, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3595, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3623, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3677, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = -4}, + {.bitmap_index = 3733, .adv_w = 192, .box_w = 10, .box_h = 15, .ofs_x = 1, .ofs_y = -4}, + {.bitmap_index = 3786, .adv_w = 192, .box_w = 8, .box_h = 11, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 3806, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3861, .adv_w = 192, .box_w = 10, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3897, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3924, .adv_w = 192, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3976, .adv_w = 192, .box_w = 12, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 4043, .adv_w = 192, .box_w = 11, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 4098, .adv_w = 192, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 4169, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 4211, .adv_w = 192, .box_w = 7, .box_h = 20, .ofs_x = 3, .ofs_y = -4}, + {.bitmap_index = 4269, .adv_w = 192, .box_w = 2, .box_h = 19, .ofs_x = 5, .ofs_y = -4}, + {.bitmap_index = 4274, .adv_w = 192, .box_w = 7, .box_h = 20, .ofs_x = 3, .ofs_y = -4}, + {.bitmap_index = 4332, .adv_w = 192, .box_w = 12, .box_h = 4, .ofs_x = 0, .ofs_y = 4} +}; + +/*--------------------- + * CHARACTER MAPPING + *--------------------*/ + + + +/*Collect the unicode lists and glyph_id offsets*/ +static const lv_font_fmt_txt_cmap_t cmaps[] = +{ + { + .range_start = 32, .range_length = 95, .glyph_id_start = 1, + .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY + } +}; + + + +/*-------------------- + * ALL CUSTOM DATA + *--------------------*/ + +/*Store all the custom data of the font*/ +static lv_font_fmt_txt_dsc_t font_dsc = { + .glyph_bitmap = gylph_bitmap, + .glyph_dsc = glyph_dsc, + .cmaps = cmaps, + .kern_dsc = NULL, + .kern_scale = 0, + .cmap_num = 1, + .bpp = 4, + .kern_classes = 0, + .bitmap_format = 1 +}; + + +/*----------------- + * PUBLIC FONT + *----------------*/ + +/*Initialize a public general font descriptor*/ +lv_font_t font_3 = { + .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ + .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ + .line_height = 22, /*The maximum line height required by the font*/ + .base_line = 5, /*Baseline measured from the bottom of the line*/ +#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) + .subpx = LV_FONT_SUBPX_NONE, +#endif + .dsc = &font_dsc /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ +}; + +#endif /*#if FONT_3*/ + From e399b7a0857dd9049b65137b1d4c7a7916229c9b Mon Sep 17 00:00:00 2001 From: Fabio Guerra Date: Wed, 12 Aug 2020 00:45:06 -0300 Subject: [PATCH 125/173] Code format with astyle. --- src/lv_font/lv_font_loader.c | 1366 +++++++++++++++++----------------- src/lv_font/lv_font_loader.h | 88 +-- 2 files changed, 724 insertions(+), 730 deletions(-) diff --git a/src/lv_font/lv_font_loader.c b/src/lv_font/lv_font_loader.c index 3a292a766..8bba8bea8 100644 --- a/src/lv_font/lv_font_loader.c +++ b/src/lv_font/lv_font_loader.c @@ -1,686 +1,680 @@ -/** - * @file lv_font_loader.c - * - */ - -/********************* - * INCLUDES - *********************/ - -#include -#include - -#include "../lvgl.h" -#include "../lv_misc/lv_fs.h" -#include "lv_font_loader.h" - -#if LV_USE_FILESYSTEM - - -/********************** - * TYPEDEFS - **********************/ -typedef struct { - lv_fs_file_t * fp; - int8_t bit_pos; - uint8_t byte_value; -} bit_iterator_t; - -typedef struct font_header_bin { - uint32_t version; - uint16_t tables_count; - uint16_t font_size; - uint16_t ascent; - int16_t descent; - uint16_t typo_ascent; - int16_t typo_descent; - uint16_t typo_line_gap; - int16_t min_y; - int16_t max_y; - uint16_t default_advance_width; - uint16_t kerning_scale; - uint8_t index_to_loc_format; - uint8_t glyph_id_format; - uint8_t advance_width_format; - uint8_t bits_per_pixel; - uint8_t xy_bits; - uint8_t wh_bits; - uint8_t advance_width_bits; - uint8_t compression_id; - uint8_t subpixels_mode; - uint8_t padding; -} font_header_bin_t; - -typedef struct cmap_table_bin -{ - uint32_t data_offset; - uint32_t range_start; - uint16_t range_length; - uint16_t glyph_id_start; - uint16_t data_entries_count; - uint8_t format_type; - uint8_t padding; -} cmap_table_bin_t; - - -/********************** - * STATIC PROTOTYPES - **********************/ -static bit_iterator_t init_bit_iterator(lv_fs_file_t * fp); -static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font); -int32_t load_kern(lv_fs_file_t *fp, lv_font_fmt_txt_dsc_t * font_dsc, uint8_t format, uint32_t start); - -static int read_bits_signed(bit_iterator_t *it, int n_bits, lv_fs_res_t * res); -static int read_bits(bit_iterator_t *it, int n_bits, lv_fs_res_t * res); - - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -/** - * Loads a `lv_font_t` object from a binary font file - * @param font_name filename where the font file is located - * @return a pointer to the font or NULL in case of error - */ -lv_font_t * lv_font_load(const char * font_name) -{ - bool success = false; - - lv_font_t * font = lv_mem_alloc(sizeof(lv_font_t)); - memset(font, 0, sizeof(lv_font_t)); - - lv_fs_file_t file; - lv_fs_res_t res = lv_fs_open(&file, font_name, LV_FS_MODE_RD); - - if(res == LV_FS_RES_OK) { - success = lvgl_load_font(&file, font); - } - - if (!success) - { - LV_LOG_WARN("Error loading font file: %s\n", font_name); - lv_font_free(font); - font = NULL; - } - - lv_fs_close(&file); - - return font; -} - - -/** - * Frees the memory allocated by the `lv_font_load()` function - * @param font lv_font_t object created by the lv_font_load function - */ -void lv_font_free(lv_font_t * font) -{ - if(NULL != font) { - lv_font_fmt_txt_dsc_t * dsc = (lv_font_fmt_txt_dsc_t *) font->dsc; - - if(NULL != dsc) { - - if (dsc->kern_classes == 0) { - lv_font_fmt_txt_kern_pair_t * kern_dsc = - (lv_font_fmt_txt_kern_pair_t *) dsc->kern_dsc; - - if(NULL != kern_dsc) { - if(kern_dsc->glyph_ids) - lv_mem_free((void *) kern_dsc->glyph_ids); - - if(kern_dsc->values) - lv_mem_free((void *) kern_dsc->values); - - lv_mem_free((void *) kern_dsc); - } - } - else { - lv_font_fmt_txt_kern_classes_t * kern_dsc = - (lv_font_fmt_txt_kern_classes_t *) dsc->kern_dsc; - - if(NULL != kern_dsc) { - if(kern_dsc->class_pair_values) - lv_mem_free((void *) kern_dsc->class_pair_values); - - if(kern_dsc->left_class_mapping) - lv_mem_free((void *) kern_dsc->left_class_mapping); - - if(kern_dsc->right_class_mapping) - lv_mem_free((void *) kern_dsc->right_class_mapping); - - lv_mem_free((void *) kern_dsc); - } - } - - lv_font_fmt_txt_cmap_t * cmaps = - (lv_font_fmt_txt_cmap_t *) dsc->cmaps; - - if(NULL != cmaps) { - for(int i = 0; i < dsc->cmap_num; ++i) { - if(NULL != cmaps[i].glyph_id_ofs_list) - lv_mem_free((void *) cmaps[i].glyph_id_ofs_list); - if(NULL != cmaps[i].unicode_list) - lv_mem_free((void *) cmaps[i].unicode_list); - } - lv_mem_free(cmaps); - } - - if(NULL != dsc->glyph_bitmap) { - lv_mem_free((void *) dsc->glyph_bitmap); - } - if(NULL != dsc->glyph_dsc) { - lv_mem_free((void *) dsc->glyph_dsc); - } - lv_mem_free(dsc); - } - lv_mem_free(font); - } -} - - -/********************** - * STATIC FUNCTIONS - **********************/ - -static bit_iterator_t init_bit_iterator(lv_fs_file_t * fp) -{ - bit_iterator_t it; - it.fp = fp; - it.bit_pos = -1; - it.byte_value = 0; - return it; -} - -static int read_bits(bit_iterator_t *it, int n_bits, lv_fs_res_t * res) -{ - int value = 0; - while(n_bits--) { - it->byte_value = it->byte_value << 1; - it->bit_pos--; - - if(it->bit_pos < 0) { - it->bit_pos = 7; - *res = lv_fs_read(it->fp, &(it->byte_value), 1, NULL); - if (*res != LV_FS_RES_OK) { - return -1; - } - } - int8_t bit = (it->byte_value & 0x80) ? 1 : 0; - - value |= (bit << n_bits); - } - *res = LV_FS_RES_OK; - return value; -} - -static int read_bits_signed(bit_iterator_t *it, int n_bits, lv_fs_res_t * res) -{ - int value = read_bits(it, n_bits, res); - if (value & (1 << (n_bits-1))) { - for (int bit = n_bits; bit < 8; ++bit) { - value |= (1 << bit); - } - } - return value; -} - -static int read_label(lv_fs_file_t *fp, int start, const char *label) -{ - lv_fs_seek(fp, start); - - uint32_t length; - char buf[4]; - - if(lv_fs_read(fp, &length, 4, NULL) != LV_FS_RES_OK - || lv_fs_read(fp, buf, 4, NULL) != LV_FS_RES_OK - || memcmp(label, buf, 4) != 0) { - LV_LOG_WARN("Error reading '%s' label.", label); - return -1; - } - - return length; -} - -static bool load_cmaps_tables(lv_fs_file_t *fp, lv_font_fmt_txt_dsc_t * font_dsc, - uint32_t cmaps_start, cmap_table_bin_t * cmap_table) -{ - for(unsigned int i = 0; i < font_dsc->cmap_num; ++i) { - if(lv_fs_read(fp, &cmap_table[i], sizeof(cmap_table_bin_t), NULL) != LV_FS_RES_OK) { - return false; - } - - lv_font_fmt_txt_cmap_t * cmap = (lv_font_fmt_txt_cmap_t *) &(font_dsc->cmaps[i]); - - cmap->range_start = cmap_table[i].range_start; - cmap->range_length = cmap_table[i].range_length; - cmap->glyph_id_start = cmap_table[i].glyph_id_start; - } - - for(unsigned int i = 0; i < font_dsc->cmap_num; ++i) { - lv_fs_res_t res = lv_fs_seek(fp, cmaps_start + cmap_table[i].data_offset); - if(res != LV_FS_RES_OK) { - return false; - } - - lv_font_fmt_txt_cmap_t * cmap = (lv_font_fmt_txt_cmap_t *) &(font_dsc->cmaps[i]); - - switch(cmap_table[i].format_type) { - case 0: - { - uint8_t ids_size = sizeof(uint8_t) * cmap_table[i].data_entries_count; - uint8_t * glyph_id_ofs_list = lv_mem_alloc(ids_size); - - cmap->glyph_id_ofs_list = glyph_id_ofs_list; - - if(lv_fs_read(fp, glyph_id_ofs_list, ids_size, NULL) != LV_FS_RES_OK) { - return false; - } - - cmap->type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL; - cmap->list_length = cmap->range_length; - cmap->unicode_list = NULL; - break; - } - case 2: - cmap->type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY; - cmap->list_length = 0; - cmap->unicode_list = NULL; - cmap->glyph_id_ofs_list = NULL; - break; - case 1: - case 3: - { - uint32_t list_size = sizeof(uint16_t) * cmap_table[i].data_entries_count; - uint16_t * unicode_list = (uint16_t *) lv_mem_alloc(list_size); - - cmap->unicode_list = unicode_list; - cmap->list_length = cmap_table[i].data_entries_count; - - if(lv_fs_read(fp, unicode_list, list_size, NULL) != LV_FS_RES_OK) { - return false; - } - - if (cmap_table[i].format_type == 1) - { - uint16_t * buf = lv_mem_alloc(sizeof(uint16_t) * cmap->list_length); - - cmap->type = LV_FONT_FMT_TXT_CMAP_SPARSE_FULL; - cmap->glyph_id_ofs_list = buf; - - if(lv_fs_read(fp, buf, sizeof(uint16_t) * cmap->list_length, NULL) != LV_FS_RES_OK) { - return false; - } - } - else - { - cmap->type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY; - cmap->glyph_id_ofs_list = NULL; - } - break; - } - default: - LV_LOG_WARN("Unknown cmaps format type %d.", cmap_table[i].format_type); - return false; - } - } - return true; -} - -static int32_t load_cmaps(lv_fs_file_t *fp, lv_font_fmt_txt_dsc_t * font_dsc, uint32_t cmaps_start) -{ - int32_t cmaps_length = read_label(fp, cmaps_start, "cmap"); - if (cmaps_length < 0) { - return -1; - } - - uint32_t cmaps_subtables_count; - if(lv_fs_read(fp, &cmaps_subtables_count, sizeof(uint32_t), NULL) != LV_FS_RES_OK) { - return -1; - } - - lv_font_fmt_txt_cmap_t * cmaps = - lv_mem_alloc(cmaps_subtables_count * sizeof(lv_font_fmt_txt_cmap_t)); - - memset(cmaps, 0, cmaps_subtables_count * sizeof(lv_font_fmt_txt_cmap_t)); - - font_dsc->cmaps = cmaps; - font_dsc->cmap_num = cmaps_subtables_count; - - cmap_table_bin_t * cmaps_tables = lv_mem_alloc(sizeof(cmap_table_bin_t) * font_dsc->cmap_num); - - bool success = load_cmaps_tables(fp, font_dsc, cmaps_start, cmaps_tables); - - lv_mem_free(cmaps_tables); - - return success ? cmaps_length : -1; -} - -static int32_t load_glyph(lv_fs_file_t *fp, lv_font_fmt_txt_dsc_t * font_dsc, - uint32_t start, uint32_t *glyph_offset, uint32_t loca_count, font_header_bin_t *header) -{ - int32_t glyph_length = read_label(fp, start, "glyf"); - if (glyph_length < 0) { - return -1; - } - - lv_font_fmt_txt_glyph_dsc_t * glyph_dsc = (lv_font_fmt_txt_glyph_dsc_t *) - lv_mem_alloc(loca_count * sizeof(lv_font_fmt_txt_glyph_dsc_t)); - - memset(glyph_dsc, 0, loca_count * sizeof(lv_font_fmt_txt_glyph_dsc_t)); - - font_dsc->glyph_dsc = glyph_dsc; - - int cur_bmp_size = 0; - - for(unsigned int i = 0; i < loca_count; ++i) { - lv_font_fmt_txt_glyph_dsc_t * gdsc = &glyph_dsc[i]; - - lv_fs_res_t res = lv_fs_seek(fp, start + glyph_offset[i]); - if(res != LV_FS_RES_OK) { - return -1; - } - - bit_iterator_t bit_it = init_bit_iterator(fp); - - if(header->advance_width_bits == 0) { - gdsc->adv_w = header->default_advance_width; - } - else { - gdsc->adv_w = read_bits(&bit_it, header->advance_width_bits, &res); - if(res != LV_FS_RES_OK) { - return -1; - } - } - - if(header->advance_width_format == 0) { - gdsc->adv_w *= 16; - } - - gdsc->ofs_x = read_bits_signed(&bit_it, header->xy_bits, &res); - if(res != LV_FS_RES_OK) { - return -1; - } - - gdsc->ofs_y = read_bits_signed(&bit_it, header->xy_bits, &res); - if(res != LV_FS_RES_OK) { - return -1; - } - - gdsc->box_w = read_bits(&bit_it, header->wh_bits, &res); - if(res != LV_FS_RES_OK) { - return -1; - } - - gdsc->box_h = read_bits(&bit_it, header->wh_bits, &res); - if(res != LV_FS_RES_OK) { - return -1; - } - - int nbits = header->advance_width_bits + 2 * header->xy_bits + 2 * header->wh_bits; - int next_offset = (i < loca_count - 1) ? glyph_offset[i + 1] : (uint32_t) (glyph_length - 1); - int bmp_size = next_offset - glyph_offset[i] - nbits / 8; - - if(i == 0) { - gdsc->adv_w = 0; - gdsc->box_w = 0; - gdsc->box_h = 0; - gdsc->ofs_x = 0; - gdsc->ofs_y = 0; - } - - gdsc->bitmap_index = cur_bmp_size; - if(gdsc->box_w * gdsc->box_h != 0) { - cur_bmp_size += bmp_size; - } - } - - uint8_t * glyph_bmp = (uint8_t *) lv_mem_alloc(sizeof(uint8_t) * cur_bmp_size); - - font_dsc->glyph_bitmap = glyph_bmp; - - cur_bmp_size = 0; - - for(unsigned int i = 1; i < loca_count; ++i) { - lv_fs_res_t res = lv_fs_seek(fp, start + glyph_offset[i]); - if(res != LV_FS_RES_OK) { - return -1; - } - bit_iterator_t bit_it = init_bit_iterator(fp); - - int nbits = header->advance_width_bits + 2 * header->xy_bits + 2 * header->wh_bits; - - read_bits(&bit_it, nbits, &res); - if(res != LV_FS_RES_OK) { - return -1; - } - - if(glyph_dsc[i].box_w * glyph_dsc[i].box_h == 0) { - continue; - } - - int next_offset = (i < loca_count - 1) ? glyph_offset[i + 1] : (uint32_t) (glyph_length - 1); - int bmp_size = next_offset - glyph_offset[i] - nbits / 8; - - for(int k = 0; k < bmp_size; ++k) { - glyph_bmp[cur_bmp_size + k] = read_bits(&bit_it, 8, &res); - if(res != LV_FS_RES_OK) { - return -1; - } - } - cur_bmp_size += bmp_size; - } - return glyph_length; -} - -static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font) -{ - lv_font_fmt_txt_dsc_t * font_dsc = (lv_font_fmt_txt_dsc_t *) - lv_mem_alloc(sizeof(lv_font_fmt_txt_dsc_t)); - - memset(font_dsc, 0, sizeof(lv_font_fmt_txt_dsc_t)); - - font->dsc = font_dsc; - - /* header */ - int32_t header_length = read_label(fp, 0, "head"); - if (header_length < 0) { - return false; - } - - font_header_bin_t font_header; - if(lv_fs_read(fp, &font_header, sizeof(font_header_bin_t), NULL) != LV_FS_RES_OK) { - return false; - } - - font->base_line = -font_header.descent; - font->line_height = font_header.ascent - font_header.descent; - font->get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt; - font->get_glyph_bitmap = lv_font_get_bitmap_fmt_txt; - -#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) - font->subpx = LV_FONT_SUBPX_NONE; -#endif - - font_dsc->bpp = font_header.bits_per_pixel; - font_dsc->kern_scale = font_header.kerning_scale; - font_dsc->bitmap_format = font_header.compression_id; - - /* cmaps */ - uint32_t cmaps_start = header_length; - int32_t cmaps_length = load_cmaps(fp, font_dsc, cmaps_start); - if (cmaps_length < 0) { - return false; - } - - /* loca */ - uint32_t loca_start = cmaps_start + cmaps_length; - int32_t loca_length = read_label(fp, loca_start, "loca"); - if (loca_length < 0) { - return false; - } - - uint32_t loca_count; - if(lv_fs_read(fp, &loca_count, sizeof(uint32_t), NULL) != LV_FS_RES_OK) { - return false; - } - - bool failed = false; - uint32_t *glyph_offset = lv_mem_alloc(sizeof(uint32_t) * (loca_count + 1)); - - for(unsigned int i = 0; i < loca_count; ++i) { - if(font_header.index_to_loc_format == 0) { - uint16_t offset; - if(lv_fs_read(fp, &offset, sizeof(uint16_t), NULL) != LV_FS_RES_OK) { - failed = true; - break; - } - glyph_offset[i] = offset; - } - else if(font_header.index_to_loc_format == 1) { - uint32_t offset; - if(lv_fs_read(fp, &offset, sizeof(uint32_t), NULL) != LV_FS_RES_OK) { - failed = true; - break; - } - glyph_offset[i] = offset; - } - else { - LV_LOG_WARN("Unknown index_to_loc_format: %d.", font_header.index_to_loc_format); - failed = true; - break; - } - } - - if (failed) { - lv_mem_free(glyph_offset); - return false; - } - - /* glyph */ - uint32_t glyph_start = loca_start + loca_length; - int32_t glyph_length = load_glyph( - fp, font_dsc, glyph_start, glyph_offset, loca_count, &font_header); - - lv_mem_free(glyph_offset); - - if (glyph_length < 0) { - return false; - } - - if (font_header.tables_count < 4) { - font_dsc->kern_dsc = NULL; - font_dsc->kern_classes = 0; - font_dsc->kern_scale = 0; - return true; - } - - uint32_t kern_start = glyph_start + glyph_length; - - int32_t kern_length = load_kern(fp, font_dsc, font_header.glyph_id_format, kern_start); - - return kern_length >= 0; -} - -int32_t load_kern(lv_fs_file_t *fp, lv_font_fmt_txt_dsc_t * font_dsc, uint8_t format, uint32_t start) -{ - int32_t kern_length = read_label(fp, start, "kern"); - if (kern_length < 0) { - return -1; - } - - uint8_t kern_format_type; - int32_t padding; - if (lv_fs_read(fp, &kern_format_type, sizeof(uint8_t), NULL) != LV_FS_RES_OK || - lv_fs_read(fp, &padding, 3 * sizeof(uint8_t), NULL) != LV_FS_RES_OK) { - return -1; - } - - if(0 == kern_format_type) { /* sorted pairs */ - lv_font_fmt_txt_kern_pair_t * kern_pair = lv_mem_alloc(sizeof(lv_font_fmt_txt_kern_pair_t)); - - memset(kern_pair, 0, sizeof(lv_font_fmt_txt_kern_pair_t)); - - font_dsc->kern_dsc = kern_pair; - font_dsc->kern_classes = 0; - - uint32_t glyph_entries; - if (lv_fs_read(fp, &glyph_entries, sizeof(uint32_t), NULL) != LV_FS_RES_OK) { - return -1; - } - - int ids_size; - if (format == 0) { - ids_size = sizeof(int8_t) * 2 * glyph_entries; - } - else { - ids_size = sizeof(int16_t) * 2 * glyph_entries; - } - - uint8_t * glyph_ids = lv_mem_alloc(ids_size); - int8_t * values = lv_mem_alloc(glyph_entries); - - kern_pair->glyph_ids_size = format; - kern_pair->pair_cnt = glyph_entries; - kern_pair->glyph_ids = glyph_ids; - kern_pair->values = values; - - if (lv_fs_read(fp, glyph_ids, ids_size, NULL) != LV_FS_RES_OK) { - return -1; - } - - if (lv_fs_read(fp, values, glyph_entries, NULL) != LV_FS_RES_OK) { - return -1; - } - } - else if(3 == kern_format_type) { /* array M*N of classes */ - - lv_font_fmt_txt_kern_classes_t * kern_classes = lv_mem_alloc(sizeof(lv_font_fmt_txt_kern_classes_t)); - - memset(kern_classes, 0, sizeof(lv_font_fmt_txt_kern_classes_t)); - - font_dsc->kern_dsc = kern_classes; - font_dsc->kern_classes = 1; - - uint16_t kern_class_mapping_length; - uint8_t kern_table_rows; - uint8_t kern_table_cols; - - if(lv_fs_read(fp, &kern_class_mapping_length, sizeof(uint16_t), NULL) != LV_FS_RES_OK || - lv_fs_read(fp, &kern_table_rows, sizeof(uint8_t), NULL) != LV_FS_RES_OK || - lv_fs_read(fp, &kern_table_cols, sizeof(uint8_t), NULL) != LV_FS_RES_OK) { - return -1; - } - - int kern_values_length = sizeof(int8_t) * kern_table_rows * kern_table_cols; - - uint8_t * kern_left = lv_mem_alloc(kern_class_mapping_length); - uint8_t * kern_right = lv_mem_alloc(kern_class_mapping_length); - int8_t * kern_values = lv_mem_alloc(kern_values_length); - - kern_classes->left_class_mapping = kern_left; - kern_classes->right_class_mapping = kern_right; - kern_classes->left_class_cnt = kern_table_rows; - kern_classes->right_class_cnt = kern_table_cols; - kern_classes->class_pair_values = kern_values; - - if(lv_fs_read(fp, kern_left, kern_class_mapping_length, NULL) != LV_FS_RES_OK || - lv_fs_read(fp, kern_right, kern_class_mapping_length, NULL) != LV_FS_RES_OK || - lv_fs_read(fp, kern_values, kern_values_length, NULL) != LV_FS_RES_OK) { - return -1; - } - } - else { - LV_LOG_WARN("Unknown kern_format_type: %d", kern_format_type); - return -1; - } - - return kern_length; -} - -#endif /*LV_USE_FILESYSTEM*/ - +/** + * @file lv_font_loader.c + * + */ + +/********************* + * INCLUDES + *********************/ + +#include +#include + +#include "../lvgl.h" +#include "../lv_misc/lv_fs.h" +#include "lv_font_loader.h" + +#if LV_USE_FILESYSTEM + + +/********************** + * TYPEDEFS + **********************/ +typedef struct { + lv_fs_file_t * fp; + int8_t bit_pos; + uint8_t byte_value; +} bit_iterator_t; + +typedef struct font_header_bin { + uint32_t version; + uint16_t tables_count; + uint16_t font_size; + uint16_t ascent; + int16_t descent; + uint16_t typo_ascent; + int16_t typo_descent; + uint16_t typo_line_gap; + int16_t min_y; + int16_t max_y; + uint16_t default_advance_width; + uint16_t kerning_scale; + uint8_t index_to_loc_format; + uint8_t glyph_id_format; + uint8_t advance_width_format; + uint8_t bits_per_pixel; + uint8_t xy_bits; + uint8_t wh_bits; + uint8_t advance_width_bits; + uint8_t compression_id; + uint8_t subpixels_mode; + uint8_t padding; +} font_header_bin_t; + +typedef struct cmap_table_bin { + uint32_t data_offset; + uint32_t range_start; + uint16_t range_length; + uint16_t glyph_id_start; + uint16_t data_entries_count; + uint8_t format_type; + uint8_t padding; +} cmap_table_bin_t; + + +/********************** + * STATIC PROTOTYPES + **********************/ +static bit_iterator_t init_bit_iterator(lv_fs_file_t * fp); +static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font); +int32_t load_kern(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc, uint8_t format, uint32_t start); + +static int read_bits_signed(bit_iterator_t * it, int n_bits, lv_fs_res_t * res); +static int read_bits(bit_iterator_t * it, int n_bits, lv_fs_res_t * res); + + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * Loads a `lv_font_t` object from a binary font file + * @param font_name filename where the font file is located + * @return a pointer to the font or NULL in case of error + */ +lv_font_t * lv_font_load(const char * font_name) +{ + bool success = false; + + lv_font_t * font = lv_mem_alloc(sizeof(lv_font_t)); + memset(font, 0, sizeof(lv_font_t)); + + lv_fs_file_t file; + lv_fs_res_t res = lv_fs_open(&file, font_name, LV_FS_MODE_RD); + + if(res == LV_FS_RES_OK) { + success = lvgl_load_font(&file, font); + } + + if(!success) { + LV_LOG_WARN("Error loading font file: %s\n", font_name); + lv_font_free(font); + font = NULL; + } + + lv_fs_close(&file); + + return font; +} + + +/** + * Frees the memory allocated by the `lv_font_load()` function + * @param font lv_font_t object created by the lv_font_load function + */ +void lv_font_free(lv_font_t * font) +{ + if(NULL != font) { + lv_font_fmt_txt_dsc_t * dsc = (lv_font_fmt_txt_dsc_t *) font->dsc; + + if(NULL != dsc) { + + if(dsc->kern_classes == 0) { + lv_font_fmt_txt_kern_pair_t * kern_dsc = + (lv_font_fmt_txt_kern_pair_t *) dsc->kern_dsc; + + if(NULL != kern_dsc) { + if(kern_dsc->glyph_ids) + lv_mem_free((void *) kern_dsc->glyph_ids); + + if(kern_dsc->values) + lv_mem_free((void *) kern_dsc->values); + + lv_mem_free((void *) kern_dsc); + } + } + else { + lv_font_fmt_txt_kern_classes_t * kern_dsc = + (lv_font_fmt_txt_kern_classes_t *) dsc->kern_dsc; + + if(NULL != kern_dsc) { + if(kern_dsc->class_pair_values) + lv_mem_free((void *) kern_dsc->class_pair_values); + + if(kern_dsc->left_class_mapping) + lv_mem_free((void *) kern_dsc->left_class_mapping); + + if(kern_dsc->right_class_mapping) + lv_mem_free((void *) kern_dsc->right_class_mapping); + + lv_mem_free((void *) kern_dsc); + } + } + + lv_font_fmt_txt_cmap_t * cmaps = + (lv_font_fmt_txt_cmap_t *) dsc->cmaps; + + if(NULL != cmaps) { + for(int i = 0; i < dsc->cmap_num; ++i) { + if(NULL != cmaps[i].glyph_id_ofs_list) + lv_mem_free((void *) cmaps[i].glyph_id_ofs_list); + if(NULL != cmaps[i].unicode_list) + lv_mem_free((void *) cmaps[i].unicode_list); + } + lv_mem_free(cmaps); + } + + if(NULL != dsc->glyph_bitmap) { + lv_mem_free((void *) dsc->glyph_bitmap); + } + if(NULL != dsc->glyph_dsc) { + lv_mem_free((void *) dsc->glyph_dsc); + } + lv_mem_free(dsc); + } + lv_mem_free(font); + } +} + + +/********************** + * STATIC FUNCTIONS + **********************/ + +static bit_iterator_t init_bit_iterator(lv_fs_file_t * fp) +{ + bit_iterator_t it; + it.fp = fp; + it.bit_pos = -1; + it.byte_value = 0; + return it; +} + +static int read_bits(bit_iterator_t * it, int n_bits, lv_fs_res_t * res) +{ + int value = 0; + while(n_bits--) { + it->byte_value = it->byte_value << 1; + it->bit_pos--; + + if(it->bit_pos < 0) { + it->bit_pos = 7; + *res = lv_fs_read(it->fp, &(it->byte_value), 1, NULL); + if(*res != LV_FS_RES_OK) { + return -1; + } + } + int8_t bit = (it->byte_value & 0x80) ? 1 : 0; + + value |= (bit << n_bits); + } + *res = LV_FS_RES_OK; + return value; +} + +static int read_bits_signed(bit_iterator_t * it, int n_bits, lv_fs_res_t * res) +{ + int value = read_bits(it, n_bits, res); + if(value & (1 << (n_bits - 1))) { + for(int bit = n_bits; bit < 8; ++bit) { + value |= (1 << bit); + } + } + return value; +} + +static int read_label(lv_fs_file_t * fp, int start, const char * label) +{ + lv_fs_seek(fp, start); + + uint32_t length; + char buf[4]; + + if(lv_fs_read(fp, &length, 4, NULL) != LV_FS_RES_OK + || lv_fs_read(fp, buf, 4, NULL) != LV_FS_RES_OK + || memcmp(label, buf, 4) != 0) { + LV_LOG_WARN("Error reading '%s' label.", label); + return -1; + } + + return length; +} + +static bool load_cmaps_tables(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc, + uint32_t cmaps_start, cmap_table_bin_t * cmap_table) +{ + for(unsigned int i = 0; i < font_dsc->cmap_num; ++i) { + if(lv_fs_read(fp, &cmap_table[i], sizeof(cmap_table_bin_t), NULL) != LV_FS_RES_OK) { + return false; + } + + lv_font_fmt_txt_cmap_t * cmap = (lv_font_fmt_txt_cmap_t *) & (font_dsc->cmaps[i]); + + cmap->range_start = cmap_table[i].range_start; + cmap->range_length = cmap_table[i].range_length; + cmap->glyph_id_start = cmap_table[i].glyph_id_start; + } + + for(unsigned int i = 0; i < font_dsc->cmap_num; ++i) { + lv_fs_res_t res = lv_fs_seek(fp, cmaps_start + cmap_table[i].data_offset); + if(res != LV_FS_RES_OK) { + return false; + } + + lv_font_fmt_txt_cmap_t * cmap = (lv_font_fmt_txt_cmap_t *) & (font_dsc->cmaps[i]); + + switch(cmap_table[i].format_type) { + case 0: { + uint8_t ids_size = sizeof(uint8_t) * cmap_table[i].data_entries_count; + uint8_t * glyph_id_ofs_list = lv_mem_alloc(ids_size); + + cmap->glyph_id_ofs_list = glyph_id_ofs_list; + + if(lv_fs_read(fp, glyph_id_ofs_list, ids_size, NULL) != LV_FS_RES_OK) { + return false; + } + + cmap->type = LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL; + cmap->list_length = cmap->range_length; + cmap->unicode_list = NULL; + break; + } + case 2: + cmap->type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY; + cmap->list_length = 0; + cmap->unicode_list = NULL; + cmap->glyph_id_ofs_list = NULL; + break; + case 1: + case 3: { + uint32_t list_size = sizeof(uint16_t) * cmap_table[i].data_entries_count; + uint16_t * unicode_list = (uint16_t *) lv_mem_alloc(list_size); + + cmap->unicode_list = unicode_list; + cmap->list_length = cmap_table[i].data_entries_count; + + if(lv_fs_read(fp, unicode_list, list_size, NULL) != LV_FS_RES_OK) { + return false; + } + + if(cmap_table[i].format_type == 1) { + uint16_t * buf = lv_mem_alloc(sizeof(uint16_t) * cmap->list_length); + + cmap->type = LV_FONT_FMT_TXT_CMAP_SPARSE_FULL; + cmap->glyph_id_ofs_list = buf; + + if(lv_fs_read(fp, buf, sizeof(uint16_t) * cmap->list_length, NULL) != LV_FS_RES_OK) { + return false; + } + } + else { + cmap->type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY; + cmap->glyph_id_ofs_list = NULL; + } + break; + } + default: + LV_LOG_WARN("Unknown cmaps format type %d.", cmap_table[i].format_type); + return false; + } + } + return true; +} + +static int32_t load_cmaps(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc, uint32_t cmaps_start) +{ + int32_t cmaps_length = read_label(fp, cmaps_start, "cmap"); + if(cmaps_length < 0) { + return -1; + } + + uint32_t cmaps_subtables_count; + if(lv_fs_read(fp, &cmaps_subtables_count, sizeof(uint32_t), NULL) != LV_FS_RES_OK) { + return -1; + } + + lv_font_fmt_txt_cmap_t * cmaps = + lv_mem_alloc(cmaps_subtables_count * sizeof(lv_font_fmt_txt_cmap_t)); + + memset(cmaps, 0, cmaps_subtables_count * sizeof(lv_font_fmt_txt_cmap_t)); + + font_dsc->cmaps = cmaps; + font_dsc->cmap_num = cmaps_subtables_count; + + cmap_table_bin_t * cmaps_tables = lv_mem_alloc(sizeof(cmap_table_bin_t) * font_dsc->cmap_num); + + bool success = load_cmaps_tables(fp, font_dsc, cmaps_start, cmaps_tables); + + lv_mem_free(cmaps_tables); + + return success ? cmaps_length : -1; +} + +static int32_t load_glyph(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc, + uint32_t start, uint32_t * glyph_offset, uint32_t loca_count, font_header_bin_t * header) +{ + int32_t glyph_length = read_label(fp, start, "glyf"); + if(glyph_length < 0) { + return -1; + } + + lv_font_fmt_txt_glyph_dsc_t * glyph_dsc = (lv_font_fmt_txt_glyph_dsc_t *) + lv_mem_alloc(loca_count * sizeof(lv_font_fmt_txt_glyph_dsc_t)); + + memset(glyph_dsc, 0, loca_count * sizeof(lv_font_fmt_txt_glyph_dsc_t)); + + font_dsc->glyph_dsc = glyph_dsc; + + int cur_bmp_size = 0; + + for(unsigned int i = 0; i < loca_count; ++i) { + lv_font_fmt_txt_glyph_dsc_t * gdsc = &glyph_dsc[i]; + + lv_fs_res_t res = lv_fs_seek(fp, start + glyph_offset[i]); + if(res != LV_FS_RES_OK) { + return -1; + } + + bit_iterator_t bit_it = init_bit_iterator(fp); + + if(header->advance_width_bits == 0) { + gdsc->adv_w = header->default_advance_width; + } + else { + gdsc->adv_w = read_bits(&bit_it, header->advance_width_bits, &res); + if(res != LV_FS_RES_OK) { + return -1; + } + } + + if(header->advance_width_format == 0) { + gdsc->adv_w *= 16; + } + + gdsc->ofs_x = read_bits_signed(&bit_it, header->xy_bits, &res); + if(res != LV_FS_RES_OK) { + return -1; + } + + gdsc->ofs_y = read_bits_signed(&bit_it, header->xy_bits, &res); + if(res != LV_FS_RES_OK) { + return -1; + } + + gdsc->box_w = read_bits(&bit_it, header->wh_bits, &res); + if(res != LV_FS_RES_OK) { + return -1; + } + + gdsc->box_h = read_bits(&bit_it, header->wh_bits, &res); + if(res != LV_FS_RES_OK) { + return -1; + } + + int nbits = header->advance_width_bits + 2 * header->xy_bits + 2 * header->wh_bits; + int next_offset = (i < loca_count - 1) ? glyph_offset[i + 1] : (uint32_t)(glyph_length - 1); + int bmp_size = next_offset - glyph_offset[i] - nbits / 8; + + if(i == 0) { + gdsc->adv_w = 0; + gdsc->box_w = 0; + gdsc->box_h = 0; + gdsc->ofs_x = 0; + gdsc->ofs_y = 0; + } + + gdsc->bitmap_index = cur_bmp_size; + if(gdsc->box_w * gdsc->box_h != 0) { + cur_bmp_size += bmp_size; + } + } + + uint8_t * glyph_bmp = (uint8_t *) lv_mem_alloc(sizeof(uint8_t) * cur_bmp_size); + + font_dsc->glyph_bitmap = glyph_bmp; + + cur_bmp_size = 0; + + for(unsigned int i = 1; i < loca_count; ++i) { + lv_fs_res_t res = lv_fs_seek(fp, start + glyph_offset[i]); + if(res != LV_FS_RES_OK) { + return -1; + } + bit_iterator_t bit_it = init_bit_iterator(fp); + + int nbits = header->advance_width_bits + 2 * header->xy_bits + 2 * header->wh_bits; + + read_bits(&bit_it, nbits, &res); + if(res != LV_FS_RES_OK) { + return -1; + } + + if(glyph_dsc[i].box_w * glyph_dsc[i].box_h == 0) { + continue; + } + + int next_offset = (i < loca_count - 1) ? glyph_offset[i + 1] : (uint32_t)(glyph_length - 1); + int bmp_size = next_offset - glyph_offset[i] - nbits / 8; + + for(int k = 0; k < bmp_size; ++k) { + glyph_bmp[cur_bmp_size + k] = read_bits(&bit_it, 8, &res); + if(res != LV_FS_RES_OK) { + return -1; + } + } + cur_bmp_size += bmp_size; + } + return glyph_length; +} + +static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font) +{ + lv_font_fmt_txt_dsc_t * font_dsc = (lv_font_fmt_txt_dsc_t *) + lv_mem_alloc(sizeof(lv_font_fmt_txt_dsc_t)); + + memset(font_dsc, 0, sizeof(lv_font_fmt_txt_dsc_t)); + + font->dsc = font_dsc; + + /* header */ + int32_t header_length = read_label(fp, 0, "head"); + if(header_length < 0) { + return false; + } + + font_header_bin_t font_header; + if(lv_fs_read(fp, &font_header, sizeof(font_header_bin_t), NULL) != LV_FS_RES_OK) { + return false; + } + + font->base_line = -font_header.descent; + font->line_height = font_header.ascent - font_header.descent; + font->get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt; + font->get_glyph_bitmap = lv_font_get_bitmap_fmt_txt; + +#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) + font->subpx = LV_FONT_SUBPX_NONE; +#endif + + font_dsc->bpp = font_header.bits_per_pixel; + font_dsc->kern_scale = font_header.kerning_scale; + font_dsc->bitmap_format = font_header.compression_id; + + /* cmaps */ + uint32_t cmaps_start = header_length; + int32_t cmaps_length = load_cmaps(fp, font_dsc, cmaps_start); + if(cmaps_length < 0) { + return false; + } + + /* loca */ + uint32_t loca_start = cmaps_start + cmaps_length; + int32_t loca_length = read_label(fp, loca_start, "loca"); + if(loca_length < 0) { + return false; + } + + uint32_t loca_count; + if(lv_fs_read(fp, &loca_count, sizeof(uint32_t), NULL) != LV_FS_RES_OK) { + return false; + } + + bool failed = false; + uint32_t * glyph_offset = lv_mem_alloc(sizeof(uint32_t) * (loca_count + 1)); + + for(unsigned int i = 0; i < loca_count; ++i) { + if(font_header.index_to_loc_format == 0) { + uint16_t offset; + if(lv_fs_read(fp, &offset, sizeof(uint16_t), NULL) != LV_FS_RES_OK) { + failed = true; + break; + } + glyph_offset[i] = offset; + } + else if(font_header.index_to_loc_format == 1) { + uint32_t offset; + if(lv_fs_read(fp, &offset, sizeof(uint32_t), NULL) != LV_FS_RES_OK) { + failed = true; + break; + } + glyph_offset[i] = offset; + } + else { + LV_LOG_WARN("Unknown index_to_loc_format: %d.", font_header.index_to_loc_format); + failed = true; + break; + } + } + + if(failed) { + lv_mem_free(glyph_offset); + return false; + } + + /* glyph */ + uint32_t glyph_start = loca_start + loca_length; + int32_t glyph_length = load_glyph( + fp, font_dsc, glyph_start, glyph_offset, loca_count, &font_header); + + lv_mem_free(glyph_offset); + + if(glyph_length < 0) { + return false; + } + + if(font_header.tables_count < 4) { + font_dsc->kern_dsc = NULL; + font_dsc->kern_classes = 0; + font_dsc->kern_scale = 0; + return true; + } + + uint32_t kern_start = glyph_start + glyph_length; + + int32_t kern_length = load_kern(fp, font_dsc, font_header.glyph_id_format, kern_start); + + return kern_length >= 0; +} + +int32_t load_kern(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc, uint8_t format, uint32_t start) +{ + int32_t kern_length = read_label(fp, start, "kern"); + if(kern_length < 0) { + return -1; + } + + uint8_t kern_format_type; + int32_t padding; + if(lv_fs_read(fp, &kern_format_type, sizeof(uint8_t), NULL) != LV_FS_RES_OK || + lv_fs_read(fp, &padding, 3 * sizeof(uint8_t), NULL) != LV_FS_RES_OK) { + return -1; + } + + if(0 == kern_format_type) { /* sorted pairs */ + lv_font_fmt_txt_kern_pair_t * kern_pair = lv_mem_alloc(sizeof(lv_font_fmt_txt_kern_pair_t)); + + memset(kern_pair, 0, sizeof(lv_font_fmt_txt_kern_pair_t)); + + font_dsc->kern_dsc = kern_pair; + font_dsc->kern_classes = 0; + + uint32_t glyph_entries; + if(lv_fs_read(fp, &glyph_entries, sizeof(uint32_t), NULL) != LV_FS_RES_OK) { + return -1; + } + + int ids_size; + if(format == 0) { + ids_size = sizeof(int8_t) * 2 * glyph_entries; + } + else { + ids_size = sizeof(int16_t) * 2 * glyph_entries; + } + + uint8_t * glyph_ids = lv_mem_alloc(ids_size); + int8_t * values = lv_mem_alloc(glyph_entries); + + kern_pair->glyph_ids_size = format; + kern_pair->pair_cnt = glyph_entries; + kern_pair->glyph_ids = glyph_ids; + kern_pair->values = values; + + if(lv_fs_read(fp, glyph_ids, ids_size, NULL) != LV_FS_RES_OK) { + return -1; + } + + if(lv_fs_read(fp, values, glyph_entries, NULL) != LV_FS_RES_OK) { + return -1; + } + } + else if(3 == kern_format_type) { /* array M*N of classes */ + + lv_font_fmt_txt_kern_classes_t * kern_classes = lv_mem_alloc(sizeof(lv_font_fmt_txt_kern_classes_t)); + + memset(kern_classes, 0, sizeof(lv_font_fmt_txt_kern_classes_t)); + + font_dsc->kern_dsc = kern_classes; + font_dsc->kern_classes = 1; + + uint16_t kern_class_mapping_length; + uint8_t kern_table_rows; + uint8_t kern_table_cols; + + if(lv_fs_read(fp, &kern_class_mapping_length, sizeof(uint16_t), NULL) != LV_FS_RES_OK || + lv_fs_read(fp, &kern_table_rows, sizeof(uint8_t), NULL) != LV_FS_RES_OK || + lv_fs_read(fp, &kern_table_cols, sizeof(uint8_t), NULL) != LV_FS_RES_OK) { + return -1; + } + + int kern_values_length = sizeof(int8_t) * kern_table_rows * kern_table_cols; + + uint8_t * kern_left = lv_mem_alloc(kern_class_mapping_length); + uint8_t * kern_right = lv_mem_alloc(kern_class_mapping_length); + int8_t * kern_values = lv_mem_alloc(kern_values_length); + + kern_classes->left_class_mapping = kern_left; + kern_classes->right_class_mapping = kern_right; + kern_classes->left_class_cnt = kern_table_rows; + kern_classes->right_class_cnt = kern_table_cols; + kern_classes->class_pair_values = kern_values; + + if(lv_fs_read(fp, kern_left, kern_class_mapping_length, NULL) != LV_FS_RES_OK || + lv_fs_read(fp, kern_right, kern_class_mapping_length, NULL) != LV_FS_RES_OK || + lv_fs_read(fp, kern_values, kern_values_length, NULL) != LV_FS_RES_OK) { + return -1; + } + } + else { + LV_LOG_WARN("Unknown kern_format_type: %d", kern_format_type); + return -1; + } + + return kern_length; +} + +#endif /*LV_USE_FILESYSTEM*/ + diff --git a/src/lv_font/lv_font_loader.h b/src/lv_font/lv_font_loader.h index 773ba8f8a..126ae5def 100644 --- a/src/lv_font/lv_font_loader.h +++ b/src/lv_font/lv_font_loader.h @@ -1,44 +1,44 @@ -/** - * @file lv_font_loader.h - * - */ - -#ifndef LV_FONT_LOADER_H -#define LV_FONT_LOADER_H - -#ifdef __cplusplus -extern "C" { -#endif - -/********************* - * INCLUDES - *********************/ - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * GLOBAL PROTOTYPES - **********************/ - -#if LV_USE_FILESYSTEM - -lv_font_t * lv_font_load(const char * fontName); -void lv_font_free(lv_font_t * font); - -#endif - -/********************** - * MACROS - **********************/ - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /*LV_FONT_LOADER_H*/ +/** + * @file lv_font_loader.h + * + */ + +#ifndef LV_FONT_LOADER_H +#define LV_FONT_LOADER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +#if LV_USE_FILESYSTEM + +lv_font_t * lv_font_load(const char * fontName); +void lv_font_free(lv_font_t * font); + +#endif + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_FONT_LOADER_H*/ From 08684b31eed30f7dc896f5309acd82c7acd88dda Mon Sep 17 00:00:00 2001 From: Ali Rostami <9710249+ali-rostami@users.noreply.github.com> Date: Wed, 12 Aug 2020 09:28:15 +0430 Subject: [PATCH 126/173] Patch 1 (#1714) update comments --- src/lv_draw/lv_img_cache.c | 2 +- src/lv_draw/lv_img_cache.h | 2 +- src/lv_draw/lv_img_decoder.c | 2 +- src/lv_draw/lv_img_decoder.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lv_draw/lv_img_cache.c b/src/lv_draw/lv_img_cache.c index 8db00b175..cef32144f 100644 --- a/src/lv_draw/lv_img_cache.c +++ b/src/lv_draw/lv_img_cache.c @@ -59,7 +59,7 @@ static uint16_t entry_cnt; * The image will be left open meaning if the image decoder open callback allocated memory then it will remain. * The image is closed if a new image is opened and the new image takes its place in the cache. * @param src source of the image. Path to file or pointer to an `lv_img_dsc_t` variable - * @param style style of the image + * @param color color The color of the image with `LV_IMG_CF_ALPHA_...` * @return pointer to the cache entry or NULL if can open the image */ lv_img_cache_entry_t * _lv_img_cache_open(const void * src, lv_color_t color) diff --git a/src/lv_draw/lv_img_cache.h b/src/lv_draw/lv_img_cache.h index 641785f8c..6106aff90 100644 --- a/src/lv_draw/lv_img_cache.h +++ b/src/lv_draw/lv_img_cache.h @@ -46,7 +46,7 @@ typedef struct { * The image will be left open meaning if the image decoder open callback allocated memory then it will remain. * The image is closed if a new image is opened and the new image takes its place in the cache. * @param src source of the image. Path to file or pointer to an `lv_img_dsc_t` variable - * @param style style of the image + * @param color The color of the image with `LV_IMG_CF_ALPHA_...` * @return pointer to the cache entry or NULL if can open the image */ lv_img_cache_entry_t * _lv_img_cache_open(const void * src, lv_color_t color); diff --git a/src/lv_draw/lv_img_decoder.c b/src/lv_draw/lv_img_decoder.c index 57e99e297..895c064bb 100644 --- a/src/lv_draw/lv_img_decoder.c +++ b/src/lv_draw/lv_img_decoder.c @@ -114,7 +114,7 @@ lv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header) * 1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_add_drv()`) * 2) Variable: Pointer to an `lv_img_dsc_t` variable * 3) Symbol: E.g. `LV_SYMBOL_OK` - * @param style the style of the image + * @param color The color of the image with `LV_IMG_CF_ALPHA_...` * @return LV_RES_OK: opened the image. `dsc->img_data` and `dsc->header` are set. * LV_RES_INV: none of the registered image decoders were able to open the image. */ diff --git a/src/lv_draw/lv_img_decoder.h b/src/lv_draw/lv_img_decoder.h index 980816425..8e3cf2662 100644 --- a/src/lv_draw/lv_img_decoder.h +++ b/src/lv_draw/lv_img_decoder.h @@ -157,7 +157,7 @@ lv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header); * 1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_add_drv()`) * 2) Variable: Pointer to an `lv_img_dsc_t` variable * 3) Symbol: E.g. `LV_SYMBOL_OK` - * @param style the style of the image + * @param color The color of the image with `LV_IMG_CF_ALPHA_...` * @return LV_RES_OK: opened the image. `dsc->img_data` and `dsc->header` are set. * LV_RES_INV: none of the registered image decoders were able to open the image. */ From 8d89bf9ed066b099e69c4a3d9e6e91fa67056495 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 12 Aug 2020 14:23:53 +0200 Subject: [PATCH 127/173] fix CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 215bf82b1..bb4989155 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ - Add `lv_tabview_set_tab_name()` function - used to change a tab's name - Add `LV_THEME_MATERIAL_FLAG_NO_TRANSITION` and `LV_THEME_MATERIAL_FLAG_NO_FOCUS` flags - Reduce code size by adding: `LV_USE_FONT_COMPRESSED` and `LV_FONT_USE_SUBPX` and applying some optimization +- Add `LV_MEMCPY_MEMSET_STD` to use standard `memcpy` and `memset` ### Bugfixes - Do not print warning for missing glyph if its height OR width is zero. From d321e0e4fc8b8da300a107ba2fc3fb6686410426 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 12 Aug 2020 14:29:50 +0200 Subject: [PATCH 128/173] fix tests --- tests/lv_test_core/lv_test_font_loader.c | 7 ++++++- tests/lv_test_main.c | 7 +++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/tests/lv_test_core/lv_test_font_loader.c b/tests/lv_test_core/lv_test_font_loader.c index 2d15b33ab..ea0fc2753 100644 --- a/tests/lv_test_core/lv_test_font_loader.c +++ b/tests/lv_test_core/lv_test_font_loader.c @@ -28,7 +28,9 @@ * STATIC PROTOTYPES **********************/ +#if LV_USE_FILESYSTEM static int compare_fonts(lv_font_t * f1, lv_font_t * f2); +#endif /********************** * STATIC VARIABLES @@ -48,6 +50,7 @@ extern lv_font_t font_3; void lv_test_font_loader(void) { +#if LV_USE_FILESYSTEM lv_font_t * font_1_bin = lv_font_load("f:font_1.fnt"); lv_font_t * font_2_bin = lv_font_load("f:font_2.fnt"); lv_font_t * font_3_bin = lv_font_load("f:font_3.fnt"); @@ -59,8 +62,10 @@ void lv_test_font_loader(void) lv_font_free(font_1_bin); lv_font_free(font_2_bin); lv_font_free(font_3_bin); +#endif } +#if LV_USE_FILESYSTEM static int compare_fonts(lv_font_t * f1, lv_font_t * f2) { lv_test_assert_true(f1 != NULL && f2 != NULL, "font not null"); @@ -198,7 +203,7 @@ static int compare_fonts(lv_font_t * f1, lv_font_t * f2) LV_LOG_INFO("No differences found!"); return 0; } - +#endif /********************** * STATIC FUNCTIONS diff --git a/tests/lv_test_main.c b/tests/lv_test_main.c index 061b6b1ef..13d8f14eb 100644 --- a/tests/lv_test_main.c +++ b/tests/lv_test_main.c @@ -23,6 +23,7 @@ int main(void) } +#if LV_USE_FILESYSTEM static lv_fs_res_t open_cb(struct _lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode) { (void) drv; @@ -77,6 +78,7 @@ static bool ready_cb(struct _lv_fs_drv_t * drv) (void) drv; return true; } +#endif static void hal_init(void) { @@ -91,6 +93,7 @@ static void hal_init(void) disp_drv.flush_cb = dummy_flush_cb; lv_disp_drv_register(&disp_drv); +#if LV_USE_FILESYSTEM lv_fs_drv_t drv; lv_fs_drv_init(&drv); /*Basic initialization*/ @@ -103,10 +106,10 @@ static void hal_init(void) drv.seek_cb = seek_cb; /*Callback to seek in a file (Move cursor) */ drv.tell_cb = tell_cb; /*Callback to tell the cursor position */ - lv_fs_drv_register(&drv); /*Finally register the drive*/ + lv_fs_drv_register(&drv); /*Finally register the drive*/ +#endif } - static void dummy_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) { LV_UNUSED(area); From f1edd3a1eac6bcac61bcaca4c752bdd49ac610b3 Mon Sep 17 00:00:00 2001 From: Fabio Guerra Date: Wed, 12 Aug 2020 10:30:44 -0300 Subject: [PATCH 129/173] Removing #ifdef for LVGL version 6 on binary font parser. --- src/lv_font/lv_font_loader.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/lv_font/lv_font_loader.c b/src/lv_font/lv_font_loader.c index 8bba8bea8..4eec1c74c 100644 --- a/src/lv_font/lv_font_loader.c +++ b/src/lv_font/lv_font_loader.c @@ -495,10 +495,7 @@ static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font) font->line_height = font_header.ascent - font_header.descent; font->get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt; font->get_glyph_bitmap = lv_font_get_bitmap_fmt_txt; - -#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) font->subpx = LV_FONT_SUBPX_NONE; -#endif font_dsc->bpp = font_header.bits_per_pixel; font_dsc->kern_scale = font_header.kerning_scale; From 6fcca7dd449d78e2daa9de3e5884a2951da67475 Mon Sep 17 00:00:00 2001 From: Fabio Guerra Date: Wed, 12 Aug 2020 11:02:05 -0300 Subject: [PATCH 130/173] Better comments, explaining memory allocation strategy when parsing fonts. --- src/lv_font/lv_font_loader.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/lv_font/lv_font_loader.c b/src/lv_font/lv_font_loader.c index 4eec1c74c..53e7f77f4 100644 --- a/src/lv_font/lv_font_loader.c +++ b/src/lv_font/lv_font_loader.c @@ -102,6 +102,11 @@ lv_font_t * lv_font_load(const char * font_name) if(!success) { LV_LOG_WARN("Error loading font file: %s\n", font_name); + /* + * When `lvgl_load_font` fails it can leak some pointers. + * All non-null pointers can be assumed as allocated and + * `lv_font_free` should free them correctly. + */ lv_font_free(font); font = NULL; } @@ -471,6 +476,18 @@ static int32_t load_glyph(lv_fs_file_t * fp, lv_font_fmt_txt_dsc_t * font_dsc, return glyph_length; } +/* + * Loads a `lv_font_t` from a binary file, given a `lv_fs_file_t`. + * + * Memory allocations on `lvgl_load_font` should be immediately zeroed and + * the pointer should be set on the `lv_font_t` data before any possible return. + * + * When something fails, it returns `false` and the memory on the `lv_font_t` + * still needs to be freed using `lv_font_free`. + * + * `lv_font_free` will assume that all non-null pointers are allocated and + * should be freed. + */ static bool lvgl_load_font(lv_fs_file_t * fp, lv_font_t * font) { lv_font_fmt_txt_dsc_t * font_dsc = (lv_font_fmt_txt_dsc_t *) From cfee7e8b8aab211e35242ba9a676c16d1e23ade9 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Thu, 13 Aug 2020 11:03:04 +0200 Subject: [PATCH 131/173] arc knob invalidation fix --- src/lv_widgets/lv_arc.c | 74 ++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 41 deletions(-) diff --git a/src/lv_widgets/lv_arc.c b/src/lv_widgets/lv_arc.c index 58d5df0fc..d9d1b2383 100644 --- a/src/lv_widgets/lv_arc.c +++ b/src/lv_widgets/lv_arc.c @@ -31,10 +31,9 @@ static lv_design_res_t lv_arc_design(lv_obj_t * arc, const lv_area_t * clip_area, lv_design_mode_t mode); static lv_res_t lv_arc_signal(lv_obj_t * arc, lv_signal_t sign, void * param); static lv_style_list_t * lv_arc_get_style(lv_obj_t * arc, uint8_t part); -static void inv_arc_area(lv_obj_t * arc, uint16_t start_angle, uint16_t end_angle); +static void inv_arc_area(lv_obj_t * arc, uint16_t start_angle, uint16_t end_angle, lv_arc_part_t part); static void get_center(lv_obj_t * arc, lv_point_t * center, lv_coord_t * arc_r); static void get_knob_area(lv_obj_t * arc, const lv_point_t * center, lv_coord_t r, lv_area_t * knob_area); -static bool has_large_knob(lv_obj_t * arc); /********************** * STATIC VARIABLES @@ -166,11 +165,11 @@ void lv_arc_set_start_angle(lv_obj_t * arc, uint16_t start) } /*Only a smaller incremental move*/ else if(ext->arc_angle_start > ext->arc_angle_end && start > ext->arc_angle_end) { - inv_arc_area(arc, LV_MATH_MIN(ext->arc_angle_start, start), LV_MATH_MAX(ext->arc_angle_start, start)); + inv_arc_area(arc, LV_MATH_MIN(ext->arc_angle_start, start), LV_MATH_MAX(ext->arc_angle_start, start), LV_ARC_PART_INDIC); } /*Only a smaller incremental move*/ else if(ext->arc_angle_start < ext->arc_angle_end && start < ext->arc_angle_end) { - inv_arc_area(arc, LV_MATH_MIN(ext->arc_angle_start, start), LV_MATH_MAX(ext->arc_angle_start, start)); + inv_arc_area(arc, LV_MATH_MIN(ext->arc_angle_start, start), LV_MATH_MAX(ext->arc_angle_start, start), LV_ARC_PART_INDIC); } /*Crossing the start angle makes the whole arc change*/ else { @@ -199,11 +198,11 @@ void lv_arc_set_end_angle(lv_obj_t * arc, uint16_t end) } /*Only a smaller incremental move*/ else if(ext->arc_angle_end > ext->arc_angle_start && end > ext->arc_angle_start) { - inv_arc_area(arc, LV_MATH_MIN(ext->arc_angle_end, end), LV_MATH_MAX(ext->arc_angle_end, end)); + inv_arc_area(arc, LV_MATH_MIN(ext->arc_angle_end, end), LV_MATH_MAX(ext->arc_angle_end, end), LV_ARC_PART_INDIC); } /*Only a smaller incremental move*/ else if(ext->arc_angle_end < ext->arc_angle_start && end < ext->arc_angle_start) { - inv_arc_area(arc, LV_MATH_MIN(ext->arc_angle_end, end), LV_MATH_MAX(ext->arc_angle_end, end)); + inv_arc_area(arc, LV_MATH_MIN(ext->arc_angle_end, end), LV_MATH_MAX(ext->arc_angle_end, end), LV_ARC_PART_INDIC); } /*Crossing the end angle makes the whole arc change*/ else { @@ -229,12 +228,12 @@ void lv_arc_set_angles(lv_obj_t * arc, uint16_t start, uint16_t end) if(start > 360) start -= 360; if(end > (start + 360)) end = start + 360; - inv_arc_area(arc, ext->arc_angle_start, ext->arc_angle_end); + inv_arc_area(arc, ext->arc_angle_start, ext->arc_angle_end, LV_ARC_PART_INDIC); ext->arc_angle_start = start; ext->arc_angle_end = end; - inv_arc_area(arc, ext->arc_angle_start, ext->arc_angle_end); + inv_arc_area(arc, ext->arc_angle_start, ext->arc_angle_end, LV_ARC_PART_INDIC); } /** @@ -256,11 +255,11 @@ void lv_arc_set_bg_start_angle(lv_obj_t * arc, uint16_t start) } /*Only a smaller incremental move*/ else if(ext->bg_angle_start > ext->bg_angle_end && start > ext->bg_angle_end) { - inv_arc_area(arc, LV_MATH_MIN(ext->bg_angle_start, start), LV_MATH_MAX(ext->bg_angle_start, start)); + inv_arc_area(arc, LV_MATH_MIN(ext->bg_angle_start, start), LV_MATH_MAX(ext->bg_angle_start, start), LV_ARC_PART_BG); } /*Only a smaller incremental move*/ else if(ext->bg_angle_start < ext->bg_angle_end && start < ext->bg_angle_end) { - inv_arc_area(arc, LV_MATH_MIN(ext->bg_angle_start, start), LV_MATH_MAX(ext->bg_angle_start, start)); + inv_arc_area(arc, LV_MATH_MIN(ext->bg_angle_start, start), LV_MATH_MAX(ext->bg_angle_start, start), LV_ARC_PART_BG); } /*Crossing the start angle makes the whole arc change*/ else { @@ -289,11 +288,11 @@ void lv_arc_set_bg_end_angle(lv_obj_t * arc, uint16_t end) } /*Only a smaller incremental move*/ else if(ext->bg_angle_end > ext->bg_angle_start && end > ext->bg_angle_start) { - inv_arc_area(arc, LV_MATH_MIN(ext->bg_angle_end, end), LV_MATH_MAX(ext->bg_angle_end, end)); + inv_arc_area(arc, LV_MATH_MIN(ext->bg_angle_end, end), LV_MATH_MAX(ext->bg_angle_end, end), LV_ARC_PART_BG); } /*Only a smaller incremental move*/ else if(ext->bg_angle_end < ext->bg_angle_start && end < ext->bg_angle_start) { - inv_arc_area(arc, LV_MATH_MIN(ext->bg_angle_end, end), LV_MATH_MAX(ext->bg_angle_end, end)); + inv_arc_area(arc, LV_MATH_MIN(ext->bg_angle_end, end), LV_MATH_MAX(ext->bg_angle_end, end), LV_ARC_PART_BG); } /*Crossing the end angle makes the whole arc change*/ else { @@ -318,12 +317,12 @@ void lv_arc_set_bg_angles(lv_obj_t * arc, uint16_t start, uint16_t end) if(start > 360) start -= 360; if(end > (start + 360)) end = start + 360; - inv_arc_area(arc, ext->bg_angle_start, ext->bg_angle_end); + inv_arc_area(arc, ext->bg_angle_start, ext->bg_angle_end, LV_ARC_PART_BG); ext->bg_angle_start = start; ext->bg_angle_end = end; - inv_arc_area(arc, ext->bg_angle_start, ext->bg_angle_end); + inv_arc_area(arc, ext->bg_angle_start, ext->bg_angle_end, LV_ARC_PART_BG); } /** @@ -850,15 +849,8 @@ static lv_style_list_t * lv_arc_get_style(lv_obj_t * arc, uint8_t part) return style_dsc_p; } -static void inv_arc_area(lv_obj_t * arc, uint16_t start_angle, uint16_t end_angle) +static void inv_arc_area(lv_obj_t * arc, uint16_t start_angle, uint16_t end_angle, lv_arc_part_t part) { - /* If the knob is large it's much harder to find which area to invalidate. - * For simplicity invalidate the whole arc in this case*/ - if(has_large_knob(arc)) { - lv_obj_invalidate(arc); - return; - } - lv_arc_ext_t * ext = lv_obj_get_ext_attr(arc); start_angle += ext->rotation_angle; @@ -877,10 +869,26 @@ static void inv_arc_area(lv_obj_t * arc, uint16_t start_angle, uint16_t end_angl lv_coord_t rout = (LV_MATH_MIN(lv_obj_get_width(arc) - left - right, lv_obj_get_height(arc) - top - bottom)) / 2; lv_coord_t x = arc->coords.x1 + rout + left; lv_coord_t y = arc->coords.y1 + rout + top; - lv_style_int_t w = lv_obj_get_style_line_width(arc, LV_ARC_PART_INDIC); - lv_style_int_t rounded = lv_obj_get_style_line_rounded(arc, LV_ARC_PART_INDIC); + lv_style_int_t w = lv_obj_get_style_line_width(arc, part); + lv_style_int_t rounded = lv_obj_get_style_line_rounded(arc, part); lv_coord_t rin = rout - w; - lv_coord_t extra_area = rounded ? w / 2 + 2 : 0; + lv_coord_t extra_area = 0; + + extra_area = rounded ? w / 2 + 2 : 0; + + if(part == LV_ARC_PART_INDIC && lv_style_list_get_style(&ext->style_knob, 0) != NULL) { + lv_coord_t knob_extra_size = lv_obj_get_draw_rect_ext_pad_size(arc, LV_ARC_PART_KNOB); + + lv_coord_t knob_left = lv_obj_get_style_pad_left(arc, LV_ARC_PART_KNOB); + lv_coord_t knob_right = lv_obj_get_style_pad_right(arc, LV_ARC_PART_KNOB); + lv_coord_t knob_top = lv_obj_get_style_pad_top(arc, LV_ARC_PART_KNOB); + lv_coord_t knob_bottom = lv_obj_get_style_pad_bottom(arc, LV_ARC_PART_KNOB); + + knob_extra_size += LV_MATH_MAX4(knob_left, knob_right, knob_top, knob_bottom); + + extra_area = LV_MATH_MAX(extra_area, w / 2 + 2 + knob_extra_size); + + } lv_area_t inv_area; @@ -962,7 +970,6 @@ static void inv_arc_area(lv_obj_t * arc, uint16_t start_angle, uint16_t end_angl } } - static void get_center(lv_obj_t * arc, lv_point_t * center, lv_coord_t * arc_r) { lv_coord_t left_bg = lv_obj_get_style_pad_left(arc, LV_ARC_PART_BG); @@ -1014,19 +1021,4 @@ static void get_knob_area(lv_obj_t * arc, const lv_point_t * center, lv_coord_t knob_area->y2 = center->y + knob_y + bottom_knob + indic_width_half; } -static bool has_large_knob(lv_obj_t * arc) -{ - if(lv_obj_get_style_pad_left(arc, LV_ARC_PART_KNOB) > 0) return true; - if(lv_obj_get_style_pad_right(arc, LV_ARC_PART_KNOB) > 0) return true; - if(lv_obj_get_style_pad_top(arc, LV_ARC_PART_KNOB) > 0) return true; - if(lv_obj_get_style_pad_bottom(arc, LV_ARC_PART_KNOB) > 0) return true; - if(lv_obj_get_style_shadow_width(arc, LV_ARC_PART_KNOB) > 0) return true; - if(lv_obj_get_style_shadow_ofs_x(arc, LV_ARC_PART_KNOB) > 0) return true; - if(lv_obj_get_style_shadow_ofs_y(arc, LV_ARC_PART_KNOB) > 0) return true; - if(lv_obj_get_style_outline_width(arc, LV_ARC_PART_KNOB) > 0) return true; - if(lv_obj_get_style_value_str(arc, LV_ARC_PART_KNOB) != NULL) return true; - - return false; -} - #endif From c2b5979e91f6015f51ec0cdf1b5061482f0dfc42 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Thu, 13 Aug 2020 12:00:57 +0200 Subject: [PATCH 132/173] arc: fix event sending --- src/lv_widgets/lv_arc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_arc.c b/src/lv_widgets/lv_arc.c index d9d1b2383..fad51e7a5 100644 --- a/src/lv_widgets/lv_arc.c +++ b/src/lv_widgets/lv_arc.c @@ -765,11 +765,12 @@ static lv_res_t lv_arc_signal(lv_obj_t * arc, lv_signal_t sign, void * param) angle += round; /*Set the new value*/ + int16_t old_value = ext->cur_value; int16_t new_value = _lv_map(angle, ext->bg_angle_start, bg_end, ext->min_value, ext->max_value); if(new_value != lv_arc_get_value(arc)) { ext->last_tick = lv_tick_get(); /*Cache timestamp for the next iteration*/ lv_arc_set_value(arc, new_value); /*set_value caches the last_angle for the next iteration*/ - if(new_value != ext->cur_value) { + if(new_value != old_value) { res = lv_event_send(arc, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; } From f59a206ab088f3215114149fde724174e1d535bf Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Thu, 13 Aug 2020 20:06:39 +0200 Subject: [PATCH 133/173] send gesture with dragging too. User can test dragging manually with lv_indev_is_dragging --- src/lv_core/lv_indev.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lv_core/lv_indev.c b/src/lv_core/lv_indev.c index 3b1d2b25c..f15852129 100644 --- a/src/lv_core/lv_indev.c +++ b/src/lv_core/lv_indev.c @@ -1490,7 +1490,6 @@ static lv_obj_t * get_dragged_obj(lv_obj_t * obj) static void indev_gesture(lv_indev_proc_t * proc) { - if(proc->types.pointer.drag_in_prog) return; if(proc->types.pointer.gesture_sent) return; lv_obj_t * gesture_obj = proc->types.pointer.act_obj; From 6980277aca60e9156c1f6e1db279da745d0dec78 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Thu, 13 Aug 2020 20:09:43 +0200 Subject: [PATCH 134/173] Update CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9e472b24..6e8d0ad68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,11 @@ # Changelog ## v7.4.0 (planned on 01.09.2020) + +### New features - arc: add set value by click feature +- arc: add `LV_ARC_PART_KNOB` similarly to slider +- send gestures even is the the obejct was dragged. User can check dragging with `lv_indev_is_dragging(lv_indev_act())` in the event function. ## v7.3.1 (planned on 18.08.2020) From f3e91634f889f19f4b2adb103f6c9531db8c1b4d Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Thu, 13 Aug 2020 21:08:50 +0200 Subject: [PATCH 135/173] fix crash if 'lv_table_set_col_cnt' is called before 'lv_table_set_row_cnt' for the first time Fixes #1716 --- src/lv_widgets/lv_table.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/lv_widgets/lv_table.c b/src/lv_widgets/lv_table.c index 0e44d1e5c..617ea440e 100644 --- a/src/lv_widgets/lv_table.c +++ b/src/lv_widgets/lv_table.c @@ -105,9 +105,9 @@ lv_obj_t * lv_table_create(lv_obj_t * par, const lv_obj_t * copy) lv_table_ext_t * copy_ext = lv_obj_get_ext_attr(copy); for(i = 0; i < LV_TABLE_CELL_STYLE_CNT; i++) { lv_style_list_copy(&ext->cell_style[i], ©_ext->cell_style[i]); - lv_table_set_row_cnt(table, copy_ext->row_cnt); - lv_table_set_col_cnt(table, copy_ext->col_cnt); } + lv_table_set_row_cnt(table, copy_ext->row_cnt); + lv_table_set_col_cnt(table, copy_ext->col_cnt); /*Refresh the style with new signal function*/ lv_obj_refresh_style(table, LV_STYLE_PROP_ALL); @@ -192,6 +192,15 @@ void lv_table_set_row_cnt(lv_obj_t * table, uint16_t row_cnt) uint16_t old_row_cnt = ext->row_cnt; ext->row_cnt = row_cnt; + if(ext->row_cnt > 0) { + ext->row_h = lv_mem_realloc(ext->row_h, ext->row_cnt * sizeof(ext->row_h[0])); + LV_ASSERT_MEM(ext->row_h); + if(ext->cell_data == NULL) return; + } else { + lv_mem_free(ext->row_h); + ext->row_h = NULL; + } + if(ext->row_cnt > 0 && ext->col_cnt > 0) { ext->cell_data = lv_mem_realloc(ext->cell_data, ext->row_cnt * ext->col_cnt * sizeof(char *)); LV_ASSERT_MEM(ext->cell_data); @@ -203,10 +212,6 @@ void lv_table_set_row_cnt(lv_obj_t * table, uint16_t row_cnt) uint32_t new_cell_cnt = ext->col_cnt * ext->row_cnt; _lv_memset_00(&ext->cell_data[old_cell_cnt], (new_cell_cnt - old_cell_cnt) * sizeof(ext->cell_data[0])); } - - ext->row_h = lv_mem_realloc(ext->row_h, ext->row_cnt * sizeof(ext->row_h[0])); - LV_ASSERT_MEM(ext->cell_data); - if(ext->cell_data == NULL) return; } else { lv_mem_free(ext->cell_data); @@ -968,10 +973,15 @@ static lv_style_list_t * lv_table_get_style(lv_obj_t * table, uint8_t part) static void refr_size(lv_obj_t * table) { + lv_coord_t h = 0; lv_coord_t w = 0; lv_table_ext_t * ext = lv_obj_get_ext_attr(table); + if(ext->row_cnt == 0 || ext->col_cnt == 0) { + lv_obj_set_size(table, w, h); + return; + } uint16_t i; for(i = 0; i < ext->col_cnt; i++) { From de1ccc269c21d5b20a0d46096eddd52d5229aea9 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Thu, 13 Aug 2020 23:28:03 +0200 Subject: [PATCH 136/173] Update README.md --- examples/arduino/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/arduino/README.md b/examples/arduino/README.md index b6a764c9e..c5938a664 100644 --- a/examples/arduino/README.md +++ b/examples/arduino/README.md @@ -10,7 +10,7 @@ To get all this to work you have to setup TFT_eSPI to work with your TFT display LVGL library has its own configuration file called `lv_conf.h`. When LVGL is installed to followings needs to be done to configure it: 1. Go to directory of the installed Arduno libraries -2. Go to `lvgl` and copy `lv_conf_template.h` as `lvgl.h` next to the `lvgl` folder. +2. Go to `lvgl` and copy `lv_conf_template.h` as `lv_conf.h` next to the `src` folder. 3. Open `lv_conf.h` and change the first `#if 0` to `#if 1` 4. Set the resolution of your display in `LV_HOR_RES_MAX` and `LV_VER_RES_MAX` 5. Set the color depth of you display in `LV_COLOR_DEPTH` From b8ebca8d6c5e21e8018f0b4b717157e9557cb322 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Fri, 14 Aug 2020 00:03:14 +0200 Subject: [PATCH 137/173] update CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cbaf94ec..294a5d0e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,9 +6,9 @@ - arc: add set value by click feature - arc: add `LV_ARC_PART_KNOB` similarly to slider - send gestures even is the the obejct was dragged. User can check dragging with `lv_indev_is_dragging(lv_indev_act())` in the event function. - - Add `lv_font_load()` function - Loads a `lv_font_t` object from a binary font file - Add `lv_font_free()` function - Frees the memory allocated by the `lv_font_load()` function +- Add style caching to reduce acces time of properties with default value ## v7.3.1 (planned on 18.08.2020) From c8cc9db7f08fe2edb865e209e2f25e0d9e927947 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Fri, 14 Aug 2020 06:43:14 +0200 Subject: [PATCH 138/173] table: fix typo --- src/lv_widgets/lv_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_widgets/lv_table.c b/src/lv_widgets/lv_table.c index 617ea440e..b10cd5960 100644 --- a/src/lv_widgets/lv_table.c +++ b/src/lv_widgets/lv_table.c @@ -195,7 +195,7 @@ void lv_table_set_row_cnt(lv_obj_t * table, uint16_t row_cnt) if(ext->row_cnt > 0) { ext->row_h = lv_mem_realloc(ext->row_h, ext->row_cnt * sizeof(ext->row_h[0])); LV_ASSERT_MEM(ext->row_h); - if(ext->cell_data == NULL) return; + if(ext->row_h == NULL) return; } else { lv_mem_free(ext->row_h); ext->row_h = NULL; From 1815ff4b99e12219764f26b47ea3ea685a0b79b0 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Fri, 14 Aug 2020 06:57:51 +0200 Subject: [PATCH 139/173] Limit extra button click area of button matrix's buttons. Fixes #1712 --- CHANGELOG.md | 2 ++ src/lv_widgets/lv_btnmatrix.c | 14 ++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e4b928be..a4c66103c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,9 @@ - Fix setting local style property multiple times - Add missing background drawing and radius handling to image button - Allow adding extra label to list buttons +- Fix crash if `lv_table_set_col_cnt` is called before `lv_table_set_row_cnt` for the first time - Fix overflow in large image transformations +- Limit extra button click area of button matrix's buttons. With large paddings it was counter intuitive. (Gaps are mapped to button when clicked). ## v7.3.0 (04.08.2020) diff --git a/src/lv_widgets/lv_btnmatrix.c b/src/lv_widgets/lv_btnmatrix.c index 842d6421b..722c4180e 100644 --- a/src/lv_widgets/lv_btnmatrix.c +++ b/src/lv_widgets/lv_btnmatrix.c @@ -20,6 +20,7 @@ * DEFINES *********************/ #define LV_OBJX_NAME "lv_btnmatrix" +#define BTN_EXTRA_CLICK_AREA_MAX (LV_DPI / 4) /********************** * TYPEDEFS @@ -1203,18 +1204,23 @@ static uint16_t get_button_from_point(lv_obj_t * btnm, lv_point_t * p) /*Get the half inner padding. Button look larger with this value. (+1 for rounding error)*/ pinner = (pinner / 2) + 1 + (pinner & 1); + pinner = LV_MATH_MIN(pinner, BTN_EXTRA_CLICK_AREA_MAX); + pright = LV_MATH_MIN(pright, BTN_EXTRA_CLICK_AREA_MAX); + ptop = LV_MATH_MIN(ptop, BTN_EXTRA_CLICK_AREA_MAX); + pbottom = LV_MATH_MIN(pbottom, BTN_EXTRA_CLICK_AREA_MAX); + for(i = 0; i < ext->btn_cnt; i++) { lv_area_copy(&btn_area, &ext->button_areas[i]); - if(btn_area.x1 <= pleft) btn_area.x1 = btnm_cords.x1; + if(btn_area.x1 <= pleft) btn_area.x1 += btnm_cords.x1 - LV_MATH_MIN(pleft, BTN_EXTRA_CLICK_AREA_MAX); else btn_area.x1 += btnm_cords.x1 - pinner; - if(btn_area.y1 <= ptop) btn_area.y1 = btnm_cords.y1; + if(btn_area.y1 <= ptop) btn_area.y1 += btnm_cords.y1 - LV_MATH_MIN(ptop, BTN_EXTRA_CLICK_AREA_MAX); else btn_area.y1 += btnm_cords.y1 - pinner; - if(btn_area.x2 >= w - pright - 2) btn_area.x2 = btnm_cords.x2; /*-2 for rounding error*/ + if(btn_area.x2 >= w - pright - 2) btn_area.x2 += btnm_cords.x1 + LV_MATH_MIN(pright, BTN_EXTRA_CLICK_AREA_MAX); /*-2 for rounding error*/ else btn_area.x2 += btnm_cords.x1 + pinner; - if(btn_area.y2 >= h - pbottom - 2) btn_area.y2 = btnm_cords.y2; /*-2 for rounding error*/ + if(btn_area.y2 >= h - pbottom - 2) btn_area.y2 += btnm_cords.y1 + LV_MATH_MIN(pbottom, BTN_EXTRA_CLICK_AREA_MAX); /*-2 for rounding error*/ else btn_area.y2 += btnm_cords.y1 + pinner; if(_lv_area_is_point_on(&btn_area, p, 0) != false) { From 96eba8e0ffdb5693f6718df31b2b2f62661d0eae Mon Sep 17 00:00:00 2001 From: Josh McAtee Date: Fri, 14 Aug 2020 08:58:52 -0700 Subject: [PATCH 140/173] Fix `lv_btnmatrix_set_one_check` not forcing one button to be checked --- CHANGELOG.md | 1 + src/lv_widgets/lv_btnmatrix.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4c66103c..9168ec83d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ - Fix crash if `lv_table_set_col_cnt` is called before `lv_table_set_row_cnt` for the first time - Fix overflow in large image transformations - Limit extra button click area of button matrix's buttons. With large paddings it was counter intuitive. (Gaps are mapped to button when clicked). +- Fix `lv_btnmatrix_set_one_check` not forcing exactly one button to be checked ## v7.3.0 (04.08.2020) diff --git a/src/lv_widgets/lv_btnmatrix.c b/src/lv_widgets/lv_btnmatrix.c index 722c4180e..966118bb6 100644 --- a/src/lv_widgets/lv_btnmatrix.c +++ b/src/lv_widgets/lv_btnmatrix.c @@ -912,7 +912,7 @@ static lv_res_t lv_btnmatrix_signal(lv_obj_t * btnm, lv_signal_t sign, void * pa /*Toggle the button if enabled*/ if(button_is_tgl_enabled(ext->ctrl_bits[ext->btn_id_pr]) && !button_is_inactive(ext->ctrl_bits[ext->btn_id_pr])) { - if(button_get_tgl_state(ext->ctrl_bits[ext->btn_id_pr])) { + if(button_get_tgl_state(ext->ctrl_bits[ext->btn_id_pr]) && !ext->one_check) { ext->ctrl_bits[ext->btn_id_pr] &= (~LV_BTNMATRIX_CTRL_CHECK_STATE); } else { From 28eb766904a40aecae56dfa03f2d3c47cc05bd00 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 17 Aug 2020 09:20:35 +0200 Subject: [PATCH 141/173] comment updates --- lv_conf_template.h | 2 +- lvgl.h | 26 +++++++++----------------- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/lv_conf_template.h b/lv_conf_template.h index 4032f5ab0..b588ffc3f 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -1,6 +1,6 @@ /** * @file lv_conf.h - * Configuration file for LVGL v7.3.0 + * Configuration file for v7.3.0 */ /* diff --git a/lvgl.h b/lvgl.h index bc3c00c70..c3190f3a5 100644 --- a/lvgl.h +++ b/lvgl.h @@ -10,6 +10,15 @@ extern "C" { #endif + +/*************************** + * CURRENT VERSION OF LVGL + ***************************/ +#define LVGL_VERSION_MAJOR 7 +#define LVGL_VERSION_MINOR 3 +#define LVGL_VERSION_PATCH 1 +#define LVGL_VERSION_INFO "dev" + /********************* * INCLUDES *********************/ @@ -72,23 +81,6 @@ extern "C" { #include "src/lv_api_map.h" -/********************* - * DEFINES - *********************/ -/*Current version of LVGL*/ -#define LVGL_VERSION_MAJOR 7 -#define LVGL_VERSION_MINOR 3 -#define LVGL_VERSION_PATCH 1 -#define LVGL_VERSION_INFO "dev" - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * GLOBAL PROTOTYPES - **********************/ - /********************** * MACROS **********************/ From 3a5ad7712ee09f29891359e51a6a75b2e0a5c900 Mon Sep 17 00:00:00 2001 From: Ali Rostami <9710249+ali-rostami@users.noreply.github.com> Date: Mon, 17 Aug 2020 16:10:44 +0430 Subject: [PATCH 142/173] init disabled days to gray color in calendar In ver6 we saw that disabled days in `calendar` were gray, which was a good thing and seemed was missed in new versions. --- src/lv_themes/lv_theme_material.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lv_themes/lv_theme_material.c b/src/lv_themes/lv_theme_material.c index 661db996d..128cdd1f0 100644 --- a/src/lv_themes/lv_theme_material.c +++ b/src/lv_themes/lv_theme_material.c @@ -557,7 +557,7 @@ static void calendar_init(void) lv_style_set_radius(&styles->calendar_date_nums, LV_STATE_DEFAULT, LV_DPX(4)); lv_style_set_text_color(&styles->calendar_date_nums, LV_STATE_CHECKED, IS_LIGHT ? lv_color_hex(0x31404f) : LV_COLOR_WHITE); - + lv_style_set_text_color(&styles->calendar_date_nums, LV_STATE_DISABLED, LV_COLOR_GRAY); lv_style_set_bg_opa(&styles->calendar_date_nums, LV_STATE_CHECKED, IS_LIGHT ? LV_OPA_20 : LV_OPA_40); lv_style_set_bg_opa(&styles->calendar_date_nums, LV_STATE_PRESSED, LV_OPA_20); lv_style_set_bg_opa(&styles->calendar_date_nums, LV_STATE_FOCUSED, LV_OPA_COVER); From 3b06d4ab8451e4762fd2a33fd3cb2e9191397586 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 17 Aug 2020 19:56:32 +0200 Subject: [PATCH 143/173] rewrite the release script --- scripts/release.py | 674 +++++++++++++++++++++++++++++---------------- 1 file changed, 443 insertions(+), 231 deletions(-) diff --git a/scripts/release.py b/scripts/release.py index 0b5946584..2908ee0ef 100755 --- a/scripts/release.py +++ b/scripts/release.py @@ -1,255 +1,467 @@ #!/usr/bin/env python - + +# Release lvgl, lv_examples, lv_drivers. docs, blog and prepare the development of the next major, minoror bugfix release +# Usage: ./release,py bugfix | minor | major +# The option means what type of versin to prepare for development after release +# +# STEPS: +# - clone all 5 repos +# - get the version numnber from lvgl.h +# - set release branch (e.g. "release/v7") +# - prepare lvgl +# - run lv_conf_internal.py +# - run code formatter +# - clear LVGL_VERSION_INFO (set to "") +# - run Doxygen +# - update the version in lvgl's library.json, library.properties, lv_conf_template.h +# - update CHANGELOG.md +# - commit changes +# - prepare lv_examples +# - upadte the required LVGL version in lv_examples.h (LV_VERSION_CHECK) +# - update the version in lv_ex_conf_template.h +# - prepare lv_drivers +# - update the version in library.json, lv_drv_conf_template.h +# - prepare docs +# - update API XML +# - clear the versiopn info (should be plain vx.y.z) +# - tag all repos with the new version +# - merge to release branches +# - blog: add release post +# - push tags and commits +# - docs: run ./updade.py release/vX +# +# If --patch +# - merge master to dev branches +# - increment patch version by 1 and append "-dev". E.g. "vX.Y.(Z+1)-dev" +# - update version numbers in lvgl and docs +# - commit and push +# - docs: run ./updade.py latest dev +# +# Else (not --patch) +# - merge master to dev +# - merge the dev to master +# - increment version number like "vX.(Y+1).0-dev" +# - apply the new version in dev branches of lvgl, lv_examples, lv_drivers, docs +# - commit and push to dev branches +# - docs: run ./updade.py latest dev + import re -import os -lastNum = re.compile(r'(?:[^\d]*(\d+)[^\d]*)+') +import os, fnmatch +import os.path +from os import path +from datetime import date +import sys - -def title(t): - print("\n---------------------------------") - print(t) - print("---------------------------------") +upstream_org_url = "https://github.com/kisvegabor/" +workdir = "./release_tmp" - -def cmd(c): +ver_major = -1 +ver_minor = -1 +ver_patch = -1 + +ver_str = "" +dev_ver_str = "" +release_br = "" +release_note = "" + +prepare_type = ['major', 'minor', 'bugfix'] + +dev_prepare = 'minor' + +def upstream(repo): + return upstream_org_url + repo + ".git" + +def cmd(c, exit_on_err = True): print("\n" + c) r = os.system(c) if r: print("### Error: " + str(r)) - -def lvgl_clone(): - title("lvgl: Clone") - cmd("git clone https://github.com/lvgl/lvgl.git") - os.chdir("./lvgl") - cmd("git co master") - -def lvgl_format(): - title("lvgl: Run code formatter") - os.chdir("./scripts") - cmd("./code-format.sh") - os.system("git ci -am 'Run code formatter'") - os.chdir("..") - -def lvgl_update_version(): - title("lvgl: Update version number") - - f = open("./lvgl.h", "r") - - outbuf = "" - major_ver = -1 - minor_ver = -1 - patch_ver = -1 - - for i in f.read().splitlines(): - r = re.search(r'^#define LVGL_VERSION_MAJOR ', i) - if r: - m = lastNum.search(i) - if m: major_ver = m.group(1) - - r = re.search(r'^#define LVGL_VERSION_MINOR ', i) - if r: - m = lastNum.search(i) - if m: minor_ver = m.group(1) - - r = re.search(r'^#define LVGL_VERSION_PATCH ', i) - if r: - m = lastNum.search(i) - if m: patch_ver = m.group(1) - - - r = re.search(r'^#define LVGL_VERSION_INFO ', i) - if r: - i = "#define LVGL_VERSION_INFO \"\"" - - outbuf += i + '\n' - - f.close() - - f = open("./lvgl.h", "w") - - f.write(outbuf) - f.close() + if exit_on_err: exit(int(r)) - s = "v" + str(major_ver) + "." + str(minor_ver) + "." + str(patch_ver) - print("New version:" + s) - return s - - - -def lvgl_update_library_json(v): - title("lvgl: Update version number in library.json") - - f = open("./library.json", "r") - vn = v[1:] - outbuf = "" +def define_set(fn, name, value): + print("In " + fn + " set " + name + " to " + value) + + new_content = "" + f = open(fn, "r") - for i in f.read().splitlines(): - r = re.search(r'"version": ', i) - if r: - i = ' "version": "' + vn + '",' - - outbuf += i + '\n' - - f.close() + for i in f.read().splitlines(): + r = re.search(r'^ *# *define +' + name, i) + if r: + d = i.split("define") + i = d[0] + "define " + name + " " + value + new_content += i + '\n' + + f.close() + + f = open(fn, "w") + f.write(new_content) + f.close() + +def clone_repos(): + cmd("rm -fr " + workdir) + cmd("mkdir " + workdir) + os.chdir(workdir) + cmd("cp -a ../repos/. .") + return - f = open("./library.json", "w") + cmd("git clone " + upstream("lvgl-1") + " lvgl; cd lvgl; git checkout master") + cmd("git clone " + upstream("lv_examples") + "; cd lv_examples; git checkout master") + cmd("git clone " + upstream("lv_drivers") + "; cd lv_drivers; git checkout master") + cmd("git clone --recurse-submodules " + upstream("docs") + "; cd docs; git checkout master") + cmd("git clone " + upstream("blog") + "; cd lv_drivers; git checkout blog") + +def get_lvgl_version(br): + print("Get LVGL's version") + + global ver_str, ver_major, ver_minor, ver_patch, release_br + + os.chdir("./lvgl") + + cmd("git checkout " + br) + + f = open("./lvgl.h", "r") - f.write(outbuf) - f.close() + lastNum = re.compile(r'(?:[^\d]*(\d+)[^\d]*)+') + for i in f.read().splitlines(): + r = re.search(r'^#define LVGL_VERSION_MAJOR ', i) + if r: + m = lastNum.search(i) + if m: ver_major = m.group(1) -def lvgl_update_lv_conf_templ(ver_str): - title("lvgl: Update version number in lv_conf_template.h") - cmd("sed -i -r 's/v[0-9]+\.[0-9]+\.[0-9]+/"+ ver_str +"/' lv_conf_template.h ") - - -def lvgl_commit_push(v): - title("lvgl: commit and push release") - - os.system('git ci -am "Release ' + v + '"') - cmd('git tag -a ' + v + ' -m "Release ' + v +'"') - cmd('git push origin master') - cmd('git push origin ' + v) - - -def lvgl_merge_to_release_branch(v): - title("lvgl: merge to release branch") - cmd('git co release/v7') - cmd('git merge master') - cmd('git push origin release/v7') - os.chdir("../") - - -def lvgl_update_api_docs(): - title("lvgl: Update API with Doxygen") - - cmd("cd scripts; doxygen"); - - -def examples_clone(): - title("examples: Clone") - cmd("git clone https://github.com/lvgl/lv_examples.git") - os.chdir("./lv_examples") - cmd("git co master") - -def examples_commit_push(v): - title("examples: commit and push release") - - os.system('git ci -am "Release ' + v + '"') - cmd('git tag -a ' + v + ' -m "Release ' + v +'"') - cmd('git push origin master') - cmd('git push origin ' + v) - - -def examples_merge_to_release_branch(v): - title("examples: merge to release branch") - cmd('git co release/v7') - cmd('git merge master') - cmd('git push origin release/v7') - os.chdir("../") - - -def drivers_clone(): - title("drivers: Clone") - cmd("git clone https://github.com/lvgl/lv_drivers.git") - os.chdir("./lv_drivers") - cmd("git co master") - -def drivers_commit_push(v): - title("drivers: commit and push release") - - os.system('git ci -am "Release ' + v + '"') - cmd('git tag -a ' + v + ' -m "Release ' + v +'"') - cmd('git push origin master') - cmd('git push origin ' + v) - -def drivers_merge_to_release_branch(v): - title("drivers: merge to release branch") - cmd('git co release/v7') - cmd('git merge master') - cmd('git push origin release/v7') - os.chdir("../") - -def docs_clone(): - title("docs: Clone") - cmd("git clone --recursive https://github.com/lvgl/docs.git") - os.chdir("./docs") - -def docs_get_api(): - title("docs: Get API files") - - cmd("git co latest --") - cmd("rm -rf xml"); - cmd("cp -r ../lvgl/docs/api_doc/xml ."); - cmd("git add xml"); - cmd('git commit -m "update API"') - -def docs_update_version(v): - title("docs: Update version number") - - f = open("./conf.py", "r") + r = re.search(r'^#define LVGL_VERSION_MINOR ', i) + if r: + m = lastNum.search(i) + if m: ver_minor = m.group(1) - outbuf = "" - - for i in f.read().splitlines(): - r = re.search(r'^version = ', i) - if r: - i = "version = '" + v + "'" + r = re.search(r'^#define LVGL_VERSION_PATCH ', i) + if r: + m = lastNum.search(i) + if m: ver_patch = m.group(1) + + f.close() + + cmd("git checkout master") + + ver_str = "v" + str(ver_major) + "." + str(ver_minor) + "." + str(ver_patch) + print("New version:" + ver_str) + + release_br = "release/v" + ver_major + + os.chdir("../") + +def update_version(): + templ = fnmatch.filter(os.listdir('.'), '*templ*') + + if templ[0]: + print("Updating version in " + templ[0]) + cmd("sed -i -r 's/v[0-9]+\.[0-9]+\.[0-9]+/"+ ver_str +"/' " + templ[0]) + + if os.path.exists("library.json"): + print("Updating version in library.json") + cmd("sed -i -r 's/[0-9]+\.[0-9]+\.[0-9]+/"+ ver_str[1:] +"/' library.json") + + if path.exists("library.properties"): + print("Updating version in library.properties") + cmd("sed -i -r 's/version=[0-9]+\.[0-9]+\.[0-9]+/"+ "version=" + ver_str[1:] + "/' library.properties") + +def lvgl_prepare(): + print("Prepare lvgl") + + global ver_str, ver_major, ver_minor, ver_patch + + os.chdir("./lvgl") + define_set("./lvgl.h", "LVGL_VERSION_INFO", '\"\"') + + # Run some scripts + os.chdir("./scripts") + cmd("./code-format.sh") + cmd("./lv_conf_checker.py") + cmd("doxygen") + os.chdir("../") - r = re.search(r'^release = ', i) - if r: - i = "version = '" + v + "'" - - outbuf += i + '\n' - - f.close() + update_version() - f = open("./conf.py", "w") - - f.write(outbuf) - f.close() - cmd("git add conf.py") - cmd('git ci -m "update conf.py to ' + v + '"') + #update CHANGLELOG + new_content = "" + f = open("./CHANGELOG.md", "r") + + global release_note + release_note = "" + note_state = 0 + for i in f.read().splitlines(): + if note_state == 0: + r = re.search(r'^## ' + ver_str, i) + if r: + i = i.replace("planned on ", "") + note_state+=1 + + elif note_state == 1: + r = re.search(r'^## ', i) + if r: + note_state+=1 + else: + release_note += i + '\n' + + new_content += i + '\n' + + f.close() + + f = open("./CHANGELOG.md", "w") + f.write(new_content) + f.close() + + cmd('git commit -am "prepare to release ' + ver_str + '"') + + os.chdir("../") + + +def lv_examples_prepare(): + print("Prepare lv_examples") + global ver_str, ver_major, ver_minor, ver_patch + + os.chdir("./lv_examples") + + update_version() + + cmd("sed -i -r 's/LV_VERSION_CHECK\([0-9]+, *[0-9]+, *[0-9]+\)/"+ "LV_VERSION_CHECK(" + ver_major + ", " + ver_minor + ", " + ver_patch + ")/' lv_examples.h") + + cmd('git commit -am "prepare to release ' + ver_str + '"') + + os.chdir("../") + +def lv_drivers_prepare(): + print("Prepare lv_drivers") + global ver_str, ver_major, ver_minor, ver_patch + + os.chdir("./lv_drivers") + + update_version() + + cmd('git commit -am "prepare to release ' + ver_str + '"') + + os.chdir("../") + +def docs_prepare(): + print("Prepare docs") + global ver_str, ver_major, ver_minor, ver_patch + + os.chdir("./docs") + + cmd("git co latest --") + cmd("rm -rf xml"); + cmd("cp -r ../lvgl/docs/api_doc/xml ."); + cmd("git add xml"); + + cmd("sed -i -r \"s/'v[0-9]+\.[0-9]+\.[0-9]+.*'/\'" + ver_str + "'/\" conf.py") + + cmd('git commit -am "prepare to release ' + ver_str + '"') + + os.chdir("../") + +def blog_add_post(): + global ver_str, release_note + + os.chdir("./blog/_posts") + + post = "---\nlayout: post\ntitle: " + ver_str + " is released\nauthor: \"kisvegabor\"\ncover: /assets/release_cover.png\n---\n\n" + post += release_note + + today = date.today() + d = today.strftime("%Y-%m-%d") + + f = open(d + "_release_" + ver_str + ".md", "w") + f.write(post) + f.close() + + cmd("git add .") + cmd("git commit -am 'Add " + ver_str + " release post'") + + os.chdir("../../") + +def add_tags(): + global ver_str + tag_cmd = " git tag -a " + ver_str + " -m 'Release " + ver_str + "' " + cmd("cd lvgl; " + tag_cmd) + cmd("cd lv_examples; " + tag_cmd) + cmd("cd lv_drivers; " + tag_cmd) + cmd("cd docs; " + tag_cmd) + +def update_release_branches(): + global release_br + merge_cmd = " git checkout " + release_br + "; git pull origin " + release_br + "; git merge master -X ours; git push origin " + release_br + "; git checkout master" + cmd("cd lvgl; " + merge_cmd) + cmd("cd lv_examples; " + merge_cmd) + cmd("cd lv_drivers; " + merge_cmd) + + merge_cmd = " git checkout " + release_br + "; git pull origin " + release_br + "; git merge latest -X ours; git push origin " + release_br + "; git checkout latest" + cmd("cd docs; " + merge_cmd) + +def publish_master(): + pub_cmd = "git push origin master; git push origin " + ver_str + cmd("cd lvgl; " + pub_cmd) + cmd("cd lv_examples; " + pub_cmd) + cmd("cd lv_drivers; " + pub_cmd) + + pub_cmd = "git push origin latest; git push origin " + ver_str + cmd("cd docs; " + pub_cmd) + cmd("cd docs; git checkout master; ./update.py " + release_br) + + pub_cmd = "git push origin master" + cmd("cd blog; " + pub_cmd) + + +def merge_to_dev(): + merge_cmd = "git checkout dev; git merge master -X ours; git checkout master" + cmd("cd lvgl; " + merge_cmd) + + merge_cmd = "git checkout dev; git merge latest -X ours; git checkout master" + cmd("cd docs; " + merge_cmd) + + +def merge_from_dev(): + merge_cmd = "git checkout master; git merge dev;" + cmd("cd lvgl; " + merge_cmd) + + merge_cmd = "git checkout latest; git merge dev;" + cmd("cd docs; " + merge_cmd) + + +def lvgl_update_master_version(): + global ver_major, ver_minor, ver_patch, ver_str + + os.chdir("./lvgl") + + cmd("git checkout master") + define_set("./lvgl.h", "LVGL_VERSION_MAJOR", ver_major) + define_set("./lvgl.h", "LVGL_VERSION_MINOR", ver_minor) + define_set("./lvgl.h", "LVGL_VERSION_PATCH", ver_patch) + define_set("./lvgl.h", "LVGL_VERSION_INFO", "dev") + + templ = fnmatch.filter(os.listdir('.'), '*templ*') + if templ[0]: + print("Updating version in " + templ[0]) + cmd("sed -i -r 's/v[0-9]+\.[0-9]+\.[0-9]+/"+ ver_str +"/' " + templ[0]) + + + cmd("git commit -am 'Update version'") + + os.chdir("../") + +def docs_update_latest_version(): + global ver_str + + os.chdir("./docs") + cmd("git checkout latest --") + cmd("sed -i -r \"s/'v[0-9]+\.[0-9]+\.[0-9]+.*'/\'" + ver_str + "'/\" conf.py") + cmd("git commit -am 'Update version'") + cmd("git checkout master --") + + os.chdir("../") + + +def lvgl_update_dev_version(): + global ver_major, ver_minor, ver_patch, dev_ver_str + + os.chdir("./lvgl") + + cmd("git checkout dev") + define_set("./lvgl.h", "LVGL_VERSION_MAJOR", ver_major) + define_set("./lvgl.h", "LVGL_VERSION_MINOR", ver_minor) + define_set("./lvgl.h", "LVGL_VERSION_PATCH", ver_patch) + define_set("./lvgl.h", "LVGL_VERSION_INFO", "\"dev\"") + + templ = fnmatch.filter(os.listdir('.'), '*templ*') + if templ[0]: + print("Updating version in " + templ[0]) + cmd("sed -i -r 's/v[0-9]+\.[0-9]+\.[0-9]+/"+ dev_ver_str +"/' " + templ[0]) + + + cmd("git commit -am 'Update dev version'") + cmd("git checkout master") + + os.chdir("../") + +def docs_update_dev_version(): + global dev_ver_str + + os.chdir("./docs") + cmd("git checkout dev --") + cmd("sed -i -r \"s/'v[0-9]+\.[0-9]+\.[0-9]+.*'/\'" + dev_ver_str + "'/\" conf.py") + cmd("git commit -am 'Update dev version'") + cmd("git checkout master --") + + os.chdir("../") -def docs_merge_to_release_branch(v): - title("docs: merge to release branch") - cmd('git co release/v7 --') - cmd('git clean -fd .') - cmd('rm -f LVGL.pdf') #To avoide possible merge conflict - cmd('git merge latest') - cmd('git push origin release/v7') +def publish_dev(): + pub_cmd = "git checkout dev; git push origin dev" + cmd("cd lvgl; " + pub_cmd) -def docs_build(): - title("docs: Build") - cmd("git checkout master") - cmd("./update.py latest release/v7") - -def clean_up(): - title("Clean up repos") - os.chdir("../") - cmd("rm -rf lvgl docs lv_examples lv_drivers") + pub_cmd = "git checkout dev; git push origin dev" + cmd("cd docs; " + pub_cmd) + cmd("cd docs; git checkout master; ./update.py latest dev") -lvgl_clone() -lvgl_format() -lvgl_update_api_docs() -ver_str = lvgl_update_version() -lvgl_update_library_json(ver_str) -lvgl_update_lv_conf_templ(ver_str) -lvgl_commit_push(ver_str) -lvgl_merge_to_release_branch(ver_str) +def cleanup(): + os.chdir("../") + cmd("rm -fr " + workdir) -examples_clone() -examples_commit_push(ver_str) -examples_merge_to_release_branch(ver_str) +if __name__ == '__main__': + if(len(sys.argv) != 2): + print("Argument error. Usage ./release.py bugfix | minor | major") + exit(1) + + dev_prepare = sys.argv[1] + if not (dev_prepare in prepare_type): + print("Invalid argument. Usage ./release.py bugfix | minor | major") + exit(1) + + clone_repos() + get_lvgl_version("master") + lvgl_prepare() + lv_examples_prepare() + lv_drivers_prepare() + docs_prepare() + blog_add_post() + add_tags() + update_release_branches() + publish_master() + + if dev_prepare == 'bugfix': + ver_patch = str(int(ver_patch) + 1) + ver_str = "v" + ver_major + "." + ver_minor + "." + ver_patch + "-dev" -drivers_clone() -drivers_commit_push(ver_str) -drivers_merge_to_release_branch(ver_str) + print("Prepare bugfix version " + ver_str) -docs_clone() -docs_get_api() -docs_update_version(ver_str) -docs_merge_to_release_branch(ver_str) -docs_build() + lvgl_update_master_version() + docs_update_latest_version() -clean_up() + get_lvgl_version("dev") + dev_ver_str = "v" + ver_major + "." + ver_minor + "." + ver_patch + "-dev" + merge_to_dev() + + lvgl_update_dev_version() + docs_update_dev_version() + publish_dev() + else: + get_lvgl_version("dev") + if dev_prepare == 'minor': + ver_minor = str(int(ver_minor) + 1) + ver_patch = "0" + else: + ver_major = str(int(ver_major) + 1) + ver_minor = "0" + ver_patch = "0" + + dev_ver_str = "v" + ver_major + "." + ver_minor + "." + ver_patch + "-dev" + + print("Prepare minor version " + ver_str) + + merge_to_dev() + merge_from_dev() + + lvgl_update_dev_version() + docs_update_dev_version() + publish_dev() + + cleanup() + \ No newline at end of file From 437e6d35ebd455cfcc5f9e77f4f7ac25415aec3a Mon Sep 17 00:00:00 2001 From: xiaobo Date: Tue, 18 Aug 2020 11:25:40 +0800 Subject: [PATCH 144/173] Reduced animation callback interface calls --- src/lv_misc/lv_anim.c | 7 +++++-- src/lv_misc/lv_anim.h | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/lv_misc/lv_anim.c b/src/lv_misc/lv_anim.c index dbe1b970b..ed3fd7929 100644 --- a/src/lv_misc/lv_anim.c +++ b/src/lv_misc/lv_anim.c @@ -475,8 +475,11 @@ static void anim_task(lv_task_t * param) if(a->path.cb) new_value = a->path.cb(&a->path, a); else new_value = lv_anim_path_linear(&a->path, a); - /*Apply the calculated value*/ - if(a->exec_cb) a->exec_cb(a->var, new_value); + if(new_value != a->current) { + a->current = new_value; + /*Apply the calculated value*/ + if(a->exec_cb) a->exec_cb(a->var, new_value); + } /*If the time is elapsed the animation is ready*/ if(a->act_time >= a->time) { diff --git a/src/lv_misc/lv_anim.h b/src/lv_misc/lv_anim.h index 1a84087b7..e48dae50f 100644 --- a/src/lv_misc/lv_anim.h +++ b/src/lv_misc/lv_anim.h @@ -82,6 +82,7 @@ typedef struct _lv_anim_t { lv_anim_ready_cb_t ready_cb; /**< Call it when the animation is ready*/ lv_anim_path_t path; /**< Describe the path (curve) of animations*/ int32_t start; /**< Start value*/ + int32_t current; /**< Current value */ int32_t end; /**< End value*/ int32_t time; /**< Animation time in ms*/ int32_t act_time; /**< Current time in animation. Set to negative to make delay.*/ @@ -171,6 +172,7 @@ static inline void lv_anim_set_delay(lv_anim_t * a, uint32_t delay) static inline void lv_anim_set_values(lv_anim_t * a, lv_anim_value_t start, lv_anim_value_t end) { a->start = start; + a->current = start; a->end = end; } From 056da0f922c57d6ca331c8f4f1cf822b11cc648b Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 18 Aug 2020 08:47:08 +0200 Subject: [PATCH 145/173] fix color picker invalidation in rectangle mode --- CHANGELOG.md | 1 + src/lv_widgets/lv_cpicker.c | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4c66103c..13713c03d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ - Fix crash if `lv_table_set_col_cnt` is called before `lv_table_set_row_cnt` for the first time - Fix overflow in large image transformations - Limit extra button click area of button matrix's buttons. With large paddings it was counter intuitive. (Gaps are mapped to button when clicked). +- Fix color picker invalidation in rectangle mode ## v7.3.0 (04.08.2020) diff --git a/src/lv_widgets/lv_cpicker.c b/src/lv_widgets/lv_cpicker.c index 552b171e4..3325fcf9f 100644 --- a/src/lv_widgets/lv_cpicker.c +++ b/src/lv_widgets/lv_cpicker.c @@ -244,9 +244,7 @@ bool lv_cpicker_set_hsv(lv_obj_t * cpicker, lv_color_hsv_t hsv) refr_knob_pos(cpicker); - if(ext->type == LV_CPICKER_TYPE_DISC) { - lv_obj_invalidate(cpicker); - } + lv_obj_invalidate(cpicker); return true; } From 74aae39e4ea24d45e6550f203e4b431c87724eab Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 18 Aug 2020 10:12:32 +0200 Subject: [PATCH 146/173] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13713c03d..e43d6ae20 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ - Fix overflow in large image transformations - Limit extra button click area of button matrix's buttons. With large paddings it was counter intuitive. (Gaps are mapped to button when clicked). - Fix color picker invalidation in rectangle mode +- Init disabled days to gray color in calendar ## v7.3.0 (04.08.2020) From e728ba19286811da908c7b34814ff8f4e147e659 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 18 Aug 2020 10:22:02 +0200 Subject: [PATCH 147/173] remove debug statements from release.py --- scripts/release.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/scripts/release.py b/scripts/release.py index 2908ee0ef..141a83444 100755 --- a/scripts/release.py +++ b/scripts/release.py @@ -52,7 +52,7 @@ from os import path from datetime import date import sys -upstream_org_url = "https://github.com/kisvegabor/" +upstream_org_url = "https://github.com/lvgl/" workdir = "./release_tmp" ver_major = -1 @@ -98,11 +98,12 @@ def define_set(fn, name, value): f.close() def clone_repos(): - cmd("rm -fr " + workdir) - cmd("mkdir " + workdir) - os.chdir(workdir) - cmd("cp -a ../repos/. .") - return + #For debuging just copy the repos + #cmd("rm -fr " + workdir) + #cmd("mkdir " + workdir) + #os.chdir(workdir) + #cmd("cp -a ../repos/. .") + #return cmd("git clone " + upstream("lvgl-1") + " lvgl; cd lvgl; git checkout master") cmd("git clone " + upstream("lv_examples") + "; cd lv_examples; git checkout master") @@ -464,4 +465,4 @@ if __name__ == '__main__': publish_dev() cleanup() - \ No newline at end of file + From c0714d9c6b7041a188a58dd402e0e0373f8cad75 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 18 Aug 2020 10:25:19 +0200 Subject: [PATCH 148/173] fix release script --- scripts/release.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/scripts/release.py b/scripts/release.py index 141a83444..28370c668 100755 --- a/scripts/release.py +++ b/scripts/release.py @@ -98,14 +98,15 @@ def define_set(fn, name, value): f.close() def clone_repos(): + cmd("rm -fr " + workdir) + cmd("mkdir " + workdir) + os.chdir(workdir) + #For debuging just copy the repos - #cmd("rm -fr " + workdir) - #cmd("mkdir " + workdir) - #os.chdir(workdir) #cmd("cp -a ../repos/. .") #return - cmd("git clone " + upstream("lvgl-1") + " lvgl; cd lvgl; git checkout master") + cmd("git clone " + upstream("lvgl") + " lvgl; cd lvgl; git checkout master") cmd("git clone " + upstream("lv_examples") + "; cd lv_examples; git checkout master") cmd("git clone " + upstream("lv_drivers") + "; cd lv_drivers; git checkout master") cmd("git clone --recurse-submodules " + upstream("docs") + "; cd docs; git checkout master") From 1088492449df4adc9c7245b149defd9340f3a807 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 18 Aug 2020 10:28:35 +0200 Subject: [PATCH 149/173] prepare to release v7.3.1 --- CHANGELOG.md | 2 +- library.json | 2 +- library.properties | 2 +- lv_conf_template.h | 2 +- lvgl.h | 2 +- src/lv_api_map.h | 3 ++- src/lv_core/lv_obj.c | 4 ++-- src/lv_widgets/lv_btnmatrix.c | 6 ++++-- src/lv_widgets/lv_linemeter.c | 7 ++++--- src/lv_widgets/lv_table.c | 3 ++- 10 files changed, 19 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e43d6ae20..85372c769 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ## v7.4.0 (planned on 01.09.2020) *Available in the `dev` branch* -## v7.3.1 (planned on 18.08.2020) +## v7.3.1 (18.08.2020) ### Bugfixes - Fix drawing value string twice diff --git a/library.json b/library.json index 6cb9ab8b3..a6eb48edf 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "lvgl", - "version": "7.3.0", + "version": "7.3.1", "keywords": "graphics, gui, embedded, tft, lvgl", "description": "Graphics library to create embedded GUI with easy-to-use graphical elements, beautiful visual effects and low memory footprint. It offers anti-aliasing, opacity, and animations using only one frame buffer.", "repository": { diff --git a/library.properties b/library.properties index 712c77392..44897bb54 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=lvgl -version=7.3.0 +version=7.3.1 author=kisvegabor maintainer=kisvegabor,embeddedt,pete-pjb sentence=Full-featured Graphics Library for Embedded Systems diff --git a/lv_conf_template.h b/lv_conf_template.h index b588ffc3f..e93be3b9d 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -1,6 +1,6 @@ /** * @file lv_conf.h - * Configuration file for v7.3.0 + * Configuration file for v7.3.1 */ /* diff --git a/lvgl.h b/lvgl.h index c3190f3a5..8052ae20c 100644 --- a/lvgl.h +++ b/lvgl.h @@ -17,7 +17,7 @@ extern "C" { #define LVGL_VERSION_MAJOR 7 #define LVGL_VERSION_MINOR 3 #define LVGL_VERSION_PATCH 1 -#define LVGL_VERSION_INFO "dev" +#define LVGL_VERSION_INFO "" /********************* * INCLUDES diff --git a/src/lv_api_map.h b/src/lv_api_map.h index d8e904e8a..6006216cb 100644 --- a/src/lv_api_map.h +++ b/src/lv_api_map.h @@ -209,7 +209,8 @@ static inline void lv_chart_clear_serie(lv_obj_t * chart, lv_chart_series_t * se #endif -static inline void lv_obj_align_origo(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_ofs, lv_coord_t y_ofs) +static inline void lv_obj_align_origo(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_ofs, + lv_coord_t y_ofs) { lv_obj_align_mid(obj, base, align, x_ofs, y_ofs); } diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index c20904733..953da5ac5 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -88,7 +88,7 @@ static void base_dir_refr_children(lv_obj_t * obj); static void obj_align_core(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, bool x_set, bool y_set, lv_coord_t x_ofs, lv_coord_t y_ofs); static void obj_align_mid_core(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, bool x_set, bool y_set, - lv_coord_t x_ofs, lv_coord_t y_ofs); + lv_coord_t x_ofs, lv_coord_t y_ofs); #if LV_USE_ANIMATION static lv_style_trans_t * trans_create(lv_obj_t * obj, lv_style_property_t prop, uint8_t part, lv_state_t prev_state, lv_state_t new_state); @@ -3894,7 +3894,7 @@ static void obj_align_core(lv_obj_t * obj, const lv_obj_t * base, lv_align_t ali } static void obj_align_mid_core(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, bool x_set, bool y_set, - lv_coord_t x_ofs, lv_coord_t y_ofs) + lv_coord_t x_ofs, lv_coord_t y_ofs) { lv_coord_t new_x = lv_obj_get_x(obj); lv_coord_t new_y = lv_obj_get_y(obj); diff --git a/src/lv_widgets/lv_btnmatrix.c b/src/lv_widgets/lv_btnmatrix.c index 722c4180e..651281233 100644 --- a/src/lv_widgets/lv_btnmatrix.c +++ b/src/lv_widgets/lv_btnmatrix.c @@ -1217,10 +1217,12 @@ static uint16_t get_button_from_point(lv_obj_t * btnm, lv_point_t * p) if(btn_area.y1 <= ptop) btn_area.y1 += btnm_cords.y1 - LV_MATH_MIN(ptop, BTN_EXTRA_CLICK_AREA_MAX); else btn_area.y1 += btnm_cords.y1 - pinner; - if(btn_area.x2 >= w - pright - 2) btn_area.x2 += btnm_cords.x1 + LV_MATH_MIN(pright, BTN_EXTRA_CLICK_AREA_MAX); /*-2 for rounding error*/ + if(btn_area.x2 >= w - pright - 2) btn_area.x2 += btnm_cords.x1 + LV_MATH_MIN(pright, + BTN_EXTRA_CLICK_AREA_MAX); /*-2 for rounding error*/ else btn_area.x2 += btnm_cords.x1 + pinner; - if(btn_area.y2 >= h - pbottom - 2) btn_area.y2 += btnm_cords.y1 + LV_MATH_MIN(pbottom, BTN_EXTRA_CLICK_AREA_MAX); /*-2 for rounding error*/ + if(btn_area.y2 >= h - pbottom - 2) btn_area.y2 += btnm_cords.y1 + LV_MATH_MIN(pbottom, + BTN_EXTRA_CLICK_AREA_MAX); /*-2 for rounding error*/ else btn_area.y2 += btnm_cords.y1 + pinner; if(_lv_area_is_point_on(&btn_area, p, 0) != false) { diff --git a/src/lv_widgets/lv_linemeter.c b/src/lv_widgets/lv_linemeter.c index 0de65871c..75019ba46 100644 --- a/src/lv_widgets/lv_linemeter.c +++ b/src/lv_widgets/lv_linemeter.c @@ -393,8 +393,8 @@ void lv_linemeter_draw_scale(lv_obj_t * lmeter, const lv_area_t * clip_area, uin lv_coord_t y_ofs = lmeter->coords.y1 + r_out + top; int16_t angle_ofs = ext->angle_ofs + 90 + (360 - ext->scale_angle) / 2; int16_t level = ext->mirrored ? - (int32_t)((int32_t)(ext->max_value - ext->cur_value) * (ext->line_cnt - 1)) / (ext->max_value - ext->min_value) : - (int32_t)((int32_t)(ext->cur_value - ext->min_value) * (ext->line_cnt - 1)) / (ext->max_value - ext->min_value); + (int32_t)((int32_t)(ext->max_value - ext->cur_value) * (ext->line_cnt - 1)) / (ext->max_value - ext->min_value) : + (int32_t)((int32_t)(ext->cur_value - ext->min_value) * (ext->line_cnt - 1)) / (ext->max_value - ext->min_value); uint8_t i; lv_color_t main_color = lv_obj_get_style_line_color(lmeter, part); @@ -523,7 +523,8 @@ void lv_linemeter_draw_scale(lv_obj_t * lmeter, const lv_area_t * clip_area, uin if((!ext->mirrored && i >= level) || (ext->mirrored && i <= level)) { line_dsc.color = end_color; line_dsc.width = end_line_width; - } else { + } + else { line_dsc.color = lv_color_mix(grad_color, main_color, (255 * i) / ext->line_cnt); } diff --git a/src/lv_widgets/lv_table.c b/src/lv_widgets/lv_table.c index b10cd5960..7bd8e4c8b 100644 --- a/src/lv_widgets/lv_table.c +++ b/src/lv_widgets/lv_table.c @@ -196,7 +196,8 @@ void lv_table_set_row_cnt(lv_obj_t * table, uint16_t row_cnt) ext->row_h = lv_mem_realloc(ext->row_h, ext->row_cnt * sizeof(ext->row_h[0])); LV_ASSERT_MEM(ext->row_h); if(ext->row_h == NULL) return; - } else { + } + else { lv_mem_free(ext->row_h); ext->row_h = NULL; } From 9680d5bbb22f88193006611e60023ed8c5f4a52d Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 18 Aug 2020 10:43:47 +0200 Subject: [PATCH 150/173] Update dev version --- lv_conf_template.h | 2 +- lvgl.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lv_conf_template.h b/lv_conf_template.h index d17601a99..ede5f0f10 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -1,6 +1,6 @@ /** * @file lv_conf.h - * Configuration file for v7.3.1 + * Configuration file for v7.5.0-dev */ /* diff --git a/lvgl.h b/lvgl.h index fd66cc098..5d1361cd7 100644 --- a/lvgl.h +++ b/lvgl.h @@ -15,9 +15,9 @@ extern "C" { * CURRENT VERSION OF LVGL ***************************/ /*Current version of LVGL*/ -#define LVGL_VERSION_MAJOR 7 -#define LVGL_VERSION_MINOR 4 -#define LVGL_VERSION_PATCH 0 +#define LVGL_VERSION_MAJOR 7 +#define LVGL_VERSION_MINOR 5 +#define LVGL_VERSION_PATCH 0 #define LVGL_VERSION_INFO "dev" /********************* From cc437620308d7d3ac3958e784674d2643366264a Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 18 Aug 2020 10:45:41 +0200 Subject: [PATCH 151/173] Update dev version --- lv_conf_template.h | 2 +- lvgl.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lv_conf_template.h b/lv_conf_template.h index ede5f0f10..6faeafad3 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -1,6 +1,6 @@ /** * @file lv_conf.h - * Configuration file for v7.5.0-dev + * Configuration file for v7.6.0-dev-dev */ /* diff --git a/lvgl.h b/lvgl.h index 5d1361cd7..c459c3842 100644 --- a/lvgl.h +++ b/lvgl.h @@ -16,7 +16,7 @@ extern "C" { ***************************/ /*Current version of LVGL*/ #define LVGL_VERSION_MAJOR 7 -#define LVGL_VERSION_MINOR 5 +#define LVGL_VERSION_MINOR 6 #define LVGL_VERSION_PATCH 0 #define LVGL_VERSION_INFO "dev" From d665294669daaefe33b624bb7f68459983431084 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 18 Aug 2020 10:53:01 +0200 Subject: [PATCH 152/173] fix release script --- scripts/release.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/release.py b/scripts/release.py index 28370c668..76f1fbef9 100755 --- a/scripts/release.py +++ b/scripts/release.py @@ -110,7 +110,7 @@ def clone_repos(): cmd("git clone " + upstream("lv_examples") + "; cd lv_examples; git checkout master") cmd("git clone " + upstream("lv_drivers") + "; cd lv_drivers; git checkout master") cmd("git clone --recurse-submodules " + upstream("docs") + "; cd docs; git checkout master") - cmd("git clone " + upstream("blog") + "; cd lv_drivers; git checkout blog") + cmd("git clone " + upstream("blog") + "; cd blog; git checkout master") def get_lvgl_version(br): print("Get LVGL's version") @@ -313,10 +313,10 @@ def publish_master(): def merge_to_dev(): - merge_cmd = "git checkout dev; git merge master -X ours; git checkout master" + merge_cmd = "git checkout dev; git pull origin dev; git merge master -X ours; git checkout master" cmd("cd lvgl; " + merge_cmd) - merge_cmd = "git checkout dev; git merge latest -X ours; git checkout master" + merge_cmd = "git checkout dev --; git pull origin dev; git merge latest -X ours; git checkout master" cmd("cd docs; " + merge_cmd) @@ -324,7 +324,7 @@ def merge_from_dev(): merge_cmd = "git checkout master; git merge dev;" cmd("cd lvgl; " + merge_cmd) - merge_cmd = "git checkout latest; git merge dev;" + merge_cmd = "git checkout latest -- ; git merge dev;" cmd("cd docs; " + merge_cmd) From 6e884615d8501e1d96f89a83f2a9303392752c70 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 18 Aug 2020 10:53:37 +0200 Subject: [PATCH 153/173] fix version --- lvgl.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lvgl.h b/lvgl.h index 8052ae20c..e7437e188 100644 --- a/lvgl.h +++ b/lvgl.h @@ -15,9 +15,9 @@ extern "C" { * CURRENT VERSION OF LVGL ***************************/ #define LVGL_VERSION_MAJOR 7 -#define LVGL_VERSION_MINOR 3 -#define LVGL_VERSION_PATCH 1 -#define LVGL_VERSION_INFO "" +#define LVGL_VERSION_MINOR 4 +#define LVGL_VERSION_PATCH 0 +#define LVGL_VERSION_INFO "dev" /********************* * INCLUDES From f116073baf4023c465deb435446566faeebfafdb Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 18 Aug 2020 10:54:10 +0200 Subject: [PATCH 154/173] fix version --- lvgl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lvgl.h b/lvgl.h index fd66cc098..59a0422c2 100644 --- a/lvgl.h +++ b/lvgl.h @@ -16,7 +16,7 @@ extern "C" { ***************************/ /*Current version of LVGL*/ #define LVGL_VERSION_MAJOR 7 -#define LVGL_VERSION_MINOR 4 +#define LVGL_VERSION_MINOR 5 #define LVGL_VERSION_PATCH 0 #define LVGL_VERSION_INFO "dev" From 71e5618380fecc259bb96d214014768ebbbd895a Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 18 Aug 2020 11:32:43 +0200 Subject: [PATCH 155/173] upadte release.py --- scripts/release.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/release.py b/scripts/release.py index 76f1fbef9..b730e83a4 100755 --- a/scripts/release.py +++ b/scripts/release.py @@ -395,12 +395,12 @@ def docs_update_dev_version(): os.chdir("../") -def publish_dev(): +def publish_dev_and_master(): pub_cmd = "git checkout dev; git push origin dev" cmd("cd lvgl; " + pub_cmd) + pub_cmd = "git checkout master; git push origin master" + cmd("cd lvgl; " + pub_cmd) - pub_cmd = "git checkout dev; git push origin dev" - cmd("cd docs; " + pub_cmd) cmd("cd docs; git checkout master; ./update.py latest dev") def cleanup(): @@ -463,7 +463,7 @@ if __name__ == '__main__': lvgl_update_dev_version() docs_update_dev_version() - publish_dev() + publish_dev_and_master() cleanup() From 677ce48beaf8168784cd826d6ee4f6985be72456 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 18 Aug 2020 17:02:42 +0200 Subject: [PATCH 156/173] tabview: fix press state style update fixes: #1728 --- src/lv_widgets/lv_btnmatrix.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lv_widgets/lv_btnmatrix.c b/src/lv_widgets/lv_btnmatrix.c index 8f334225d..4acb82643 100644 --- a/src/lv_widgets/lv_btnmatrix.c +++ b/src/lv_widgets/lv_btnmatrix.c @@ -726,7 +726,7 @@ static lv_design_res_t lv_btnmatrix_design(lv_obj_t * btnm, const lv_area_t * cl draw_rect_dsc_act = &draw_rect_chk_dsc; draw_label_dsc_act = &draw_label_chk_dsc; } - else if(btn_state == LV_STATE_CHECKED) { + else if(btn_state == LV_STATE_DISABLED) { if(!disabled_inited) { btnm->state = LV_STATE_DISABLED; _lv_obj_disable_style_caching(btnm, true); @@ -745,6 +745,7 @@ static lv_design_res_t lv_btnmatrix_design(lv_obj_t * btnm, const lv_area_t * cl /*In other cases get the styles directly without caching them*/ else { btnm->state = btn_state; + _lv_obj_disable_style_caching(btnm, true); lv_draw_rect_dsc_init(&draw_rect_tmp_dsc); lv_draw_label_dsc_init(&draw_label_tmp_dsc); lv_obj_init_draw_rect_dsc(btnm, LV_BTNMATRIX_PART_BTN, &draw_rect_tmp_dsc); @@ -752,8 +753,8 @@ static lv_design_res_t lv_btnmatrix_design(lv_obj_t * btnm, const lv_area_t * cl draw_label_tmp_dsc.flag = txt_flag; draw_rect_dsc_act = &draw_rect_tmp_dsc; draw_label_dsc_act = &draw_label_tmp_dsc; - btnm->state = state_ori; + _lv_obj_disable_style_caching(btnm, false); } lv_style_int_t border_part_ori = draw_rect_dsc_act->border_side; From 45cc51d48cd96269958016d0d2c1217d2f646d2c Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 19 Aug 2020 23:28:34 +0200 Subject: [PATCH 157/173] release.py: publish blog post --- scripts/release.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/release.py b/scripts/release.py index b730e83a4..70b93ac1c 100755 --- a/scripts/release.py +++ b/scripts/release.py @@ -303,6 +303,7 @@ def publish_master(): cmd("cd lvgl; " + pub_cmd) cmd("cd lv_examples; " + pub_cmd) cmd("cd lv_drivers; " + pub_cmd) + cmd("cd blog; " + pub_cmd) pub_cmd = "git push origin latest; git push origin " + ver_str cmd("cd docs; " + pub_cmd) From 809497f7070c1d10cba9dd3f875df275d24091fd Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 19 Aug 2020 23:30:57 +0200 Subject: [PATCH 158/173] release.py: fix blog post name --- scripts/release.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/release.py b/scripts/release.py index 70b93ac1c..feaa3707b 100755 --- a/scripts/release.py +++ b/scripts/release.py @@ -271,7 +271,7 @@ def blog_add_post(): today = date.today() d = today.strftime("%Y-%m-%d") - f = open(d + "_release_" + ver_str + ".md", "w") + f = open(d + "-release_" + ver_str + ".md", "w") f.write(post) f.close() @@ -303,7 +303,6 @@ def publish_master(): cmd("cd lvgl; " + pub_cmd) cmd("cd lv_examples; " + pub_cmd) cmd("cd lv_drivers; " + pub_cmd) - cmd("cd blog; " + pub_cmd) pub_cmd = "git push origin latest; git push origin " + ver_str cmd("cd docs; " + pub_cmd) From 953753263ce0262ac0d51c531d8ec10d83658d1d Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Thu, 20 Aug 2020 07:06:18 +0200 Subject: [PATCH 159/173] fix warning --- src/lv_core/lv_style.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lv_core/lv_style.c b/src/lv_core/lv_style.c index 950275497..3a2ad6d80 100644 --- a/src/lv_core/lv_style.c +++ b/src/lv_core/lv_style.c @@ -875,7 +875,8 @@ lv_res_t _lv_style_list_get_color(lv_style_list_t * list, lv_style_property_t pr int16_t weight = -1; - lv_color_t value_act = { 0 }; + lv_color_t value_act; + value_act.full = 0; int16_t ci; for(ci = 0; ci < list->style_cnt; ci++) { From f4b4df8a17a86463dc11ac38cd456d218c4e2196 Mon Sep 17 00:00:00 2001 From: Amir Gonnen Date: Fri, 21 Aug 2020 00:53:23 +0300 Subject: [PATCH 160/173] lv_arc_set_reverse: remove prototype with no implementation (#1741) Required for Micropython --- src/lv_widgets/lv_arc.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/lv_widgets/lv_arc.h b/src/lv_widgets/lv_arc.h index 94f711661..602527b2c 100644 --- a/src/lv_widgets/lv_arc.h +++ b/src/lv_widgets/lv_arc.h @@ -159,14 +159,6 @@ void lv_arc_set_value(lv_obj_t * arc, int16_t value); */ void lv_arc_set_range(lv_obj_t * arc, int16_t min, int16_t max); -/** - * Reverse arc behavior. The indicator will grow from arc end instead of arc start. - * position. - * @param arc pointer to a arc object - * @param reverse true: enable disable reverse behavior; false: disable - */ -void lv_arc_set_reverse(lv_obj_t * arc, bool reverse); - /** * Set the threshold of arc knob increments * position. From 35e09885fb2c3c16fe82313593774502be6de54c Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Sat, 22 Aug 2020 17:37:29 -0400 Subject: [PATCH 161/173] lv_arc: use rotation when calculating drag angle fixes #1745 --- src/lv_widgets/lv_arc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lv_widgets/lv_arc.c b/src/lv_widgets/lv_arc.c index 96311fa6d..98ad5339e 100644 --- a/src/lv_widgets/lv_arc.c +++ b/src/lv_widgets/lv_arc.c @@ -743,6 +743,7 @@ static lv_res_t lv_arc_signal(lv_obj_t * arc, lv_signal_t sign, void * param) } angle = 360 - _lv_atan2(p.x, p.y) + 90; /*Some transformation is required*/ + angle -= ext->rotation_angle; if(angle < ext->bg_angle_start) angle = ext->bg_angle_start; if(angle > bg_end) angle = bg_end; From c0f6ff4d42a3fcf2434878a01443fb2faead77cf Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sun, 23 Aug 2020 07:44:29 +0200 Subject: [PATCH 162/173] fix color bleeding on border drawing Fixes https://forum.lvgl.io/t/border-dont-cover-calendar/3029/4 --- CHANGELOG.md | 3 +++ src/lv_core/lv_obj.c | 2 +- src/lv_draw/lv_draw_rect.c | 1 + src/lv_draw/lv_draw_rect.h | 1 + 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0947a95b5..6c44410b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ - Add `lv_font_free()` function - Frees the memory allocated by the `lv_font_load()` function - Add style caching to reduce acces time of properties with default value +### Bugfixes +- Fix color bleeding on border drawing + ## v7.3.1 (18.08.2020) ### Bugfixes diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 3db3ae401..50dc7bf6a 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -3801,7 +3801,7 @@ static lv_design_res_t lv_obj_design(lv_obj_t * obj, const lv_area_t * clip_area lv_draw_rect_dsc_init(&draw_dsc); /*If the border is drawn later disable loading its properties*/ if(lv_obj_get_style_border_post(obj, LV_OBJ_PART_MAIN)) { - draw_dsc.border_opa = LV_OPA_TRANSP; + draw_dsc.border_post = 1; } lv_obj_init_draw_rect_dsc(obj, LV_OBJ_PART_MAIN, &draw_dsc); diff --git a/src/lv_draw/lv_draw_rect.c b/src/lv_draw/lv_draw_rect.c index b4ce5a0b4..08682b789 100644 --- a/src/lv_draw/lv_draw_rect.c +++ b/src/lv_draw/lv_draw_rect.c @@ -391,6 +391,7 @@ LV_ATTRIBUTE_FAST_MEM static void draw_border(const lv_area_t * coords, const lv if(dsc->border_opa <= LV_OPA_MIN) return; if(dsc->border_width == 0) return; if(dsc->border_side == LV_BORDER_SIDE_NONE) return; + if(dsc->border_post) return; int32_t coords_w = lv_area_get_width(coords); int32_t coords_h = lv_area_get_height(coords); diff --git a/src/lv_draw/lv_draw_rect.h b/src/lv_draw/lv_draw_rect.h index 17f4a7248..1d3c4c4f7 100644 --- a/src/lv_draw/lv_draw_rect.h +++ b/src/lv_draw/lv_draw_rect.h @@ -41,6 +41,7 @@ typedef struct { lv_style_int_t border_side; lv_opa_t border_opa; lv_blend_mode_t border_blend_mode; + uint8_t border_post :1; /*There is a border it will be drawn later. */ /*Outline*/ lv_color_t outline_color; From 7e4769e3199f6ff8a23a7d2d5486cf669b96ac50 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sun, 23 Aug 2020 08:49:27 +0200 Subject: [PATCH 163/173] fix using LV_SCROLLBAR_UNHIDE after LV_SCROLLBAR_ON Fixes https://forum.lvgl.io/t/lv-sb-mode-unhide-has-an-unsuitable-value/3081 --- CHANGELOG.md | 1 + src/lv_widgets/lv_page.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c44410b5..83ca3fe6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ ### Bugfixes - Fix color bleeding on border drawing +- Fix using 'LV_SCROLLBAR_UNHIDE' after 'LV_SCROLLBAR_ON' ## v7.3.1 (18.08.2020) diff --git a/src/lv_widgets/lv_page.h b/src/lv_widgets/lv_page.h index ff317fba1..051dce509 100644 --- a/src/lv_widgets/lv_page.h +++ b/src/lv_widgets/lv_page.h @@ -41,7 +41,7 @@ enum { LV_SCROLLBAR_MODE_DRAG = 0x2, /**< Show scroll bars when page is being dragged*/ LV_SCROLLBAR_MODE_AUTO = 0x3, /**< Show scroll bars when the scrollable container is large enough to be scrolled*/ LV_SCROLLBAR_MODE_HIDE = 0x4, /**< Hide the scroll bar temporally*/ - LV_SCROLLBAR_MODE_UNHIDE = 0x5, /**< Unhide the previously hidden scroll bar. Recover original mode too*/ + LV_SCROLLBAR_MODE_UNHIDE = 0x8, /**< Unhide the previously hidden scroll bar. Recover original mode too*/ }; typedef uint8_t lv_scrollbar_mode_t; From 851493a1888a5e952a55c3c2d76e6ad52c4419a2 Mon Sep 17 00:00:00 2001 From: Ali Rostami <9710249+ali-rostami@users.noreply.github.com> Date: Sun, 23 Aug 2020 15:50:07 +0430 Subject: [PATCH 164/173] Update `lv_obj_refresh_style` description (#1746) --- src/lv_core/lv_obj.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 50dc7bf6a..04a0bc1a2 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -1332,6 +1332,7 @@ bool lv_obj_remove_style_local_prop(lv_obj_t * obj, uint8_t part, lv_style_prope /** * Notify an object (and its children) about its style is modified * @param obj pointer to an object + * @param part the part of the object which style property should be refreshed. * @param prop `LV_STYLE_PROP_ALL` or an `LV_STYLE_...` property. It is used to optimize what needs to be refreshed. */ void lv_obj_refresh_style(lv_obj_t * obj, uint8_t part, lv_style_property_t prop) From ba94b9cc941e74926cfec7cbb3c97d3919259354 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 24 Aug 2020 06:39:57 +0200 Subject: [PATCH 165/173] fix croping of last column/row if an image is zoomed Fixes #1742 --- CHANGELOG.md | 1 + src/lv_draw/lv_img_buf.c | 35 +++++++++++++++++++++-------------- src/lv_draw/lv_img_buf.h | 2 +- src/lv_widgets/lv_img.c | 3 +-- 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 83ca3fe6f..9c413c189 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ ### Bugfixes - Fix color bleeding on border drawing - Fix using 'LV_SCROLLBAR_UNHIDE' after 'LV_SCROLLBAR_ON' +- Fix croping of last column/row if an image is zoomed ## v7.3.1 (18.08.2020) diff --git a/src/lv_draw/lv_img_buf.c b/src/lv_draw/lv_img_buf.c index 5ddf40577..868116362 100644 --- a/src/lv_draw/lv_img_buf.c +++ b/src/lv_draw/lv_img_buf.c @@ -481,7 +481,20 @@ void _lv_img_buf_get_transformed_area(lv_area_t * res, lv_coord_t w, lv_coord_t res->x2 = w - 1; res->y2 = h - 1; return; + } + + res->x1 = (((-pivot->x) * zoom) >> 8) - 1; + res->y1 = (((-pivot->y) * zoom) >> 8) - 1; + res->x2 = (((w - pivot->x) * zoom) >> 8) + 2; + res->y2 = (((h - pivot->y) * zoom) >> 8) + 2; + + if(angle == 0) { + res->x1 += pivot->x; + res->y1 += pivot->y; + res->x2 += pivot->x; + res->y2 += pivot->y; + return; } int32_t angle_low = angle / 10; @@ -509,29 +522,23 @@ void _lv_img_buf_get_transformed_area(lv_area_t * res, lv_coord_t w, lv_coord_t lv_coord_t xt; lv_coord_t yt; - lv_area_t a; - a.x1 = ((-pivot->x) * zoom) >> 8; - a.y1 = ((-pivot->y) * zoom) >> 8; - a.x2 = ((w - pivot->x) * zoom) >> 8; - a.y2 = ((h - pivot->y) * zoom) >> 8; - - xt = a.x1; - yt = a.y1; + xt = res->x1; + yt = res->y1; lt.x = ((cosma * xt - sinma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->x; lt.y = ((sinma * xt + cosma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->y; - xt = a.x2; - yt = a.y1; + xt = res->x2; + yt = res->y1; rt.x = ((cosma * xt - sinma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->x; rt.y = ((sinma * xt + cosma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->y; - xt = a.x1; - yt = a.y2; + xt = res->x1; + yt = res->y2; lb.x = ((cosma * xt - sinma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->x; lb.y = ((sinma * xt + cosma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->y; - xt = a.x2; - yt = a.y2; + xt = res->x2; + yt = res->y2; rb.x = ((cosma * xt - sinma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->x; rb.y = ((sinma * xt + cosma * yt) >> _LV_TRANSFORM_TRIGO_SHIFT) + pivot->y; diff --git a/src/lv_draw/lv_img_buf.h b/src/lv_draw/lv_img_buf.h index d0d3991fc..29ee2b089 100644 --- a/src/lv_draw/lv_img_buf.h +++ b/src/lv_draw/lv_img_buf.h @@ -174,7 +174,7 @@ typedef struct { uint8_t has_alpha : 1; uint8_t native_color : 1; - uint16_t zoom_inv; + uint32_t zoom_inv; /*Runtime data*/ lv_coord_t xs; diff --git a/src/lv_widgets/lv_img.c b/src/lv_widgets/lv_img.c index 99fa31ae6..546b1b1c9 100644 --- a/src/lv_widgets/lv_img.c +++ b/src/lv_widgets/lv_img.c @@ -567,7 +567,6 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area lv_img_ext_t * ext = lv_obj_get_ext_attr(img); if(mode == LV_DESIGN_COVER_CHK) { - if(lv_obj_get_style_clip_corner(img, LV_IMG_PART_MAIN)) return LV_DESIGN_RES_MASKED; if(ext->src_type == LV_IMG_SRC_UNKNOWN || ext->src_type == LV_IMG_SRC_SYMBOL) return LV_DESIGN_RES_NOT_COVER; @@ -583,7 +582,7 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area int32_t zoom_final = lv_obj_get_style_transform_zoom(img, LV_IMG_PART_MAIN); zoom_final = (zoom_final * ext->zoom) >> 8; - if(zoom_final != LV_IMG_ZOOM_NONE) { + if(zoom_final == LV_IMG_ZOOM_NONE) { if(_lv_area_is_in(clip_area, &img->coords, 0) == false) return LV_DESIGN_RES_NOT_COVER; } else { From 961f295b94519da8f9e4ce01fc3ac9172025dfd9 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 24 Aug 2020 09:50:05 +0200 Subject: [PATCH 166/173] img: fix zooming and rotateing mosaic images --- CHANGELOG.md | 1 + src/lv_widgets/lv_img.c | 92 ++++++++++++++++++++++++++--------------- 2 files changed, 60 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c413c189..b88c1fefe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - Fix color bleeding on border drawing - Fix using 'LV_SCROLLBAR_UNHIDE' after 'LV_SCROLLBAR_ON' - Fix croping of last column/row if an image is zoomed +- Fix zooming and rotateing mosaic images ## v7.3.1 (18.08.2020) diff --git a/src/lv_widgets/lv_img.c b/src/lv_widgets/lv_img.c index 546b1b1c9..19223bb56 100644 --- a/src/lv_widgets/lv_img.c +++ b/src/lv_widgets/lv_img.c @@ -303,8 +303,10 @@ void lv_img_set_pivot(lv_obj_t * img, lv_coord_t pivot_x, lv_coord_t pivot_y) lv_style_int_t transf_angle = lv_obj_get_style_transform_angle(img, LV_IMG_PART_MAIN); transf_angle += ext->angle; + lv_coord_t w = lv_obj_get_width(img); + lv_coord_t h = lv_obj_get_height(img); lv_area_t a; - _lv_img_buf_get_transformed_area(&a, ext->w, ext->h, transf_angle, transf_zoom, &ext->pivot); + _lv_img_buf_get_transformed_area(&a, w, h, transf_angle, transf_zoom, &ext->pivot); a.x1 += img->coords.x1; a.y1 += img->coords.y1; a.x2 += img->coords.x1; @@ -315,7 +317,7 @@ void lv_img_set_pivot(lv_obj_t * img, lv_coord_t pivot_x, lv_coord_t pivot_y) ext->pivot.y = pivot_y; lv_obj_refresh_ext_draw_pad(img); - _lv_img_buf_get_transformed_area(&a, ext->w, ext->h, transf_angle, transf_zoom, &ext->pivot); + _lv_img_buf_get_transformed_area(&a, w, h, transf_angle, transf_zoom, &ext->pivot); a.x1 += img->coords.x1; a.y1 += img->coords.y1; a.x2 += img->coords.x1; @@ -341,8 +343,10 @@ void lv_img_set_angle(lv_obj_t * img, int16_t angle) lv_style_int_t transf_angle = lv_obj_get_style_transform_angle(img, LV_IMG_PART_MAIN); + lv_coord_t w = lv_obj_get_width(img); + lv_coord_t h = lv_obj_get_height(img); lv_area_t a; - _lv_img_buf_get_transformed_area(&a, ext->w, ext->h, transf_angle + ext->angle, transf_zoom, &ext->pivot); + _lv_img_buf_get_transformed_area(&a, w, h, transf_angle + ext->angle, transf_zoom, &ext->pivot); a.x1 += img->coords.x1; a.y1 += img->coords.y1; a.x2 += img->coords.x1; @@ -352,7 +356,7 @@ void lv_img_set_angle(lv_obj_t * img, int16_t angle) ext->angle = angle; lv_obj_refresh_ext_draw_pad(img); - _lv_img_buf_get_transformed_area(&a, ext->w, ext->h, transf_angle + ext->angle, transf_zoom, &ext->pivot); + _lv_img_buf_get_transformed_area(&a, w, h, transf_angle + ext->angle, transf_zoom, &ext->pivot); a.x1 += img->coords.x1; a.y1 += img->coords.y1; a.x2 += img->coords.x1; @@ -382,8 +386,10 @@ void lv_img_set_zoom(lv_obj_t * img, uint16_t zoom) lv_style_int_t transf_angle = lv_obj_get_style_transform_angle(img, LV_IMG_PART_MAIN); transf_angle += ext->angle; + lv_coord_t w = lv_obj_get_width(img); + lv_coord_t h = lv_obj_get_height(img); lv_area_t a; - _lv_img_buf_get_transformed_area(&a, ext->w, ext->h, transf_angle, (transf_zoom * ext->zoom) >> 8, &ext->pivot); + _lv_img_buf_get_transformed_area(&a, w, h, transf_angle, (transf_zoom * ext->zoom) >> 8, &ext->pivot); a.x1 += img->coords.x1; a.y1 += img->coords.y1; a.x2 += img->coords.x1; @@ -393,7 +399,7 @@ void lv_img_set_zoom(lv_obj_t * img, uint16_t zoom) ext->zoom = zoom; lv_obj_refresh_ext_draw_pad(img); - _lv_img_buf_get_transformed_area(&a, ext->w, ext->h, transf_angle, (transf_zoom * ext->zoom) >> 8, &ext->pivot); + _lv_img_buf_get_transformed_area(&a, w, h, transf_angle, (transf_zoom * ext->zoom) >> 8, &ext->pivot); a.x1 += img->coords.x1; a.y1 += img->coords.y1; a.x2 += img->coords.x1; @@ -602,9 +608,6 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area } else if(mode == LV_DESIGN_DRAW_MAIN) { if(ext->h == 0 || ext->w == 0) return true; - lv_area_t img_coords; - - lv_obj_get_coords(img, &img_coords); lv_draw_rect_dsc_t bg_dsc; lv_draw_rect_dsc_init(&bg_dsc); @@ -622,13 +625,16 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area int32_t angle_final = lv_obj_get_style_transform_angle(img, LV_IMG_PART_MAIN); angle_final += ext->angle; + lv_coord_t obj_w = lv_obj_get_width(img); + lv_coord_t obj_h = lv_obj_get_height(img); + lv_area_t bg_coords; - _lv_img_buf_get_transformed_area(&bg_coords, lv_area_get_width(&img_coords), lv_area_get_height(&img_coords), + _lv_img_buf_get_transformed_area(&bg_coords, obj_w, obj_h, angle_final, zoom_final, &ext->pivot); - bg_coords.x1 += img_coords.x1; - bg_coords.y1 += img_coords.y1; - bg_coords.x2 += img_coords.x1; - bg_coords.y2 += img_coords.y1; + bg_coords.x1 += img->coords.x1; + bg_coords.y1 += img->coords.y1; + bg_coords.x2 += img->coords.x1; + bg_coords.y2 += img->coords.y1; bg_coords.x1 -= lv_obj_get_style_pad_left(img, LV_IMG_PART_MAIN); bg_coords.x2 += lv_obj_get_style_pad_right(img, LV_IMG_PART_MAIN); bg_coords.y1 -= lv_obj_get_style_pad_top(img, LV_IMG_PART_MAIN); @@ -649,12 +655,6 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area } if(ext->src_type == LV_IMG_SRC_FILE || ext->src_type == LV_IMG_SRC_VARIABLE) { - img_coords.x1 += ext->offset.x; - img_coords.y1 += ext->offset.y; - - if(img_coords.x1 > img->coords.x1) img_coords.x1 -= ext->w; - if(img_coords.y1 > img->coords.y1) img_coords.y1 -= ext->h; - LV_LOG_TRACE("lv_img_design: start to draw image"); lv_draw_img_dsc_t img_dsc; @@ -671,15 +671,37 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area img_dsc.pivot.y = ext->pivot.y; img_dsc.antialias = ext->antialias; - lv_area_t cords_tmp; - cords_tmp.y1 = img_coords.y1; - cords_tmp.y2 = img_coords.y1 + ext->h - 1; + lv_coord_t zoomed_src_w = (int32_t)((int32_t)ext->w * zoom_final) >> 8; + lv_coord_t zoomed_src_h = (int32_t)((int32_t)ext->h * zoom_final) >> 8; + lv_area_t zommed_coords; + lv_obj_get_coords(img, &zommed_coords); - for(; cords_tmp.y1 <= img_coords.y2; cords_tmp.y1 += ext->h, cords_tmp.y2 += ext->h) { - cords_tmp.x1 = img_coords.x1; - cords_tmp.x2 = img_coords.x1 + ext->w - 1; - for(; cords_tmp.x1 <= img_coords.x2; cords_tmp.x1 += ext->w, cords_tmp.x2 += ext->w) { - lv_draw_img(&cords_tmp, clip_area, ext->src, &img_dsc); + zommed_coords.x1 += (int32_t)((int32_t)ext->offset.x * zoom_final) >> 8; + zommed_coords.y1 += (int32_t)((int32_t)ext->offset.y * zoom_final) >> 8; + zommed_coords.x2 = zommed_coords.x1 + ((int32_t)((int32_t)(obj_w - 1) * zoom_final) >> 8); + zommed_coords.y2 = zommed_coords.y1 + ((int32_t)((int32_t)(obj_h - 1) * zoom_final) >> 8); + + if(zommed_coords.x1 > img->coords.x1) zommed_coords.x1 -= ext->w; + if(zommed_coords.y1 > img->coords.y1) zommed_coords.y1 -= ext->h; + + lv_area_t clip_real; + _lv_img_buf_get_transformed_area(&clip_real, lv_obj_get_width(img), lv_obj_get_height(img), angle_final, zoom_final, &ext->pivot); + clip_real.x1 += img->coords.x1; + clip_real.x2 += img->coords.x1; + clip_real.y1 += img->coords.y1; + clip_real.y2 += img->coords.y1; + + if(_lv_area_intersect(&clip_real, &clip_real, clip_area) == false) return LV_DESIGN_RES_OK; + + lv_area_t coords_tmp; + coords_tmp.y1 = zommed_coords.y1; + coords_tmp.y2 = zommed_coords.y1 + ext->h - 1; + + for(; coords_tmp.y1 <= zommed_coords.y2; coords_tmp.y1 += zoomed_src_h, coords_tmp.y2 += zoomed_src_h) { + coords_tmp.x1 = zommed_coords.x1; + coords_tmp.x2 = zommed_coords.x1 + ext->w - 1; + for(; coords_tmp.x1 <= zommed_coords.x2; coords_tmp.x1 += zoomed_src_w, coords_tmp.x2 += zoomed_src_w) { + lv_draw_img(&coords_tmp, &clip_real, ext->src, &img_dsc); } } } @@ -690,7 +712,7 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area lv_obj_init_draw_label_dsc(img, LV_IMG_PART_MAIN, &label_dsc); label_dsc.color = lv_obj_get_style_image_recolor(img, LV_IMG_PART_MAIN); - lv_draw_label(&img_coords, clip_area, &label_dsc, ext->src, NULL); + lv_draw_label(&img->coords, clip_area, &label_dsc, ext->src, NULL); } else { /*Trigger the error handler of image drawer*/ @@ -787,12 +809,14 @@ static lv_res_t lv_img_signal(lv_obj_t * img, lv_signal_t sign, void * param) /*If the image has angle provide enough room for the rotated corners */ if(transf_angle || transf_zoom != LV_IMG_ZOOM_NONE) { lv_area_t a; - _lv_img_buf_get_transformed_area(&a, ext->w, ext->h, transf_angle, transf_zoom, &ext->pivot); + lv_coord_t w = lv_obj_get_width(img); + lv_coord_t h = lv_obj_get_height(img); + _lv_img_buf_get_transformed_area(&a, w, h, transf_angle, transf_zoom, &ext->pivot); lv_coord_t pad_ori = img->ext_draw_pad; img->ext_draw_pad = LV_MATH_MAX(img->ext_draw_pad, pad_ori - a.x1); img->ext_draw_pad = LV_MATH_MAX(img->ext_draw_pad, pad_ori - a.y1); - img->ext_draw_pad = LV_MATH_MAX(img->ext_draw_pad, pad_ori + a.x2 - ext->w); - img->ext_draw_pad = LV_MATH_MAX(img->ext_draw_pad, pad_ori + a.y2 - ext->h); + img->ext_draw_pad = LV_MATH_MAX(img->ext_draw_pad, pad_ori + a.x2 - w); + img->ext_draw_pad = LV_MATH_MAX(img->ext_draw_pad, pad_ori + a.y2 - h); } /*Handle the padding of the background*/ @@ -821,8 +845,10 @@ static lv_res_t lv_img_signal(lv_obj_t * img, lv_signal_t sign, void * param) if(ext->w == lv_obj_get_width(img) && ext->h == lv_obj_get_height(img) && (zoom != LV_IMG_ZOOM_NONE || angle != 0 || ext->pivot.x != ext->w / 2 || ext->pivot.y != ext->h / 2)) { + lv_coord_t w = lv_obj_get_width(img); + lv_coord_t h = lv_obj_get_height(img); lv_area_t coords; - _lv_img_buf_get_transformed_area(&coords, ext->w, ext->h, angle, zoom, &ext->pivot); + _lv_img_buf_get_transformed_area(&coords, w, h, angle, zoom, &ext->pivot); coords.x1 += img->coords.x1; coords.y1 += img->coords.y1; coords.x2 += img->coords.x1; From ede60854290bbe0fe11e3264d459af1eb177b910 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 24 Aug 2020 10:14:01 +0200 Subject: [PATCH 167/173] img: imporve zoom precision --- src/lv_draw/lv_img_buf.c | 2 +- src/lv_draw/lv_img_buf.h | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/lv_draw/lv_img_buf.c b/src/lv_draw/lv_img_buf.c index 868116362..722fcbf73 100644 --- a/src/lv_draw/lv_img_buf.c +++ b/src/lv_draw/lv_img_buf.c @@ -455,7 +455,7 @@ void _lv_img_buf_transform_init(lv_img_transform_dsc_t * dsc) dsc->tmp.img_dsc.header.w = dsc->cfg.src_w; dsc->tmp.img_dsc.header.h = dsc->cfg.src_h; - dsc->tmp.zoom_inv = (256 * 256) / dsc->cfg.zoom; + dsc->tmp.zoom_inv = ((256 * 256) << _LV_ZOOM_INV_UPSCALE) / dsc->cfg.zoom; dsc->res.opa = LV_OPA_COVER; dsc->res.color = dsc->cfg.color; diff --git a/src/lv_draw/lv_img_buf.h b/src/lv_draw/lv_img_buf.h index 29ee2b089..c80a2b907 100644 --- a/src/lv_draw/lv_img_buf.h +++ b/src/lv_draw/lv_img_buf.h @@ -49,6 +49,7 @@ extern "C" { #define LV_IMG_ZOOM_NONE 256 #define _LV_TRANSFORM_TRIGO_SHIFT 10 +#define _LV_ZOOM_INV_UPSCALE 4 /********************** * TYPEDEFS @@ -307,8 +308,8 @@ static inline bool _lv_img_buf_transform(lv_img_transform_dsc_t * dsc, lv_coord_ ys = ((dsc->tmp.sinma * xt + dsc->tmp.cosma * yt) >> (_LV_TRANSFORM_TRIGO_SHIFT - 8)) + dsc->tmp.pivot_y_256; } else if(dsc->cfg.angle == 0) { - xt *= dsc->tmp.zoom_inv; - yt *= dsc->tmp.zoom_inv; + xt = (xt * dsc->tmp.zoom_inv) >> _LV_ZOOM_INV_UPSCALE; + yt = (yt * dsc->tmp.zoom_inv) >> _LV_ZOOM_INV_UPSCALE; xs = xt + dsc->tmp.pivot_x_256; ys = yt + dsc->tmp.pivot_y_256; } From 54b3ba39fb89ecfd348ed479738892a192a4957a Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 24 Aug 2020 10:52:48 +0200 Subject: [PATCH 168/173] Fix deleting tabview with LEFT/RIGHT tab position --- CHANGELOG.md | 3 ++- src/lv_widgets/lv_tabview.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b88c1fefe..efdc797a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,8 @@ - Fix color bleeding on border drawing - Fix using 'LV_SCROLLBAR_UNHIDE' after 'LV_SCROLLBAR_ON' - Fix croping of last column/row if an image is zoomed -- Fix zooming and rotateing mosaic images +- Fix zooming and rotateing mosaic images7 +- Fix deleting tabview with LEF/RIGHT tab position ## v7.3.1 (18.08.2020) diff --git a/src/lv_widgets/lv_tabview.c b/src/lv_widgets/lv_tabview.c index 4b5cd0f6e..5cc773444 100644 --- a/src/lv_widgets/lv_tabview.c +++ b/src/lv_widgets/lv_tabview.c @@ -628,7 +628,7 @@ static lv_res_t lv_tabview_signal(lv_obj_t * tabview, lv_signal_t sign, void * p lv_tabview_ext_t * ext = lv_obj_get_ext_attr(tabview); if(sign == LV_SIGNAL_CLEANUP) { uint8_t i; - for(i = 0; ext->tab_name_ptr[i][0] != '\0'; i++) lv_mem_free(ext->tab_name_ptr[i]); + for(i = 0; ext->tab_name_ptr[i][0] != '\0' && ext->tab_name_ptr[i][0] != '\n'; i++) lv_mem_free(ext->tab_name_ptr[i]); lv_mem_free(ext->tab_name_ptr); ext->tab_name_ptr = NULL; From 78f2451b2a0c49fd05cd1ad754a69aed7961de57 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 24 Aug 2020 16:00:53 +0200 Subject: [PATCH 169/173] imporve image zoom precision --- CHANGELOG.md | 2 +- src/lv_draw/lv_img_buf.c | 4 +++- src/lv_draw/lv_img_buf.h | 6 +++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index efdc797a5..66f4c4760 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ - Fix using 'LV_SCROLLBAR_UNHIDE' after 'LV_SCROLLBAR_ON' - Fix croping of last column/row if an image is zoomed - Fix zooming and rotateing mosaic images7 -- Fix deleting tabview with LEF/RIGHT tab position +- Fix deleting tabview with LEFT/RIGHT tab position ## v7.3.1 (18.08.2020) diff --git a/src/lv_draw/lv_img_buf.c b/src/lv_draw/lv_img_buf.c index 722fcbf73..cc4d1cb0f 100644 --- a/src/lv_draw/lv_img_buf.c +++ b/src/lv_draw/lv_img_buf.c @@ -455,7 +455,9 @@ void _lv_img_buf_transform_init(lv_img_transform_dsc_t * dsc) dsc->tmp.img_dsc.header.w = dsc->cfg.src_w; dsc->tmp.img_dsc.header.h = dsc->cfg.src_h; - dsc->tmp.zoom_inv = ((256 * 256) << _LV_ZOOM_INV_UPSCALE) / dsc->cfg.zoom; + /* The inverse of the zoom will be sued during the transformation + * + dsc->cfg.zoom / 2 for rounding*/ + dsc->tmp.zoom_inv = (((256 * 256) << _LV_ZOOM_INV_UPSCALE) + dsc->cfg.zoom / 2) / dsc->cfg.zoom; dsc->res.opa = LV_OPA_COVER; dsc->res.color = dsc->cfg.color; diff --git a/src/lv_draw/lv_img_buf.h b/src/lv_draw/lv_img_buf.h index c80a2b907..d549c8109 100644 --- a/src/lv_draw/lv_img_buf.h +++ b/src/lv_draw/lv_img_buf.h @@ -49,7 +49,7 @@ extern "C" { #define LV_IMG_ZOOM_NONE 256 #define _LV_TRANSFORM_TRIGO_SHIFT 10 -#define _LV_ZOOM_INV_UPSCALE 4 +#define _LV_ZOOM_INV_UPSCALE 5 /********************** * TYPEDEFS @@ -314,8 +314,8 @@ static inline bool _lv_img_buf_transform(lv_img_transform_dsc_t * dsc, lv_coord_ ys = yt + dsc->tmp.pivot_y_256; } else { - xt *= dsc->tmp.zoom_inv; - yt *= dsc->tmp.zoom_inv; + xt = (xt * dsc->tmp.zoom_inv) >> _LV_ZOOM_INV_UPSCALE; + yt = (yt * dsc->tmp.zoom_inv) >> _LV_ZOOM_INV_UPSCALE; xs = ((dsc->tmp.cosma * xt - dsc->tmp.sinma * yt) >> (_LV_TRANSFORM_TRIGO_SHIFT)) + dsc->tmp.pivot_x_256; ys = ((dsc->tmp.sinma * xt + dsc->tmp.cosma * yt) >> (_LV_TRANSFORM_TRIGO_SHIFT)) + dsc->tmp.pivot_y_256; } From 52c61b115f15585d632494bb4f08063cb9d98d17 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 25 Aug 2020 11:54:12 +0200 Subject: [PATCH 170/173] minor image zoom fixes --- src/lv_draw/lv_img_buf.h | 8 ++++---- src/lv_widgets/lv_img.c | 6 ++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/lv_draw/lv_img_buf.h b/src/lv_draw/lv_img_buf.h index d549c8109..5b43456ac 100644 --- a/src/lv_draw/lv_img_buf.h +++ b/src/lv_draw/lv_img_buf.h @@ -308,14 +308,14 @@ static inline bool _lv_img_buf_transform(lv_img_transform_dsc_t * dsc, lv_coord_ ys = ((dsc->tmp.sinma * xt + dsc->tmp.cosma * yt) >> (_LV_TRANSFORM_TRIGO_SHIFT - 8)) + dsc->tmp.pivot_y_256; } else if(dsc->cfg.angle == 0) { - xt = (xt * dsc->tmp.zoom_inv) >> _LV_ZOOM_INV_UPSCALE; - yt = (yt * dsc->tmp.zoom_inv) >> _LV_ZOOM_INV_UPSCALE; + xt = (int32_t)((int32_t)xt * dsc->tmp.zoom_inv) >> _LV_ZOOM_INV_UPSCALE; + yt = (int32_t)((int32_t)yt * dsc->tmp.zoom_inv) >> _LV_ZOOM_INV_UPSCALE; xs = xt + dsc->tmp.pivot_x_256; ys = yt + dsc->tmp.pivot_y_256; } else { - xt = (xt * dsc->tmp.zoom_inv) >> _LV_ZOOM_INV_UPSCALE; - yt = (yt * dsc->tmp.zoom_inv) >> _LV_ZOOM_INV_UPSCALE; + xt = (int32_t)((int32_t)xt * dsc->tmp.zoom_inv) >> _LV_ZOOM_INV_UPSCALE; + yt = (int32_t)((int32_t)yt * dsc->tmp.zoom_inv) >> _LV_ZOOM_INV_UPSCALE; xs = ((dsc->tmp.cosma * xt - dsc->tmp.sinma * yt) >> (_LV_TRANSFORM_TRIGO_SHIFT)) + dsc->tmp.pivot_x_256; ys = ((dsc->tmp.sinma * xt + dsc->tmp.cosma * yt) >> (_LV_TRANSFORM_TRIGO_SHIFT)) + dsc->tmp.pivot_y_256; } diff --git a/src/lv_widgets/lv_img.c b/src/lv_widgets/lv_img.c index 19223bb56..89ed3c864 100644 --- a/src/lv_widgets/lv_img.c +++ b/src/lv_widgets/lv_img.c @@ -672,7 +672,9 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area img_dsc.antialias = ext->antialias; lv_coord_t zoomed_src_w = (int32_t)((int32_t)ext->w * zoom_final) >> 8; + if(zoomed_src_w <= 0) return LV_DESIGN_RES_OK; lv_coord_t zoomed_src_h = (int32_t)((int32_t)ext->h * zoom_final) >> 8; + if(zoomed_src_h <= 0) return LV_DESIGN_RES_OK; lv_area_t zommed_coords; lv_obj_get_coords(img, &zommed_coords); @@ -697,10 +699,10 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area coords_tmp.y1 = zommed_coords.y1; coords_tmp.y2 = zommed_coords.y1 + ext->h - 1; - for(; coords_tmp.y1 <= zommed_coords.y2; coords_tmp.y1 += zoomed_src_h, coords_tmp.y2 += zoomed_src_h) { + for(; coords_tmp.y1 < zommed_coords.y2; coords_tmp.y1 += zoomed_src_h, coords_tmp.y2 += zoomed_src_h) { coords_tmp.x1 = zommed_coords.x1; coords_tmp.x2 = zommed_coords.x1 + ext->w - 1; - for(; coords_tmp.x1 <= zommed_coords.x2; coords_tmp.x1 += zoomed_src_w, coords_tmp.x2 += zoomed_src_w) { + for(; coords_tmp.x1 < zommed_coords.x2; coords_tmp.x1 += zoomed_src_w, coords_tmp.x2 += zoomed_src_w) { lv_draw_img(&coords_tmp, &clip_real, ext->src, &img_dsc); } } From 14a2a60bf936d2b072478a24e5f3e6f1a37b221b Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 25 Aug 2020 15:18:45 +0200 Subject: [PATCH 171/173] Fix btnmatrix to not send event when CLICK_TRIG = true and the cursor slid from a pressed button Fixes: https://forum.lvgl.io/t/v7-3-register-button-in-button-matrix-only-after-touch-release-not-button-release/3117 --- src/lv_widgets/lv_btnmatrix.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/lv_widgets/lv_btnmatrix.c b/src/lv_widgets/lv_btnmatrix.c index 4acb82643..8855bddb3 100644 --- a/src/lv_widgets/lv_btnmatrix.c +++ b/src/lv_widgets/lv_btnmatrix.c @@ -904,12 +904,13 @@ static lv_res_t lv_btnmatrix_signal(lv_obj_t * btnm, lv_signal_t sign, void * pa lv_indev_reset_long_press(param); /*Start the log press time again on the new button*/ if(btn_pr != LV_BTNMATRIX_BTN_NONE && button_is_inactive(ext->ctrl_bits[btn_pr]) == false && - button_is_hidden(ext->ctrl_bits[btn_pr]) == false) { + button_is_hidden(ext->ctrl_bits[btn_pr]) == false) + { + invalidate_button_area(btnm, btn_pr); /* Send VALUE_CHANGED for the newly pressed button */ - uint32_t b = btn_pr; - res = lv_event_send(btnm, LV_EVENT_VALUE_CHANGED, &b); - if(res == LV_RES_OK) { - invalidate_button_area(btnm, btn_pr); + if(button_is_click_trig(ext->ctrl_bits[btn_pr]) == false) { + uint32_t b = btn_pr; + lv_event_send(btnm, LV_EVENT_VALUE_CHANGED, &b); } } } From e7364f321d906fb96909768d6fb5532e03a1a694 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 25 Aug 2020 15:21:25 +0200 Subject: [PATCH 172/173] update CHANGELOG --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66f4c4760..d5cff76ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,8 +14,9 @@ - Fix color bleeding on border drawing - Fix using 'LV_SCROLLBAR_UNHIDE' after 'LV_SCROLLBAR_ON' - Fix croping of last column/row if an image is zoomed -- Fix zooming and rotateing mosaic images7 +- Fix zooming and rotateing mosaic images - Fix deleting tabview with LEFT/RIGHT tab position +- Fix btnmatrix to not send event when CLICK_TRIG = true and the cursor slid from a pressed button ## v7.3.1 (18.08.2020) From 037d3d90908dfb130929c037c6e79c89cde4a227 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 26 Aug 2020 15:21:24 +0200 Subject: [PATCH 173/173] run code formatter --- src/lv_core/lv_obj.c | 270 +++++++++++++++++----------------- src/lv_core/lv_style.h | 54 +++---- src/lv_draw/lv_draw_rect.h | 2 +- src/lv_font/lv_font_loader.c | 2 +- src/lv_widgets/lv_arc.c | 46 +++--- src/lv_widgets/lv_arc.h | 4 +- src/lv_widgets/lv_btnmatrix.c | 3 +- src/lv_widgets/lv_img.c | 3 +- 8 files changed, 195 insertions(+), 189 deletions(-) diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 04a0bc1a2..30c5f6c6c 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -1442,10 +1442,10 @@ void _lv_obj_disable_style_caching(lv_obj_t * obj, bool dis) list->ignore_cache = dis; } for(part = _LV_OBJ_PART_REAL_FIRST; part < 0xFF; part++) { - lv_style_list_t * list = lv_obj_get_style_list(obj, part); - if(list == NULL) break; - list->ignore_cache = dis; - } + lv_style_list_t * list = lv_obj_get_style_list(obj, part); + if(list == NULL) break; + list->ignore_cache = dis; + } } /*----------------- @@ -2512,61 +2512,61 @@ lv_style_int_t _lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_styl while(parent) { lv_style_list_t * list = lv_obj_get_style_list(parent, part); if(!list->ignore_cache && list->style_cnt > 0) { - if(!list->valid_cache) update_style_cache((lv_obj_t*)parent, part, prop & (~LV_STYLE_STATE_MASK)); + if(!list->valid_cache) update_style_cache((lv_obj_t *)parent, part, prop & (~LV_STYLE_STATE_MASK)); bool def = false; switch(prop & (~LV_STYLE_STATE_MASK)) { - case LV_STYLE_BG_GRAD_DIR: - if(list->bg_grad_dir_none) def = true; - break; - case LV_STYLE_CLIP_CORNER: - if(list->clip_corner_off) def = true; - break; - case LV_STYLE_TEXT_LETTER_SPACE: - case LV_STYLE_TEXT_LINE_SPACE: - if(list->text_space_zero) def = true; - break; - case LV_STYLE_TRANSFORM_ANGLE: - case LV_STYLE_TRANSFORM_WIDTH: - case LV_STYLE_TRANSFORM_HEIGHT: - case LV_STYLE_TRANSFORM_ZOOM: - if(list->transform_all_zero) def = true; - break; - case LV_STYLE_BORDER_WIDTH: - if(list->border_width_zero) def = true; - break; - case LV_STYLE_BORDER_SIDE: - if(list->border_side_full) def = true; - break; - case LV_STYLE_BORDER_POST: - if(list->border_post_off) def = true; - break; - case LV_STYLE_OUTLINE_WIDTH: - if(list->outline_width_zero) def = true; - break; - case LV_STYLE_RADIUS: - if(list->radius_zero) def = true; - break; - case LV_STYLE_SHADOW_WIDTH: - if(list->shadow_width_zero) def = true; - break; - case LV_STYLE_PAD_TOP: - case LV_STYLE_PAD_BOTTOM: - case LV_STYLE_PAD_LEFT: - case LV_STYLE_PAD_RIGHT: - if(list->pad_all_zero) def = true; - break; - case LV_STYLE_BG_BLEND_MODE: - case LV_STYLE_BORDER_BLEND_MODE: - case LV_STYLE_IMAGE_BLEND_MODE: - case LV_STYLE_LINE_BLEND_MODE: - case LV_STYLE_OUTLINE_BLEND_MODE: - case LV_STYLE_PATTERN_BLEND_MODE: - case LV_STYLE_SHADOW_BLEND_MODE: - case LV_STYLE_TEXT_BLEND_MODE: - case LV_STYLE_VALUE_BLEND_MODE: - if(list->blend_mode_all_normal) def = true; - break; + case LV_STYLE_BG_GRAD_DIR: + if(list->bg_grad_dir_none) def = true; + break; + case LV_STYLE_CLIP_CORNER: + if(list->clip_corner_off) def = true; + break; + case LV_STYLE_TEXT_LETTER_SPACE: + case LV_STYLE_TEXT_LINE_SPACE: + if(list->text_space_zero) def = true; + break; + case LV_STYLE_TRANSFORM_ANGLE: + case LV_STYLE_TRANSFORM_WIDTH: + case LV_STYLE_TRANSFORM_HEIGHT: + case LV_STYLE_TRANSFORM_ZOOM: + if(list->transform_all_zero) def = true; + break; + case LV_STYLE_BORDER_WIDTH: + if(list->border_width_zero) def = true; + break; + case LV_STYLE_BORDER_SIDE: + if(list->border_side_full) def = true; + break; + case LV_STYLE_BORDER_POST: + if(list->border_post_off) def = true; + break; + case LV_STYLE_OUTLINE_WIDTH: + if(list->outline_width_zero) def = true; + break; + case LV_STYLE_RADIUS: + if(list->radius_zero) def = true; + break; + case LV_STYLE_SHADOW_WIDTH: + if(list->shadow_width_zero) def = true; + break; + case LV_STYLE_PAD_TOP: + case LV_STYLE_PAD_BOTTOM: + case LV_STYLE_PAD_LEFT: + case LV_STYLE_PAD_RIGHT: + if(list->pad_all_zero) def = true; + break; + case LV_STYLE_BG_BLEND_MODE: + case LV_STYLE_BORDER_BLEND_MODE: + case LV_STYLE_IMAGE_BLEND_MODE: + case LV_STYLE_LINE_BLEND_MODE: + case LV_STYLE_OUTLINE_BLEND_MODE: + case LV_STYLE_PATTERN_BLEND_MODE: + case LV_STYLE_SHADOW_BLEND_MODE: + case LV_STYLE_TEXT_BLEND_MODE: + case LV_STYLE_VALUE_BLEND_MODE: + if(list->blend_mode_all_normal) def = true; + break; } if(def) { @@ -2694,19 +2694,19 @@ lv_opa_t _lv_obj_get_style_opa(const lv_obj_t * obj, uint8_t part, lv_style_prop lv_style_list_t * list = lv_obj_get_style_list(parent, part); if(!list->ignore_cache && list->style_cnt > 0) { - if(!list->valid_cache) update_style_cache((lv_obj_t*)parent, part, prop & (~LV_STYLE_STATE_MASK)); + if(!list->valid_cache) update_style_cache((lv_obj_t *)parent, part, prop & (~LV_STYLE_STATE_MASK)); bool def = false; switch(prop & (~LV_STYLE_STATE_MASK)) { - case LV_STYLE_OPA_SCALE: - if(list->opa_scale_cover) def = true; - break; - case LV_STYLE_BG_OPA: - if(list->bg_opa_cover) return LV_OPA_COVER; /*Special case, not the default value is used*/ - if(list->bg_opa_transp) def = true; - break; - case LV_STYLE_IMAGE_RECOLOR_OPA: - if(list->img_recolor_opa_transp) def = true; - break; + case LV_STYLE_OPA_SCALE: + if(list->opa_scale_cover) def = true; + break; + case LV_STYLE_BG_OPA: + if(list->bg_opa_cover) return LV_OPA_COVER; /*Special case, not the default value is used*/ + if(list->bg_opa_transp) def = true; + break; + case LV_STYLE_IMAGE_RECOLOR_OPA: + if(list->img_recolor_opa_transp) def = true; + break; } if(def) { @@ -2773,18 +2773,18 @@ const void * _lv_obj_get_style_ptr(const lv_obj_t * obj, uint8_t part, lv_style_ lv_style_list_t * list = lv_obj_get_style_list(parent, part); if(!list->ignore_cache && list->style_cnt > 0) { - if(!list->valid_cache) update_style_cache((lv_obj_t*)parent, part, prop & (~LV_STYLE_STATE_MASK)); + if(!list->valid_cache) update_style_cache((lv_obj_t *)parent, part, prop & (~LV_STYLE_STATE_MASK)); bool def = false; switch(prop & (~LV_STYLE_STATE_MASK)) { - case LV_STYLE_VALUE_STR: - if(list->value_txt_str) def = true; - break; - case LV_STYLE_PATTERN_IMAGE: - if(list->pattern_img_null) def = true; - break; - case LV_STYLE_TEXT_FONT: - if(list->text_font_normal) def = true; - break; + case LV_STYLE_VALUE_STR: + if(list->value_txt_str) def = true; + break; + case LV_STYLE_PATTERN_IMAGE: + if(list->pattern_img_null) def = true; + break; + case LV_STYLE_TEXT_FONT: + if(list->text_font_normal) def = true; + break; } if(def) { @@ -4472,44 +4472,44 @@ static bool style_prop_is_cacheble(lv_style_property_t prop) { switch(prop) { - case LV_STYLE_PROP_ALL: - case LV_STYLE_BG_GRAD_DIR: - case LV_STYLE_CLIP_CORNER: - case LV_STYLE_TEXT_LETTER_SPACE: - case LV_STYLE_TEXT_LINE_SPACE: - case LV_STYLE_TEXT_FONT: - case LV_STYLE_TRANSFORM_ANGLE: - case LV_STYLE_TRANSFORM_WIDTH: - case LV_STYLE_TRANSFORM_HEIGHT: - case LV_STYLE_TRANSFORM_ZOOM: - case LV_STYLE_BORDER_WIDTH: - case LV_STYLE_OUTLINE_WIDTH: - case LV_STYLE_RADIUS: - case LV_STYLE_SHADOW_WIDTH: - case LV_STYLE_OPA_SCALE: - case LV_STYLE_BG_OPA: - case LV_STYLE_BORDER_SIDE: - case LV_STYLE_BORDER_POST: - case LV_STYLE_IMAGE_RECOLOR_OPA: - case LV_STYLE_VALUE_STR: - case LV_STYLE_PATTERN_IMAGE: - case LV_STYLE_PAD_TOP: - case LV_STYLE_PAD_BOTTOM: - case LV_STYLE_PAD_LEFT: - case LV_STYLE_PAD_RIGHT: - case LV_STYLE_BG_BLEND_MODE: - case LV_STYLE_BORDER_BLEND_MODE: - case LV_STYLE_IMAGE_BLEND_MODE: - case LV_STYLE_LINE_BLEND_MODE: - case LV_STYLE_OUTLINE_BLEND_MODE: - case LV_STYLE_PATTERN_BLEND_MODE: - case LV_STYLE_SHADOW_BLEND_MODE: - case LV_STYLE_TEXT_BLEND_MODE: - case LV_STYLE_VALUE_BLEND_MODE: - return true; - break; - default: - return false; + case LV_STYLE_PROP_ALL: + case LV_STYLE_BG_GRAD_DIR: + case LV_STYLE_CLIP_CORNER: + case LV_STYLE_TEXT_LETTER_SPACE: + case LV_STYLE_TEXT_LINE_SPACE: + case LV_STYLE_TEXT_FONT: + case LV_STYLE_TRANSFORM_ANGLE: + case LV_STYLE_TRANSFORM_WIDTH: + case LV_STYLE_TRANSFORM_HEIGHT: + case LV_STYLE_TRANSFORM_ZOOM: + case LV_STYLE_BORDER_WIDTH: + case LV_STYLE_OUTLINE_WIDTH: + case LV_STYLE_RADIUS: + case LV_STYLE_SHADOW_WIDTH: + case LV_STYLE_OPA_SCALE: + case LV_STYLE_BG_OPA: + case LV_STYLE_BORDER_SIDE: + case LV_STYLE_BORDER_POST: + case LV_STYLE_IMAGE_RECOLOR_OPA: + case LV_STYLE_VALUE_STR: + case LV_STYLE_PATTERN_IMAGE: + case LV_STYLE_PAD_TOP: + case LV_STYLE_PAD_BOTTOM: + case LV_STYLE_PAD_LEFT: + case LV_STYLE_PAD_RIGHT: + case LV_STYLE_BG_BLEND_MODE: + case LV_STYLE_BORDER_BLEND_MODE: + case LV_STYLE_IMAGE_BLEND_MODE: + case LV_STYLE_LINE_BLEND_MODE: + case LV_STYLE_OUTLINE_BLEND_MODE: + case LV_STYLE_PATTERN_BLEND_MODE: + case LV_STYLE_SHADOW_BLEND_MODE: + case LV_STYLE_TEXT_BLEND_MODE: + case LV_STYLE_VALUE_BLEND_MODE: + return true; + break; + default: + return false; } } @@ -4564,32 +4564,29 @@ static void update_style_cache(lv_obj_t * obj, uint8_t part, uint16_t prop) if(lv_obj_get_style_transform_angle(obj, part) != 0 || lv_obj_get_style_transform_width(obj, part) != 0 || lv_obj_get_style_transform_height(obj, part) != 0 || - lv_obj_get_style_transform_zoom(obj, part) != LV_IMG_ZOOM_NONE) - { + lv_obj_get_style_transform_zoom(obj, part) != LV_IMG_ZOOM_NONE) { list->transform_all_zero = 0; } list->pad_all_zero = 1; if(lv_obj_get_style_pad_top(obj, part) != 0 || - lv_obj_get_style_pad_bottom(obj, part) != 0 || - lv_obj_get_style_pad_left(obj, part) != 0 || - lv_obj_get_style_pad_right(obj, part) != 0) - { + lv_obj_get_style_pad_bottom(obj, part) != 0 || + lv_obj_get_style_pad_left(obj, part) != 0 || + lv_obj_get_style_pad_right(obj, part) != 0) { list->pad_all_zero = 0; } list->blend_mode_all_normal = 1; #if LV_USE_BLEND_MODES if(lv_obj_get_style_bg_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || - lv_obj_get_style_border_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || - lv_obj_get_style_pattern_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || - lv_obj_get_style_outline_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || - lv_obj_get_style_value_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || - lv_obj_get_style_text_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || - lv_obj_get_style_line_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || - lv_obj_get_style_image_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || - lv_obj_get_style_shadow_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL) - { + lv_obj_get_style_border_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_pattern_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_outline_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_value_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_text_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_line_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_image_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL || + lv_obj_get_style_shadow_blend_mode(obj, part) != LV_BLEND_MODE_NORMAL) { list->blend_mode_all_normal = 0; } #endif @@ -4619,7 +4616,7 @@ static void update_style_cache_children(lv_obj_t * obj) list->text_space_zero = 1; if(lv_obj_get_style_text_letter_space(obj, part) != 0 || - lv_obj_get_style_text_line_space(obj, part) != 0) { + lv_obj_get_style_text_line_space(obj, part) != 0) { list->text_space_zero = 0; } @@ -4647,7 +4644,8 @@ static void invalidate_style_cache(lv_obj_t * obj, uint8_t part, lv_style_proper lv_style_list_t * list = lv_obj_get_style_list(obj, part); if(list == NULL) return; list->valid_cache = 0; - } else { + } + else { for(part = 0; part < _LV_OBJ_PART_REAL_FIRST; part++) { lv_style_list_t * list = lv_obj_get_style_list(obj, part); @@ -4655,10 +4653,10 @@ static void invalidate_style_cache(lv_obj_t * obj, uint8_t part, lv_style_proper list->valid_cache = 0; } for(part = _LV_OBJ_PART_REAL_FIRST; part < 0xFF; part++) { - lv_style_list_t * list = lv_obj_get_style_list(obj, part); - if(list == NULL) break; - list->valid_cache = 0; - } + lv_style_list_t * list = lv_obj_get_style_list(obj, part); + if(list == NULL) break; + list->valid_cache = 0; + } } lv_obj_t * child = lv_obj_get_child(obj, NULL); diff --git a/src/lv_core/lv_style.h b/src/lv_core/lv_style.h index 7ed69dbc5..8d9d15d8e 100644 --- a/src/lv_core/lv_style.h +++ b/src/lv_core/lv_style.h @@ -221,37 +221,37 @@ typedef struct { #if LV_USE_ASSERT_STYLE uint32_t sentinel; #endif - uint32_t style_cnt :6; - uint32_t has_local :1; - uint32_t has_trans :1; - uint32_t skip_trans :1; /*1: Temporally skip the transition style if any*/ - uint32_t ignore_trans :1; /*1: Mark that this style list shouldn't receive transitions at all*/ - uint32_t valid_cache :1; /*1: The cache is valid and can be used*/ - uint32_t ignore_cache :1; /*1: Ignore cache while getting value of properties*/ + uint32_t style_cnt : 6; + uint32_t has_local : 1; + uint32_t has_trans : 1; + uint32_t skip_trans : 1; /*1: Temporally skip the transition style if any*/ + uint32_t ignore_trans : 1; /*1: Mark that this style list shouldn't receive transitions at all*/ + uint32_t valid_cache : 1; /*1: The cache is valid and can be used*/ + uint32_t ignore_cache : 1; /*1: Ignore cache while getting value of properties*/ - uint32_t radius_zero :1; - uint32_t opa_scale_cover :1; - uint32_t clip_corner_off :1; - uint32_t transform_all_zero :1; - uint32_t pad_all_zero :1; - uint32_t blend_mode_all_normal :1; - uint32_t bg_opa_transp :1; - uint32_t bg_opa_cover :1; - uint32_t bg_grad_dir_none :1; + uint32_t radius_zero : 1; + uint32_t opa_scale_cover : 1; + uint32_t clip_corner_off : 1; + uint32_t transform_all_zero : 1; + uint32_t pad_all_zero : 1; + uint32_t blend_mode_all_normal : 1; + uint32_t bg_opa_transp : 1; + uint32_t bg_opa_cover : 1; + uint32_t bg_grad_dir_none : 1; - uint32_t border_width_zero :1; - uint32_t border_side_full :1; - uint32_t border_post_off :1; + uint32_t border_width_zero : 1; + uint32_t border_side_full : 1; + uint32_t border_post_off : 1; - uint32_t outline_width_zero :1; - uint32_t pattern_img_null :1; - uint32_t shadow_width_zero :1; - uint32_t value_txt_str :1; - uint32_t img_recolor_opa_transp :1; + uint32_t outline_width_zero : 1; + uint32_t pattern_img_null : 1; + uint32_t shadow_width_zero : 1; + uint32_t value_txt_str : 1; + uint32_t img_recolor_opa_transp : 1; - uint32_t text_space_zero :1; - uint32_t text_decor_none :1; - uint32_t text_font_normal :1; + uint32_t text_space_zero : 1; + uint32_t text_decor_none : 1; + uint32_t text_font_normal : 1; } lv_style_list_t; /********************** diff --git a/src/lv_draw/lv_draw_rect.h b/src/lv_draw/lv_draw_rect.h index 1d3c4c4f7..0bf884832 100644 --- a/src/lv_draw/lv_draw_rect.h +++ b/src/lv_draw/lv_draw_rect.h @@ -41,7 +41,7 @@ typedef struct { lv_style_int_t border_side; lv_opa_t border_opa; lv_blend_mode_t border_blend_mode; - uint8_t border_post :1; /*There is a border it will be drawn later. */ + uint8_t border_post : 1; /*There is a border it will be drawn later. */ /*Outline*/ lv_color_t outline_color; diff --git a/src/lv_font/lv_font_loader.c b/src/lv_font/lv_font_loader.c index 53e7f77f4..cb9e78a21 100644 --- a/src/lv_font/lv_font_loader.c +++ b/src/lv_font/lv_font_loader.c @@ -102,7 +102,7 @@ lv_font_t * lv_font_load(const char * font_name) if(!success) { LV_LOG_WARN("Error loading font file: %s\n", font_name); - /* + /* * When `lvgl_load_font` fails it can leak some pointers. * All non-null pointers can be assumed as allocated and * `lv_font_free` should free them correctly. diff --git a/src/lv_widgets/lv_arc.c b/src/lv_widgets/lv_arc.c index 98ad5339e..4afc26609 100644 --- a/src/lv_widgets/lv_arc.c +++ b/src/lv_widgets/lv_arc.c @@ -165,11 +165,13 @@ void lv_arc_set_start_angle(lv_obj_t * arc, uint16_t start) } /*Only a smaller incremental move*/ else if(ext->arc_angle_start > ext->arc_angle_end && start > ext->arc_angle_end) { - inv_arc_area(arc, LV_MATH_MIN(ext->arc_angle_start, start), LV_MATH_MAX(ext->arc_angle_start, start), LV_ARC_PART_INDIC); + inv_arc_area(arc, LV_MATH_MIN(ext->arc_angle_start, start), LV_MATH_MAX(ext->arc_angle_start, start), + LV_ARC_PART_INDIC); } /*Only a smaller incremental move*/ else if(ext->arc_angle_start < ext->arc_angle_end && start < ext->arc_angle_end) { - inv_arc_area(arc, LV_MATH_MIN(ext->arc_angle_start, start), LV_MATH_MAX(ext->arc_angle_start, start), LV_ARC_PART_INDIC); + inv_arc_area(arc, LV_MATH_MIN(ext->arc_angle_start, start), LV_MATH_MAX(ext->arc_angle_start, start), + LV_ARC_PART_INDIC); } /*Crossing the start angle makes the whole arc change*/ else { @@ -351,14 +353,14 @@ void lv_arc_set_type(lv_obj_t * arc, lv_arc_type_t type) { LV_ASSERT_OBJ(arc, LV_OBJX_NAME); - lv_arc_ext_t *ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); + lv_arc_ext_t * ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); int16_t val = ext->cur_value; ext->type = type; ext->cur_value = -1; /** Force set_value handling*/ int16_t bg_midpoint, bg_end = ext->bg_angle_end; - if (ext->bg_angle_end < ext->bg_angle_start) bg_end = ext->bg_angle_end + 360; + if(ext->bg_angle_end < ext->bg_angle_start) bg_end = ext->bg_angle_end + 360; switch(ext->type) { case LV_ARC_TYPE_SYMMETRIC: @@ -396,7 +398,7 @@ void lv_arc_set_value(lv_obj_t * arc, int16_t value) ext->cur_value = new_value; int16_t bg_midpoint, range_midpoint, bg_end = ext->bg_angle_end; - if (ext->bg_angle_end < ext->bg_angle_start) bg_end = ext->bg_angle_end + 360; + if(ext->bg_angle_end < ext->bg_angle_start) bg_end = ext->bg_angle_end + 360; int16_t angle; switch(ext->type) { @@ -404,11 +406,12 @@ void lv_arc_set_value(lv_obj_t * arc, int16_t value) bg_midpoint = (ext->bg_angle_start + bg_end) / 2; range_midpoint = (int32_t)(ext->min_value + ext->max_value) / 2; - if (ext->cur_value < range_midpoint) { + if(ext->cur_value < range_midpoint) { angle = _lv_map(ext->cur_value, ext->min_value, range_midpoint, ext->bg_angle_start, bg_midpoint); lv_arc_set_start_angle(arc, angle); lv_arc_set_end_angle(arc, bg_midpoint); - } else { + } + else { angle = _lv_map(ext->cur_value, range_midpoint, ext->max_value, bg_midpoint, bg_end); lv_arc_set_start_angle(arc, bg_midpoint); lv_arc_set_end_angle(arc, angle); @@ -433,7 +436,7 @@ void lv_arc_set_value(lv_obj_t * arc, int16_t value) */ void lv_arc_set_range(lv_obj_t * arc, int16_t min, int16_t max) { - LV_ASSERT_OBJ(arc, LV_OBJX_NAME); + LV_ASSERT_OBJ(arc, LV_OBJX_NAME); lv_arc_ext_t * ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); if(ext->min_value == min && ext->max_value == max) return; @@ -461,7 +464,7 @@ void lv_arc_set_chg_rate(lv_obj_t * arc, uint16_t rate) { LV_ASSERT_OBJ(arc, LV_OBJX_NAME); - lv_arc_ext_t *ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); + lv_arc_ext_t * ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); ext->chg_rate = rate; } @@ -549,7 +552,7 @@ int16_t lv_arc_get_min_value(const lv_obj_t * arc) { LV_ASSERT_OBJ(arc, LV_OBJX_NAME); - lv_arc_ext_t *ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); + lv_arc_ext_t * ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); return ext->min_value; } @@ -562,7 +565,7 @@ int16_t lv_arc_get_max_value(const lv_obj_t * arc) { LV_ASSERT_OBJ(arc, LV_OBJX_NAME); - lv_arc_ext_t *ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); + lv_arc_ext_t * ext = (lv_arc_ext_t *)lv_obj_get_ext_attr(arc); return ext->max_value; } @@ -640,7 +643,8 @@ static lv_design_res_t lv_arc_design(lv_obj_t * arc, const lv_area_t * clip_area lv_draw_line_dsc_init(&arc_dsc); lv_obj_init_draw_line_dsc(arc, LV_ARC_PART_BG, &arc_dsc); - lv_draw_arc(center.x, center.y, arc_r, ext->bg_angle_start + ext->rotation_angle, ext->bg_angle_end + ext->rotation_angle, clip_area, + lv_draw_arc(center.x, center.y, arc_r, ext->bg_angle_start + ext->rotation_angle, + ext->bg_angle_end + ext->rotation_angle, clip_area, &arc_dsc); } @@ -656,7 +660,8 @@ static lv_design_res_t lv_arc_design(lv_obj_t * arc, const lv_area_t * clip_area lv_draw_line_dsc_init(&arc_dsc); lv_obj_init_draw_line_dsc(arc, LV_ARC_PART_INDIC, &arc_dsc); - lv_draw_arc(center.x, center.y, indic_r, ext->arc_angle_start + ext->rotation_angle, ext->arc_angle_end + ext->rotation_angle, clip_area, + lv_draw_arc(center.x, center.y, indic_r, ext->arc_angle_start + ext->rotation_angle, + ext->arc_angle_end + ext->rotation_angle, clip_area, &arc_dsc); } @@ -738,7 +743,7 @@ static lv_res_t lv_arc_signal(lv_obj_t * arc, lv_signal_t sign, void * param) /*Calculate the angle of the pressed point*/ int16_t angle; int16_t bg_end = ext->bg_angle_end; - if (ext->bg_angle_end < ext->bg_angle_start) { + if(ext->bg_angle_end < ext->bg_angle_start) { bg_end = ext->bg_angle_end + 360; } @@ -752,9 +757,10 @@ static lv_res_t lv_arc_signal(lv_obj_t * arc, lv_signal_t sign, void * param) uint32_t delta_tick = lv_tick_elaps(ext->last_tick); int16_t delta_angle_max = (ext->chg_rate * delta_tick) / 1000; - if (delta_angle > delta_angle_max) { + if(delta_angle > delta_angle_max) { delta_angle = delta_angle_max; - } else if (delta_angle < -delta_angle_max) { + } + else if(delta_angle < -delta_angle_max) { delta_angle = -delta_angle_max; } @@ -807,7 +813,7 @@ static lv_res_t lv_arc_signal(lv_obj_t * arc, lv_signal_t sign, void * param) lv_arc_set_value(arc, lv_arc_get_value(arc) - 1); } - if (old_value != ext->cur_value) { + if(old_value != ext->cur_value) { res = lv_event_send(arc, LV_EVENT_VALUE_CHANGED, NULL); if(res != LV_RES_OK) return res; } @@ -1005,9 +1011,11 @@ static void get_knob_area(lv_obj_t * arc, const lv_point_t * center, lv_coord_t uint16_t angle = ext->rotation_angle; if(ext->type == LV_ARC_TYPE_NORMAL) { angle += ext->arc_angle_end; - } else if(ext->type == LV_ARC_TYPE_REVERSE) { + } + else if(ext->type == LV_ARC_TYPE_REVERSE) { angle += ext->arc_angle_start; - } else if(ext->type == LV_ARC_TYPE_SYMMETRIC) { + } + else if(ext->type == LV_ARC_TYPE_SYMMETRIC) { int32_t range_midpoint = (int32_t)(ext->min_value + ext->max_value) / 2; if(ext->cur_value < range_midpoint) angle += ext->arc_angle_start; else angle += ext->arc_angle_end; diff --git a/src/lv_widgets/lv_arc.h b/src/lv_widgets/lv_arc.h index 602527b2c..56ed81e39 100644 --- a/src/lv_widgets/lv_arc.h +++ b/src/lv_widgets/lv_arc.h @@ -48,8 +48,8 @@ typedef struct { int16_t cur_value; /*Current value of the arc*/ int16_t min_value; /*Minimum value of the arc*/ int16_t max_value; /*Maximum value of the arc*/ - uint16_t dragging :1; - uint16_t type :2; + uint16_t dragging : 1; + uint16_t type : 2; uint16_t chg_rate; /*Drag angle rate of change of the arc (degrees/sec)*/ uint32_t last_tick; /*Last dragging event timestamp of the arc*/ int16_t last_angle; /*Last dragging angle of the arc*/ diff --git a/src/lv_widgets/lv_btnmatrix.c b/src/lv_widgets/lv_btnmatrix.c index 8855bddb3..9f39dd638 100644 --- a/src/lv_widgets/lv_btnmatrix.c +++ b/src/lv_widgets/lv_btnmatrix.c @@ -904,8 +904,7 @@ static lv_res_t lv_btnmatrix_signal(lv_obj_t * btnm, lv_signal_t sign, void * pa lv_indev_reset_long_press(param); /*Start the log press time again on the new button*/ if(btn_pr != LV_BTNMATRIX_BTN_NONE && button_is_inactive(ext->ctrl_bits[btn_pr]) == false && - button_is_hidden(ext->ctrl_bits[btn_pr]) == false) - { + button_is_hidden(ext->ctrl_bits[btn_pr]) == false) { invalidate_button_area(btnm, btn_pr); /* Send VALUE_CHANGED for the newly pressed button */ if(button_is_click_trig(ext->ctrl_bits[btn_pr]) == false) { diff --git a/src/lv_widgets/lv_img.c b/src/lv_widgets/lv_img.c index 89ed3c864..911db34ea 100644 --- a/src/lv_widgets/lv_img.c +++ b/src/lv_widgets/lv_img.c @@ -687,7 +687,8 @@ static lv_design_res_t lv_img_design(lv_obj_t * img, const lv_area_t * clip_area if(zommed_coords.y1 > img->coords.y1) zommed_coords.y1 -= ext->h; lv_area_t clip_real; - _lv_img_buf_get_transformed_area(&clip_real, lv_obj_get_width(img), lv_obj_get_height(img), angle_final, zoom_final, &ext->pivot); + _lv_img_buf_get_transformed_area(&clip_real, lv_obj_get_width(img), lv_obj_get_height(img), angle_final, zoom_final, + &ext->pivot); clip_real.x1 += img->coords.x1; clip_real.x2 += img->coords.x1; clip_real.y1 += img->coords.y1;