minor style fixes + integrate shadow drawing

This commit is contained in:
Gabor Kiss-Vamosi
2019-12-28 01:27:20 +01:00
parent 93f6e48fd4
commit da59655d35
7 changed files with 460 additions and 409 deletions

View File

@@ -2011,6 +2011,8 @@ lv_coord_t lv_obj_get_ext_draw_pad(const lv_obj_t * obj)
lv_style_dsc_t * lv_obj_get_style(const lv_obj_t * obj, uint8_t type)
{
if(type == LV_OBJ_STYLE_MAIN) return &obj->style_dsc;
void * p = &type;
lv_res_t res;
res = lv_signal_send((lv_obj_t*)obj, LV_SIGNAL_GET_STYLE, &p);
@@ -2105,6 +2107,11 @@ lv_style_value_t lv_obj_get_style_value(const lv_obj_t * obj, uint8_t type, lv_s
return LV_BLEND_MODE_NORMAL;
}
break;
case LV_STYLE_SHADOW_BLEND_MODE:
if(dsc->cache.shadow_blend_mode == LV_STYLE_CACHE_BLEND_MODE_NORMAL) {
return LV_BLEND_MODE_NORMAL;
}
break;
case LV_STYLE_RADIUS:
if(dsc->cache.border_width != LV_STYLE_CACHE_RADIUS_SKIPPED) {
return dsc->cache.border_width == LV_STYLE_CACHE_RADIUS_CIRCLE ? LV_RADIUS_CIRCLE : dsc->cache.radius;
@@ -2265,6 +2272,8 @@ lv_color_t lv_obj_get_style_color(const lv_obj_t * obj, uint8_t type, lv_style_p
return LV_COLOR_BLACK;
case LV_STYLE_BORDER_COLOR:
return LV_COLOR_BLACK;
case LV_STYLE_SHADOW_COLOR:
return LV_COLOR_GRAY;
}
return LV_COLOR_WHITE;
@@ -2891,6 +2900,18 @@ void lv_obj_init_draw_rect_dsc(lv_obj_t * obj, uint8_t type, lv_draw_rect_dsc_t
}
}
draw_dsc->shadow_width = lv_obj_get_style_value(obj, type, LV_STYLE_SHADOW_WIDTH);
if(draw_dsc->shadow_width) {
draw_dsc->shadow_opa = lv_obj_get_style_opa(obj, type, LV_STYLE_SHADOW_OPA);
if(draw_dsc->shadow_opa > LV_OPA_MIN) {
draw_dsc->shadow_ofs_x = lv_obj_get_style_value(obj, type, LV_STYLE_SHADOW_OFFSET_X);
draw_dsc->shadow_ofs_y = lv_obj_get_style_value(obj, type, LV_STYLE_SHADOW_OFFSET_Y);
draw_dsc->shadow_spread = lv_obj_get_style_value(obj, type, LV_STYLE_SHADOW_SPREAD);
draw_dsc->shadow_color = lv_obj_get_style_color(obj, type, LV_STYLE_SHADOW_COLOR);
}
}
lv_opa_t opa_scale = lv_obj_get_style_opa(obj, type, LV_STYLE_OPA_SCALE);
if(opa_scale < LV_OPA_MAX) {
draw_dsc->bg_opa = (uint16_t)((uint16_t)draw_dsc->bg_opa * opa_scale) >> 8;
@@ -3215,6 +3236,10 @@ static lv_res_t style_cache_update_core(lv_obj_t * obj, uint8_t type)
if(value == LV_BLEND_MODE_NORMAL) dsc->cache.image_blend_mode = LV_STYLE_CACHE_BLEND_MODE_NORMAL;
else dsc->cache.image_blend_mode = LV_STYLE_CACHE_BLEND_MODE_SKIPPED;
value = lv_obj_get_style_value(obj, type, LV_STYLE_SHADOW_BLEND_MODE);
if(value == LV_BLEND_MODE_NORMAL) dsc->cache.shadow_blend_mode = LV_STYLE_CACHE_BLEND_MODE_NORMAL;
else dsc->cache.shadow_blend_mode = LV_STYLE_CACHE_BLEND_MODE_SKIPPED;
value = lv_obj_get_style_value(obj, type, LV_STYLE_RADIUS);
if(value == LV_RADIUS_CIRCLE) dsc->cache.radius = LV_STYLE_CACHE_RADIUS_CIRCLE;

View File

@@ -523,12 +523,14 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
#if MASK_AREA_DEBUG
static lv_color_t debug_color = LV_COLOR_RED;
LV_STYLE_CREATE(style_debug, &lv_style_plain);
style_debug.body.main_color = debug_color;
style_debug.body.grad_color = debug_color;
style_debug.body.border.width = 2;
style_debug.body.border.color.full = (debug_color.full + 0x13) * 9;
lv_draw_rect(&obj_ext_mask, &obj_ext_mask, &style_debug, LV_OPA_50);
lv_draw_rect_dsc_t draw_dsc;
lv_draw_rect_dsc_init(&draw_dsc);
draw_dsc.bg_color.full = debug_color.full;
draw_dsc.bg_opa = LV_OPA_50;
draw_dsc.border_width = 2;
draw_dsc.border_color.full = (debug_color.full + 0x13) * 9;
lv_draw_rect(&obj_ext_mask, &obj_ext_mask, &draw_dsc);
debug_color.full *= 17;
debug_color.full += 0xA1;
#endif

View File

@@ -118,14 +118,41 @@ void lv_style_built_in_init(void)
lv_style_set_value(&lv_style_btn, LV_STYLE_PAD_TOP, LV_DPI / 20);
lv_style_set_value(&lv_style_btn, LV_STYLE_PAD_BOTTOM, LV_DPI / 20);
lv_style_set_value(&lv_style_btn, LV_STYLE_PAD_INNER, LV_DPI / 16);
// lv_style_set_value(&lv_style_btn, LV_STYLE_RADIUS, LV_DPI / 20);
// lv_style_set_value(&lv_style_btn, LV_STYLE_BORDER_WIDTH, LV_DPI / 50 > 0 ? LV_DPI / 50 : 1);
// lv_style_set_value(&lv_style_btn, LV_STYLE_BG_GRAD_DIR, LV_GRAD_DIR_VER);
lv_style_set_value(&lv_style_btn, LV_STYLE_PAD_LEFT | LV_STYLE_STATE_PRESSED, LV_DPI / 20);
lv_style_set_value(&lv_style_btn, LV_STYLE_PAD_RIGHT | LV_STYLE_STATE_PRESSED, LV_DPI / 20);
lv_style_set_value(&lv_style_btn, LV_STYLE_PAD_TOP | LV_STYLE_STATE_PRESSED, LV_DPI / 20);
lv_style_set_value(&lv_style_btn, LV_STYLE_PAD_BOTTOM | LV_STYLE_STATE_PRESSED, LV_DPI / 20);
lv_style_set_value(&lv_style_btn, LV_STYLE_PAD_INNER | LV_STYLE_STATE_PRESSED, LV_DPI / 16);
lv_style_set_value(&lv_style_btn, LV_STYLE_PAD_LEFT | LV_STYLE_STATE_FOCUS, LV_DPI / 20);
lv_style_set_value(&lv_style_btn, LV_STYLE_PAD_RIGHT | LV_STYLE_STATE_FOCUS, LV_DPI / 20);
lv_style_set_value(&lv_style_btn, LV_STYLE_PAD_TOP | LV_STYLE_STATE_FOCUS, LV_DPI / 20);
lv_style_set_value(&lv_style_btn, LV_STYLE_PAD_BOTTOM | LV_STYLE_STATE_FOCUS, LV_DPI / 20);
lv_style_set_value(&lv_style_btn, LV_STYLE_PAD_INNER | LV_STYLE_STATE_FOCUS, LV_DPI / 16);
lv_style_set_value(&lv_style_btn, LV_STYLE_PAD_LEFT | LV_STYLE_STATE_EDIT, LV_DPI / 20);
lv_style_set_value(&lv_style_btn, LV_STYLE_PAD_RIGHT | LV_STYLE_STATE_EDIT, LV_DPI / 20);
lv_style_set_value(&lv_style_btn, LV_STYLE_PAD_TOP | LV_STYLE_STATE_EDIT, LV_DPI / 20);
lv_style_set_value(&lv_style_btn, LV_STYLE_PAD_BOTTOM | LV_STYLE_STATE_EDIT, LV_DPI / 20);
lv_style_set_value(&lv_style_btn, LV_STYLE_PAD_INNER | LV_STYLE_STATE_EDIT, LV_DPI / 16);
lv_style_set_value(&lv_style_btn, LV_STYLE_PAD_LEFT | LV_STYLE_STATE_HOVER, LV_DPI / 20);
lv_style_set_value(&lv_style_btn, LV_STYLE_PAD_RIGHT | LV_STYLE_STATE_HOVER, LV_DPI / 20);
lv_style_set_value(&lv_style_btn, LV_STYLE_PAD_TOP | LV_STYLE_STATE_HOVER, LV_DPI / 20);
lv_style_set_value(&lv_style_btn, LV_STYLE_PAD_BOTTOM | LV_STYLE_STATE_HOVER, LV_DPI / 20);
lv_style_set_value(&lv_style_btn, LV_STYLE_PAD_INNER | LV_STYLE_STATE_HOVER, LV_DPI / 16);
lv_style_set_value(&lv_style_btn, LV_STYLE_RADIUS, 5);
lv_style_set_value(&lv_style_btn, LV_STYLE_BORDER_WIDTH, 2);//LV_DPI / 50 > 0 ? LV_DPI / 50 : 1);
lv_style_set_value(&lv_style_btn, LV_STYLE_BG_GRAD_DIR, LV_GRAD_DIR_VER);
lv_style_set_color(&lv_style_btn, LV_STYLE_BG_COLOR, LV_COLOR_RED);
// lv_style_set_color(&lv_style_btn, LV_STYLE_BG_GRAD_COLOR, LV_COLOR_RED);
// lv_style_set_color(&lv_style_btn, LV_STYLE_BORDER_COLOR, LV_COLOR_NAVY);
lv_style_set_color(&lv_style_btn, LV_STYLE_BG_GRAD_COLOR | LV_STYLE_STATE_PRESSED, LV_COLOR_BLACK);
lv_style_set_color(&lv_style_btn, LV_STYLE_BG_GRAD_COLOR, LV_COLOR_MAROON);
lv_style_set_color(&lv_style_btn, LV_STYLE_BORDER_COLOR, LV_COLOR_NAVY);
lv_style_set_color(&lv_style_btn, LV_STYLE_BG_GRAD_COLOR | LV_STYLE_STATE_PRESSED, LV_COLOR_LIME);
lv_style_set_color(&lv_style_btn, LV_STYLE_TEXT_COLOR, LV_COLOR_WHITE);
lv_style_set_opa(&lv_style_btn, LV_STYLE_BG_OPA, LV_OPA_50);
lv_style_set_opa(&lv_style_btn, LV_STYLE_BORDER_OPA, LV_OPA_50);
lv_style_set_opa(&lv_style_btn, LV_STYLE_TEXT_OPA, LV_OPA_50);
lv_style_set_value(&lv_style_btn, LV_STYLE_SHADOW_WIDTH, 5);
lv_style_set_value(&lv_style_btn, LV_STYLE_SHADOW_OFFSET_Y, 3);
/*Color styles*/
lv_style_init(&lv_style_light);
@@ -609,8 +636,8 @@ static inline int32_t get_property_index(const lv_style_t * style, lv_style_prop
int16_t id_guess = -1;
uint16_t group = (id_to_find >> 4) & 0xF;
if((style->used_groups & (1 << group)) == 0) return id_guess;
// uint16_t group = (id_to_find >> 4) & 0xF;
// if((style->used_groups & (1 << group)) == 0) return id_guess;
size_t i = 0;
while(i < style->size) {
@@ -620,11 +647,11 @@ static inline int32_t get_property_index(const lv_style_t * style, lv_style_prop
lv_style_attr_t attr_act;
attr_act.full = style->map[i + 1];
if(style->map[i] == id_to_find) {
/*If there the state has perfectly match return this property*/
/*If the state perfectly matches return this property*/
if(attr_act.bits.state == attr.bits.state) {
return i;
}
/* Be sure the property not specifies other state the the requested.
/* Be sure the property not specifies other state than the requested.
* E.g. For HOVER+PRESS, HOVER only is OK, but HOVER+FOCUS not*/
else if((attr_act.bits.state & (~attr.bits.state)) == 0) {
/* Use this property if it describes better the requested state than the current candidate.

View File

@@ -70,10 +70,10 @@ typedef union {
}lv_style_attr_t;
#define LV_STYLE_ID_VALUE 0x0
#define LV_STYLE_ID_COLOR 0x6
#define LV_STYLE_ID_OPA 0xA
#define LV_STYLE_ID_PTR 0xE
#define LV_STYLE_ID_VALUE 0x0 /*6 pcs*/
#define LV_STYLE_ID_COLOR 0x6 /*4 pcs*/
#define LV_STYLE_ID_OPA 0xA /*4 pcs*/
#define LV_STYLE_ID_PTR 0xE /*2 pcs*/
enum {
LV_STYLE_PROP_INIT(LV_STYLE_RADIUS, 0x0, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_NONE),
@@ -184,7 +184,7 @@ typedef struct {
uint32_t pad_inner :6;
uint32_t bg_grad_dir :2;
/*32 bit*/
/*31 bit*/
uint32_t border_width :3;
uint32_t line_width :3;
uint32_t letter_space :3;
@@ -205,6 +205,7 @@ typedef struct {
uint32_t text_blend_mode :1;
uint32_t line_blend_mode :1;
uint32_t image_blend_mode :1;
uint32_t shadow_blend_mode :1;
/*32 bit*/
uint32_t radius :4;

View File

@@ -48,10 +48,11 @@ static void shadow_blur_corner(lv_coord_t size, lv_coord_t sw, lv_opa_t * res_bu
void lv_draw_rect_dsc_init(lv_draw_rect_dsc_t * dsc)
{
memset(dsc, 0x00, sizeof(lv_draw_rect_dsc_t));
dsc->bg_opa = LV_OPA_COVER;
dsc->bg_grad_color_stop = 0xFF;
dsc->bg_opa = LV_OPA_COVER;
dsc->border_opa = LV_OPA_COVER;
dsc->shadow_opa = LV_OPA_COVER;
dsc->border_part = LV_BORDER_PART_FULL;
}
/**
@@ -487,382 +488,380 @@ static lv_color_t grad_get(lv_draw_rect_dsc_t * dsc, lv_coord_t s, lv_coord_t i)
static void draw_shadow(const lv_area_t * coords, const lv_area_t * clip, lv_draw_rect_dsc_t * dsc)
{
// /*Check whether the shadow is visible*/
// if(style->body.shadow.width == 0) return;
//
// if(style->body.shadow.width == 1 && style->body.shadow.offset.x == 0 &&
// style->body.shadow.offset.y == 0 && style->body.shadow.spread <= 0) {
// return;
// }
//
// lv_coord_t sw = style->body.shadow.width;
//
// lv_area_t sh_rect_area;
// sh_rect_area.x1 = coords->x1 + style->body.shadow.offset.x - style->body.shadow.spread;
// sh_rect_area.x2 = coords->x2 + style->body.shadow.offset.x + style->body.shadow.spread;
// sh_rect_area.y1 = coords->y1 + style->body.shadow.offset.y - style->body.shadow.spread;
// sh_rect_area.y2 = coords->y2 + style->body.shadow.offset.y + style->body.shadow.spread;
//
// lv_area_t sh_area;
// sh_area.x1 = sh_rect_area.x1 - sw / 2 - 1;
// sh_area.x2 = sh_rect_area.x2 + sw / 2 + 1;
// sh_area.y1 = sh_rect_area.y1 - sw / 2 - 1;
// sh_area.y2 = sh_rect_area.y2 + sw / 2 + 1;
//
// lv_opa_t opa = style->body.shadow.opa;
//
// if(opa_scale != LV_OPA_COVER) opa = (opa * opa_scale) >> 8;
//
// if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;
//
// lv_disp_t * disp = lv_refr_get_disp_refreshing();
// lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
//
// /* Get clipped fill area which is the real draw area.
// * It is always the same or inside `fill_area` */
// lv_area_t draw_area;
// bool is_common;
// is_common = lv_area_intersect(&draw_area, &sh_area, clip);
// if(is_common == false) return;
//
// const lv_area_t * disp_area = &vdb->area;
//
// /* Now `draw_area` has absolute coordinates.
// * Make it relative to `disp_area` to simplify draw to `disp_buf`*/
// draw_area.x1 -= disp_area->x1;
// draw_area.y1 -= disp_area->y1;
// draw_area.x2 -= disp_area->x1;
// draw_area.y2 -= disp_area->y1;
//
// /*Consider 1 px smaller bg to be sure the edge will be covered by the shadow*/
// lv_area_t bg_coords;
// lv_area_copy(&bg_coords, coords);
// bg_coords.x1 += 1;
// bg_coords.y1 += 1;
// bg_coords.x2 -= 1;
// bg_coords.y2 -= 1;
//
// /*Get the real radius*/
// lv_coord_t r_bg = style->body.radius;
// lv_coord_t short_side = LV_MATH_MIN(lv_area_get_width(&bg_coords), lv_area_get_height(&bg_coords));
// if(r_bg > short_side >> 1) r_bg = short_side >> 1;
//
// lv_coord_t r_sh = style->body.radius;
// short_side = LV_MATH_MIN(lv_area_get_width(&sh_rect_area), lv_area_get_height(&sh_rect_area));
// if(r_sh > short_side >> 1) r_sh = short_side >> 1;
//
//
// 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);
//
// bool simple_mode = true;
// if(lv_draw_mask_get_cnt() > 0) simple_mode = false;
// else if(style->body.shadow.offset.x != 0 || style->body.shadow.offset.y != 0) simple_mode = false;
// else if(style->body.shadow.spread != 0) simple_mode = false;
//
// lv_coord_t y_max;
//
// /*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_draw_mask_radius_param_t mask_rout_param;
// lv_draw_mask_radius_init(&mask_rout_param, &bg_coords, r_bg, true);
//
// int16_t mask_rout_id = LV_MASK_ID_INV;
// mask_rout_id = lv_draw_mask_add(&mask_rout_param, NULL);
//
// lv_area_t a;
//
// /*Draw the top right corner*/
// a.x2 = sh_area.x2;
// a.x1 = a.x2 - corner_size + 1;
// a.y1 = sh_area.y1;
// a.y2 = a.y1;
//
// lv_coord_t first_px;
// first_px = 0;
// if(disp_area->x1 > a.x1) {
// first_px = disp_area->x1 - a.x1;
// }
//
// lv_coord_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;
//
// lv_coord_t ver_mid_dist = (a.y1 + corner_size) - (sh_area.y1 + lv_area_get_height(&sh_area) / 2);
// lv_coord_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;
//
// lv_coord_t y;
// for(y = 0; y < corner_size - ver_mid_dist + ver_mid_corr; y++) {
// 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,
// style->body.shadow.color, mask_buf + first_px, mask_res, opa, style->body.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;
//
// sh_buf_tmp = sh_buf ;
//
// for(y = 0; y < corner_size - ver_mid_dist; y++) {
// 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,
// style->body.shadow.color, mask_buf + first_px, mask_res, opa, style->body.shadow.blend_mode);
// a.y1--;
// a.y2--;
// sh_buf_tmp += corner_size;
// }
//
// /*Fill the right side*/
// a.y1 = sh_area.y1 + corner_size;
// a.y2 = a.y1;
// sh_buf_tmp = sh_buf + corner_size * (corner_size - 1);
//
// lv_coord_t x;
//
// 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;
//
// 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,
// style->body.shadow.color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa_tmp, style->body.shadow.blend_mode);
// }
// va.x1++;
// va.x2++;
// }
// }
// }
// else {
// for(y = corner_size; y < lv_area_get_height(&sh_area) - corner_size; y++) {
// 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,
// style->body.shadow.color, mask_buf+first_px, mask_res, opa, style->body.shadow.blend_mode);
// a.y1++;
// a.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++) {
// 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];
// sh_buf_tmp[corner_size - x - 1] = tmp;
// }
// sh_buf_tmp += corner_size;
// }
//
// /*Draw the top left corner*/
// a.x1 = sh_area.x1;
// a.x2 = a.x1 + corner_size - 1;
// a.y1 = sh_area.y1;
// a.y2 = a.y1;
//
// 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 ;
// }
//
// first_px = 0;
// if(disp_area->x1 >= a.x1) {
// first_px = disp_area->x1 - a.x1;
// a.x1 += first_px;
// }
//
// sh_buf_tmp = sh_buf ;
// for(y = 0; y < corner_size - ver_mid_dist + ver_mid_corr; y++) {
// 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,
// style->body.shadow.color, mask_buf + first_px, mask_res, opa, style->body.shadow.blend_mode);
// a.y1++;
// a.y2++;
// sh_buf_tmp += corner_size;
// }
//
// /*Draw the bottom left corner*/
// a.y1 = sh_area.y2;
// a.y2 = a.y1;
//
// sh_buf_tmp = sh_buf ;
//
// for(y = 0; y < corner_size - ver_mid_dist; y++) {
// 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,
// style->body.shadow.color, mask_buf + first_px, mask_res, opa, style->body.shadow.blend_mode);
// a.y1--;
// a.y2--;
// sh_buf_tmp += corner_size;
// }
//
// /*Fill the left side*/
// a.y1 = sh_area.y1+corner_size;
// a.y2 = a.y1;
//
// sh_buf_tmp = sh_buf + corner_size * (corner_size - 1);
//
// 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;
//
// 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,
// style->body.shadow.color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa_tmp, style->body.shadow.blend_mode);
// va.x1++;
// va.x2++;
// }
// }
// }
// else {
// for(y = corner_size; y < lv_area_get_height(&sh_area) - corner_size; y++) {
// 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,
// style->body.shadow.color, mask_buf + first_px, mask_res, opa, style->body.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;
//
//
// 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) {
//
// sh_buf_tmp = sh_buf + corner_size - 1;
//
// 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;
// }
//
// for(y = 0; y < y_max; y++) {
// if(simple_mode == false) {
// 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));
// if(mask_res == LV_DRAW_MASK_RES_FULL_COVER) mask_res = LV_DRAW_MASK_RES_CHANGED;
//
// lv_blend_fill(clip, &a,
// style->body.shadow.color, mask_buf, mask_res, opa, style->body.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,
// style->body.shadow.color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa_tmp, style->body.shadow.blend_mode);
// }
//
// a.y1++;
// a.y2++;
// sh_buf_tmp += corner_size;
// }
//
// /*Fill the bottom side*/
// lv_coord_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;
//
// for(y = y_min; y < corner_size; y++) {
// if(simple_mode == false) {
// 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));
// if(mask_res == LV_DRAW_MASK_RES_FULL_COVER) mask_res = LV_DRAW_MASK_RES_CHANGED;
// lv_blend_fill(clip, &a,
// style->body.shadow.color, mask_buf, mask_res, opa, style->body.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,
// style->body.shadow.color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa_tmp, style->body.shadow.blend_mode);
// }
//
// a.y1++;
// a.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++) {
// memset(mask_buf, 0xFF, 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,
// style->body.shadow.color, mask_buf, mask_res, opa, style->body.shadow.blend_mode);
//
// a.y1++;
// a.y2++;
// }
// }
// }
//
// lv_draw_mask_remove_id(mask_rout_id);
// lv_mem_buf_release(mask_buf);
// lv_mem_buf_release(sh_buf);
/*Check whether the shadow is visible*/
if(dsc->shadow_width == 0) return;
if(dsc->shadow_width == 1 && dsc->shadow_ofs_x == 0 &&
dsc->shadow_ofs_y == 0 && dsc->shadow_spread <= 0) {
return;
}
lv_coord_t sw = dsc->shadow_width;
lv_area_t sh_rect_area;
sh_rect_area.x1 = coords->x1 + dsc->shadow_ofs_x - dsc->shadow_spread;
sh_rect_area.x2 = coords->x2 + dsc->shadow_ofs_x + dsc->shadow_spread;
sh_rect_area.y1 = coords->y1 + dsc->shadow_ofs_y - dsc->shadow_spread;
sh_rect_area.y2 = coords->y2 + dsc->shadow_ofs_y + dsc->shadow_spread;
lv_area_t sh_area;
sh_area.x1 = sh_rect_area.x1 - sw / 2 - 1;
sh_area.x2 = sh_rect_area.x2 + sw / 2 + 1;
sh_area.y1 = sh_rect_area.y1 - sw / 2 - 1;
sh_area.y2 = sh_rect_area.y2 + sw / 2 + 1;
lv_opa_t opa = dsc->shadow_opa;
if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;
lv_disp_t * disp = lv_refr_get_disp_refreshing();
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
/* Get clipped fill area which is the real draw area.
* It is always the same or inside `fill_area` */
lv_area_t draw_area;
bool is_common;
is_common = lv_area_intersect(&draw_area, &sh_area, clip);
if(is_common == false) return;
const lv_area_t * disp_area = &vdb->area;
/* Now `draw_area` has absolute coordinates.
* Make it relative to `disp_area` to simplify draw to `disp_buf`*/
draw_area.x1 -= disp_area->x1;
draw_area.y1 -= disp_area->y1;
draw_area.x2 -= disp_area->x1;
draw_area.y2 -= disp_area->y1;
/*Consider 1 px smaller bg to be sure the edge will be covered by the shadow*/
lv_area_t bg_coords;
lv_area_copy(&bg_coords, coords);
bg_coords.x1 += 1;
bg_coords.y1 += 1;
bg_coords.x2 -= 1;
bg_coords.y2 -= 1;
/*Get the real radius*/
lv_coord_t r_bg = dsc->radius;
lv_coord_t short_side = LV_MATH_MIN(lv_area_get_width(&bg_coords), lv_area_get_height(&bg_coords));
if(r_bg > short_side >> 1) r_bg = short_side >> 1;
lv_coord_t r_sh = dsc->radius;
short_side = LV_MATH_MIN(lv_area_get_width(&sh_rect_area), lv_area_get_height(&sh_rect_area));
if(r_sh > short_side >> 1) r_sh = short_side >> 1;
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, dsc->shadow_width, r_sh);
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;
else if(dsc->shadow_spread != 0) simple_mode = false;
lv_coord_t y_max;
/*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_draw_mask_radius_param_t mask_rout_param;
lv_draw_mask_radius_init(&mask_rout_param, &bg_coords, r_bg, true);
int16_t mask_rout_id = LV_MASK_ID_INV;
mask_rout_id = lv_draw_mask_add(&mask_rout_param, NULL);
lv_area_t a;
/*Draw the top right corner*/
a.x2 = sh_area.x2;
a.x1 = a.x2 - corner_size + 1;
a.y1 = sh_area.y1;
a.y2 = a.y1;
lv_coord_t first_px;
first_px = 0;
if(disp_area->x1 > a.x1) {
first_px = disp_area->x1 - a.x1;
}
lv_coord_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;
lv_coord_t ver_mid_dist = (a.y1 + corner_size) - (sh_area.y1 + lv_area_get_height(&sh_area) / 2);
lv_coord_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;
lv_coord_t y;
for(y = 0; y < corner_size - ver_mid_dist + ver_mid_corr; y++) {
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;
sh_buf_tmp = sh_buf ;
for(y = 0; y < corner_size - ver_mid_dist; y++) {
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;
}
/*Fill the right side*/
a.y1 = sh_area.y1 + corner_size;
a.y2 = a.y1;
sh_buf_tmp = sh_buf + corner_size * (corner_size - 1);
lv_coord_t x;
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;
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);
}
va.x1++;
va.x2++;
}
}
}
else {
for(y = corner_size; y < lv_area_get_height(&sh_area) - corner_size; y++) {
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++;
}
}
/*Invert the shadow corner buffer and draw the corners on the left*/
sh_buf_tmp = sh_buf ;
for(y = 0; y < corner_size; y++) {
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];
sh_buf_tmp[corner_size - x - 1] = tmp;
}
sh_buf_tmp += corner_size;
}
/*Draw the top left corner*/
a.x1 = sh_area.x1;
a.x2 = a.x1 + corner_size - 1;
a.y1 = sh_area.y1;
a.y2 = a.y1;
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 ;
}
first_px = 0;
if(disp_area->x1 >= a.x1) {
first_px = disp_area->x1 - a.x1;
a.x1 += first_px;
}
sh_buf_tmp = sh_buf ;
for(y = 0; y < corner_size - ver_mid_dist + ver_mid_corr; y++) {
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 left corner*/
a.y1 = sh_area.y2;
a.y2 = a.y1;
sh_buf_tmp = sh_buf ;
for(y = 0; y < corner_size - ver_mid_dist; y++) {
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;
}
/*Fill the left side*/
a.y1 = sh_area.y1+corner_size;
a.y2 = a.y1;
sh_buf_tmp = sh_buf + corner_size * (corner_size - 1);
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;
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++;
}
}
}
else {
for(y = corner_size; y < lv_area_get_height(&sh_area) - corner_size; y++) {
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;
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) {
sh_buf_tmp = sh_buf + corner_size - 1;
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;
}
for(y = 0; y < y_max; y++) {
if(simple_mode == false) {
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));
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;
}
/*Fill the bottom side*/
lv_coord_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;
for(y = y_min; y < corner_size; y++) {
if(simple_mode == false) {
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));
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;
}
}
/*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++) {
memset(mask_buf, 0xFF, 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++;
}
}
}
lv_draw_mask_remove_id(mask_rout_id);
lv_mem_buf_release(mask_buf);
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)
@@ -912,12 +911,6 @@ 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;
for(i = 0; i < size * size; i++) {
@@ -947,7 +940,6 @@ 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

@@ -45,9 +45,11 @@ typedef struct {
/*Shadow*/
lv_color_t shadow_color;
lv_style_value_t shadow_blur;
lv_style_value_t shadow_width;
lv_style_value_t shadow_ofs_x;
lv_style_value_t shadow_ofs_y;
lv_style_value_t shadow_spread;
lv_style_value_t shadow_blend_mode;
lv_opa_t shadow_opa;
}lv_draw_rect_dsc_t;

View File

@@ -456,7 +456,9 @@ static lv_design_res_t lv_btn_design(lv_obj_t * btn, const lv_area_t * clip_area
lv_draw_rect_dsc_t draw_dsc;
lv_draw_rect_dsc_init(&draw_dsc);
lv_obj_init_draw_rect_dsc(btn, LV_OBJ_STYLE_MAIN, &draw_dsc);
// draw_dsc.shadow_width = 5;
// draw_dsc.shadow_ofs_y = 3;
draw_dsc.shadow_opa = LV_OPA_COVER;
lv_draw_rect(&btn->coords, clip_area, &draw_dsc);
if(lv_obj_get_style_value(btn, LV_OBJ_STYLE_MAIN, LV_STYLE_BG_CLIP_CORNER)) {