diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index e0ad6c42c..18a633acd 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -18,9 +18,10 @@ #include "../lv_misc/lv_async.h" #include "../lv_misc/lv_fs.h" #include "../lv_hal/lv_hal.h" +#include "../lv_misc/lv_gc.h" +#include "../lv_misc/lv_math.h" #include #include -#include "../lv_misc/lv_gc.h" #if defined(LV_GC_INCLUDE) #include LV_GC_INCLUDE @@ -2186,7 +2187,11 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param) /*Return 'invalid' if the child change signal is not enabled*/ if(lv_obj_is_protected(obj, LV_PROTECT_CHILD_CHG) != false) res = LV_RES_INV; } else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) { - if(style->body.shadow.width > obj->ext_draw_pad) obj->ext_draw_pad = style->body.shadow.width; + lv_coord_t shadow = (style->body.shadow.width >> 1) + 1; + shadow += style->body.shadow.spread; + shadow += LV_MATH_MAX(style->body.shadow.offset.x, style->body.shadow.offset.y); + + if(shadow > obj->ext_draw_pad) obj->ext_draw_pad = shadow; } else if(sign == LV_SIGNAL_STYLE_CHG) { lv_obj_refresh_ext_draw_pad(obj); } else if(sign == LV_SIGNAL_GET_TYPE) { diff --git a/src/lv_core/lv_style.c b/src/lv_core/lv_style.c index da561a7df..058eb7c41 100644 --- a/src/lv_core/lv_style.c +++ b/src/lv_core/lv_style.c @@ -87,8 +87,11 @@ void lv_style_init(void) lv_style_scr.body.border.part = LV_BORDER_FULL; lv_style_scr.body.shadow.color = LV_COLOR_GRAY; - lv_style_scr.body.shadow.type = LV_SHADOW_FULL; lv_style_scr.body.shadow.width = 0; + lv_style_scr.body.shadow.opa = LV_OPA_COVER; + lv_style_scr.body.shadow.offset.x = 0; + lv_style_scr.body.shadow.offset.y = 0; + lv_style_scr.body.shadow.spread = 0; lv_style_scr.text.opa = LV_OPA_COVER; lv_style_scr.text.color = lv_color_make(0x30, 0x30, 0x30); @@ -163,7 +166,7 @@ void lv_style_init(void) lv_style_copy(&lv_style_btn_rel, &lv_style_plain); lv_style_btn_rel.body.main_color = lv_color_make(0x76, 0xa2, 0xd0); lv_style_btn_rel.body.grad_color = lv_color_make(0x19, 0x3a, 0x5d); - lv_style_btn_rel.body.radius = LV_RADIUS_CIRCLE; //LV_DPI / 15; + lv_style_btn_rel.body.radius = 5;//LV_RADIUS_CIRCLE; //LV_DPI / 15; lv_style_btn_rel.body.opa = 200; lv_style_btn_rel.body.padding.left = LV_DPI / 4; lv_style_btn_rel.body.padding.right = LV_DPI / 4; @@ -174,7 +177,10 @@ void lv_style_init(void) lv_style_btn_rel.body.border.width = 2;//LV_DPI / 50 >= 1 ? LV_DPI / 50 : 1; lv_style_btn_rel.body.border.opa = LV_OPA_10; lv_style_btn_rel.body.shadow.color = LV_COLOR_BLACK; - lv_style_btn_rel.body.shadow.width = 40; + lv_style_btn_rel.body.shadow.width = 6; +// lv_style_btn_rel.body.shadow.spread = 15; + lv_style_btn_rel.body.shadow.offset.x = -5; + lv_style_btn_rel.body.shadow.offset.y = 5; lv_style_btn_rel.text.color = lv_color_make(0xff, 0xff, 0xff); lv_style_btn_rel.image.color = lv_color_make(0xff, 0xff, 0xff); @@ -237,6 +243,9 @@ void lv_style_mix(const lv_style_t * start, const lv_style_t * end, lv_style_t * STYLE_ATTR_MIX(body.border.width, ratio); STYLE_ATTR_MIX(body.border.opa, ratio); STYLE_ATTR_MIX(body.shadow.width, ratio); + STYLE_ATTR_MIX(body.shadow.offset.x, ratio); + STYLE_ATTR_MIX(body.shadow.offset.y, ratio); + STYLE_ATTR_MIX(body.shadow.spread, ratio); STYLE_ATTR_MIX(body.padding.left, ratio); STYLE_ATTR_MIX(body.padding.right, ratio); STYLE_ATTR_MIX(body.padding.top, ratio); @@ -264,13 +273,11 @@ void lv_style_mix(const lv_style_t * start, const lv_style_t * end, lv_style_t * res->body.border.part = start->body.border.part; res->glass = start->glass; res->text.font = start->text.font; - res->body.shadow.type = start->body.shadow.type; res->line.rounded = start->line.rounded; } else { res->body.border.part = end->body.border.part; res->glass = end->glass; res->text.font = end->text.font; - res->body.shadow.type = end->body.shadow.type; res->line.rounded = end->line.rounded; } } diff --git a/src/lv_core/lv_style.h b/src/lv_core/lv_style.h index 83c46f123..309e54566 100644 --- a/src/lv_core/lv_style.h +++ b/src/lv_core/lv_style.h @@ -40,15 +40,8 @@ enum { }; typedef uint8_t lv_border_part_t; -/*Shadow types*/ -enum { - LV_SHADOW_BOTTOM = 0, /**< Only draw bottom shadow */ - LV_SHADOW_FULL, /**< Draw shadow on all sides */ -}; -typedef uint8_t lv_shadow_type_t; - /** - * Objects in LittlevGL can be assigned a style - which holds information about + * Styles can be assigned to objects - which holds information about * how the object should be drawn. * * This allows for easy customization without having to modify the object's design @@ -79,7 +72,9 @@ typedef struct { lv_color_t color; lv_coord_t width; - lv_shadow_type_t type; /**< Which parts of the shadow to draw */ + lv_coord_t spread; + lv_point_t offset; + lv_opa_t opa; } shadow; struct diff --git a/src/lv_draw/lv_draw_rect.c b/src/lv_draw/lv_draw_rect.c index b2c520af3..05bf6f987 100644 --- a/src/lv_draw/lv_draw_rect.c +++ b/src/lv_draw/lv_draw_rect.c @@ -344,18 +344,19 @@ static void draw_bg(const lv_area_t * coords, const lv_area_t * clip, const lv_s static void draw_shadow(const lv_area_t * coords, const lv_area_t * clip, const lv_style_t * style, lv_opa_t opa_scale) { - if(style->body.shadow.width == 0) return; + /*Check whether the shadow is visible*/ + if(style->body.shadow.width == 0 && 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_coord_t x_ofs = 0; - lv_coord_t y_ofs = 0; - lv_area_t sh_area; - sh_area.x1 = coords->x1 - sw / 2 - 1 + x_ofs; - sh_area.x2 = coords->x2 + sw / 2 + 1 + x_ofs; - sh_area.y1 = coords->y1 - sw / 2 - 1 + y_ofs; - sh_area.y2 = coords->y2 + sw / 2 + 1 + y_ofs; + sh_area.x1 = coords->x1 - sw / 2 - 1 + style->body.shadow.offset.x - style->body.shadow.spread; + sh_area.x2 = coords->x2 + sw / 2 + 1 + style->body.shadow.offset.x + style->body.shadow.spread; + sh_area.y1 = coords->y1 - sw / 2 - 1 + style->body.shadow.offset.y - style->body.shadow.spread; + sh_area.y2 = coords->y2 + sw / 2 + 1 + style->body.shadow.offset.y + style->body.shadow.spread; lv_opa_t opa = style->body.opa; @@ -540,7 +541,7 @@ static void draw_shadow(const lv_area_t * coords, const lv_area_t * clip, const } first_px = 0; - if(disp_area->x1 > a.x1) { + if(disp_area->x1 >= a.x1) { first_px = disp_area->x1 - a.x1; a.x1 += first_px; } @@ -621,7 +622,7 @@ static void draw_shadow(const lv_area_t * coords, const lv_area_t * clip, const sh_buf_tmp = sh_buf + corner_size - 1; y_max = corner_size; - if(other_mask_cnt == 0) y_max = sw / 2 + 1 - y_ofs; + if(other_mask_cnt == 0) y_max = sw / 2 + 1 - style->body.shadow.offset.y; for(y = 0; y < y_max; y++) { if(other_mask_cnt != 0) { @@ -672,10 +673,13 @@ static void draw_shadow(const lv_area_t * coords, const lv_area_t * clip, const } #define SHADOW_UPSACALE_SHIFT 6 -#define SHADOW_ENHANCE 0 +#define SHADOW_ENHANCE 1 static void shadow_draw_corner_buf(const lv_area_t * coords, lv_opa_t * sh_buf, lv_coord_t sw, lv_coord_t r) { + + + if(sw == 0) sw = 1; lv_coord_t size = sw + r; lv_area_t sh_area; @@ -692,6 +696,7 @@ static void shadow_draw_corner_buf(const lv_area_t * coords, lv_opa_t * sh_buf, #if SHADOW_ENHANCE sw = sw/2; + if(sw == 0) sw = 1; #endif lv_mask_res_t mask_res; @@ -727,6 +732,14 @@ static void shadow_draw_corner_buf(const lv_area_t * coords, lv_opa_t * sh_buf, // return; + if(sw == 1) { + lv_coord_t i; + for(i = 0; i < size * size; i++) { + sh_buf[i] = (sh_ups_buf[i] >> SHADOW_UPSACALE_SHIFT); + } + return; + } + shadow_blur_corner(size, sw, sh_buf, sh_ups_buf); diff --git a/src/lv_themes/lv_theme_alien.c b/src/lv_themes/lv_theme_alien.c index 987a36310..8dc852826 100644 --- a/src/lv_themes/lv_theme_alien.c +++ b/src/lv_themes/lv_theme_alien.c @@ -85,7 +85,6 @@ static void basic_init(void) def.body.border.opa = LV_OPA_COVER; def.body.shadow.color = LV_COLOR_SILVER; def.body.shadow.width = 0; - def.body.shadow.type = LV_SHADOW_FULL; def.text.color = lv_color_hex3(0xDDD); def.text.font = _font; diff --git a/src/lv_themes/lv_theme_material.c b/src/lv_themes/lv_theme_material.c index 6eb8f0538..dc34cf8b4 100644 --- a/src/lv_themes/lv_theme_material.c +++ b/src/lv_themes/lv_theme_material.c @@ -72,7 +72,6 @@ static void basic_init(void) panel.body.border.color = lv_color_hex3(0xbbb); panel.body.border.opa = LV_OPA_COVER; panel.body.shadow.color = DEF_SHADOW_COLOR; - panel.body.shadow.type = LV_SHADOW_BOTTOM; panel.body.shadow.width = 4; panel.body.padding.left = LV_DPI / 8; panel.body.padding.right = LV_DPI / 8; @@ -117,7 +116,6 @@ static void btn_init(void) rel.body.padding.bottom = LV_DPI / 8; rel.body.padding.inner = LV_DPI / 10; rel.body.shadow.color = DEF_SHADOW_COLOR; - rel.body.shadow.type = LV_SHADOW_BOTTOM; rel.body.shadow.width = 6; rel.text.color = lv_color_hsv_to_rgb(_hue, 5, 95); rel.image.color = lv_color_hsv_to_rgb(_hue, 5, 95); @@ -273,7 +271,6 @@ static void sw_init(void) lv_style_copy(&sw_knob_on, theme.style.slider.knob); sw_knob_on.body.shadow.width = 3; - sw_knob_on.body.shadow.type = LV_SHADOW_BOTTOM; sw_knob_on.body.shadow.color = DEF_SHADOW_COLOR; lv_style_copy(&sw_knob_off, &sw_knob_on); @@ -406,7 +403,6 @@ static void cb_init(void) #if LV_USE_CB != 0 static lv_style_t rel, pr, tgl_rel, tgl_pr, ina; lv_style_copy(&rel, theme.style.panel); - rel.body.shadow.type = LV_SHADOW_BOTTOM; rel.body.shadow.width = 3; lv_style_copy(&pr, &rel); @@ -417,7 +413,6 @@ static void cb_init(void) lv_style_copy(&tgl_rel, &rel); tgl_rel.body.main_color = lv_color_hsv_to_rgb(_hue, 75, 85); tgl_rel.body.grad_color = tgl_rel.body.main_color; - tgl_rel.body.shadow.type = LV_SHADOW_FULL; tgl_rel.body.shadow.width = 0; lv_style_copy(&tgl_pr, &tgl_rel); @@ -688,7 +683,6 @@ static void tabview_init(void) btn_bg.body.border.opa = LV_OPA_COVER; btn_bg.body.shadow.width = 5; btn_bg.body.shadow.color = DEF_SHADOW_COLOR; - btn_bg.body.shadow.type = LV_SHADOW_BOTTOM; btn_bg.body.padding.inner = 0; btn_bg.body.padding.left = 0; btn_bg.body.padding.right = 0; diff --git a/src/lv_themes/lv_theme_mono.c b/src/lv_themes/lv_theme_mono.c index 9c2e7743f..ad0164fca 100644 --- a/src/lv_themes/lv_theme_mono.c +++ b/src/lv_themes/lv_theme_mono.c @@ -157,7 +157,6 @@ static void led_init(void) led.body.radius = LV_RADIUS_CIRCLE; led.body.shadow.width = LV_DPI / 8; led.body.shadow.color = LV_COLOR_BLACK; - led.body.shadow.type = LV_SHADOW_FULL; theme.style.led = &led; #endif diff --git a/src/lv_themes/lv_theme_nemo.c b/src/lv_themes/lv_theme_nemo.c index cd4bd002a..1bfa22132 100644 --- a/src/lv_themes/lv_theme_nemo.c +++ b/src/lv_themes/lv_theme_nemo.c @@ -87,7 +87,6 @@ static void basic_init(void) def.body.border.opa = LV_OPA_COVER; def.body.shadow.color = LV_COLOR_SILVER; def.body.shadow.width = 0; - def.body.shadow.type = LV_SHADOW_FULL; def.text.color = lv_color_hex3(0xDDD); def.text.font = _font; diff --git a/src/lv_themes/lv_theme_night.c b/src/lv_themes/lv_theme_night.c index c908939cf..9c14b3532 100644 --- a/src/lv_themes/lv_theme_night.c +++ b/src/lv_themes/lv_theme_night.c @@ -115,7 +115,6 @@ static void btn_init(void) btn_rel.body.padding.right = LV_DPI / 4; btn_rel.body.padding.top = LV_DPI / 8; btn_rel.body.padding.bottom = LV_DPI / 8; - btn_rel.body.shadow.type = LV_SHADOW_BOTTOM; btn_rel.body.shadow.color = lv_color_hex3(0x111); btn_rel.body.shadow.width = LV_DPI / 30; btn_rel.text.color = lv_color_hex3(0xeee);