diff --git a/src/lv_draw/lv_draw_triangle.c b/src/lv_draw/lv_draw_triangle.c index d786566df..278481959 100644 --- a/src/lv_draw/lv_draw_triangle.c +++ b/src/lv_draw/lv_draw_triangle.c @@ -12,7 +12,13 @@ /********************* * DEFINES *********************/ - +/* Draw the tall rectangles from vertical lines + * and from the flat triangles from horizontal lines + * to minimize the number of lines. + * It's still not perfect because some pixels on the edges are overdrawn. + * (Looks fine LV_OPA_COVER) + */ +#define FLAT_TALL_OPTIMIZED 0 /********************** * TYPEDEFS **********************/ @@ -24,7 +30,9 @@ /********************** * STATIC VARIABLES **********************/ +#if FLAT_TALL_OPTIMIZED void tri_draw_flat(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa); +#endif void tri_draw_tall(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa); static void point_swap(lv_point_t * p1, lv_point_t * p2); @@ -47,6 +55,7 @@ void lv_draw_triangle(const lv_point_t * points, const lv_area_t * mask, const l lv_opa_t opa_scale) { + opa_scale = LV_OPA_50; /*Return is the triangle is degenerated*/ if(points[0].x == points[1].x && points[0].y == points[1].y) return; if(points[1].x == points[2].x && points[1].y == points[2].y) return; @@ -59,37 +68,32 @@ void lv_draw_triangle(const lv_point_t * points, const lv_area_t * mask, const l ? style->body.opa : (uint16_t)((uint16_t)style->body.opa * opa_scale) >> 8; +#if FLAT_TALL_OPTIMIZED == 0 + tri_draw_tall(points, mask, style, opa); +#else /*Is the triangle flat or tall?*/ lv_coord_t x_min = LV_MATH_MIN(LV_MATH_MIN(points[0].x, points[1].x), points[2].x); lv_coord_t x_max = LV_MATH_MAX(LV_MATH_MAX(points[0].x, points[1].x), points[2].x); lv_coord_t y_min = LV_MATH_MIN(LV_MATH_MIN(points[0].y, points[1].y), points[2].y); lv_coord_t y_max = LV_MATH_MAX(LV_MATH_MAX(points[0].y, points[1].y), points[2].y); - - static lv_color_t c = LV_COLOR_BLACK; - c.full += 0xAA234; - lv_style_t style_tmp; - lv_style_copy(&style_tmp, style); -// style_tmp.body.main_color = c; - - /* If smaller in x then it's tall. * Draw from horizontal lines*/ if(x_max - x_min < y_max - y_min) { - style_tmp.body.main_color = LV_COLOR_RED; - tri_draw_tall(points, mask, &style_tmp, opa); + tri_draw_tall(points, mask, style, opa); } /*Else flat so draw from vertical lines*/ else { - style_tmp.body.main_color = LV_COLOR_BLUE; - tri_draw_flat(points, mask, &style_tmp, opa); + tri_draw_flat(points, mask, style, opa); } +#endif } /********************** * STATIC FUNCTIONS **********************/ +#if FLAT_TALL_OPTIMIZED void tri_draw_flat(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa) { /*Return if the points are out of the mask*/ @@ -162,9 +166,9 @@ void tri_draw_flat(const lv_point_t * points, const lv_area_t * mask, const lv_s /* Get the area of a line. * Adjust it a little bit to perfectly match (no redrawn pixels) with the adjacent triangles*/ draw_area.x1 = LV_MATH_MIN(act_area.x1, act_area.x2); - draw_area.x2 = LV_MATH_MAX(act_area.x1, act_area.x2) - 1; - draw_area.y1 = LV_MATH_MIN(act_area.y1, act_area.y2) - 1; - draw_area.y2 = LV_MATH_MAX(act_area.y1, act_area.y2) - 1; + draw_area.x2 = LV_MATH_MAX(act_area.x1, act_area.x2) - (FLAT_TALL_OPTIMIZED == 0 ? 1 : 0); + draw_area.y1 = LV_MATH_MIN(act_area.y1, act_area.y2); + draw_area.y2 = LV_MATH_MAX(act_area.y1, act_area.y2); lv_draw_fill(&draw_area, mask, style->body.main_color, opa); @@ -178,8 +182,9 @@ void tri_draw_flat(const lv_point_t * points, const lv_area_t * mask, const lv_s dy1 = LV_MATH_ABS(tri[1].y - tri[2].y); sy1 = tri[1].y < tri[2].y ? 1 : -1; err1 = (dx1 > dy1 ? dx1 : -dy1) / 2; - } else if(edge1.x == tri[2].x && edge1.y == tri[2].y) + } else if(edge1.x == tri[2].x && edge1.y == tri[2].y) { return; + } err_tmp1 = err1; if(err_tmp1 > -dx1) { err1 -= dy1; @@ -194,7 +199,7 @@ void tri_draw_flat(const lv_point_t * points, const lv_area_t * mask, const lv_s /*Calc. the next point of edge2*/ y2_tmp = edge2.y; do { - if(edge2.x == tri[2].x && edge2.y == tri[2].y) return; + if(edge2.x == tri[2].x && edge2.y == tri[2].y) return; err_tmp2 = err2; if(err_tmp2 > -dx2) { err2 -= dy2; @@ -207,7 +212,7 @@ void tri_draw_flat(const lv_point_t * points, const lv_area_t * mask, const lv_s } while(edge2.y == y2_tmp); } } - +#endif void tri_draw_tall(const lv_point_t * points, const lv_area_t * mask, const lv_style_t * style, lv_opa_t opa) { @@ -266,7 +271,7 @@ void tri_draw_tall(const lv_point_t * points, const lv_area_t * mask, const lv_s draw_area.x1 = LV_MATH_MIN(act_area.x1, act_area.x2); draw_area.x2 = LV_MATH_MAX(act_area.x1, act_area.x2); draw_area.y1 = LV_MATH_MIN(act_area.y1, act_area.y2); - draw_area.y2 = LV_MATH_MAX(act_area.y1, act_area.y2) - 1; + draw_area.y2 = LV_MATH_MAX(act_area.y1, act_area.y2) - (FLAT_TALL_OPTIMIZED == 0 ? 1 : 0); lv_draw_fill(&draw_area, mask, style->body.main_color, opa); @@ -280,8 +285,9 @@ void tri_draw_tall(const lv_point_t * points, const lv_area_t * mask, const lv_s dy1 = LV_MATH_ABS(tri[1].y - tri[2].y); sy1 = tri[1].y < tri[2].y ? 1 : -1; err1 = (dx1 > dy1 ? dx1 : -dy1) / 2; - } else if(edge1.y == tri[2].y && edge1.x == tri[2].x) + } else if(edge1.y == tri[2].y && edge1.x == tri[2].x) { return; + } err_tmp1 = err1; if(err_tmp1 > -dx1) { err1 -= dy1; @@ -296,7 +302,10 @@ void tri_draw_tall(const lv_point_t * points, const lv_area_t * mask, const lv_s /*Calc. the next point of edge2*/ x2_tmp = edge2.x; do { - if(edge2.y == tri[2].y && edge2.x == tri[2].x) return; + if(edge2.y == tri[2].y && edge2.x == tri[2].x) { + return; + } + err_tmp2 = err2; if(err_tmp2 > -dx2) { err2 -= dy2;