From 236c7ad6259f2029a14115898dea41d72a641006 Mon Sep 17 00:00:00 2001 From: Liam Howatt <30486941+liamHowatt@users.noreply.github.com> Date: Thu, 6 Feb 2025 07:28:01 -0500 Subject: [PATCH] fix(area): lv_area_diff remove overlap (#7696) --- src/misc/lv_area.c | 8 ++-- tests/src/test_cases/test_area.c | 69 ++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 4 deletions(-) diff --git a/src/misc/lv_area.c b/src/misc/lv_area.c index 4410076d6..215002c16 100644 --- a/src/misc/lv_area.c +++ b/src/misc/lv_area.c @@ -130,7 +130,7 @@ int8_t lv_area_diff(lv_area_t res_p[], const lv_area_t * a1_p, const lv_area_t * n.x1 = a1_p->x1; n.y1 = a1_p->y1; n.x2 = a1_p->x2; - n.y2 = a1_p->y1 + th; + n.y2 = a1_p->y1 + th - 1; res_p[res_c++] = n; } @@ -138,7 +138,7 @@ int8_t lv_area_diff(lv_area_t res_p[], const lv_area_t * a1_p, const lv_area_t * int32_t bh = a1_h - (a2_p->y2 - a1_p->y1); if(bh > 0 && a2_p->y2 < a1_p->y2) { n.x1 = a1_p->x1; - n.y1 = a2_p->y2; + n.y1 = a2_p->y2 + 1; n.x2 = a1_p->x2; n.y2 = a2_p->y2 + bh; res_p[res_c++] = n; @@ -154,7 +154,7 @@ int8_t lv_area_diff(lv_area_t res_p[], const lv_area_t * a1_p, const lv_area_t * if(lw > 0 && sh > 0) { n.x1 = a1_p->x1; n.y1 = y1; - n.x2 = a1_p->x1 + lw; + n.x2 = a1_p->x1 + lw - 1; n.y2 = y1 + sh; res_p[res_c++] = n; } @@ -162,7 +162,7 @@ int8_t lv_area_diff(lv_area_t res_p[], const lv_area_t * a1_p, const lv_area_t * /*Compute the right rectangle*/ int32_t rw = a1_w - (a2_p->x2 - a1_p->x1); if(rw > 0) { - n.x1 = a2_p->x2; + n.x1 = a2_p->x2 + 1; n.y1 = y1; n.x2 = a2_p->x2 + rw; n.y2 = y1 + sh; diff --git a/tests/src/test_cases/test_area.c b/tests/src/test_cases/test_area.c index e683acc66..8d9542e5c 100644 --- a/tests/src/test_cases/test_area.c +++ b/tests/src/test_cases/test_area.c @@ -119,4 +119,73 @@ void test_pct(void) TEST_ASSERT_EQUAL_INT32(-PCT_MAX_VALUE, LV_COORD_GET_PCT(pct_coord)); } +void test_area_diff(void) +{ + lv_area_t expected[4] = { + {0, 0, 100, 29}, /* wide top rectangle */ + {0, 91, 100, 100}, /* wide bottom rectangle */ + {0, 30, 39, 90}, /* left rectangle */ + {81, 30, 100, 90} /* right rectangle */ + }; + lv_area_t outer = {0, 0, 100, 100}; + lv_area_t remove = {40, 30, 80, 90}; + lv_area_t actual[4]; + lv_memset(actual, 0, sizeof(actual)); + + int8_t area_count = lv_area_diff(actual, &outer, &remove); + TEST_ASSERT_EQUAL_INT8(area_count, 4); + + TEST_PRINTF("%d %d %d %d", actual[0].x1, actual[0].y1, actual[0].x2, actual[0].y2); + TEST_ASSERT_TRUE(lv_area_is_equal(&expected[0], &actual[0])); + TEST_PRINTF("%d %d %d %d", actual[1].x1, actual[1].y1, actual[1].x2, actual[1].y2); + TEST_ASSERT_TRUE(lv_area_is_equal(&expected[1], &actual[1])); + TEST_PRINTF("%d %d %d %d", actual[2].x1, actual[2].y1, actual[2].x2, actual[2].y2); + TEST_ASSERT_TRUE(lv_area_is_equal(&expected[2], &actual[2])); + TEST_PRINTF("%d %d %d %d", actual[3].x1, actual[3].y1, actual[3].x2, actual[3].y2); + TEST_ASSERT_TRUE(lv_area_is_equal(&expected[3], &actual[3])); + + + /* no left edge */ + lv_area_set(&remove, 0, 10, 10, 20); + area_count = lv_area_diff(actual, &outer, &remove); + TEST_ASSERT_EQUAL_INT8(area_count, 3); + + lv_area_set(&remove, 1, 10, 10, 20); + area_count = lv_area_diff(actual, &outer, &remove); + TEST_ASSERT_EQUAL_INT8(area_count, 4); + + /* no right edge */ + lv_area_set(&remove, 90, 10, 100, 20); + area_count = lv_area_diff(actual, &outer, &remove); + TEST_ASSERT_EQUAL_INT8(area_count, 3); + + lv_area_set(&remove, 90, 10, 99, 20); + area_count = lv_area_diff(actual, &outer, &remove); + TEST_ASSERT_EQUAL_INT8(area_count, 4); + + /* no top edge */ + lv_area_set(&remove, 10, 0, 20, 20); + area_count = lv_area_diff(actual, &outer, &remove); + TEST_ASSERT_EQUAL_INT8(area_count, 3); + + lv_area_set(&remove, 10, 1, 20, 20); + area_count = lv_area_diff(actual, &outer, &remove); + TEST_ASSERT_EQUAL_INT8(area_count, 4); + + /* no bottom edge */ + lv_area_set(&remove, 10, 90, 20, 100); + area_count = lv_area_diff(actual, &outer, &remove); + TEST_ASSERT_EQUAL_INT8(area_count, 3); + + lv_area_set(&remove, 10, 90, 20, 99); + area_count = lv_area_diff(actual, &outer, &remove); + TEST_ASSERT_EQUAL_INT8(area_count, 4); + + + /* top and left edges missing */ + lv_area_set(&remove, -50, -50, 50, 50); + area_count = lv_area_diff(actual, &outer, &remove); + TEST_ASSERT_EQUAL_INT8(area_count, 2); +} + #endif