arc draw: improve speed

This commit is contained in:
Gabor Kiss-Vamosi
2020-02-05 03:29:16 +01:00
parent 2c7579e947
commit 4c5f713914
11 changed files with 538 additions and 142 deletions

View File

@@ -819,9 +819,6 @@ static void indev_proc_press(lv_indev_proc_t * proc)
lv_event_send(indev_obj_act, LV_EVENT_PRESSED, NULL);
if(indev_reset_check(proc)) return;
indev_click_focus(&indev_act->proc);
if(indev_reset_check(proc)) return;
if(indev_act->proc.wait_until_release) return;
}
}
@@ -947,6 +944,7 @@ static void indev_proc_release(lv_indev_proc_t * proc)
if(indev_reset_check(proc)) return;
}
indev_click_focus(&indev_act->proc);
if(indev_reset_check(proc)) return;
/*Send LV_EVENT_DRAG_THROW_BEGIN if required */

View File

@@ -2270,6 +2270,7 @@ lv_opa_t lv_obj_get_style_opa(const lv_obj_t * obj, uint8_t part, lv_style_prope
case LV_STYLE_IMAGE_OPA:
case LV_STYLE_LINE_OPA:
case LV_STYLE_BORDER_OPA:
case LV_STYLE_SHADOW_OPA:
case LV_STYLE_PATTERN_OPA:
return LV_OPA_COVER;
}
@@ -3011,6 +3012,7 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
} else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
lv_coord_t shadow = lv_obj_get_style_shadow_width(obj, LV_OBJ_PART_MAIN);
if(shadow) {
shadow = shadow / 2; /*THe blur adds only half width*/
shadow++;
shadow += lv_obj_get_style_shadow_spread(obj, LV_OBJ_PART_MAIN);
shadow += LV_MATH_MAX(LV_MATH_ABS(lv_obj_get_style_shadow_offset_x(obj, LV_OBJ_PART_MAIN)),

View File

@@ -13,14 +13,33 @@
/*********************
* DEFINES
*********************/
#define SPLIT_RADIUS_LIMIT 10 /*With radius greater then this the arc will drawn in quarters. A quarter is drawn only if there is arc in it */
#define SPLIT_ANGLE_GAP_LIMIT 60 /*With small gaps in the arc don't bother with splitting because there is nothing to skip.
/**********************
* TYPEDEFS
**********************/
typedef struct {
lv_coord_t center_x;
lv_coord_t center_y;
lv_coord_t radius;
uint16_t start_angle;
uint16_t end_angle;
uint16_t start_quarter;
uint16_t end_quarter;
lv_coord_t width;
lv_draw_rect_dsc_t * draw_dsc;
const lv_area_t * draw_area;
const lv_area_t * clip_area;
}quarter_draw_dsc_t;
/**********************
* STATIC PROTOTYPES
**********************/
static void draw_quarter_0(quarter_draw_dsc_t* q);
static void draw_quarter_1(quarter_draw_dsc_t* q);
static void draw_quarter_2(quarter_draw_dsc_t* q);
static void draw_quarter_3(quarter_draw_dsc_t* q);
static void get_rounded_area(int16_t angle, lv_coord_t radius, uint8_t tickness, lv_area_t * res_area);
/**********************
@@ -71,7 +90,34 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, uin
area.x2 = center_x + radius - 1; /*-1 because the center already belongs to the left/bottom part*/
area.y2 = center_y + radius - 1;
int32_t angle_gap;
if(end_angle > start_angle) {
angle_gap = 360 - (end_angle - start_angle);
} else {
angle_gap = end_angle - start_angle;
}
if(angle_gap > SPLIT_ANGLE_GAP_LIMIT && radius > SPLIT_RADIUS_LIMIT) {
/*Handle each quarter individually and skip which is empty*/
quarter_draw_dsc_t q_dsc;
q_dsc.center_x = center_x;
q_dsc.center_y = center_y;
q_dsc.radius = radius;
q_dsc.start_angle = start_angle;
q_dsc.end_angle = end_angle;
q_dsc.start_quarter= start_angle / 90;
q_dsc.end_quarter = end_angle / 90;
q_dsc.width = dsc->width;
q_dsc.draw_dsc = &cir_dsc;
q_dsc.draw_area = &area;
q_dsc.clip_area = clip_area;
draw_quarter_0(&q_dsc);
draw_quarter_1(&q_dsc);
draw_quarter_2(&q_dsc);
draw_quarter_3(&q_dsc);
} else {
lv_draw_rect(&area, clip_area, &cir_dsc);
}
lv_draw_mask_remove_id(mask_angle_id);
@@ -108,6 +154,219 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, uin
/**********************
* STATIC FUNCTIONS
**********************/
static void draw_quarter_0(quarter_draw_dsc_t * q)
{
lv_area_t quarter_area;
if(q->start_quarter == 0 && q->end_quarter == 0 && q->start_angle < q->end_angle) {
/*Small arc here*/
quarter_area.y1 = q->center_y + ((lv_trigo_sin(q->start_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
quarter_area.x2 = q->center_x + ((lv_trigo_sin(q->start_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT);
quarter_area.y2 = q->center_y + ((lv_trigo_sin(q->end_angle) * q->radius) >> LV_TRIGO_SHIFT);
quarter_area.x1 = q->center_x + ((lv_trigo_sin(q->end_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
}
else if(q->start_quarter == 0 || q->end_quarter == 0) {
/*Start and/or end arcs here*/
if(q->start_quarter == 0) {
quarter_area.x1 = q->center_x;
quarter_area.y2 = q->center_y + q->radius;
quarter_area.y1 = q->center_y + ((lv_trigo_sin(q->start_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
quarter_area.x2 = q->center_x + ((lv_trigo_sin(q->start_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT);
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
}
if(q->end_quarter == 0) {
quarter_area.x2 = q->center_x + q->radius;
quarter_area.y1 = q->center_y;
quarter_area.y2 = q->center_y + ((lv_trigo_sin(q->end_angle) * q->radius) >> LV_TRIGO_SHIFT);
quarter_area.x1 = q->center_x + ((lv_trigo_sin(q->end_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
}
}
else if((q->start_quarter == q->end_quarter && q->start_quarter != 0 && q->end_angle < q->start_angle) ||
(q->start_quarter == 2 && q->end_quarter == 1) ||
(q->start_quarter == 3 && q->end_quarter == 2) ||
(q->start_quarter == 3 && q->end_quarter == 1)) {
/*Arc crosses here*/
quarter_area.x1 = q->center_x;
quarter_area.y1 = q->center_y;
quarter_area.x2 = q->center_x + q->radius;
quarter_area.y2 = q->center_y + q->radius;
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
}
}
static void draw_quarter_1(quarter_draw_dsc_t * q)
{
lv_area_t quarter_area;
if(q->start_quarter == 1 && q->end_quarter == 1 && q->start_angle < q->end_angle) {
/*Small arc here*/
quarter_area.y2 = q->center_y + ((lv_trigo_sin(q->start_angle) * (q->radius)) >> LV_TRIGO_SHIFT);
quarter_area.x2 = q->center_x + ((lv_trigo_sin(q->start_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
quarter_area.y1 = q->center_y + ((lv_trigo_sin(q->end_angle) * q->radius - q->width) >> LV_TRIGO_SHIFT);
quarter_area.x1 = q->center_x + ((lv_trigo_sin(q->end_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT);
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
}
else if(q->start_quarter == 1 || q->end_quarter == 1) {
/*Start and/or end arcs here*/
if(q->start_quarter == 1) {
quarter_area.x1 = q->center_x - q->radius;
quarter_area.y1 = q->center_y;
quarter_area.y2 = q->center_y + ((lv_trigo_sin(q->start_angle) * (q->radius)) >> LV_TRIGO_SHIFT);
quarter_area.x2 = q->center_x + ((lv_trigo_sin(q->start_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
}
if(q->end_quarter == 1) {
quarter_area.x2 = q->center_x - 1;
quarter_area.y2 = q->center_y + q->radius;
quarter_area.y1 = q->center_y + ((lv_trigo_sin(q->end_angle) * (q->radius- q->width)) >> LV_TRIGO_SHIFT);
quarter_area.x1 = q->center_x + ((lv_trigo_sin(q->end_angle + 90) * (q->radius )) >> LV_TRIGO_SHIFT);
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
}
}
else if((q->start_quarter == q->end_quarter && q->start_quarter != 1 && q->end_angle < q->start_angle) ||
(q->start_quarter == 0 && q->end_quarter == 2) ||
(q->start_quarter == 0 && q->end_quarter == 3) ||
(q->start_quarter == 3 && q->end_quarter == 2)) {
/*Arc crosses here*/
quarter_area.x1 = q->center_x - q->radius;
quarter_area.y1 = q->center_y;
quarter_area.x2 = q->center_x - 1;
quarter_area.y2 = q->center_y + q->radius;
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
}
}
static void draw_quarter_2(quarter_draw_dsc_t * q)
{
lv_area_t quarter_area;
if(q->start_quarter == 2 && q->end_quarter == 2 && q->start_angle < q->end_angle) {
/*Small arc here*/
quarter_area.x1 = q->center_x + ((lv_trigo_sin(q->start_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT);
quarter_area.y2 = q->center_y + ((lv_trigo_sin(q->start_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
quarter_area.y1 = q->center_y + ((lv_trigo_sin(q->end_angle) * q->radius) >> LV_TRIGO_SHIFT);
quarter_area.x2 = q->center_x + ((lv_trigo_sin(q->end_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
}
else if(q->start_quarter == 2 || q->end_quarter == 2) {
/*Start and/or end arcs here*/
if(q->start_quarter == 2) {
quarter_area.x2 = q->center_x - 1;
quarter_area.y1 = q->center_y - q->radius;
quarter_area.x1 = q->center_x + ((lv_trigo_sin(q->start_angle + 90) * (q->radius )) >> LV_TRIGO_SHIFT);
quarter_area.y2 = q->center_y + ((lv_trigo_sin(q->start_angle) * (q->radius- q->width)) >> LV_TRIGO_SHIFT);
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
}
if(q->end_quarter == 2) {
quarter_area.x1 = q->center_x - q->radius;
quarter_area.y2 = q->center_y - 1;
quarter_area.x2 = q->center_x + ((lv_trigo_sin(q->end_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
quarter_area.y1 = q->center_y + ((lv_trigo_sin(q->end_angle) * (q->radius)) >> LV_TRIGO_SHIFT);
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
}
}
else if((q->start_quarter == q->end_quarter && q->start_quarter != 2 && q->end_angle < q->start_angle) ||
(q->start_quarter == 0 && q->end_quarter == 3) ||
(q->start_quarter == 1 && q->end_quarter == 3) ||
(q->start_quarter == 3 && q->end_quarter == 1)) {
/*Arc crosses here*/
quarter_area.x1 = q->center_x - q->radius;
quarter_area.y1 = q->center_y - q->radius;
quarter_area.x2 = q->center_x - 1;
quarter_area.y2 = q->center_y - 1;
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
}
}
static void draw_quarter_3(quarter_draw_dsc_t * q)
{
lv_area_t quarter_area;
if(q->start_quarter == 3 && q->end_quarter == 3 && q->start_angle < q->end_angle) {
/*Small arc here*/
quarter_area.x1 = q->center_x + ((lv_trigo_sin(q->start_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
quarter_area.y1 = q->center_y + ((lv_trigo_sin(q->start_angle) * (q->radius)) >> LV_TRIGO_SHIFT);
quarter_area.x2 = q->center_x + ((lv_trigo_sin(q->end_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT);
quarter_area.y2 = q->center_y + ((lv_trigo_sin(q->end_angle) * q->radius - q->width) >> LV_TRIGO_SHIFT);
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
}
else if(q->start_quarter == 3 || q->end_quarter == 3) {
/*Start and/or end arcs here*/
if(q->start_quarter == 3) {
quarter_area.x2 = q->center_x + q->radius;
quarter_area.y2 = q->center_y - 1;
quarter_area.x1 = q->center_x + ((lv_trigo_sin(q->start_angle + 90) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
quarter_area.y1 = q->center_y + ((lv_trigo_sin(q->start_angle) * (q->radius)) >> LV_TRIGO_SHIFT);
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
}
if(q->end_quarter == 3) {
quarter_area.x1 = q->center_x;
quarter_area.y1 = q->center_y - q->radius;
quarter_area.x2 = q->center_x + ((lv_trigo_sin(q->end_angle + 90) * (q->radius)) >> LV_TRIGO_SHIFT);
quarter_area.y2 = q->center_y + ((lv_trigo_sin(q->end_angle) * (q->radius - q->width)) >> LV_TRIGO_SHIFT);
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
}
}
else if((q->start_quarter == q->end_quarter && q->start_quarter != 3 && q->end_angle < q->start_angle) ||
(q->start_quarter == 2 && q->end_quarter == 0) ||
(q->start_quarter == 1 && q->end_quarter == 0) ||
(q->start_quarter == 2 && q->end_quarter == 1)) {
/*Arc crosses here*/
quarter_area.x1 = q->center_x;
quarter_area.y1 = q->center_y - q->radius;
quarter_area.x2 = q->center_x + q->radius;
quarter_area.y2 = q->center_y - 1;
bool ok = lv_area_intersect(&quarter_area, &quarter_area, q->clip_area);
if(ok) lv_draw_rect(q->draw_area, &quarter_area, q->draw_dsc);
}
}
static void get_rounded_area(int16_t angle, lv_coord_t radius, uint8_t tickness, lv_area_t * res_area)
{

View File

@@ -436,17 +436,17 @@ static void draw_letter_normal(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph
int32_t col, row;
uint8_t width_byte_scr = g->box_w >> 3; /*Width in bytes (on the screen finally) (e.g. w = 11 -> 2 bytes wide)*/
if(g->box_w & 0x7) width_byte_scr++;
uint16_t width_bit = g->box_w * bpp; /*Letter width in bits*/
int32_t box_w = g->box_w;
int32_t box_h = g->box_h;
int32_t width_byte_scr = box_w >> 3; /*Width in bytes (on the screen finally) (e.g. w = 11 -> 2 bytes wide)*/
if(box_w & 0x7) width_byte_scr++;
int32_t width_bit = box_w * bpp; /*Letter width in bits*/
/* Calculate the col/row start/end on the map*/
int32_t col_start = pos_x >= clip_area->x1 ? 0 : clip_area->x1 - pos_x;
int32_t col_end = pos_x + g->box_w <= clip_area->x2 ? g->box_w : clip_area->x2 - pos_x + 1;
int32_t col_end = pos_x + box_w <= clip_area->x2 ? box_w : clip_area->x2 - pos_x + 1;
int32_t row_start = pos_y >= clip_area->y1 ? 0 : clip_area->y1 - pos_y;
int32_t row_end = pos_y + g->box_h <= clip_area->y2 ? g->box_h : clip_area->y2 - pos_y + 1;
int32_t row_end = pos_y + box_h <= clip_area->y2 ? box_h : clip_area->y2 - pos_y + 1;
/*Move on the map too*/
uint32_t bit_ofs = (row_start * width_bit) + (col_start * bpp);
@@ -457,7 +457,7 @@ static void draw_letter_normal(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph
uint32_t col_bit;
col_bit = bit_ofs & 0x7; /* "& 0x7" equals to "% 8" just faster */
uint32_t mask_buf_size = g->box_w * g->box_h > LV_HOR_RES_MAX ? g->box_w * g->box_h : LV_HOR_RES_MAX;
uint32_t mask_buf_size = box_w * box_h > LV_HOR_RES_MAX ? box_w * box_h : LV_HOR_RES_MAX;
lv_opa_t * mask_buf = lv_mem_buf_get(mask_buf_size);
int32_t mask_p = 0;
int32_t mask_p_start;
@@ -481,8 +481,8 @@ static void draw_letter_normal(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph
if(opa == LV_OPA_COVER) {
px_opa = bpp == 8 ? letter_px : bpp_opa_table[letter_px];
} else {
px_opa = bpp == 8 ? (uint16_t)((uint16_t)letter_px * opa) >> 8
: (uint16_t)((uint16_t)bpp_opa_table[letter_px] * opa) >> 8;
px_opa = bpp == 8 ? (uint32_t)((uint32_t)letter_px * opa) >> 8
: (uint32_t)((uint32_t)bpp_opa_table[letter_px] * opa) >> 8;
}
mask_buf[mask_p] = px_opa;
@@ -525,7 +525,7 @@ static void draw_letter_normal(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph
mask_p = 0;
}
col_bit += ((g->box_w - col_end) + col_start) * bpp;
col_bit += ((box_w - col_end) + col_start) * bpp;
map_p += (col_bit >> 3);
col_bit = col_bit & 0x7;
@@ -575,27 +575,29 @@ static void draw_letter_subpx(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph_
int32_t col, row;
uint32_t width_byte_scr = g->box_w >> 3; /*Width in bytes (on the screen finally) (e.g. w = 11 -> 2 bytes wide)*/
if(g->box_w & 0x7) width_byte_scr++;
uint16_t width_bit = g->box_w * bpp; /*Letter width in bits*/
int32_t box_w = g->box_w;
int32_t box_h = g->box_h;
int32_t width_byte_scr = box_w >> 3; /*Width in bytes (on the screen finally) (e.g. w = 11 -> 2 bytes wide)*/
if(box_w & 0x7) width_byte_scr++;
int32_t width_bit = box_w * bpp; /*Letter width in bits*/
/* Calculate the col/row start/end on the map*/
int32_t col_start = pos_x >= clip_area->x1 ? 0 : (clip_area->x1 - pos_x) * 3;
int32_t col_end = pos_x + g->box_w / 3 <= clip_area->x2 ? g->box_w : (clip_area->x2 - pos_x + 1) * 3;
int32_t col_end = pos_x + box_w / 3 <= clip_area->x2 ? box_w : (clip_area->x2 - pos_x + 1) * 3;
int32_t row_start = pos_y >= clip_area->y1 ? 0 : clip_area->y1 - pos_y;
int32_t row_end = pos_y + g->box_h <= clip_area->y2 ? g->box_h : clip_area->y2 - pos_y + 1;
int32_t row_end = pos_y + box_h <= clip_area->y2 ? box_h : clip_area->y2 - pos_y + 1;
/*Move on the map too*/
uint32_t bit_ofs = (row_start * width_bit) + (col_start * bpp);
int32_t bit_ofs = (row_start * width_bit) + (col_start * bpp);
map_p += bit_ofs >> 3;
uint8_t letter_px;
lv_opa_t px_opa;
uint32_t col_bit;
int32_t col_bit;
col_bit = bit_ofs & 0x7; /* "& 0x7" equals to "% 8" just faster */
uint32_t mask_buf_size = g->box_w * g->box_h > LV_HOR_RES_MAX ? g->box_w * g->box_h : LV_HOR_RES_MAX;
int32_t mask_buf_size = box_w * box_h > LV_HOR_RES_MAX ? g->box_w * g->box_h : LV_HOR_RES_MAX;
lv_opa_t * mask_buf = lv_mem_buf_get(mask_buf_size);
int32_t mask_p = 0;
int32_t mask_p_start;
@@ -663,17 +665,17 @@ static void draw_letter_subpx(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph_
#endif
#if LV_SUBPX_BGR
res_color.ch.blue = (uint16_t)((uint16_t)txt_rgb[0] * font_rgb[0] + (bg_rgb[0] * (255 - font_rgb[0]))) >> 8;
res_color.ch.red = (uint16_t)((uint16_t)txt_rgb[2] * font_rgb[2] + (bg_rgb[2] * (255 - font_rgb[2]))) >> 8;
res_color.ch.blue = (uint326_t)((uint32_t)txt_rgb[0] * font_rgb[0] + (bg_rgb[0] * (255 - font_rgb[0]))) >> 8;
res_color.ch.red = (uint32_t)((uint32_t)txt_rgb[2] * font_rgb[2] + (bg_rgb[2] * (255 - font_rgb[2]))) >> 8;
#else
res_color.ch.red = (uint16_t)((uint16_t)txt_rgb[0] * font_rgb[0] + (bg_rgb[0] * (255 - font_rgb[0]))) >> 8;
res_color.ch.blue = (uint16_t)((uint16_t)txt_rgb[2] * font_rgb[2] + (bg_rgb[2] * (255 - font_rgb[2]))) >> 8;
res_color.ch.red = (uint32_t)((uint16_t)txt_rgb[0] * font_rgb[0] + (bg_rgb[0] * (255 - font_rgb[0]))) >> 8;
res_color.ch.blue = (uint32_t)((uint16_t)txt_rgb[2] * font_rgb[2] + (bg_rgb[2] * (255 - font_rgb[2]))) >> 8;
#endif
#if LV_COLOR_16_SWAP == 0
res_color.ch.green = (uint16_t)((uint16_t)txt_rgb[1] * font_rgb[1] + (bg_rgb[1] * (255 - font_rgb[1]))) >> 8;
res_color.ch.green = (uint32_t)((uint32_t)txt_rgb[1] * font_rgb[1] + (bg_rgb[1] * (255 - font_rgb[1]))) >> 8;
#else
uint8_t green = (uint16_t)((uint16_t)txt_rgb[1] * font_rgb[1] + (bg_rgb[1] * (255 - font_rgb[1]))) >> 8;
uint8_t green = (uint32_t)((uint32_t)txt_rgb[1] * font_rgb[1] + (bg_rgb[1] * (255 - font_rgb[1]))) >> 8;
res_color.ch.green_h = green >> 3;
res_color.ch.green_l = green & 0x7;
#endif
@@ -716,7 +718,7 @@ static void draw_letter_subpx(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph_
mask_p = 0;
}
col_bit += ((g->box_w - col_end) + col_start) * bpp;
col_bit += ((box_w - col_end) + col_start) * bpp;
map_p += (col_bit >> 3);
col_bit = col_bit & 0x7;

View File

@@ -1119,9 +1119,9 @@ static lv_draw_mask_res_t lv_draw_mask_map(lv_opa_t * mask_buf, lv_coord_t abs_x
static inline lv_opa_t mask_mix(lv_opa_t mask_act, lv_opa_t mask_new)
{
if(mask_new > LV_OPA_MAX) return mask_act;
if(mask_new < LV_OPA_MIN) return 0;
if(mask_new >= LV_OPA_MAX) return mask_act;
if(mask_new <= LV_OPA_MIN) return 0;
return (uint16_t)((uint16_t) (mask_act * mask_new) >> 8);
return (int32_t)((int32_t) (mask_act * mask_new) >> 8);
}

View File

@@ -161,9 +161,10 @@ static void draw_bg(const lv_area_t * coords, const lv_area_t * clip, lv_draw_re
/*Create a mask if there is a radius*/
lv_opa_t * mask_buf = lv_mem_buf_get(draw_area_w);
uint16_t other_mask_cnt = lv_draw_mask_get_cnt();
bool simple_mode = true;
if(lv_draw_mask_get_cnt()!= 0) simple_mode = false;
else if(dsc->bg_grad_dir == LV_GRAD_DIR_HOR) simple_mode = false;
if(other_mask_cnt) simple_mode = false;
else if(dsc->bg_grad_dir != LV_GRAD_DIR_NONE) simple_mode = false;
int16_t mask_rout_id = LV_MASK_ID_INV;
@@ -181,7 +182,7 @@ static void draw_bg(const lv_area_t * coords, const lv_area_t * clip, lv_draw_re
dsc->bg_color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa,
dsc->bg_blend_mode);
}
/*More complex case: there is a radius, gradient or mask.*/
/*More complex case: there is a radius, gradient or other mask.*/
else {
lv_draw_mask_radius_param_t mask_rout_param;
if(rout > 0) {
@@ -189,7 +190,6 @@ static void draw_bg(const lv_area_t * coords, const lv_area_t * clip, lv_draw_re
mask_rout_id = lv_draw_mask_add(&mask_rout_param, NULL);
}
if(opa >= LV_OPA_MIN) {
/*Draw the background line by line*/
int32_t h;
lv_draw_mask_res_t mask_res = LV_DRAW_MASK_RES_FULL_COVER;
@@ -251,14 +251,7 @@ static void draw_bg(const lv_area_t * coords, const lv_area_t * clip, lv_draw_re
lv_blend_fill(clip, &fill_area2,
grad_color, mask_buf, mask_res, opa, dsc->bg_blend_mode);
/*Central part*/
fill_area2.x1 = coords_bg.x1 + rout;
fill_area2.x2 = coords_bg.x2 - rout;
lv_blend_fill(clip, &fill_area2,
grad_color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, dsc->bg_blend_mode);
/*Right part*/
fill_area2.x1 = coords_bg.x2 - rout + 1;
fill_area2.x2 = coords_bg.x2;
@@ -279,11 +272,29 @@ static void draw_bg(const lv_area_t * coords, const lv_area_t * clip, lv_draw_re
fill_area.y2++;
}
if(simple_mode) {
lv_area_t fill_area;
/*Central part*/
fill_area.x1 = coords_bg.x1 + rout;
fill_area.x2 = coords_bg.x2 - rout;
fill_area.y1 = coords_bg.y1;
fill_area.y2 = coords_bg.y1 + rout;
lv_blend_fill(clip, &fill_area,
grad_color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, dsc->bg_blend_mode);
fill_area.y1 = coords_bg.y2 - rout;
fill_area.y2 = coords_bg.y2;
lv_blend_fill(clip, &fill_area,
grad_color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, dsc->bg_blend_mode);
}
if(grad_map) lv_mem_buf_release(grad_map);
}
lv_draw_mask_remove_id(mask_rout_id);
}
lv_mem_buf_release(mask_buf);
@@ -954,6 +965,7 @@ static void shadow_draw_corner_buf(const lv_area_t * coords, lv_opa_t * sh_buf,
#endif
lv_mem_buf_release(sh_ups_buf);
}
static void shadow_blur_corner(lv_coord_t size, lv_coord_t sw, lv_opa_t * res_buf, uint16_t * sh_ups_buf)

View File

@@ -228,7 +228,6 @@ static lv_design_res_t lv_arc_design(lv_obj_t * arc, const lv_area_t * clip_area
lv_draw_arc(x, y, r, ext->bg_angle_start, ext->bg_angle_end, clip_area, &arc_dsc);
lv_draw_line_dsc_init(&arc_dsc);
lv_obj_init_draw_line_dsc(arc, LV_ARC_PART_ARC, &arc_dsc);

View File

@@ -778,7 +778,6 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
}
} else if(sign == LV_SIGNAL_PRESSED) {
invalidate_button_area(btnm, ext->btn_id_pr);
invalidate_button_area(btnm, ext->btn_id_focused);
lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act());
@@ -787,12 +786,13 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
/*Search the pressed area*/
lv_indev_get_point(param, &p);
btn_pr = get_button_from_point(btnm, &p);
if(button_is_inactive(ext->ctrl_bits[btn_pr]) == false &&
button_is_hidden(ext->ctrl_bits[btn_pr]) == false) {
invalidate_button_area(btnm, ext->btn_id_pr) /*Invalidate the old area*/;
ext->btn_id_pr = btn_pr;
ext->btn_id_act = btn_pr;
ext->btn_id_focused = btn_pr;
invalidate_button_area(btnm, ext->btn_id_pr); /*Invalidate the new area*/
}
} else if(indev_type == LV_INDEV_TYPE_KEYPAD || (indev_type == LV_INDEV_TYPE_ENCODER && lv_group_get_editing(lv_obj_get_group(btnm)))) {
ext->btn_id_pr = ext->btn_id_focused;
invalidate_button_area(btnm, ext->btn_id_focused);
@@ -812,11 +812,12 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
lv_indev_get_point(param, &p);
btn_pr = get_button_from_point(btnm, &p);
/*Invalidate to old and the new areas*/;
if(btn_pr != ext->btn_id_pr) {
if(btn_pr != ext->btn_id_pr &&
button_is_inactive(ext->ctrl_bits[btn_pr]) == false &&
button_is_hidden(ext->ctrl_bits[btn_pr]) == false) {
lv_indev_reset_long_press(param); /*Start the log press time again on the new button*/
if(ext->btn_id_pr != LV_BTNM_BTN_NONE) {
invalidate_button_area(btnm, ext->btn_id_pr);
invalidate_button_area(btnm, ext->btn_id_focused);
}
if(btn_pr != LV_BTNM_BTN_NONE) {
uint32_t b = ext->btn_id_act;
@@ -828,7 +829,6 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
}
ext->btn_id_pr = btn_pr;
ext->btn_id_focused = btn_pr;
ext->btn_id_act = btn_pr;
} else if(sign == LV_SIGNAL_RELEASED) {
if(ext->btn_id_pr != LV_BTNM_BTN_NONE) {
@@ -845,6 +845,7 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
/*Invalidate to old pressed area*/;
invalidate_button_area(btnm, ext->btn_id_pr);
ext->btn_id_focused = ext->btn_id_pr;
ext->btn_id_pr = LV_BTNM_BTN_NONE;
if(button_is_click_trig(ext->ctrl_bits[ext->btn_id_act]) == true &&
@@ -926,7 +927,9 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
for(area_below = ext->btn_id_focused; area_below < ext->btn_cnt; area_below++) {
if(ext->button_areas[area_below].y1 > ext->button_areas[ext->btn_id_focused].y1 &&
pr_center >= ext->button_areas[area_below].x1 &&
pr_center <= ext->button_areas[area_below].x2 + pad_inner) {
pr_center <= ext->button_areas[area_below].x2 + pad_inner &&
button_is_inactive(ext->ctrl_bits[area_below]) == false &&
button_is_hidden(ext->ctrl_bits[area_below]) == false) {
break;
}
}
@@ -948,7 +951,9 @@ static lv_res_t lv_btnm_signal(lv_obj_t * btnm, lv_signal_t sign, void * param)
for(area_above = ext->btn_id_focused; area_above >= 0; area_above--) {
if(ext->button_areas[area_above].y1 < ext->button_areas[ext->btn_id_focused].y1 &&
pr_center >= ext->button_areas[area_above].x1 - pad_inner &&
pr_center <= ext->button_areas[area_above].x2) {
pr_center <= ext->button_areas[area_above].x2 &&
button_is_inactive(ext->ctrl_bits[area_above]) == false &&
button_is_hidden(ext->ctrl_bits[area_above]) == false) {
break;
}
}

View File

@@ -794,14 +794,16 @@ static lv_res_t lv_list_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * para
}
}
}
else if(sign == LV_SIGNAL_PRESSED) {
else if(sign == LV_SIGNAL_RELEASED) {
if(lv_indev_is_dragging(lv_indev_get_act()) == false) {
lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn));
lv_list_focus_btn(list, btn);
#if LV_USE_GROUP
#if LV_USE_GROUP
if(lv_obj_get_group(list)) {
lv_group_focus_obj(list);
}
#endif
#endif
}
}
else if(sign == LV_SIGNAL_CLEANUP) {
#if LV_USE_GROUP

View File

@@ -87,7 +87,7 @@ lv_obj_t * lv_preload_create(lv_obj_t * par, const lv_obj_t * copy)
ext->arc_length = LV_PRELOAD_DEF_ARC_LENGTH;
ext->anim_type = LV_PRELOAD_DEF_ANIM;
ext->anim_dir = LV_PRELOAD_DIR_FORWARD;
ext->time = LV_PRELOAD_DEF_SPIN_TIME;
ext->time = LV_PRELOAD_DEF_SPIN_TIME*5;
/*The signal and design functions are not copied so set them here*/
lv_obj_set_signal_cb(preload, lv_preload_signal);

View File

@@ -134,6 +134,8 @@ static void basic_init(void)
lv_style_set_bg_color(&scr, LV_STYLE_STATE_NORMAL, COLOR_SCREEN);
lv_style_set_text_color(&scr, LV_STYLE_STATE_NORMAL, lv_color_hex(0xb8b8b9));
#define PERF_TEST 3
#if PERF_TEST == 0
lv_style_init(&panel);
lv_style_set_radius(&panel, LV_STYLE_STATE_NORMAL, LV_DPI / 25);
lv_style_set_bg_opa(&panel, LV_STYLE_STATE_NORMAL, LV_OPA_COVER);
@@ -141,7 +143,7 @@ static void basic_init(void)
// lv_style_set_color(&panel, LV_STYLE_BG_COLOR | LV_STYLE_STATE_FOCUS, LV_COLOR_RED);
lv_style_set_border_color(&panel, LV_STYLE_STATE_NORMAL, lv_color_lighten(COLOR_CONTAINER, LV_OPA_10));
lv_style_set_border_width(&panel, LV_STYLE_STATE_NORMAL, LV_DPI / 50 > 0 ? LV_DPI / 50 : 1);
// lv_style_set_border_side(&panel, LV_STYLE_STATE_NORMAL , LV_BORDER_SIDE_TOP);
lv_style_set_border_side(&panel, LV_STYLE_STATE_NORMAL , LV_BORDER_SIDE_TOP);
lv_style_set_pad_left(&panel, LV_STYLE_STATE_NORMAL, LV_DPI / 5);
lv_style_set_pad_right(&panel, LV_STYLE_STATE_NORMAL, LV_DPI / 5);
lv_style_set_pad_top(&panel, LV_STYLE_STATE_NORMAL, LV_DPI / 5);
@@ -173,10 +175,125 @@ static void basic_init(void)
lv_style_set_pad_inner(&btn, LV_STYLE_STATE_NORMAL, LV_DPI / 10);
lv_style_set_transition_time(&btn, LV_STYLE_TRANSITION_TIME, 500);
lv_style_set_bg_color(&btn, LV_STYLE_STATE_FOCUS, lv_color_mix(LV_COLOR_RED, COLOR_ACCENT, LV_OPA_50));
lv_style_set_shadow_opa(&btn, LV_STYLE_STATE_NORMAL, LV_OPA_COVER);
lv_style_set_shadow_width(&btn, LV_STYLE_STATE_NORMAL, 8);
lv_style_set_shadow_offset_y(&btn, LV_STYLE_STATE_NORMAL, 3);
#elif PERF_TEST == 1
lv_style_init(&panel);
lv_style_set_radius(&panel, LV_STYLE_STATE_NORMAL, 0);
lv_style_set_bg_opa(&panel, LV_STYLE_STATE_NORMAL, LV_OPA_COVER);
lv_style_set_bg_color(&panel, LV_STYLE_STATE_NORMAL, LV_COLOR_GRAY);
lv_style_set_pad_left(&panel, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_pad_right(&panel, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_pad_top(&panel, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_pad_bottom(&panel, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_pad_inner(&panel, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_text_color(&panel, LV_STYLE_STATE_NORMAL, LV_COLOR_RED);
lv_style_set_image_recolor(&panel, LV_STYLE_STATE_NORMAL, LV_COLOR_RED);
lv_style_set_line_color(&panel, LV_STYLE_STATE_NORMAL, LV_COLOR_RED);
lv_style_init(&btn);
lv_style_set_bg_opa(&btn, LV_STYLE_STATE_NORMAL, LV_OPA_COVER);
lv_style_set_bg_color(&btn, LV_STYLE_STATE_NORMAL, LV_COLOR_BLUE);
lv_style_set_bg_color(&btn, LV_STYLE_STATE_PRESSED, LV_COLOR_NAVY);
lv_style_set_bg_color(&btn, LV_STYLE_STATE_DISABLED, LV_COLOR_GRAY);
lv_style_set_text_color(&btn, LV_STYLE_STATE_NORMAL, LV_COLOR_WHITE);
lv_style_set_text_color(&btn, LV_STYLE_STATE_PRESSED, LV_COLOR_BLACK);
lv_style_set_text_color(&btn, LV_STYLE_STATE_DISABLED, LV_COLOR_SILVER);
lv_style_set_image_recolor(&btn, LV_STYLE_STATE_NORMAL, LV_COLOR_WHITE);
lv_style_set_image_recolor(&btn, LV_STYLE_STATE_PRESSED,LV_COLOR_BLACK);
lv_style_set_pad_left(&btn, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_pad_right(&btn, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_pad_top(&btn, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_pad_bottom(&btn, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_pad_inner(&btn, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
#elif PERF_TEST == 2
lv_style_init(&panel);
lv_style_set_radius(&panel, LV_STYLE_STATE_NORMAL, 5);
lv_style_set_bg_opa(&panel, LV_STYLE_STATE_NORMAL, LV_OPA_COVER);
lv_style_set_bg_color(&panel, LV_STYLE_STATE_NORMAL, LV_COLOR_GRAY);
lv_style_set_border_color(&panel, LV_STYLE_STATE_NORMAL, LV_COLOR_BLACK);
lv_style_set_border_color(&panel, LV_STYLE_STATE_FOCUS, LV_COLOR_RED);
lv_style_set_border_width(&panel, LV_STYLE_STATE_NORMAL, 2);
lv_style_set_pad_left(&panel, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_pad_right(&panel, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_pad_top(&panel, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_pad_bottom(&panel, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_pad_inner(&panel, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_text_color(&panel, LV_STYLE_STATE_NORMAL, LV_COLOR_RED);
lv_style_set_image_recolor(&panel, LV_STYLE_STATE_NORMAL, LV_COLOR_RED);
lv_style_set_line_color(&panel, LV_STYLE_STATE_NORMAL, LV_COLOR_RED);
lv_style_init(&btn);
lv_style_set_radius(&btn, LV_STYLE_STATE_NORMAL, 5);
lv_style_set_bg_opa(&btn, LV_STYLE_STATE_NORMAL, LV_OPA_COVER);
lv_style_set_bg_grad_dir(&btn, LV_STYLE_STATE_NORMAL, LV_GRAD_DIR_NONE);
lv_style_set_bg_color(&btn, LV_STYLE_STATE_NORMAL, LV_COLOR_BLUE);
lv_style_set_bg_grad_color(&btn, LV_STYLE_STATE_NORMAL, LV_COLOR_LIME);
lv_style_set_bg_color(&btn, LV_STYLE_STATE_PRESSED, LV_COLOR_NAVY);
lv_style_set_bg_color(&btn, LV_STYLE_STATE_DISABLED, LV_COLOR_GRAY);
lv_style_set_border_color(&btn, LV_STYLE_STATE_NORMAL, LV_COLOR_BLACK);
lv_style_set_border_color(&btn, LV_STYLE_STATE_FOCUS, LV_COLOR_RED);
lv_style_set_border_width(&btn, LV_STYLE_STATE_NORMAL, 2);
lv_style_set_text_color(&btn, LV_STYLE_STATE_NORMAL, LV_COLOR_WHITE);
lv_style_set_text_color(&btn, LV_STYLE_STATE_PRESSED, LV_COLOR_BLACK);
lv_style_set_text_color(&btn, LV_STYLE_STATE_DISABLED, LV_COLOR_SILVER);
lv_style_set_image_recolor(&btn, LV_STYLE_STATE_NORMAL, LV_COLOR_WHITE);
lv_style_set_image_recolor(&btn, LV_STYLE_STATE_PRESSED,LV_COLOR_BLACK);
lv_style_set_pad_left(&btn, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_pad_right(&btn, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_pad_top(&btn, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_pad_bottom(&btn, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_pad_inner(&btn, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
#elif PERF_TEST == 3
lv_style_init(&panel);
lv_style_set_radius(&panel, LV_STYLE_STATE_NORMAL, 10);
lv_style_set_bg_opa(&panel, LV_STYLE_STATE_NORMAL, LV_OPA_50);
lv_style_set_bg_color(&panel, LV_STYLE_STATE_NORMAL, LV_COLOR_GRAY);
lv_style_set_border_color(&panel, LV_STYLE_STATE_NORMAL, LV_COLOR_BLACK);
lv_style_set_border_color(&panel, LV_STYLE_STATE_FOCUS, LV_COLOR_RED);
lv_style_set_border_width(&panel, LV_STYLE_STATE_NORMAL, 2);
lv_style_set_border_opa(&panel, LV_STYLE_STATE_NORMAL, LV_OPA_80);
// lv_style_set_shadow_width(&panel, LV_STYLE_STATE_NORMAL, 5);
// lv_style_set_shadow_offset_y(&panel, LV_STYLE_STATE_NORMAL, 3);
// lv_style_set_shadow_color(&panel, LV_STYLE_STATE_NORMAL, LV_COLOR_BLUE);
lv_style_set_pad_left(&panel, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_pad_right(&panel, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_pad_top(&panel, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_pad_bottom(&panel, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_pad_inner(&panel, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_text_color(&panel, LV_STYLE_STATE_NORMAL, LV_COLOR_RED);
lv_style_set_image_recolor(&panel, LV_STYLE_STATE_NORMAL, LV_COLOR_RED);
lv_style_set_line_color(&panel, LV_STYLE_STATE_NORMAL, LV_COLOR_RED);
lv_style_init(&btn);
lv_style_set_radius(&btn, LV_STYLE_STATE_NORMAL, 5);
lv_style_set_bg_opa(&btn, LV_STYLE_STATE_NORMAL, LV_OPA_50);
lv_style_set_bg_grad_dir(&btn, LV_STYLE_STATE_NORMAL, LV_GRAD_DIR_VER);
lv_style_set_bg_color(&btn, LV_STYLE_STATE_NORMAL, LV_COLOR_BLUE);
lv_style_set_bg_grad_color(&btn, LV_STYLE_STATE_NORMAL, LV_COLOR_LIME);
lv_style_set_bg_color(&btn, LV_STYLE_STATE_PRESSED, LV_COLOR_NAVY);
lv_style_set_bg_color(&btn, LV_STYLE_STATE_DISABLED, LV_COLOR_GRAY);
lv_style_set_border_color(&btn, LV_STYLE_STATE_NORMAL, LV_COLOR_BLACK);
lv_style_set_border_color(&btn, LV_STYLE_STATE_FOCUS, LV_COLOR_RED);
lv_style_set_border_width(&btn, LV_STYLE_STATE_NORMAL, 2);
lv_style_set_border_opa(&btn, LV_STYLE_STATE_NORMAL, LV_OPA_50);
lv_style_set_shadow_width(&btn, LV_STYLE_STATE_NORMAL, 10);
// lv_style_set_shadow_width(&btn, LV_STYLE_STATE_PRESSED, 2);
lv_style_set_shadow_offset_x(&btn, LV_STYLE_STATE_NORMAL, 35);
lv_style_set_shadow_offset_y(&btn, LV_STYLE_STATE_NORMAL, 80);
lv_style_set_shadow_offset_y(&btn, LV_STYLE_STATE_PRESSED, 1);
lv_style_set_shadow_color(&btn, LV_STYLE_STATE_NORMAL, LV_COLOR_BLUE);
// lv_style_set_shadow_spread(&btn, LV_STYLE_STATE_NORMAL, 5);
lv_style_set_text_color(&btn, LV_STYLE_STATE_NORMAL, LV_COLOR_WHITE);
lv_style_set_text_color(&btn, LV_STYLE_STATE_PRESSED, LV_COLOR_BLACK);
lv_style_set_text_color(&btn, LV_STYLE_STATE_DISABLED, LV_COLOR_SILVER);
lv_style_set_image_recolor(&btn, LV_STYLE_STATE_NORMAL, LV_COLOR_WHITE);
lv_style_set_image_recolor(&btn, LV_STYLE_STATE_PRESSED,LV_COLOR_BLACK);
lv_style_set_pad_left(&btn, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_pad_right(&btn, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_pad_top(&btn, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_pad_bottom(&btn, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_pad_inner(&btn, LV_STYLE_STATE_NORMAL, LV_DPI / 20);
lv_style_set_transition_time(&btn, LV_STYLE_STATE_NORMAL, 200);
#endif
}
static void cont_init(void)