From cc060e81b44887fc6e3ec438fa3cc9bbcbdea1ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Costa?= Date: Mon, 6 Oct 2025 09:39:02 +0200 Subject: [PATCH] fix(draw): fix render issue when triangle overhangs by sorting points (#9002) --- src/draw/sw/lv_draw_sw_triangle.c | 4 +- tests/ref_imgs/widgets/canvas_2.png | Bin 0 -> 11656 bytes tests/ref_imgs_vg_lite/widgets/canvas_2.png | Bin 0 -> 6951 bytes tests/src/test_cases/widgets/test_canvas.c | 190 ++++++++++++++++++++ 4 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 tests/ref_imgs/widgets/canvas_2.png create mode 100644 tests/ref_imgs_vg_lite/widgets/canvas_2.png diff --git a/src/draw/sw/lv_draw_sw_triangle.c b/src/draw/sw/lv_draw_sw_triangle.c index 8d7a4b119f..0cfc36d889 100644 --- a/src/draw/sw/lv_draw_sw_triangle.c +++ b/src/draw/sw/lv_draw_sw_triangle.c @@ -88,8 +88,10 @@ void lv_draw_sw_triangle(lv_draw_task_t * t, const lv_draw_triangle_dsc_t * dsc) if(p[1].y < p[2].y) lv_point_swap(&p[1], &p[2]); } - /*Be sure p[0] is on the top*/ + /*Be sure p[0] is on top followed by lowest point (p[1]) and middle point last (p[2])*/ + if(p[0].y > p[2].y) lv_point_swap(&p[0], &p[2]); if(p[0].y > p[1].y) lv_point_swap(&p[0], &p[1]); + if(p[1].y < p[2].y) lv_point_swap(&p[1], &p[2]); /*If right == true p[2] is on the right side of the p[0] p[1] line*/ bool right = ((p[1].x - p[0].x) * (p[2].y - p[0].y) - (p[1].y - p[0].y) * (p[2].x - p[0].x)) < 0; diff --git a/tests/ref_imgs/widgets/canvas_2.png b/tests/ref_imgs/widgets/canvas_2.png new file mode 100644 index 0000000000000000000000000000000000000000..a06b3c35a3e2559b6d96dd028d461a1f92ea5f98 GIT binary patch literal 11656 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 literal 0 HcmV?d00001 diff --git a/tests/src/test_cases/widgets/test_canvas.c b/tests/src/test_cases/widgets/test_canvas.c index ea9b51b326..f0d4123953 100644 --- a/tests/src/test_cases/widgets/test_canvas.c +++ b/tests/src/test_cases/widgets/test_canvas.c @@ -168,4 +168,194 @@ void test_canvas_fill_and_set_px(void) TEST_ASSERT_EQUAL_SCREENSHOT("widgets/canvas_1.png"); } +void test_canvas_triangles(void) +{ + lv_obj_t * canvas = lv_canvas_create(lv_screen_active()); + lv_obj_center(canvas); + + LV_DRAW_BUF_DEFINE_STATIC(buf, 500, 500, LV_COLOR_FORMAT_RGB888); + LV_DRAW_BUF_INIT_STATIC(buf); + canvas_draw_buf_reshape(&buf); + lv_canvas_set_draw_buf(canvas, &buf); + + lv_layer_t layer; + lv_canvas_init_layer(canvas, &layer); + lv_canvas_fill_bg(canvas, lv_color_hex(0xAFAFAF), LV_OPA_COVER); + + { + /* 1. Right-angled with vertical side on left (bottom-left corner at right angle) */ + lv_draw_triangle_dsc_t tri_dsc; + lv_draw_triangle_dsc_init(&tri_dsc); + tri_dsc.color = lv_color_hex(0xff0000); + tri_dsc.p[0].x = 50; + tri_dsc.p[0].y = 50; + tri_dsc.p[1].x = 50; + tri_dsc.p[1].y = 100; + tri_dsc.p[2].x = 100; + tri_dsc.p[2].y = 100; + lv_draw_triangle(&layer, &tri_dsc); + } + + { + /* 2. Right-angled with vertical side on right (bottom-right corner at right angle) */ + lv_draw_triangle_dsc_t tri_dsc; + lv_draw_triangle_dsc_init(&tri_dsc); + tri_dsc.color = lv_color_hex(0x00ff00); + tri_dsc.p[0].x = 150; + tri_dsc.p[0].y = 50; + tri_dsc.p[1].x = 200; + tri_dsc.p[1].y = 50; + tri_dsc.p[2].x = 200; + tri_dsc.p[2].y = 100; + lv_draw_triangle(&layer, &tri_dsc); + } + + { + /* 3. Pointing up (no vertical sides) */ + lv_draw_triangle_dsc_t tri_dsc; + lv_draw_triangle_dsc_init(&tri_dsc); + tri_dsc.color = lv_color_hex(0x0000ff); + tri_dsc.p[0].x = 250; + tri_dsc.p[0].y = 50; + tri_dsc.p[1].x = 230; + tri_dsc.p[1].y = 100; + tri_dsc.p[2].x = 270; + tri_dsc.p[2].y = 100; + lv_draw_triangle(&layer, &tri_dsc); + } + + { + /* 4. Pointing down (no vertical sides) */ + lv_draw_triangle_dsc_t tri_dsc; + lv_draw_triangle_dsc_init(&tri_dsc); + tri_dsc.color = lv_color_hex(0xffff00); + tri_dsc.p[0].x = 350; + tri_dsc.p[0].y = 50; + tri_dsc.p[1].x = 390; + tri_dsc.p[1].y = 50; + tri_dsc.p[2].x = 370; + tri_dsc.p[2].y = 100; + lv_draw_triangle(&layer, &tri_dsc); + } + + { + /* 5. Pointing left (no vertical sides) */ + lv_draw_triangle_dsc_t tri_dsc; + lv_draw_triangle_dsc_init(&tri_dsc); + tri_dsc.color = lv_color_hex(0xff00ff); + tri_dsc.p[0].x = 50; + tri_dsc.p[0].y = 150; + tri_dsc.p[1].x = 100; + tri_dsc.p[1].y = 130; + tri_dsc.p[2].x = 100; + tri_dsc.p[2].y = 170; + lv_draw_triangle(&layer, &tri_dsc); + } + + { + /* 6. Pointing right (no vertical sides) */ + lv_draw_triangle_dsc_t tri_dsc; + lv_draw_triangle_dsc_init(&tri_dsc); + tri_dsc.color = lv_color_hex(0x00ffff); + tri_dsc.p[0].x = 150; + tri_dsc.p[0].y = 130; + tri_dsc.p[1].x = 150; + tri_dsc.p[1].y = 170; + tri_dsc.p[2].x = 200; + tri_dsc.p[2].y = 150; + lv_draw_triangle(&layer, &tri_dsc); + } + + { + /* 7. Obtuse triangle (one angle > 90°) */ + lv_draw_triangle_dsc_t tri_dsc; + lv_draw_triangle_dsc_init(&tri_dsc); + tri_dsc.color = lv_color_hex(0x800080); + tri_dsc.p[0].x = 250; + tri_dsc.p[0].y = 150; + tri_dsc.p[1].x = 300; + tri_dsc.p[1].y = 140; + tri_dsc.p[2].x = 280; + tri_dsc.p[2].y = 180; + lv_draw_triangle(&layer, &tri_dsc); + } + + { + /* 8. Acute equilateral-ish triangle */ + lv_draw_triangle_dsc_t tri_dsc; + lv_draw_triangle_dsc_init(&tri_dsc); + tri_dsc.color = lv_color_hex(0xffa500); + tri_dsc.p[0].x = 350; + tri_dsc.p[0].y = 150; + tri_dsc.p[1].x = 330; + tri_dsc.p[1].y = 180; + tri_dsc.p[2].x = 370; + tri_dsc.p[2].y = 180; + lv_draw_triangle(&layer, &tri_dsc); + } + + { + /* 9. Very flat wide triangle (horizontal base) */ + lv_draw_triangle_dsc_t tri_dsc; + lv_draw_triangle_dsc_init(&tri_dsc); + tri_dsc.color = lv_color_hex(0x008000); + tri_dsc.p[0].x = 100; + tri_dsc.p[0].y = 250; + tri_dsc.p[1].x = 50; + tri_dsc.p[1].y = 280; + tri_dsc.p[2].x = 150; + tri_dsc.p[2].y = 280; + lv_draw_triangle(&layer, &tri_dsc); + } + + { + /* 10. Tall thin triangle */ + lv_draw_triangle_dsc_t tri_dsc; + lv_draw_triangle_dsc_init(&tri_dsc); + tri_dsc.color = lv_color_hex(0x000080); + tri_dsc.p[0].x = 250; + tri_dsc.p[0].y = 230; + tri_dsc.p[1].x = 240; + tri_dsc.p[1].y = 290; + tri_dsc.p[2].x = 260; + tri_dsc.p[2].y = 290; + lv_draw_triangle(&layer, &tri_dsc); + } + + { + /* 11. Y value of last point is the biggest one */ + lv_draw_triangle_dsc_t tri_dsc; + lv_draw_triangle_dsc_init(&tri_dsc); + tri_dsc.color = lv_color_hex(0x800000); + + tri_dsc.p[0].x = 350; + tri_dsc.p[0].y = 230; + + tri_dsc.p[1].x = 350; + tri_dsc.p[1].y = 280; + tri_dsc.p[2].x = 390; + tri_dsc.p[2].y = 290; + lv_draw_triangle(&layer, &tri_dsc); + } + { + /* 12. Y value of last point is the smallest one */ + lv_draw_triangle_dsc_t tri_dsc; + lv_draw_triangle_dsc_init(&tri_dsc); + tri_dsc.color = lv_color_hex(0x808000); + + tri_dsc.p[0].x = 100; + tri_dsc.p[0].y = 350; + + tri_dsc.p[1].x = 100; + tri_dsc.p[1].y = 400; + tri_dsc.p[2].x = 150; + tri_dsc.p[2].y = 320; + lv_draw_triangle(&layer, &tri_dsc); + } + + lv_canvas_finish_layer(canvas, &layer); + + TEST_ASSERT_EQUAL_SCREENSHOT("widgets/canvas_2.png"); +} + #endif