From 3d4c4aea3c9435b80a8f3c2dcfe1b484f9db6775 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 3 May 2021 18:54:24 +0200 Subject: [PATCH] feat(draw) allow using argb images, border and outline with LV_DRAW_COMPLEX=0 too --- src/core/lv_obj_draw.c | 1 + src/draw/lv_draw_img.c | 35 +++++++++++++-------- src/draw/lv_draw_rect.c | 67 ++++++++++++++++++++++++++++++++--------- 3 files changed, 76 insertions(+), 27 deletions(-) diff --git a/src/core/lv_obj_draw.c b/src/core/lv_obj_draw.c index 244377661..4cd2f703b 100644 --- a/src/core/lv_obj_draw.c +++ b/src/core/lv_obj_draw.c @@ -145,6 +145,7 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint32_t part, lv_draw_rect_dsc_t draw_dsc->border_opa = lv_obj_get_style_border_opa(obj, part); if(draw_dsc->border_opa > LV_OPA_MIN) { draw_dsc->border_color = lv_obj_get_style_border_color_filtered(obj, part); + draw_dsc->border_side = lv_obj_get_style_border_side(obj, part); } } } diff --git a/src/draw/lv_draw_img.c b/src/draw/lv_draw_img.c index 8c3aef444..7db037309 100644 --- a/src/draw/lv_draw_img.c +++ b/src/draw/lv_draw_img.c @@ -361,7 +361,6 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const _lv_blend_map(clip_area, map_area, (lv_color_t *)map_p, NULL, LV_DRAW_MASK_RES_FULL_COVER, draw_dsc->opa, draw_dsc->blend_mode); } -#if LV_DRAW_COMPLEX #if LV_USE_GPU_NXP_PXP /*Simple case without masking and transformations*/ @@ -382,6 +381,7 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const #endif /*In the other cases every pixel need to be checked one-by-one*/ else { +//#if LV_DRAW_COMPLEX /*The pixel size in byte is different if an alpha byte is added too*/ uint8_t px_size_byte = alpha_byte ? LV_IMG_PX_SIZE_ALPHA_BYTE : sizeof(lv_color_t); @@ -476,6 +476,7 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const lv_color_t * map2 = lv_mem_buf_get(mask_buf_size * sizeof(lv_color_t)); lv_opa_t * mask_buf = lv_mem_buf_get(mask_buf_size); +#if LV_DRAW_COMPLEX lv_img_transform_dsc_t trans_dsc; lv_memset_00(&trans_dsc, sizeof(lv_img_transform_dsc_t)); if(transform) { @@ -496,6 +497,7 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const _lv_img_buf_transform_init(&trans_dsc); } +#endif uint16_t recolor_premult[3] = {0}; lv_opa_t recolor_opa_inv = 255 - draw_dsc->recolor_opa; if(draw_dsc->recolor_opa != 0) { @@ -513,13 +515,19 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const int32_t x; int32_t y; +#if LV_DRAW_COMPLEX int32_t rot_y = disp_area->y1 + draw_area.y1 - map_area->y1; +#endif for(y = 0; y < draw_area_h; y++) { map_px = map_buf_tmp; +#if LV_DRAW_COMPLEX uint32_t px_i_start = px_i; - int32_t rot_x = disp_area->x1 + draw_area.x1 - map_area->x1; +#endif + for(x = 0; x < draw_area_w; x++, map_px += px_size_byte, px_i++) { + +#if LV_DRAW_COMPLEX if(transform) { /*Transform*/ @@ -535,7 +543,9 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const } } /*No transform*/ - else { + else +#else + { if(alpha_byte) { lv_opa_t px_opa = map_px[LV_IMG_PX_SIZE_ALPHA_BYTE - 1]; mask_buf[px_i] = px_opa; @@ -560,14 +570,15 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const c.full = *((uint32_t *)map_px); c.ch.alpha = 0xFF; #endif - if(chroma_key) { - if(c.full == chroma_keyed_color.full) { - mask_buf[px_i] = LV_OPA_TRANSP; -#if LV_COLOR_DEPTH == 32 - map2[px_i].full = 0; + } #endif - continue; - } + if(chroma_key) { + if(c.full == chroma_keyed_color.full) { + mask_buf[px_i] = LV_OPA_TRANSP; +#if LV_COLOR_DEPTH == 32 + map2[px_i].full = 0; +#endif + continue; } } @@ -577,7 +588,7 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const map2[px_i].full = c.full; } - +#if LV_DRAW_COMPLEX /*Apply the masks if any*/ if(other_mask_cnt) { lv_draw_mask_res_t mask_res_sub; @@ -591,6 +602,7 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const mask_res = LV_DRAW_MASK_RES_CHANGED; } } +#endif map_buf_tmp += map_w * px_size_byte; if(px_i + lv_area_get_width(&draw_area) < mask_buf_size) { @@ -624,7 +636,6 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const lv_mem_buf_release(map2); } } -#endif } static void show_error(const lv_area_t * coords, const lv_area_t * clip_area, const char * msg) diff --git a/src/draw/lv_draw_rect.c b/src/draw/lv_draw_rect.c index 753f64096..d8f73ceb9 100644 --- a/src/draw/lv_draw_rect.c +++ b/src/draw/lv_draw_rect.c @@ -43,10 +43,14 @@ LV_ATTRIBUTE_FAST_MEM static void draw_shadow(const lv_area_t * coords, const lv 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_full_border(const lv_area_t * area_inner, const lv_area_t * area_outer, const lv_area_t * clip, lv_coord_t radius, bool radius_is_in, lv_color_t color, lv_opa_t opa, lv_blend_mode_t blend_mode); +#else +static void draw_simple_border(const lv_area_t * clip, const lv_area_t * area_inner, const lv_area_t * area_outer, + lv_color_t color, lv_opa_t opa, lv_border_side_t side); +#endif + #if LV_DRAW_COMPLEX 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); #endif @@ -418,11 +422,11 @@ LV_ATTRIBUTE_FAST_MEM static void draw_border(const lv_area_t * coords, const lv area_inner.y1 += ((dsc->border_side & LV_BORDER_SIDE_TOP) ? dsc->border_width : - (dsc->border_width + rout)); area_inner.y2 -= ((dsc->border_side & LV_BORDER_SIDE_BOTTOM) ? dsc->border_width : - (dsc->border_width + rout)); +#if LV_DRAW_COMPLEX if(dsc->border_side == LV_BORDER_SIDE_FULL) { draw_full_border(&area_inner, coords, clip, dsc->radius, false, dsc->border_color, dsc->border_opa, dsc->blend_mode); } -#if LV_DRAW_COMPLEX else { lv_opa_t opa = dsc->border_opa; if(opa > LV_OPA_MAX) opa = LV_OPA_COVER; @@ -509,7 +513,9 @@ LV_ATTRIBUTE_FAST_MEM static void draw_border(const lv_area_t * coords, const lv lv_draw_mask_remove_id(mask_rout_id); lv_mem_buf_release(mask_buf); } -#endif /*LV_DRAW_COMPLEX*/ +#else /*LV_DRAW_COMPLEX*/ + draw_simple_border(clip, &area_inner, coords, dsc->border_color, dsc->border_opa, dsc->border_side); +#endif } #if LV_DRAW_COMPLEX @@ -1198,15 +1204,19 @@ static void draw_outline(const lv_area_t * coords, const lv_area_t * clip, const area_outer.y1 -= dsc->outline_width; area_outer.y2 += dsc->outline_width; +#if LV_DRAW_COMPLEX draw_full_border(&area_inner, &area_outer, clip, dsc->radius, true, dsc->outline_color, dsc->outline_opa, dsc->blend_mode); +#else + draw_simple_border(clip, &area_inner, &area_outer, dsc->outline_color, dsc->outline_opa, LV_BORDER_SIDE_FULL); +#endif } +#if LV_DRAW_COMPLEX static void draw_full_border(const lv_area_t * area_inner, const lv_area_t * area_outer, const lv_area_t * clip, lv_coord_t radius, bool radius_is_in, lv_color_t color, lv_opa_t opa, lv_blend_mode_t blend_mode) { -#if LV_DRAW_COMPLEX uint8_t other_mask_cnt = lv_draw_mask_get_cnt(); bool simple_mode = true; if(other_mask_cnt) simple_mode = false; @@ -1387,15 +1397,42 @@ static void draw_full_border(const lv_area_t * area_inner, const lv_area_t * are lv_draw_mask_remove_id(mask_rin_id); lv_draw_mask_remove_id(mask_rout_id); lv_mem_buf_release(mask_buf); - -#else /*LV_DRAW_COMPLEX*/ - LV_UNUSED(area_inner); - LV_UNUSED(area_outer); - LV_UNUSED(clip); - LV_UNUSED(radius); - LV_UNUSED(radius_is_in); - LV_UNUSED(color); - LV_UNUSED(opa); - LV_UNUSED(blend_mode); -#endif /*LV_DRAW_COMPLEX*/ +} +#endif /*LV_DRAW_COMPLEX*/ + +static void draw_simple_border(const lv_area_t * clip, const lv_area_t * area_inner, const lv_area_t * area_outer, + lv_color_t color, lv_opa_t opa, lv_border_side_t side) +{ + lv_area_t a; + /*Top*/ + a.x1 = area_outer->x1; + a.x2 = area_outer->x2; + a.y1 = area_outer->y1; + a.y2 = area_inner->y1; + if(side & LV_BORDER_SIDE_TOP) { + _lv_blend_fill(clip, &a, color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, LV_BLEND_MODE_NORMAL); + } + + /*Bottom*/ + a.y1 = area_inner->y2; + a.y2 = area_outer->y2; + if(side & LV_BORDER_SIDE_BOTTOM) { + _lv_blend_fill(clip, &a, color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, LV_BLEND_MODE_NORMAL); + } + /*Left*/ + a.x1 = area_outer->x1; + a.x2 = area_inner->x1; + a.y1 = (side & LV_BORDER_SIDE_TOP) ? area_inner->y1 : area_outer->y1; + a.y2 = (side & LV_BORDER_SIDE_BOTTOM) ? area_inner->y2 : area_outer->y2; + if(side & LV_BORDER_SIDE_LEFT) { + _lv_blend_fill(clip, &a, color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, LV_BLEND_MODE_NORMAL); + } + + /*Right*/ + a.x1 = area_inner->x2; + a.x2 = area_outer->x2; + if(side & LV_BORDER_SIDE_RIGHT) { + _lv_blend_fill(clip, &a, color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, LV_BLEND_MODE_NORMAL); + } + }