diff --git a/src/lv_draw/lv_draw_rect.c b/src/lv_draw/lv_draw_rect.c index bea17d931..142d5786a 100644 --- a/src/lv_draw/lv_draw_rect.c +++ b/src/lv_draw/lv_draw_rect.c @@ -30,8 +30,8 @@ static void draw_bg(const lv_area_t * coords, const lv_area_t * clip, const lv_s static void draw_border(const lv_area_t * coords, const lv_area_t * clip, const lv_style_t * style, lv_opa_t opa_scale); static void draw_shadow(const lv_area_t * coords, const lv_area_t * clip, const lv_style_t * style, lv_opa_t opa_scale); static lv_color_t grad_get(const lv_style_t * style, lv_coord_t s, lv_coord_t i); -static void shadow_draw_corner_buf(const lv_area_t * coords, lv_opa_t * sh_buf, lv_coord_t s, lv_coord_t r); -static void shadow_blur_corner(lv_coord_t size, lv_coord_t sw, lv_opa_t * res_buf, uint16_t * sh_ups_buf); +static void shadow_draw_corner_buf(const lv_area_t * coords, uint16_t * sh_buf, lv_coord_t s, lv_coord_t r); +static void shadow_blur_corner(lv_coord_t size, lv_coord_t sw, uint16_t * sh_ups_buf); /********************** * STATIC VARIABLES @@ -555,8 +555,8 @@ static void draw_shadow(const lv_area_t * coords, const lv_area_t * clip, const lv_coord_t corner_size = sw + r_sh; - lv_opa_t * sh_buf = lv_mem_buf_get(corner_size * corner_size); - shadow_draw_corner_buf(&sh_rect_area, sh_buf, style->body.shadow.width, r_sh); + lv_opa_t * sh_buf = lv_mem_buf_get(corner_size * corner_size * sizeof(uint16_t)); + shadow_draw_corner_buf(&sh_rect_area, (uint16_t *)sh_buf, style->body.shadow.width, r_sh); bool simple_mode = true; if(lv_draw_mask_get_cnt() > 0) simple_mode = false; @@ -866,7 +866,7 @@ static void draw_shadow(const lv_area_t * coords, const lv_area_t * clip, const lv_mem_buf_release(sh_buf); } -static void shadow_draw_corner_buf(const lv_area_t * coords, lv_opa_t * sh_buf, lv_coord_t sw, lv_coord_t r) +static void shadow_draw_corner_buf(const lv_area_t * coords, uint16_t * sh_buf, lv_coord_t sw, lv_coord_t r) { lv_coord_t sw_ori = sw; lv_coord_t size = sw_ori + r; @@ -890,21 +890,15 @@ static void shadow_draw_corner_buf(const lv_area_t * coords, lv_opa_t * sh_buf, else sw = sw_ori >> 1; #endif - /* The basic idea of shadow drawing is - * - */ - - lv_draw_mask_res_t mask_res; lv_coord_t y; lv_opa_t * mask_line = lv_mem_buf_get(size); - uint16_t * sh_ups_buf = lv_mem_buf_get(size * size * sizeof(uint16_t)); - uint16_t * sh_ups_tmp_buf = sh_ups_buf; + uint16_t * sh_ups_tmp_buf = (uint16_t *)sh_buf; for(y = 0; y < size; y++) { memset(mask_line, 0xFF, size); mask_res = mask_param.dsc.cb(mask_line, 0, y, size, &mask_param); if(mask_res == LV_DRAW_MASK_RES_FULL_TRANSP) { - memset(sh_ups_tmp_buf, 0x00, size * sizeof(sh_ups_buf[0])); + memset(sh_ups_tmp_buf, 0x00, size * sizeof(sh_ups_tmp_buf[0])); } else { lv_coord_t i; sh_ups_tmp_buf[0] = (mask_line[0] << SHADOW_UPSACALE_SHIFT) / sw; @@ -918,52 +912,53 @@ static void shadow_draw_corner_buf(const lv_area_t * coords, lv_opa_t * sh_buf, } lv_mem_buf_release(mask_line); - // uint32_t k; - // for(k = 0; k < size * size; k++) { - // sh_buf[k] = (sh_ups_buf[k] * sw) >> SHADOW_UPSACALE_SHIFT ; - // } - // return; - if(sw == 1) { - lv_coord_t i; + uint32_t i; + lv_opa_t * res_buf = (lv_opa_t *)sh_buf; for(i = 0; i < size * size; i++) { - sh_buf[i] = (sh_ups_buf[i] >> SHADOW_UPSACALE_SHIFT); + res_buf[i] = (sh_buf[i] >> SHADOW_UPSACALE_SHIFT); } - lv_mem_buf_release(sh_ups_buf); return; } - shadow_blur_corner(size, sw, sh_buf, sh_ups_buf); + shadow_blur_corner(size, sw, sh_buf); -#if SHADOW_ENHANCE +#if SHADOW_ENHANCE == 0 + /*The result is required in lv_opa_t not uint16_t*/ + uint32_t x; + lv_opa_t * res_buf = (lv_opa_t *)sh_buf; + for(x = 0; x < size * size; x++) { + res_buf[x] = sh_buf[x]; + } +#else sw = sw_ori - sw; - if(sw <= 1) { - lv_mem_buf_release(sh_ups_buf); - return; - } + if(sw > 1) { + uint32_t i; + sh_buf[0] = (sh_buf[0] << SHADOW_UPSACALE_SHIFT) / sw; + for(i = 1; i < (uint32_t) size * size; i++) { + if(sh_buf[i] == sh_buf[i-1]) sh_buf[i] = sh_buf[i-1]; + else sh_buf[i] = (sh_buf[i] << SHADOW_UPSACALE_SHIFT) / sw; + } - uint32_t i; - sh_ups_buf[0] = (sh_buf[0] << SHADOW_UPSACALE_SHIFT) / sw; - for(i = 1; i < (uint32_t) size * size; i++) { - if(sh_buf[i] == sh_buf[i-1]) sh_ups_buf[i] = sh_ups_buf[i-1]; - else sh_ups_buf[i] = (sh_buf[i] << SHADOW_UPSACALE_SHIFT) / sw; + shadow_blur_corner(size, sw, sh_buf); + } + uint32_t x; + lv_opa_t * res_buf = (lv_opa_t *)sh_buf; + for(x = 0; x < size * size; x++) { + res_buf[x] = sh_buf[x]; } - - shadow_blur_corner(size, sw, sh_buf, sh_ups_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) +static void shadow_blur_corner(lv_coord_t size, lv_coord_t sw, uint16_t * sh_ups_buf) { lv_coord_t s_left = sw >> 1; lv_coord_t s_right = (sw >> 1); if((sw & 1) == 0) s_left--; /*Horizontal blur*/ - uint16_t * sh_ups_hor_buf = lv_mem_buf_get(size * sizeof(uint16_t)); + uint16_t * sh_ups_blur_buf = lv_mem_buf_get(size * sizeof(uint16_t)); lv_coord_t x; lv_coord_t y; @@ -973,7 +968,7 @@ static void shadow_blur_corner(lv_coord_t size, lv_coord_t sw, lv_opa_t * res_bu for(y = 0; y < size; y++) { int32_t v = sh_ups_tmp_buf[size-1] * sw; for(x = size - 1; x >=0; x--) { - sh_ups_hor_buf[x] = v; + sh_ups_blur_buf[x] = v; /*Forget the right pixel*/ uint32_t right_val = 0; @@ -987,7 +982,7 @@ static void shadow_blur_corner(lv_coord_t size, lv_coord_t sw, lv_opa_t * res_bu v += left_val; } - memcpy(sh_ups_tmp_buf, sh_ups_hor_buf, size * sizeof(uint16_t)); + memcpy(sh_ups_tmp_buf, sh_ups_blur_buf, size * sizeof(uint16_t)); sh_ups_tmp_buf += size; } @@ -1001,10 +996,9 @@ static void shadow_blur_corner(lv_coord_t size, lv_coord_t sw, lv_opa_t * res_bu for(x = 0; x < size; x++) { sh_ups_tmp_buf = &sh_ups_buf[x]; - lv_opa_t * sh_buf_tmp = &res_buf[x]; int32_t v = sh_ups_tmp_buf[0] * sw; - for(y = 0; y < size ; y++, sh_ups_tmp_buf += size, sh_buf_tmp += size) { - sh_buf_tmp[0] = v < 0 ? 0 : (v >> SHADOW_UPSACALE_SHIFT); + for(y = 0; y < size ; y++, sh_ups_tmp_buf += size) { + sh_ups_blur_buf[y] = v < 0 ? 0 : (v >> SHADOW_UPSACALE_SHIFT); /*Forget the top pixel*/ uint32_t top_val; @@ -1018,8 +1012,14 @@ static void shadow_blur_corner(lv_coord_t size, lv_coord_t sw, lv_opa_t * res_bu else bottom_val = sh_ups_buf[(size - 1) * size + x]; v += bottom_val; } + + /*Write back the result into `sh_ups_buf`*/ + sh_ups_tmp_buf = &sh_ups_buf[x]; + for(y = 0; y < size; y++, sh_ups_tmp_buf += size) { + (*sh_ups_tmp_buf) = sh_ups_blur_buf[y]; + } } - lv_mem_buf_release(sh_ups_hor_buf); + lv_mem_buf_release(sh_ups_blur_buf); }