diff --git a/src/lv_draw/lv_draw_line.c b/src/lv_draw/lv_draw_line.c index 90fbcc68c..d76ce1aa1 100644 --- a/src/lv_draw/lv_draw_line.c +++ b/src/lv_draw/lv_draw_line.c @@ -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); diff --git a/src/lv_draw/lv_draw_line.h b/src/lv_draw/lv_draw_line.h index b8d54ad42..1616209d9 100644 --- a/src/lv_draw/lv_draw_line.h +++ b/src/lv_draw/lv_draw_line.h @@ -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; /********************** diff --git a/src/lv_widgets/lv_linemeter.c b/src/lv_widgets/lv_linemeter.c index c6e5f2079..505c8871a 100644 --- a/src/lv_widgets/lv_linemeter.c +++ b/src/lv_widgets/lv_linemeter.c @@ -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);