1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

add dashed line support to horizontal and vertical lines

This commit is contained in:
Gabor Kiss-Vamosi 2020-01-15 00:08:29 +01:00
parent 4f33b531b4
commit 533b949595
5 changed files with 64 additions and 10 deletions

View File

@ -2708,6 +2708,11 @@ void lv_obj_init_draw_line_dsc(lv_obj_t * obj, uint8_t part, lv_draw_line_dsc_t
draw_dsc->color = lv_obj_get_style_color(obj, part, LV_STYLE_LINE_COLOR);
draw_dsc->blend_mode = lv_obj_get_style_int(obj, part, LV_STYLE_LINE_BLEND_MODE);
draw_dsc->dash_width = lv_obj_get_style_int(obj, part, LV_STYLE_LINE_DASH_WIDTH);
if(draw_dsc->dash_width) {
draw_dsc->dash_gap = lv_obj_get_style_int(obj, part, LV_STYLE_LINE_DASH_GAP);
}
}
/**

View File

@ -124,6 +124,8 @@ enum {
LV_STYLE_PROP_INIT(LV_STYLE_LINE_WIDTH, 0x7, LV_STYLE_ID_VALUE + 0, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_LINE_BLEND_MODE, 0x7, LV_STYLE_ID_VALUE + 1, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_LINE_DASH_WIDTH, 0x7, LV_STYLE_ID_VALUE + 2, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_LINE_DASH_GAP, 0x7, LV_STYLE_ID_VALUE + 3, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_LINE_COLOR, 0x7, LV_STYLE_ID_COLOR + 0, LV_STYLE_ATTR_NONE),
LV_STYLE_PROP_INIT(LV_STYLE_LINE_OPA, 0x7, LV_STYLE_ID_OPA + 0, LV_STYLE_ATTR_NONE),

View File

@ -123,8 +123,11 @@ static void draw_line_hor(const lv_point_t * point1, const lv_point_t * point2,
lv_coord_t w_half0 = w >> 1;
lv_coord_t w_half1 = w_half0 + (w & 0x1); /*Compensate rounding error*/
bool dashed = dsc->dash_gap && dsc->dash_width ? true : false;
int16_t other_mask_cnt = lv_draw_mask_get_cnt();
bool simple_mode = true;
if(lv_draw_mask_get_cnt()) simple_mode = false;
else if(dashed) simple_mode = false;
lv_area_t draw_area;
draw_area.x1 = LV_MATH_MIN(point1->x, point2->x);
@ -133,7 +136,7 @@ static void draw_line_hor(const lv_point_t * point1, const lv_point_t * point2,
draw_area.y2 = point1->y + w_half0;
/*If there is no mask then simply draw a rectangle*/
if(other_mask_cnt == 0) {
if(simple_mode) {
lv_blend_fill(clip, &draw_area,
dsc->color, NULL, LV_DRAW_MASK_RES_FULL_COVER,opa,
LV_BLEND_MODE_NORMAL);
@ -148,10 +151,10 @@ static void draw_line_hor(const lv_point_t * point1, const lv_point_t * point2,
/* Now `draw_area` has absolute coordinates.
* Make it relative to `disp_area` to simplify draw to `disp_buf`*/
draw_area.x1 -= vdb->area.x1;
draw_area.y1 -= vdb->area.y1;
draw_area.x2 -= vdb->area.x1;
draw_area.y2 -= vdb->area.y1;
draw_area.x1 -= disp_area->x1;
draw_area.y1 -= disp_area->y1;
draw_area.x2 -= disp_area->x1;
draw_area.y2 -= disp_area->y1;
lv_coord_t draw_area_w = lv_area_get_width(&draw_area);
@ -161,6 +164,8 @@ static void draw_line_hor(const lv_point_t * point1, const lv_point_t * point2,
fill_area.y1 = draw_area.y1 + disp_area->y1;
fill_area.y2 = fill_area.y1;
lv_style_int_t dash_start = (vdb->area.x1 + draw_area.x1) % (dsc->dash_gap + dsc->dash_width);
lv_opa_t * mask_buf = lv_mem_buf_get(draw_area_w);
lv_coord_t h;
lv_draw_mask_res_t mask_res;
@ -168,6 +173,26 @@ static void draw_line_hor(const lv_point_t * point1, const lv_point_t * point2,
memset(mask_buf, LV_OPA_COVER, draw_area_w);
mask_res = lv_draw_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w);
if(dashed) {
if(mask_res != LV_DRAW_MASK_RES_FULL_TRANSP) {
lv_style_int_t dash_cnt = dash_start;
uint32_t i;
for(i = 0; i < draw_area_w; i++, dash_cnt++) {
if(dash_cnt <= dsc->dash_width) {
int16_t diff = dsc->dash_width - dash_cnt;
i += diff;
dash_cnt += diff;
} else if(dash_cnt >= dsc->dash_gap + dsc->dash_width) {
dash_cnt = 0;
} else {
mask_buf[i] = 0x00;
}
}
mask_res = LV_DRAW_MASK_RES_CHANGED;
}
}
lv_blend_fill(clip, &fill_area,
dsc->color, mask_buf, mask_res, dsc->opa,
dsc->blend_mode);
@ -193,8 +218,11 @@ static void draw_line_ver(const lv_point_t * point1, const lv_point_t * point2,
lv_coord_t w_half0 = w >> 1;
lv_coord_t w_half1 = w_half0 + (w & 0x1); /*Compensate rounding error*/
bool dashed = dsc->dash_gap && dsc->dash_width ? true : false;
int16_t other_mask_cnt = lv_draw_mask_get_cnt();
bool simple_mode = true;
if(lv_draw_mask_get_cnt()) simple_mode = false;
else if(dashed) simple_mode = false;
lv_area_t draw_area;
draw_area.x1 = point1->x - w_half1;
@ -203,8 +231,7 @@ static void draw_line_ver(const lv_point_t * point1, const lv_point_t * point2,
draw_area.y2 = LV_MATH_MAX(point1->y, point2->y) - 1;
/*If there is no mask then simply draw a rectangle*/
if(other_mask_cnt == 0) {
if(simple_mode) {
lv_blend_fill(clip, &draw_area,
dsc->color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa,
dsc->blend_mode);
@ -233,12 +260,29 @@ static void draw_line_ver(const lv_point_t * point1, const lv_point_t * point2,
fill_area.y2 = fill_area.y1;
lv_opa_t * mask_buf = lv_mem_buf_get(draw_area_w);
lv_style_int_t dash_start = (vdb->area.y1 + draw_area.y1) % (dsc->dash_gap + dsc->dash_width);
lv_style_int_t dash_cnt = dash_start;
lv_coord_t h;
lv_draw_mask_res_t mask_res;
for(h = draw_area.y1; h <= draw_area.y2; h++) {
memset(mask_buf, LV_OPA_COVER, draw_area_w);
mask_res = lv_draw_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w);
if(dashed) {
if(mask_res != LV_DRAW_MASK_RES_FULL_TRANSP) {
if(dash_cnt > dsc->dash_width) {
mask_res = LV_DRAW_MASK_RES_FULL_TRANSP;
}
if(dash_cnt >= dsc->dash_gap + dsc->dash_width) {
dash_cnt = 0;
}
}
dash_cnt ++;
}
lv_blend_fill(clip, &fill_area,
dsc->color, mask_buf, mask_res, dsc->opa,
LV_BLEND_MODE_NORMAL);

View File

@ -24,8 +24,10 @@ extern "C" {
typedef struct {
lv_color_t color;
lv_style_int_t width;
lv_style_int_t dash_width;
lv_style_int_t dash_gap;
lv_opa_t opa;
lv_blend_mode_t blend_mode;
lv_blend_mode_t blend_mode :2;
uint8_t round_start :1;
uint8_t round_end :1;
}lv_draw_line_dsc_t;

View File

@ -91,6 +91,7 @@ static void basic_init(void)
lv_style_set_opa(&scr, LV_STYLE_BG_OPA, LV_OPA_COVER);
lv_style_set_color(&scr, LV_STYLE_BG_COLOR, LV_COLOR_MAKE(0x20, 0x20, 0x20));
lv_style_set_color(&scr, LV_STYLE_TEXT_COLOR , LV_COLOR_GRAY);
lv_style_set_int(&scr, LV_STYLE_LINE_WIDTH, 2);
lv_style_init(&transp);
lv_style_set_opa(&transp, LV_STYLE_BG_OPA, LV_OPA_TRANSP);