feat(draw) allow using argb images, border and outline with LV_DRAW_COMPLEX=0 too

This commit is contained in:
Gabor Kiss-Vamosi
2021-05-03 18:54:24 +02:00
parent 9b2b6deb97
commit 3d4c4aea3c
3 changed files with 76 additions and 27 deletions

View File

@@ -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); draw_dsc->border_opa = lv_obj_get_style_border_opa(obj, part);
if(draw_dsc->border_opa > LV_OPA_MIN) { if(draw_dsc->border_opa > LV_OPA_MIN) {
draw_dsc->border_color = lv_obj_get_style_border_color_filtered(obj, part); 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);
} }
} }
} }

View File

@@ -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, _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); draw_dsc->blend_mode);
} }
#if LV_DRAW_COMPLEX
#if LV_USE_GPU_NXP_PXP #if LV_USE_GPU_NXP_PXP
/*Simple case without masking and transformations*/ /*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 #endif
/*In the other cases every pixel need to be checked one-by-one*/ /*In the other cases every pixel need to be checked one-by-one*/
else { else {
//#if LV_DRAW_COMPLEX
/*The pixel size in byte is different if an alpha byte is added too*/ /*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); 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_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); lv_opa_t * mask_buf = lv_mem_buf_get(mask_buf_size);
#if LV_DRAW_COMPLEX
lv_img_transform_dsc_t trans_dsc; lv_img_transform_dsc_t trans_dsc;
lv_memset_00(&trans_dsc, sizeof(lv_img_transform_dsc_t)); lv_memset_00(&trans_dsc, sizeof(lv_img_transform_dsc_t));
if(transform) { 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); _lv_img_buf_transform_init(&trans_dsc);
} }
#endif
uint16_t recolor_premult[3] = {0}; uint16_t recolor_premult[3] = {0};
lv_opa_t recolor_opa_inv = 255 - draw_dsc->recolor_opa; lv_opa_t recolor_opa_inv = 255 - draw_dsc->recolor_opa;
if(draw_dsc->recolor_opa != 0) { 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 x;
int32_t y; int32_t y;
#if LV_DRAW_COMPLEX
int32_t rot_y = disp_area->y1 + draw_area.y1 - map_area->y1; int32_t rot_y = disp_area->y1 + draw_area.y1 - map_area->y1;
#endif
for(y = 0; y < draw_area_h; y++) { for(y = 0; y < draw_area_h; y++) {
map_px = map_buf_tmp; map_px = map_buf_tmp;
#if LV_DRAW_COMPLEX
uint32_t px_i_start = px_i; uint32_t px_i_start = px_i;
int32_t rot_x = disp_area->x1 + draw_area.x1 - map_area->x1; 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++) { for(x = 0; x < draw_area_w; x++, map_px += px_size_byte, px_i++) {
#if LV_DRAW_COMPLEX
if(transform) { if(transform) {
/*Transform*/ /*Transform*/
@@ -535,7 +543,9 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const
} }
} }
/*No transform*/ /*No transform*/
else { else
#else
{
if(alpha_byte) { if(alpha_byte) {
lv_opa_t px_opa = map_px[LV_IMG_PX_SIZE_ALPHA_BYTE - 1]; lv_opa_t px_opa = map_px[LV_IMG_PX_SIZE_ALPHA_BYTE - 1];
mask_buf[px_i] = px_opa; 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.full = *((uint32_t *)map_px);
c.ch.alpha = 0xFF; c.ch.alpha = 0xFF;
#endif #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 #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; map2[px_i].full = c.full;
} }
#if LV_DRAW_COMPLEX
/*Apply the masks if any*/ /*Apply the masks if any*/
if(other_mask_cnt) { if(other_mask_cnt) {
lv_draw_mask_res_t mask_res_sub; 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; mask_res = LV_DRAW_MASK_RES_CHANGED;
} }
} }
#endif
map_buf_tmp += map_w * px_size_byte; map_buf_tmp += map_w * px_size_byte;
if(px_i + lv_area_get_width(&draw_area) < mask_buf_size) { 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); lv_mem_buf_release(map2);
} }
} }
#endif
} }
static void show_error(const lv_area_t * coords, const lv_area_t * clip_area, const char * msg) static void show_error(const lv_area_t * coords, const lv_area_t * clip_area, const char * msg)

View File

@@ -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_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_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); 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, 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); 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 #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); 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 #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.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)); 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) { if(dsc->border_side == LV_BORDER_SIDE_FULL) {
draw_full_border(&area_inner, coords, clip, dsc->radius, false, dsc->border_color, dsc->border_opa, draw_full_border(&area_inner, coords, clip, dsc->radius, false, dsc->border_color, dsc->border_opa,
dsc->blend_mode); dsc->blend_mode);
} }
#if LV_DRAW_COMPLEX
else { else {
lv_opa_t opa = dsc->border_opa; lv_opa_t opa = dsc->border_opa;
if(opa > LV_OPA_MAX) opa = LV_OPA_COVER; 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_draw_mask_remove_id(mask_rout_id);
lv_mem_buf_release(mask_buf); 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 #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.y1 -= dsc->outline_width;
area_outer.y2 += 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, draw_full_border(&area_inner, &area_outer, clip, dsc->radius, true, dsc->outline_color, dsc->outline_opa,
dsc->blend_mode); 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, 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) 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(); uint8_t other_mask_cnt = lv_draw_mask_get_cnt();
bool simple_mode = true; bool simple_mode = true;
if(other_mask_cnt) simple_mode = false; 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_rin_id);
lv_draw_mask_remove_id(mask_rout_id); lv_draw_mask_remove_id(mask_rout_id);
lv_mem_buf_release(mask_buf); lv_mem_buf_release(mask_buf);
}
#else /*LV_DRAW_COMPLEX*/ #endif /*LV_DRAW_COMPLEX*/
LV_UNUSED(area_inner);
LV_UNUSED(area_outer); static void draw_simple_border(const lv_area_t * clip, const lv_area_t * area_inner, const lv_area_t * area_outer,
LV_UNUSED(clip); lv_color_t color, lv_opa_t opa, lv_border_side_t side)
LV_UNUSED(radius); {
LV_UNUSED(radius_is_in); lv_area_t a;
LV_UNUSED(color); /*Top*/
LV_UNUSED(opa); a.x1 = area_outer->x1;
LV_UNUSED(blend_mode); a.x2 = area_outer->x2;
#endif /*LV_DRAW_COMPLEX*/ 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);
}
} }