mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-28 07:03:00 +08:00
draw fixes
This commit is contained in:
parent
4e11456706
commit
033ed99f1f
@ -71,7 +71,7 @@ void lv_style_init(void)
|
||||
|
||||
/*Screen style*/
|
||||
lv_style_scr.glass = 0;
|
||||
lv_style_scr.body.opa = LV_OPA_COVER;
|
||||
lv_style_scr.body.opa = LV_OPA_TRANSP;
|
||||
lv_style_scr.body.main_color = LV_COLOR_WHITE;
|
||||
lv_style_scr.body.grad_color = LV_COLOR_WHITE;
|
||||
lv_style_scr.body.radius = 0;
|
||||
@ -111,12 +111,13 @@ void lv_style_init(void)
|
||||
|
||||
lv_style_scr.line.opa = LV_OPA_COVER;
|
||||
lv_style_scr.line.color = lv_color_make(0x20, 0x20, 0x20);
|
||||
lv_style_scr.line.width = 2;
|
||||
lv_style_scr.line.width = 1;
|
||||
lv_style_scr.line.rounded = 0;
|
||||
lv_style_scr.line.blend_mode = LV_BLEND_MODE_NORMAL;
|
||||
|
||||
/*Plain style (by default near the same as the screen style)*/
|
||||
lv_style_copy(&lv_style_plain, &lv_style_scr);
|
||||
lv_style_plain.body.opa = LV_OPA_COVER;
|
||||
lv_style_plain.body.padding.left = LV_DPI / 20;
|
||||
lv_style_plain.body.padding.right = LV_DPI / 20;
|
||||
lv_style_plain.body.padding.top = LV_DPI / 20;
|
||||
@ -173,7 +174,7 @@ void lv_style_init(void)
|
||||
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_DPI / 15;
|
||||
lv_style_btn_rel.body.opa = LV_OPA_COVER;
|
||||
lv_style_btn_rel.body.opa = LV_OPA_50;
|
||||
// lv_style_btn_rel.body.blend_mode = LV_BLEND_MODE_ADDITIVE;
|
||||
lv_style_btn_rel.body.padding.left = LV_DPI / 4;
|
||||
lv_style_btn_rel.body.padding.right = LV_DPI / 4;
|
||||
|
@ -17,6 +17,7 @@
|
||||
*********************/
|
||||
#define FILL_DIRECT_LEN 32
|
||||
#define FILL_DIRECT_MASK 0x1F
|
||||
#define GPU_WIDTH_LIMIT 32
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
@ -36,6 +37,8 @@ static void fill_true_color_blended(const lv_area_t * disp_area, lv_color_t * di
|
||||
|
||||
|
||||
|
||||
static inline lv_color_t color_mix_with_alpha(lv_color_t bg_color, lv_opa_t bg_opa, lv_color_t fg_color, lv_opa_t fg_opa);
|
||||
|
||||
static inline lv_color_t color_blend_true_color_additive(lv_color_t bg, lv_color_t fg, lv_opa_t opa);
|
||||
static inline lv_color_t color_blend_true_color_subtractive(lv_color_t fg, lv_color_t bg, lv_opa_t opa);
|
||||
|
||||
@ -77,7 +80,6 @@ void lv_blend_fill(const lv_area_t * clip_area, const lv_area_t * fill_area,
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
||||
const lv_area_t * disp_area = &vdb->area;
|
||||
lv_color_t * disp_buf = vdb->buf_act;
|
||||
lv_img_cf_t cf = LV_IMG_CF_TRUE_COLOR;
|
||||
|
||||
|
||||
/* Get clipped fill area which is the real draw area.
|
||||
@ -94,20 +96,15 @@ void lv_blend_fill(const lv_area_t * clip_area, const lv_area_t * fill_area,
|
||||
draw_area.x2 -= disp_area->x1;
|
||||
draw_area.y2 -= disp_area->y1;
|
||||
|
||||
if(cf == LV_IMG_CF_TRUE_COLOR && mode == LV_BLEND_MODE_NORMAL) {
|
||||
if(mode == LV_BLEND_MODE_NORMAL) {
|
||||
fill_true_color_normal(disp_area, disp_buf, &draw_area, color, opa, mask, mask_res);
|
||||
}
|
||||
else {
|
||||
fill_true_color_blended(disp_area, disp_buf, &draw_area, color, opa, mask, mask_res, mode);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void lv_blend_map(const lv_area_t * clip_area, const lv_area_t * map_area, const lv_color_t * map_buf,
|
||||
const lv_opa_t * mask, lv_draw_mask_res_t mask_res,
|
||||
lv_opa_t opa, lv_blend_mode_t mode)
|
||||
@ -127,7 +124,6 @@ void lv_blend_map(const lv_area_t * clip_area, const lv_area_t * map_area, const
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
||||
const lv_area_t * disp_area = &vdb->area;
|
||||
lv_color_t * disp_buf = vdb->buf_act;
|
||||
lv_img_cf_t cf = LV_IMG_CF_TRUE_COLOR;
|
||||
|
||||
/* Now `draw_area` has absolute coordinates.
|
||||
* Make it relative to `disp_area` to simplify draw to `disp_buf`*/
|
||||
@ -139,6 +135,9 @@ void lv_blend_map(const lv_area_t * clip_area, const lv_area_t * map_area, const
|
||||
/*Get the width of the `disp_area` it will be used to go to the next line*/
|
||||
lv_coord_t disp_w = lv_area_get_width(disp_area);
|
||||
|
||||
/*Get the width of the `draw_area` it will be used to go to the next line of the mask*/
|
||||
lv_coord_t draw_area_w = lv_area_get_width(&draw_area);
|
||||
|
||||
/*Get the width of the `mask_area` it will be used to go to the next line*/
|
||||
lv_coord_t map_w = lv_area_get_width(map_area);
|
||||
|
||||
@ -155,8 +154,23 @@ void lv_blend_map(const lv_area_t * clip_area, const lv_area_t * map_area, const
|
||||
if(mask_res == LV_DRAW_MASK_RES_FULL_COVER) {
|
||||
/*Go to the first px of the map*/
|
||||
map_buf_tmp += (draw_area.x1 - (map_area->x1 - disp_area->x1));
|
||||
|
||||
#if LV_USE_GPU
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
if(disp->driver.gpu_blend_cb &&
|
||||
((draw_area_w > GPU_WIDTH_LIMIT * 4 && opa == LV_OPA_COVER) ||
|
||||
(draw_area_w > GPU_WIDTH_LIMIT && opa != LV_OPA_COVER))) {
|
||||
for(y = draw_area.y1; y <= draw_area.y2; y++) {
|
||||
disp->driver.gpu_blend_cb(&disp->driver, &disp_buf_tmp[draw_area.x1], map_buf_tmp, draw_area_w, opa);
|
||||
disp_buf_tmp += disp_w;
|
||||
map_buf_tmp += map_w;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if(opa > LV_OPA_MAX) {
|
||||
lv_coord_t draw_area_w = lv_area_get_width(&draw_area);
|
||||
|
||||
for(y = draw_area.y1; y <= draw_area.y2; y++) {
|
||||
memcpy(&disp_buf_tmp[draw_area.x1], map_buf_tmp, draw_area_w * sizeof(lv_color_t));
|
||||
@ -170,9 +184,6 @@ void lv_blend_map(const lv_area_t * clip_area, const lv_area_t * map_area, const
|
||||
}
|
||||
/*Masked*/
|
||||
else {
|
||||
/*Get the width of the `draw_area` it will be used to go to the next line of the mask*/
|
||||
lv_coord_t draw_area_w = lv_area_get_width(&draw_area);
|
||||
|
||||
/* The mask is relative to the clipped area.
|
||||
* In the cycles below mask will be indexed from `draw_area.x1`
|
||||
* but it corresponds to zero index. So prepare `mask_tmp` accordingly. */
|
||||
@ -194,9 +205,16 @@ void lv_blend_map(const lv_area_t * clip_area, const lv_area_t * map_area, const
|
||||
for(x = draw_area.x1; x <= draw_area.x2; x++) {
|
||||
if(mask_tmp[x] == 0) continue;
|
||||
if(mask_tmp[x] != last_mask || last_dest_color.full != disp_buf_tmp[x].full || last_map_color.full != map_buf_tmp[x].full) {
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
if(disp->driver.screen_transp) {
|
||||
last_res_color = color_mix_with_alpha(disp_buf_tmp[x], disp_buf_tmp[x].ch.alpha, map_buf_tmp[x], mask_tmp[x]);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if(mask_tmp[x] > LV_OPA_MAX) last_res_color = map_buf_tmp[x];
|
||||
else if(mask_tmp[x] < LV_OPA_MIN) last_res_color = disp_buf_tmp[x];
|
||||
else last_res_color = lv_color_mix(map_buf_tmp[x], disp_buf_tmp[x], mask_tmp[x]);
|
||||
}
|
||||
last_mask = mask_tmp[x];
|
||||
last_dest_color.full = disp_buf_tmp[x].full;
|
||||
last_map_color.full = map_buf_tmp[x].full;
|
||||
@ -213,8 +231,6 @@ void lv_blend_map(const lv_area_t * clip_area, const lv_area_t * map_area, const
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -227,9 +243,14 @@ static void fill_true_color_normal(const lv_area_t * disp_area, lv_color_t * dis
|
||||
const lv_opa_t * mask, lv_draw_mask_res_t mask_res)
|
||||
{
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
|
||||
/*Get the width of the `disp_area` it will be used to go to the next line*/
|
||||
lv_coord_t disp_w = lv_area_get_width(disp_area);
|
||||
|
||||
/*Get the width of the `draw_area` it will be used to go to the next line of the mask*/
|
||||
lv_coord_t draw_area_w = lv_area_get_width(draw_area);
|
||||
|
||||
/*Create a temp. disp_buf which always point to current line to draw*/
|
||||
lv_color_t * disp_buf_tmp = disp_buf + disp_w * draw_area->y1;
|
||||
|
||||
@ -239,9 +260,16 @@ static void fill_true_color_normal(const lv_area_t * disp_area, lv_color_t * dis
|
||||
/*Simple fill (maybe with opacity), no masking*/
|
||||
if(mask_res == LV_DRAW_MASK_RES_FULL_COVER) {
|
||||
if(opa > LV_OPA_MAX) {
|
||||
lv_coord_t draw_area_w = lv_area_get_width(draw_area);
|
||||
lv_color_t * disp_buf_tmp_ori = disp_buf_tmp;
|
||||
|
||||
#if LV_USE_GPU
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
if(disp->driver.gpu_fill_cb && draw_area_w > GPU_WIDTH_LIMIT) {
|
||||
disp->driver.gpu_fill_cb(&disp->driver, disp_buf, disp_w, draw_area, color);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*Fill the first line. Use `memcpy` because it's faster then simple value assignment*/
|
||||
/*Set the first pixels manually*/
|
||||
lv_coord_t direct_fill_end = LV_MATH_MIN(draw_area->x2, draw_area->x1 + FILL_DIRECT_LEN + (draw_area_w & FILL_DIRECT_MASK) - 1);
|
||||
@ -261,14 +289,35 @@ static void fill_true_color_normal(const lv_area_t * disp_area, lv_color_t * dis
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
#if LV_USE_GPU
|
||||
if(disp->driver.gpu_blend_cb && draw_area_w > GPU_WIDTH_LIMIT) {
|
||||
static lv_color_t blend_buf[LV_HOR_RES_MAX];
|
||||
for(x = 0; x < draw_area_w ; x++) blend_buf[x].full = color.full;
|
||||
|
||||
for(y = draw_area->y1; y <= draw_area->y2; y++) {
|
||||
disp->driver.gpu_blend_cb(&disp->driver, &disp_buf_tmp[draw_area->x1], blend_buf, draw_area_w, opa);
|
||||
disp_buf_tmp += disp_w;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
lv_color_t last_dest_color = LV_COLOR_BLACK;
|
||||
lv_color_t last_res_color = lv_color_mix(color, last_dest_color, opa);
|
||||
for(y = draw_area->y1; y <= draw_area->y2; y++) {
|
||||
for(x = draw_area->x1; x <= draw_area->x2; x++) {
|
||||
if(last_dest_color.full != disp_buf_tmp[x].full) {
|
||||
last_dest_color = disp_buf_tmp[x];
|
||||
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
if(disp->driver.screen_transp) {
|
||||
last_res_color = color_mix_with_alpha(disp_buf_tmp[x], disp_buf_tmp[x].ch.alpha, color, opa);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
last_res_color = lv_color_mix(color, disp_buf_tmp[x], opa);
|
||||
}
|
||||
}
|
||||
disp_buf_tmp[x] = last_res_color;
|
||||
}
|
||||
disp_buf_tmp += disp_w;
|
||||
@ -277,9 +326,6 @@ static void fill_true_color_normal(const lv_area_t * disp_area, lv_color_t * dis
|
||||
}
|
||||
/*Masked*/
|
||||
else {
|
||||
/*Get the width of the `draw_area` it will be used to go to the next line of the mask*/
|
||||
lv_coord_t draw_area_w = lv_area_get_width(draw_area);
|
||||
|
||||
/* The mask is relative to the clipped area.
|
||||
* In the cycles below mask will be indexed from `draw_area.x1`
|
||||
* but it corresponds to zero index. So prepare `mask_tmp` accordingly. */
|
||||
@ -298,10 +344,17 @@ static void fill_true_color_normal(const lv_area_t * disp_area, lv_color_t * dis
|
||||
for(x = draw_area->x1; x <= draw_area->x2; x++) {
|
||||
if(mask_tmp[x] == 0) continue;
|
||||
if(mask_tmp[x] != last_mask || last_dest_color.full != disp_buf_tmp[x].full) {
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
if(disp->driver.screen_transp) {
|
||||
last_res_color = color_mix_with_alpha(disp_buf_tmp[x], disp_buf_tmp[x].ch.alpha, color, mask_tmp[x]);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if(mask_tmp[x] > LV_OPA_MAX) last_res_color = color;
|
||||
else if(mask_tmp[x] < LV_OPA_MIN) last_res_color = disp_buf_tmp[x];
|
||||
else if(disp_buf_tmp[x].full == color.full) last_res_color = disp_buf_tmp[x];
|
||||
else last_res_color = lv_color_mix(color, disp_buf_tmp[x], mask_tmp[x]);
|
||||
}
|
||||
last_mask = mask_tmp[x];
|
||||
last_dest_color.full = disp_buf_tmp[x].full;
|
||||
}
|
||||
@ -318,11 +371,17 @@ static void fill_true_color_normal(const lv_area_t * disp_area, lv_color_t * dis
|
||||
if(mask_tmp[x] == 0) continue;
|
||||
if(mask_tmp[x] != last_mask || last_dest_color.full != disp_buf_tmp[x].full) {
|
||||
lv_opa_t opa_tmp = (uint16_t)((uint16_t)mask_tmp[x] * opa) >> 8;
|
||||
|
||||
#if LV_COLOR_SCREEN_TRANSP
|
||||
if(disp->driver.screen_transp) {
|
||||
last_res_color = color_mix_with_alpha(disp_buf_tmp[x], disp_buf_tmp[x].ch.alpha, color, opa_tmp);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if(opa_tmp > LV_OPA_MAX) last_res_color = lv_color_mix(color, disp_buf_tmp[x], mask_tmp[x]);
|
||||
else if(opa_tmp < LV_OPA_MIN) last_res_color = disp_buf_tmp[x];
|
||||
else if(disp_buf_tmp[x].full == color.full) last_res_color = disp_buf_tmp[x];
|
||||
else last_res_color = lv_color_mix(color, disp_buf_tmp[x],opa_tmp);
|
||||
}
|
||||
last_mask = mask_tmp[x];
|
||||
last_dest_color.full = disp_buf_tmp[x].full;
|
||||
}
|
||||
@ -413,7 +472,7 @@ static void fill_true_color_blended(const lv_area_t * disp_area, lv_color_t * di
|
||||
}
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
|
||||
/**
|
||||
* Mix two colors. Both color can have alpha value. It requires ARGB888 colors.
|
||||
* @param bg_color background color
|
||||
@ -466,7 +525,6 @@ static inline lv_color_t color_mix_with_alpha(lv_color_t bg_color, lv_opa_t bg_o
|
||||
return c;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline lv_color_t color_blend_true_color_additive(lv_color_t fg, lv_color_t bg, lv_opa_t opa)
|
||||
{
|
||||
|
@ -615,13 +615,13 @@ static void lv_draw_map(const lv_area_t * map_area, const lv_area_t * clip_area,
|
||||
}
|
||||
|
||||
lv_draw_mask_res_t mask_res;
|
||||
mask_res = (alpha_byte || chroma_key) ? LV_DRAW_MASK_RES_CHANGED : LV_DRAW_MASK_RES_FULL_COVER;
|
||||
lv_coord_t x;
|
||||
lv_coord_t y;
|
||||
for(y = 0; y < lv_area_get_height(&draw_area); y++) {
|
||||
map_px = map_buf_tmp;
|
||||
px_i_start = px_i;
|
||||
|
||||
mask_res = (alpha_byte || chroma_key) ? LV_DRAW_MASK_RES_CHANGED : LV_DRAW_MASK_RES_FULL_COVER;
|
||||
for(x = 0; x < lv_area_get_width(&draw_area); x++, map_px += px_size_byte, px_i++) {
|
||||
if(alpha_byte) {
|
||||
lv_opa_t px_opa = map_px[LV_IMG_PX_SIZE_ALPHA_BYTE - 1];
|
||||
@ -636,7 +636,7 @@ static void lv_draw_map(const lv_area_t * map_area, const lv_area_t * clip_area,
|
||||
#elif LV_COLOR_DEPTH == 16
|
||||
c.full = map_px[0] + (map_px[1] << 8);
|
||||
#elif LV_COLOR_DEPTH == 32
|
||||
c.full = map_px[0] + (map_px[1] << 8) + (map_px[2] << 16);
|
||||
c.full = *((uint32_t*)map_px);
|
||||
#endif
|
||||
|
||||
if (chroma_key) {
|
||||
@ -674,6 +674,7 @@ static void lv_draw_map(const lv_area_t * map_area, const lv_area_t * clip_area,
|
||||
blend_area.y2 = blend_area.y1;
|
||||
|
||||
px_i = 0;
|
||||
mask_res = (alpha_byte || chroma_key) ? LV_DRAW_MASK_RES_CHANGED : LV_DRAW_MASK_RES_FULL_COVER;
|
||||
|
||||
/*Prepare the `mask_buf`if there are other masks*/
|
||||
if(other_mask_cnt) {
|
||||
|
@ -54,8 +54,6 @@ void lv_draw_rect(const lv_area_t * coords, const lv_area_t * clip, const lv_sty
|
||||
|
||||
draw_bg(coords, clip, style, opa_scale);
|
||||
draw_shadow(coords, clip, style, opa_scale);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**********************
|
||||
|
@ -69,7 +69,7 @@ lv_obj_t * lv_objmask_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
|
||||
/*Init the new object mask object mask*/
|
||||
if(copy == NULL) {
|
||||
lv_objmask_set_style(new_objmask, LV_OBJMASK_STYLE_BG, &lv_style_plain_color);
|
||||
lv_objmask_set_style(new_objmask, LV_OBJMASK_STYLE_BG, &lv_style_plain);
|
||||
|
||||
}
|
||||
/*Copy an existing object mask*/
|
||||
@ -158,7 +158,7 @@ static lv_design_res_t lv_objmask_design(lv_obj_t * objmask, const lv_area_t * c
|
||||
lv_draw_mask_remove_custom(objmask);
|
||||
}
|
||||
|
||||
return true;
|
||||
return LV_DESIGN_RES_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -108,7 +108,7 @@ lv_obj_t * lv_page_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
|
||||
/*Init the new page object*/
|
||||
if(copy == NULL) {
|
||||
ext->bg.masked = 1;
|
||||
ext->bg.masked = 0;
|
||||
ext->scrl = lv_cont_create(new_page, NULL);
|
||||
lv_obj_set_signal_cb(ext->scrl, lv_page_scrollable_signal);
|
||||
lv_obj_set_design_cb(ext->scrl, lv_scrl_design);
|
||||
|
Loading…
x
Reference in New Issue
Block a user