optimize shadow drawing

This commit is contained in:
Gabor Kiss-Vamosi
2020-03-31 10:16:11 +02:00
parent f545db3117
commit 1692cc7b7d

View File

@@ -19,6 +19,7 @@
*********************/
#define SHADOW_UPSACALE_SHIFT 6
#define SHADOW_ENHANCE 1
#define SHADOW_CACHE_SIZE 100
#define SPLIT_LIMIT 50
/**********************
@@ -41,6 +42,9 @@ static void draw_value(const lv_area_t * coords, const lv_area_t * clip, lv_draw
/**********************
* STATIC VARIABLES
**********************/
static uint8_t sh_cache[SHADOW_CACHE_SIZE * SHADOW_CACHE_SIZE];
static int32_t sh_cache_size = -1;
static int32_t sh_cache_r = -1;
/**********************
* MACROS
@@ -623,9 +627,23 @@ static void draw_shadow(const lv_area_t * coords, const lv_area_t * clip, lv_dra
int32_t corner_size = sw + 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, dsc->shadow_width, r_sh);
lv_opa_t * sh_buf;
if(sh_cache_size == corner_size && sh_cache_r == r_sh) {
sh_buf = lv_mem_buf_get(corner_size * corner_size);
lv_memcpy(sh_buf, sh_cache, corner_size * corner_size);
} else {
sh_buf = lv_mem_buf_get(corner_size * corner_size * sizeof(uint16_t));
shadow_draw_corner_buf(&sh_rect_area, (uint16_t *)sh_buf, dsc->shadow_width, r_sh);
if(corner_size * corner_size < sizeof(sh_cache)) {
lv_memcpy(sh_cache, sh_buf, corner_size * corner_size);
sh_cache_size = corner_size;
sh_cache_r = r_sh;
}
}
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->shadow_ofs_x != 0 || dsc->shadow_ofs_y != 0) simple_mode = false;
@@ -633,7 +651,7 @@ static void draw_shadow(const lv_area_t * coords, const lv_area_t * clip, lv_dra
/*Create a mask*/
lv_draw_mask_res_t mask_res;
lv_opa_t * mask_buf = lv_mem_buf_get(lv_area_get_width(&sh_rect_area));
lv_opa_t * mask_buf = lv_mem_buf_get(lv_area_get_width(&sh_area));
lv_draw_mask_radius_param_t mask_rout_param;
lv_draw_mask_radius_init(&mask_rout_param, &bg_coords, r_bg, true);
@@ -641,108 +659,132 @@ static void draw_shadow(const lv_area_t * coords, const lv_area_t * clip, lv_dra
int16_t mask_rout_id = lv_draw_mask_add(&mask_rout_param, NULL);
lv_area_t a;
bool top = false;
bool bottom = false;
bool mid = false;
a.x1 = sh_area.x1;
a.x2 = sh_area.x2;
a.y1 = sh_area.y1;
a.y2 = sh_area.y1 + corner_size;
if(lv_area_is_on(&a, clip)) top = true;
a.y1 = sh_area.y2 - corner_size;
a.y2 = sh_area.y2;
if(lv_area_is_on(&a, clip)) bottom = true;
a.y1 = sh_area.y1 + corner_size;
a.y2 = sh_area.y2 - corner_size;
if(lv_area_is_on(&a, clip)) mid = true;
/*Draw the top right corner*/
int32_t y;
lv_opa_t * sh_buf_tmp;
a.x2 = sh_area.x2;
a.x1 = a.x2 - corner_size + 1;
a.y1 = sh_area.y1;
a.y2 = a.y1;
a.y2 = a.y1 + corner_size - 1;
int32_t first_px;
first_px = 0;
if(disp_area->x1 > a.x1) {
first_px = disp_area->x1 - a.x1;
lv_area_t ca;
bool has_com = lv_area_intersect(&ca, &a, clip);
if(has_com) {
lv_coord_t h = lv_area_get_height(&ca);
lv_coord_t w = lv_area_get_width(&ca);
sh_buf_tmp = sh_buf + (ca.x1 - a.x1);
sh_buf_tmp += corner_size * (ca.y1 - a.y1);
lv_area_t fa;
lv_area_copy(&fa, &ca);
fa.y2 = fa.y1;
for(y = 0; y < h; y++) {
lv_memcpy(mask_buf, sh_buf_tmp, w);
mask_res = lv_draw_mask_apply(mask_buf, fa.x1, fa.y1, w);
if(mask_res == LV_DRAW_MASK_RES_FULL_COVER) mask_res = LV_DRAW_MASK_RES_CHANGED;
lv_blend_fill(clip, &fa, dsc->shadow_color, mask_buf,
mask_res, opa, dsc->shadow_blend_mode);
fa.y1++;
fa.y2++;
sh_buf_tmp += corner_size;
}
}
int32_t hor_mid_dist = (sh_area.x1 + lv_area_get_width(&sh_area) / 2) - (a.x1 + first_px);
if(hor_mid_dist > 0) {
first_px += hor_mid_dist;
}
a.x1 += first_px;
int32_t ver_mid_dist = (a.y1 + corner_size) - (sh_area.y1 + lv_area_get_height(&sh_area) / 2);
int32_t ver_mid_corr = 0;
if(ver_mid_dist <= 0) ver_mid_dist = 0;
else {
if(lv_area_get_height(&sh_area) & 0x1) ver_mid_corr = 1;
}
lv_opa_t * sh_buf_tmp = sh_buf;
int32_t y;
for(y = 0; y < corner_size - ver_mid_dist + ver_mid_corr; y++) {
lv_memcpy(mask_buf, sh_buf_tmp, corner_size);
mask_res = lv_draw_mask_apply(mask_buf + first_px, a.x1, a.y1, lv_area_get_width(&a));
if(mask_res == LV_DRAW_MASK_RES_FULL_COVER) mask_res = LV_DRAW_MASK_RES_CHANGED;
lv_blend_fill(clip, &a,
dsc->shadow_color, mask_buf + first_px, mask_res, opa, dsc->shadow_blend_mode);
a.y1++;
a.y2++;
sh_buf_tmp += corner_size;
}
/*Draw the bottom right corner*/
a.y1 = sh_area.y2;
a.y2 = a.y1;
a.x2 = sh_area.x2;
a.x1 = a.x2 - corner_size + 1;
a.y1 = sh_area.y2 - corner_size + 1;
a.y2 = sh_area.y2;
sh_buf_tmp = sh_buf ;
has_com = lv_area_intersect(&ca, &a, clip);
if(has_com) {
lv_coord_t h = lv_area_get_height(&ca);
lv_coord_t w = lv_area_get_width(&ca);
sh_buf_tmp = sh_buf + (ca.x1 - a.x1);
sh_buf_tmp += corner_size * (a.y2 - ca.y2);
for(y = 0; y < corner_size - ver_mid_dist; y++) {
lv_memcpy(mask_buf, sh_buf_tmp, corner_size);
mask_res = lv_draw_mask_apply(mask_buf + first_px, a.x1, a.y1, lv_area_get_width(&a));
if(mask_res == LV_DRAW_MASK_RES_FULL_COVER) mask_res = LV_DRAW_MASK_RES_CHANGED;
lv_area_t fa;
lv_area_copy(&fa, &ca);
fa.y1 = fa.y2; /*Fill from bottom to top*/
lv_blend_fill(clip, &a,
dsc->shadow_color, mask_buf + first_px, mask_res, opa, dsc->shadow_blend_mode);
a.y1--;
a.y2--;
sh_buf_tmp += corner_size;
for(y = 0; y < h; y++) {
lv_memcpy(mask_buf, sh_buf_tmp, w);
mask_res = lv_draw_mask_apply(mask_buf, fa.x1, fa.y1, w);
if(mask_res == LV_DRAW_MASK_RES_FULL_COVER) mask_res = LV_DRAW_MASK_RES_CHANGED;
lv_blend_fill(clip, &fa, dsc->shadow_color, mask_buf,
mask_res, opa, dsc->shadow_blend_mode);
fa.y1--;
fa.y2--;
sh_buf_tmp += corner_size;
}
}
/*Fill the right side*/
a.x2 = sh_area.x2;
a.x1 = a.x2 - corner_size + 1;
a.y1 = sh_area.y1 + corner_size;
a.y2 = a.y1;
sh_buf_tmp = sh_buf + corner_size * (corner_size - 1);
a.y2 = sh_area.y2 - corner_size;
int32_t x;
has_com = lv_area_intersect(&ca, &a, clip);
if(has_com) {
if(simple_mode) ca.x1 = LV_MATH_MAX(ca.x1, coords->x2);
/*Draw horizontal lines*/
lv_coord_t w = lv_area_get_width(&ca);
if(w > 0) {
lv_coord_t h = lv_area_get_height(&ca);
if(simple_mode) {
/*Draw vertical lines*/
lv_area_t va;
va.x1 = a.x1;
va.x2 = a.x1;
va.y1 = sh_area.y1 + corner_size;
va.y2 = sh_area.y2 - corner_size;
/*The last line of the shadow is repeated on the side*/
sh_buf_tmp = sh_buf + corner_size * (corner_size - 1);
sh_buf_tmp += ca.x1 - a.x1;
if(va.y1 <= va.y2) {
for(x = a.x1; x < a.x2; x++) {
if(x > coords->x2) {
lv_opa_t opa_tmp = sh_buf_tmp[x - a.x1 + first_px];
if(opa_tmp != LV_OPA_COVER || opa != LV_OPA_COVER) opa_tmp = (opa * opa_tmp) >> 8;
lv_blend_fill(clip, &va,
dsc->shadow_color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa_tmp, dsc->shadow_blend_mode);
lv_area_t fa;
lv_area_copy(&fa, &ca);
fa.y2 = fa.y1;
mask_res = LV_DRAW_MASK_RES_FULL_COVER;
for(y = 0; y < h; y++) {
lv_memcpy(mask_buf, sh_buf_tmp, w);
if(simple_mode) {
mask_res = LV_DRAW_MASK_RES_CHANGED;
} else {
mask_res = lv_draw_mask_apply(mask_buf, fa.x1, fa.y1, w);
if(mask_res == LV_DRAW_MASK_RES_FULL_COVER) mask_res = LV_DRAW_MASK_RES_CHANGED;
}
va.x1++;
va.x2++;
}
}
}
else {
for(y = corner_size; y < lv_area_get_height(&sh_area) - corner_size; y++) {
lv_memcpy(mask_buf, sh_buf_tmp, corner_size);
mask_res = lv_draw_mask_apply(mask_buf + first_px, a.x1, a.y1, lv_area_get_width(&a));
if(mask_res == LV_DRAW_MASK_RES_FULL_COVER) mask_res = LV_DRAW_MASK_RES_CHANGED;
lv_blend_fill(clip, &a,
dsc->shadow_color, mask_buf + first_px, mask_res, opa, dsc->shadow_blend_mode);
a.y1++;
a.y2++;
lv_blend_fill(clip, &fa,
dsc->shadow_color, mask_buf, mask_res, dsc->shadow_opa, dsc->shadow_blend_mode);
fa.y1++;
fa.y2++;
}
}
}
/*Invert the shadow corner buffer and draw the corners on the left*/
sh_buf_tmp = sh_buf ;
for(y = 0; y < corner_size; y++) {
uint32_t x;
for(x = 0; x < corner_size / 2; x++) {
lv_opa_t tmp = sh_buf_tmp[x];
sh_buf_tmp[x] = sh_buf_tmp[corner_size - x - 1];
@@ -755,175 +797,205 @@ static void draw_shadow(const lv_area_t * coords, const lv_area_t * clip, lv_dra
a.x1 = sh_area.x1;
a.x2 = a.x1 + corner_size - 1;
a.y1 = sh_area.y1;
a.y2 = a.y1;
a.y2 = a.y1 + corner_size - 1;
if(a.x2 > sh_area.x1 + lv_area_get_width(&sh_area) / 2 - 1) {
a.x2 = sh_area.x1 + lv_area_get_width(&sh_area) / 2 - 1 ;
}
has_com = lv_area_intersect(&ca, &a, clip);
if(has_com) {
lv_coord_t h = lv_area_get_height(&ca);
lv_coord_t w = lv_area_get_width(&ca);
sh_buf_tmp = sh_buf + (ca.x1 - a.x1);
sh_buf_tmp += corner_size * (ca.y1 - a.y1);
first_px = 0;
if(clip->x1 >= a.x1) {
first_px = clip->x1 - a.x1;
a.x1 += first_px;
}
lv_area_t fa;
lv_area_copy(&fa, &ca);
fa.y2 = fa.y1;
sh_buf_tmp = sh_buf ;
for(y = 0; y < corner_size - ver_mid_dist + ver_mid_corr; y++) {
lv_memcpy(mask_buf, sh_buf_tmp, corner_size);
mask_res = lv_draw_mask_apply(mask_buf + first_px, a.x1, a.y1, lv_area_get_width(&a));
if(mask_res == LV_DRAW_MASK_RES_FULL_COVER) mask_res = LV_DRAW_MASK_RES_CHANGED;
for(y = 0; y < h; y++) {
lv_memcpy(mask_buf, sh_buf_tmp, w);
mask_res = lv_draw_mask_apply(mask_buf, fa.x1, fa.y1, w);
if(mask_res == LV_DRAW_MASK_RES_FULL_COVER) mask_res = LV_DRAW_MASK_RES_CHANGED;
lv_blend_fill(clip, &a,
dsc->shadow_color, mask_buf + first_px, mask_res, opa, dsc->shadow_blend_mode);
a.y1++;
a.y2++;
sh_buf_tmp += corner_size;
lv_blend_fill(clip, &fa, dsc->shadow_color, mask_buf,
mask_res, opa, dsc->shadow_blend_mode);
fa.y1++;
fa.y2++;
sh_buf_tmp += corner_size;
}
}
/*Draw the bottom left corner*/
a.y1 = sh_area.y2;
a.y2 = a.y1;
a.x1 = sh_area.x1;
a.x2 = a.x1 + corner_size - 1;
a.y1 = sh_area.y2 - corner_size + 1;
a.y2 = sh_area.y2;
sh_buf_tmp = sh_buf ;
has_com = lv_area_intersect(&ca, &a, clip);
if(has_com) {
lv_coord_t h = lv_area_get_height(&ca);
lv_coord_t w = lv_area_get_width(&ca);
sh_buf_tmp = sh_buf + (ca.x1 - a.x1);
sh_buf_tmp += corner_size * (a.y2 - ca.y2);
for(y = 0; y < corner_size - ver_mid_dist; y++) {
lv_memcpy(mask_buf, sh_buf_tmp, corner_size);
mask_res = lv_draw_mask_apply(mask_buf + first_px, a.x1, a.y1, lv_area_get_width(&a));
if(mask_res == LV_DRAW_MASK_RES_FULL_COVER) mask_res = LV_DRAW_MASK_RES_CHANGED;
lv_area_t fa;
lv_area_copy(&fa, &ca);
fa.y1 = fa.y2; /*Fill from bottom to top*/
lv_blend_fill(clip, &a,
dsc->shadow_color, mask_buf + first_px, mask_res, opa, dsc->shadow_blend_mode);
a.y1--;
a.y2--;
sh_buf_tmp += corner_size;
for(y = 0; y < h; y++) {
lv_memcpy(mask_buf, sh_buf_tmp, w);
mask_res = lv_draw_mask_apply(mask_buf, fa.x1, fa.y1, w);
if(mask_res == LV_DRAW_MASK_RES_FULL_COVER) mask_res = LV_DRAW_MASK_RES_CHANGED;
lv_blend_fill(clip, &fa, dsc->shadow_color, mask_buf,
mask_res, opa, dsc->shadow_blend_mode);
fa.y1--;
fa.y2--;
sh_buf_tmp += corner_size;
}
}
/*Fill the left side*/
a.x1 = sh_area.x1;
a.x2 = a.x1 + corner_size - 1;
a.y1 = sh_area.y1 + corner_size;
a.y2 = a.y1;
a.y2 = sh_area.y2 - corner_size;
sh_buf_tmp = sh_buf + corner_size * (corner_size - 1);
has_com = lv_area_intersect(&ca, &a, clip);
if(has_com) {
if(simple_mode) {
if(simple_mode) ca.x2 = LV_MATH_MIN(coords->x1, ca.x2);
/*Draw vertical lines*/
lv_area_t va;
va.x1 = a.x1;
va.x2 = a.x1;
va.y1 = sh_area.y1 + corner_size;
va.y2 = sh_area.y2 - corner_size;
lv_coord_t w = lv_area_get_width(&ca);
if(w > 0) {
lv_coord_t h = lv_area_get_height(&ca);
/*The last line of the shadow is repeated on the side*/
sh_buf_tmp = sh_buf + corner_size * (corner_size - 1);
sh_buf_tmp += ca.x1 - a.x1;
if(va.y1 <= va.y2) {
for(x = a.x1; x < coords->x1; x++) {
lv_opa_t opa_tmp = sh_buf_tmp[x - a.x1 + first_px];
if(opa_tmp != LV_OPA_COVER || opa != LV_OPA_COVER) opa_tmp = (opa * opa_tmp) >> 8;
lv_blend_fill(clip, &va,
dsc->shadow_color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa_tmp, dsc->shadow_blend_mode);
va.x1++;
va.x2++;
lv_area_t fa;
lv_area_copy(&fa, &ca);
fa.y2 = fa.y1;
for(y = 0; y < h; y++) {
lv_memcpy(mask_buf, sh_buf_tmp, w);
if(simple_mode) {
mask_res = LV_DRAW_MASK_RES_CHANGED;
} else {
mask_res = lv_draw_mask_apply(mask_buf, fa.x1, fa.y1, w);
if(mask_res == LV_DRAW_MASK_RES_FULL_COVER) mask_res = LV_DRAW_MASK_RES_CHANGED;
}
lv_blend_fill(clip, &fa,
dsc->shadow_color, mask_buf, mask_res, dsc->shadow_opa, dsc->shadow_blend_mode);
fa.y1++;
fa.y2++;
}
}
}
else {
for(y = corner_size; y < lv_area_get_height(&sh_area) - corner_size; y++) {
lv_memcpy(mask_buf, sh_buf_tmp, corner_size);
mask_res = lv_draw_mask_apply(mask_buf + first_px, a.x1, a.y1, lv_area_get_width(&a));
if(mask_res == LV_DRAW_MASK_RES_FULL_COVER) mask_res = LV_DRAW_MASK_RES_CHANGED;
lv_blend_fill(clip, &a,
dsc->shadow_color, mask_buf + first_px, mask_res, opa, dsc->shadow_blend_mode);
a.y1++;
a.y2++;
}
}
/*Fill the top side*/
a.x1 = sh_area.x1 + corner_size;
a.x2 = sh_area.x2 - corner_size;
a.y1 = sh_area.y1;
a.y2 = a.y1;
a.y2 = sh_area.y1 + corner_size - 1;
first_px = 0;
if(disp_area->x1 > a.x1) {
first_px = disp_area->x1 - a.x1;
a.x1 += first_px;
}
if(a.x1 <= a.x2) {
has_com = lv_area_intersect(&ca, &a, clip);
if(has_com) {
if(simple_mode) ca.y2 = LV_MATH_MIN(ca.y2, coords->y1);
/*Draw horizontal lines*/
lv_coord_t w = lv_area_get_width(&ca);
lv_coord_t h = lv_area_get_height(&ca);
sh_buf_tmp = sh_buf + corner_size - 1;
sh_buf_tmp += corner_size * (ca.y1 - a.y1);
int32_t y_max = corner_size - ver_mid_dist;
if(simple_mode) {
y_max = sw / 2 + 1;
if(y_max > corner_size - ver_mid_dist) y_max = corner_size - ver_mid_dist;
}
lv_area_t fa;
lv_area_copy(&fa, &ca);
fa.y2 = fa.y1;
mask_res = LV_DRAW_MASK_RES_FULL_COVER;
for(y = 0; y < h; y++) {
lv_opa_t opa_tmp = sh_buf_tmp[0];
if(opa_tmp != LV_OPA_COVER || opa != LV_OPA_COVER) opa_tmp = (opa * opa_tmp) >> 8;
for(y = 0; y < y_max; y++) {
if(simple_mode == false) {
lv_memset(mask_buf, sh_buf_tmp[0], lv_area_get_width(&a));
mask_res = lv_draw_mask_apply(mask_buf, a.x1, a.y1, lv_area_get_width(&a));
lv_memset(mask_buf, opa_tmp, w);
if(simple_mode) {
mask_res = LV_DRAW_MASK_RES_CHANGED;
} else {
mask_res = lv_draw_mask_apply(mask_buf, fa.x1, fa.y1, w);
if(mask_res == LV_DRAW_MASK_RES_FULL_COVER) mask_res = LV_DRAW_MASK_RES_CHANGED;
lv_blend_fill(clip, &a,
dsc->shadow_color, mask_buf, mask_res, opa, dsc->shadow_blend_mode);
}
else {
lv_opa_t opa_tmp = sh_buf_tmp[0];
if(opa_tmp != LV_OPA_COVER || opa != LV_OPA_COVER) opa_tmp = (opa * opa_tmp) >> 8;
lv_blend_fill(clip, &a,
dsc->shadow_color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa_tmp, dsc->shadow_blend_mode);
}
a.y1++;
a.y2++;
lv_blend_fill(clip, &fa, dsc->shadow_color, mask_buf,
mask_res, LV_OPA_COVER, dsc->shadow_blend_mode);
fa.y1++;
fa.y2++;
sh_buf_tmp += corner_size;
}
}
/*Fill the bottom side*/
int32_t y_min = simple_mode ? (corner_size - (sh_area.y2 - coords->y2)) : ver_mid_dist;
if(y_min < 0) y_min = 0;
sh_buf_tmp = sh_buf + corner_size * (corner_size - y_min - 1) + corner_size - 1;
a.y1 = sh_area.y2 - corner_size + 1 + y_min;
a.y2 = a.y1;
/*Fill the bottom side*/
a.x1 = sh_area.x1 + corner_size;
a.x2 = sh_area.x2 - corner_size;
a.y1 = sh_area.y2 - corner_size + 1;
a.y2 = sh_area.y2;
for(y = y_min; y < corner_size; y++) {
if(simple_mode == false) {
lv_memset(mask_buf, sh_buf_tmp[0], lv_area_get_width(&a));
mask_res = lv_draw_mask_apply(mask_buf, a.x1, a.y1, lv_area_get_width(&a));
has_com = lv_area_intersect(&ca, &a, clip);
if(has_com) {
if(simple_mode) ca.y1 = LV_MATH_MAX(ca.y1, coords->y2);
/*Draw horizontal lines*/
lv_coord_t w = lv_area_get_width(&ca);
lv_coord_t h = lv_area_get_height(&ca);
sh_buf_tmp = sh_buf + corner_size - 1;
sh_buf_tmp += corner_size * (a.y2 - ca.y2);
lv_area_t fa;
lv_area_copy(&fa, &ca);
fa.y1 = fa.y2;
for(y = 0; y < h; y++) {
lv_opa_t opa_tmp = sh_buf_tmp[0];
if(opa_tmp != LV_OPA_COVER || opa != LV_OPA_COVER) opa_tmp = (opa * opa_tmp) >> 8;
lv_memset(mask_buf, opa_tmp, w);
if(simple_mode) {
mask_res = LV_DRAW_MASK_RES_CHANGED;
} else {
mask_res = lv_draw_mask_apply(mask_buf, fa.x1, fa.y1, w);
if(mask_res == LV_DRAW_MASK_RES_FULL_COVER) mask_res = LV_DRAW_MASK_RES_CHANGED;
lv_blend_fill(clip, &a,
dsc->shadow_color, mask_buf, mask_res, opa, dsc->shadow_blend_mode);
}
else {
lv_opa_t opa_tmp = sh_buf_tmp[0];
if(opa_tmp != LV_OPA_COVER || opa != LV_OPA_COVER) opa_tmp = (opa * opa_tmp) >> 8;
lv_blend_fill(clip, &a,
dsc->shadow_color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa_tmp, dsc->shadow_blend_mode);
}
a.y1++;
a.y2++;
sh_buf_tmp -= corner_size;
lv_blend_fill(clip, &fa, dsc->shadow_color, mask_buf,
mask_res, LV_OPA_COVER, dsc->shadow_blend_mode);
fa.y1--;
fa.y2--;
sh_buf_tmp += corner_size;
}
}
/*Finally fill the middle area*/
if(simple_mode == false) {
a.y1 = sh_area.y1 + corner_size;
a.y2 = a.y1;
if(a.x1 <= a.x2) {
for(y = 0; y < lv_area_get_height(&sh_area) - corner_size * 2; y++) {
lv_memset_ff(mask_buf, lv_area_get_width(&a));
mask_res = lv_draw_mask_apply(mask_buf, a.x1, a.y1, lv_area_get_width(&a));
lv_blend_fill(clip, &a,
dsc->shadow_color, mask_buf, mask_res, opa, dsc->shadow_blend_mode);
a.y1++;
a.y2++;
}
/*Draw the middle area*/
a.x1 = sh_area.x1 + corner_size;
a.x2 = sh_area.x2 - corner_size;
a.y1 = sh_area.y1 + corner_size;
a.y2 = sh_area.y2 - corner_size;
has_com = lv_area_intersect(&ca, &a, clip);
if(has_com && simple_mode == false) {
/*Draw horizontal lines*/
lv_coord_t w = lv_area_get_width(&ca);
lv_coord_t h = lv_area_get_height(&ca);
lv_area_t fa;
lv_area_copy(&fa, &ca);
fa.y2 = fa.y1;
for(y = 0; y < h; y++) {
lv_memset(mask_buf, dsc->shadow_opa, w);
mask_res = lv_draw_mask_apply(mask_buf, fa.x1, fa.y1, w);
if(mask_res == LV_DRAW_MASK_RES_FULL_COVER) mask_res = LV_DRAW_MASK_RES_CHANGED;
lv_blend_fill(clip, &fa, dsc->shadow_color, mask_buf,
mask_res, LV_OPA_COVER, dsc->shadow_blend_mode);
fa.y1++;
fa.y2++;
}
}