diff --git a/src/lv_draw/lv_draw_arc.c b/src/lv_draw/lv_draw_arc.c index 4ae1f66a3..7b10df6f8 100644 --- a/src/lv_draw/lv_draw_arc.c +++ b/src/lv_draw/lv_draw_arc.c @@ -47,7 +47,6 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, const lv_area_t * clip_area, uint16_t start_angle, uint16_t end_angle, const lv_style_t * style, lv_opa_t opa_scale) { - lv_style_t circle_style; lv_style_copy(&circle_style, style); circle_style.body.radius = LV_RADIUS_CIRCLE; @@ -55,7 +54,6 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, cons circle_style.body.border.width = style->line.width; circle_style.body.border.color = style->line.color; - lv_draw_mask_param_t mask_angle_param; lv_draw_mask_angle_init(&mask_angle_param, center_x, center_y, start_angle, end_angle); @@ -71,6 +69,10 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, cons lv_draw_mask_remove_id(mask_angle_id); + if(style->line.rounded) { + /*TODO*/ + } + } diff --git a/src/lv_draw/lv_draw_triangle.c b/src/lv_draw/lv_draw_triangle.c index 48e3c8c07..9615555c7 100644 --- a/src/lv_draw/lv_draw_triangle.c +++ b/src/lv_draw/lv_draw_triangle.c @@ -87,7 +87,7 @@ void lv_draw_triangle(const lv_point_t * points, const lv_area_t * clip, const l break; } - if(points[i_right].x < points[y_min_i].x) { + if(points[i_right].x < points[i_left].x) { int8_t tmp; tmp = i_right; i_right = i_left; @@ -137,23 +137,113 @@ void lv_draw_triangle(const lv_point_t * points, const lv_area_t * clip, const l * @param style style of the polygon * @param opa_scale scale down all opacities by the factor (0..255) */ -void lv_draw_polygon(const lv_point_t * points, uint32_t point_cnt, const lv_area_t * mask, const lv_style_t * style, +void lv_draw_polygon(const lv_point_t * points, uint16_t point_cnt, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale) { if(point_cnt < 3) return; if(points == NULL) return; - uint32_t i; - lv_point_t tri[3]; - tri[0].x = points[0].x; - tri[0].y = points[0].y; - for(i = 0; i < point_cnt - 1; i++) { - tri[1].x = points[i].x; - tri[1].y = points[i].y; - tri[2].x = points[i + 1].x; - tri[2].y = points[i + 1].y; - lv_draw_triangle(tri, mask, style, opa_scale); + int16_t i; + lv_area_t poly_mask = {.x1 = LV_COORD_MAX, .y1 = LV_COORD_MAX, .x2 = LV_COORD_MIN, .y2 = LV_COORD_MIN}; + + for(i = 0; i < point_cnt; i++) { + poly_mask.x1 = LV_MATH_MIN(poly_mask.x1, points[i].x); + poly_mask.y1 = LV_MATH_MIN(poly_mask.y1, points[i].y); + poly_mask.x2 = LV_MATH_MAX(poly_mask.x2, points[i].x); + poly_mask.y2 = LV_MATH_MAX(poly_mask.y2, points[i].y); } + + + bool is_common; + is_common = lv_area_intersect(&poly_mask, &poly_mask, mask); + if(!is_common) return; + + /*Find the lowest point*/ + lv_coord_t y_min = points[0].y; + int16_t y_min_i = 0; + + for(i = 1; i < point_cnt; i++) { + if(points[i].y < y_min) { + y_min = points[i].y; + y_min_i = i; + } + } + + + lv_draw_mask_param_t * mp = lv_draw_buf_get(sizeof(lv_draw_mask_param_t) * point_cnt); + lv_draw_mask_param_t * mp_next = mp; + + int32_t i_prev_left = y_min_i; + int32_t i_prev_right = y_min_i; + int32_t i_next_left; + int32_t i_next_right; + uint32_t mask_cnt = 0; + + /* Check if the order of points is inverted or not. + * The normal case is when the left point is on `y_min_i - 1`*/ + i_next_left = y_min_i - 1; + if(i_next_left < 0) i_next_left = point_cnt + i_next_left; + + i_next_right = y_min_i + 1; + if(i_next_right > point_cnt - 1) i_next_right = 0; + + bool inv = false; + if(points[i_next_left].x > points[i_next_right].x && points[i_next_left].y < points[i_next_right].y) inv = true; + + do { + if(!inv) { + i_next_left = i_prev_left - 1; + if(i_next_left < 0) i_next_left = point_cnt + i_next_left; + + i_next_right = i_prev_right + 1; + if(i_next_right > point_cnt - 1) i_next_right = 0; + } else { + i_next_left = i_prev_left + 1; + if(i_next_left > point_cnt - 1) i_next_left = 0; + + i_next_right = i_prev_right - 1; + if(i_next_right < 0) i_next_right = point_cnt + i_next_right; + } + + if(points[i_next_left].y >= points[i_prev_left].y) { + if(points[i_next_left].y != points[i_prev_left].y && + points[i_next_left].x != points[i_prev_left].x) { + lv_draw_mask_line_points_init(mp_next, points[i_prev_left].x, points[i_prev_left].y, + points[i_next_left].x, points[i_next_left].y, + LV_DRAW_MASK_LINE_SIDE_RIGHT); + lv_draw_mask_add(mp_next, mp); + mp_next++; + } + mask_cnt++; + i_prev_left = i_next_left; + } + + if(mask_cnt == point_cnt) break; + + if(points[i_next_right].y >= points[i_prev_right].y) { + if(points[i_next_right].y != points[i_prev_right].y && + points[i_next_right].x != points[i_prev_right].x) { + + lv_draw_mask_line_points_init(mp_next, points[i_prev_right].x, points[i_prev_right].y, + points[i_next_right].x, points[i_next_right].y, + LV_DRAW_MASK_LINE_SIDE_LEFT); + lv_draw_mask_add(mp_next, mp); + mp_next++; + } + mask_cnt++; + i_prev_right = i_next_right; + } + + }while( mask_cnt < point_cnt); + + + + lv_draw_rect(&poly_mask, &poly_mask, style, opa_scale); + + lv_draw_mask_remove_custom(mp); + + lv_draw_buf_release(mp); + } /********************** diff --git a/src/lv_draw/lv_draw_triangle.h b/src/lv_draw/lv_draw_triangle.h index fa8a79466..b5c76522e 100644 --- a/src/lv_draw/lv_draw_triangle.h +++ b/src/lv_draw/lv_draw_triangle.h @@ -44,7 +44,7 @@ void lv_draw_triangle(const lv_point_t * points, const lv_area_t * clip, const l * @param style style of the polygon * @param opa_scale scale down all opacities by the factor (0..255) */ -void lv_draw_polygon(const lv_point_t * points, uint32_t point_cnt, const lv_area_t * mask, const lv_style_t * style, +void lv_draw_polygon(const lv_point_t * points, uint16_t point_cnt, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa_scale); /**********************