mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-28 07:03:00 +08:00
optmize line drawing
This commit is contained in:
parent
9f7365103b
commit
afcb5c70bc
@ -395,8 +395,13 @@ static void draw_line_skew(const lv_point_t * point1, const lv_point_t * point2,
|
||||
|
||||
int16_t mask_left_id = lv_draw_mask_add(&mask_left_param, NULL);
|
||||
int16_t mask_right_id = lv_draw_mask_add(&mask_right_param, NULL);
|
||||
int16_t mask_top_id = lv_draw_mask_add(&mask_top_param, NULL);
|
||||
int16_t mask_bottom_id = lv_draw_mask_add(&mask_bottom_param, NULL);
|
||||
int16_t mask_top_id = LV_MASK_ID_INV;
|
||||
int16_t mask_bottom_id = LV_MASK_ID_INV;
|
||||
|
||||
if(!dsc->raw_end) {
|
||||
mask_top_id = lv_draw_mask_add(&mask_top_param, NULL);
|
||||
mask_bottom_id = lv_draw_mask_add(&mask_bottom_param, NULL);
|
||||
}
|
||||
|
||||
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
||||
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
||||
@ -413,42 +418,54 @@ static void draw_line_skew(const lv_point_t * point1, const lv_point_t * point2,
|
||||
* It's easy to calculate with steep lines, but the area can be very wide with very flat lines.
|
||||
* So deal with it only with steep lines. */
|
||||
int32_t draw_area_w = lv_area_get_width(&draw_area);
|
||||
if(!flat) draw_area_w = LV_MATH_MIN(draw_area_w, dsc->width * 2 + 2);
|
||||
|
||||
/*Draw the background line by line*/
|
||||
int32_t h;
|
||||
lv_opa_t * mask_buf = lv_mem_buf_get(draw_area_w);
|
||||
size_t mask_buf_size = LV_MATH_MIN(lv_area_get_size(&draw_area), LV_HOR_RES_MAX);
|
||||
lv_opa_t * mask_buf = lv_mem_buf_get(mask_buf_size);
|
||||
|
||||
lv_area_t fill_area;
|
||||
fill_area.x1 = draw_area.x1 + disp_area->x1;
|
||||
fill_area.x2 = draw_area.x2 + disp_area->x1;
|
||||
fill_area.y1 = draw_area.y1 + disp_area->y1;
|
||||
fill_area.y2 = fill_area.y1;
|
||||
|
||||
lv_point_t v;
|
||||
v.x = p2.x - p1.x;
|
||||
v.y = p2.y - p1.y;
|
||||
int32_t x = vdb->area.x1 + draw_area.x1;
|
||||
|
||||
uint32_t mask_p = 0;
|
||||
|
||||
lv_memset_ff(mask_buf, mask_buf_size);
|
||||
/*Fill the first row with 'color'*/
|
||||
for(h = draw_area.y1 + disp_area->y1; h <= draw_area.y2 + disp_area->y1; h++) {
|
||||
lv_memset_ff(mask_buf, draw_area_w);
|
||||
|
||||
if(!flat) {
|
||||
/*Where is the current point?*/
|
||||
x = (v.y * p1.x - v.x * p1.y + v.x * h) / v.y - dsc->width - 1;
|
||||
if(x < draw_area.x1 + disp_area->x1) x = draw_area.x1 + disp_area->x1;
|
||||
fill_area.x1 = x;
|
||||
fill_area.x2 = fill_area.x1 + draw_area_w - 1;
|
||||
lv_draw_mask_res_t mask_res = lv_draw_mask_apply(&mask_buf[mask_p], x, h, draw_area_w);
|
||||
if(mask_res == LV_DRAW_MASK_RES_FULL_TRANSP) {
|
||||
lv_memset_00(&mask_buf[mask_p], draw_area_w);
|
||||
}
|
||||
|
||||
lv_draw_mask_res_t mask_res = lv_draw_mask_apply(mask_buf, x, h, draw_area_w);
|
||||
mask_p += draw_area_w;
|
||||
if((uint32_t) mask_p + draw_area_w < mask_buf_size) {
|
||||
fill_area.y2 ++;
|
||||
}
|
||||
else {
|
||||
lv_blend_fill(&fill_area, clip,
|
||||
dsc->color, mask_buf, LV_DRAW_MASK_RES_CHANGED, dsc->opa,
|
||||
dsc->blend_mode);
|
||||
|
||||
lv_blend_fill(clip, &fill_area,
|
||||
dsc->color, mask_buf, mask_res, opa,
|
||||
dsc->blend_mode);
|
||||
fill_area.y1 = fill_area.y2 + 1;
|
||||
fill_area.y2 = fill_area.y1;
|
||||
mask_p = 0;
|
||||
lv_memset_ff(mask_buf, mask_buf_size);
|
||||
}
|
||||
}
|
||||
|
||||
/*Flush the last part*/
|
||||
if(fill_area.y1 != fill_area.y2) {
|
||||
fill_area.y2--;
|
||||
lv_blend_fill( &fill_area, clip,
|
||||
dsc->color, mask_buf, LV_DRAW_MASK_RES_CHANGED, dsc->opa,
|
||||
dsc->blend_mode);
|
||||
|
||||
fill_area.y1++;
|
||||
fill_area.y2++;
|
||||
}
|
||||
|
||||
lv_mem_buf_release(mask_buf);
|
||||
|
@ -31,6 +31,7 @@ typedef struct {
|
||||
lv_blend_mode_t blend_mode : 2;
|
||||
uint8_t round_start : 1;
|
||||
uint8_t round_end : 1;
|
||||
uint8_t raw_end : 1; /*Do not bother with perpendicular line ending is it's not visible for any reason*/
|
||||
} lv_draw_line_dsc_t;
|
||||
|
||||
/**********************
|
||||
|
@ -55,17 +55,17 @@ lv_obj_t * lv_linemeter_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
LV_LOG_TRACE("line meter create started");
|
||||
|
||||
/*Create the ancestor of line meter*/
|
||||
lv_obj_t * new_lmeter = lv_obj_create(par, copy);
|
||||
LV_ASSERT_MEM(new_lmeter);
|
||||
if(new_lmeter == NULL) return NULL;
|
||||
lv_obj_t * linemeter = lv_obj_create(par, copy);
|
||||
LV_ASSERT_MEM(linemeter);
|
||||
if(linemeter == NULL) return NULL;
|
||||
|
||||
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_lmeter);
|
||||
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(linemeter);
|
||||
|
||||
/*Allocate the line meter type specific extended data*/
|
||||
lv_linemeter_ext_t * ext = lv_obj_allocate_ext_attr(new_lmeter, sizeof(lv_linemeter_ext_t));
|
||||
lv_linemeter_ext_t * ext = lv_obj_allocate_ext_attr(linemeter, sizeof(lv_linemeter_ext_t));
|
||||
LV_ASSERT_MEM(ext);
|
||||
if(ext == NULL) {
|
||||
lv_obj_del(new_lmeter);
|
||||
lv_obj_del(linemeter);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -78,13 +78,13 @@ lv_obj_t * lv_linemeter_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
ext->angle_ofs = 0;
|
||||
|
||||
/*The signal and design functions are not copied so set them here*/
|
||||
lv_obj_set_signal_cb(new_lmeter, lv_linemeter_signal);
|
||||
lv_obj_set_design_cb(new_lmeter, lv_linemeter_design);
|
||||
lv_obj_set_signal_cb(linemeter, lv_linemeter_signal);
|
||||
lv_obj_set_design_cb(linemeter, lv_linemeter_design);
|
||||
|
||||
/*Init the new line meter line meter*/
|
||||
if(copy == NULL) {
|
||||
lv_obj_set_size(new_lmeter, LV_DPI, LV_DPI);
|
||||
lv_theme_apply(new_lmeter, LV_THEME_LINEMETER);
|
||||
lv_obj_set_size(linemeter, LV_DPI, LV_DPI);
|
||||
lv_theme_apply(linemeter, LV_THEME_LINEMETER);
|
||||
}
|
||||
/*Copy an existing line meter*/
|
||||
else {
|
||||
@ -95,13 +95,13 @@ lv_obj_t * lv_linemeter_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
ext->max_value = copy_ext->max_value;
|
||||
ext->cur_value = copy_ext->cur_value;
|
||||
|
||||
// /*Refresh the style with new signal function*/
|
||||
// lv_obj_refresh_style(new_lmeter);
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(linemeter, LV_STYLE_PROP_ALL);
|
||||
}
|
||||
|
||||
LV_LOG_INFO("line meter created");
|
||||
|
||||
return new_lmeter;
|
||||
return linemeter;
|
||||
}
|
||||
|
||||
/*=====================
|
||||
@ -293,6 +293,7 @@ void lv_linemeter_draw_scale(lv_obj_t * lmeter, const lv_area_t * clip_area, uin
|
||||
lv_draw_line_dsc_t line_dsc;
|
||||
lv_draw_line_dsc_init(&line_dsc);
|
||||
lv_obj_init_draw_line_dsc(lmeter, part, &line_dsc);
|
||||
line_dsc.raw_end = 1;
|
||||
|
||||
lv_style_int_t end_line_width = lv_obj_get_style_scale_end_line_width(lmeter, part);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user