From e373b705db54a14b847f574252190e1a98e1c160 Mon Sep 17 00:00:00 2001 From: Liam <30486941+liamHowatt@users.noreply.github.com> Date: Sun, 21 Apr 2024 03:05:35 -0400 Subject: [PATCH] fix(area): increase coordinate percent range beyond +-1000 (#6051) --- src/misc/lv_area.h | 21 ++++-- tests/src/test_cases/test_area.c | 121 +++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+), 8 deletions(-) create mode 100644 tests/src/test_cases/test_area.c diff --git a/src/misc/lv_area.h b/src/misc/lv_area.h index 90df8249f..27b08e023 100644 --- a/src/misc/lv_area.h +++ b/src/misc/lv_area.h @@ -15,6 +15,7 @@ extern "C" { *********************/ #include "../lv_conf_internal.h" #include "lv_types.h" +#include "lv_math.h" /********************* * DEFINES @@ -343,20 +344,24 @@ static inline void lv_point_precise_swap(lv_point_precise_t * p1, lv_point_preci #define LV_COORD_SET_SPEC(x) ((x) | _LV_COORD_TYPE_SPEC) -/*Special coordinates*/ -#define LV_PCT(x) (x < 0 ? LV_COORD_SET_SPEC(1000 - (x)) : LV_COORD_SET_SPEC(x)) -#define LV_COORD_IS_PCT(x) ((LV_COORD_IS_SPEC(x) && _LV_COORD_PLAIN(x) <= 2000)) -#define LV_COORD_GET_PCT(x) (_LV_COORD_PLAIN(x) > 1000 ? 1000 - _LV_COORD_PLAIN(x) : _LV_COORD_PLAIN(x)) -#define LV_SIZE_CONTENT LV_COORD_SET_SPEC(2001) - -LV_EXPORT_CONST_INT(LV_SIZE_CONTENT); - /*Max coordinate value*/ #define LV_COORD_MAX ((1 << _LV_COORD_TYPE_SHIFT) - 1) #define LV_COORD_MIN (-LV_COORD_MAX) +/*Special coordinates*/ +#define LV_SIZE_CONTENT LV_COORD_SET_SPEC(LV_COORD_MAX) +#define _LV_PCT_STORED_MAX (LV_COORD_MAX - 1) +#if _LV_PCT_STORED_MAX % 2 != 0 +#error _LV_PCT_STORED_MAX should be an even number +#endif +#define _LV_PCT_POS_MAX (_LV_PCT_STORED_MAX / 2) +#define LV_PCT(x) (LV_COORD_SET_SPEC(((x) < 0 ? (_LV_PCT_POS_MAX - LV_MAX((x), -_LV_PCT_POS_MAX)) : LV_MIN((x), _LV_PCT_POS_MAX)))) +#define LV_COORD_IS_PCT(x) ((LV_COORD_IS_SPEC(x) && _LV_COORD_PLAIN(x) <= _LV_PCT_STORED_MAX)) +#define LV_COORD_GET_PCT(x) (_LV_COORD_PLAIN(x) > _LV_PCT_POS_MAX ? _LV_PCT_POS_MAX - _LV_COORD_PLAIN(x) : _LV_COORD_PLAIN(x)) + LV_EXPORT_CONST_INT(LV_COORD_MAX); LV_EXPORT_CONST_INT(LV_COORD_MIN); +LV_EXPORT_CONST_INT(LV_SIZE_CONTENT); /** * Convert a percentage value to `int32_t`. diff --git a/tests/src/test_cases/test_area.c b/tests/src/test_cases/test_area.c new file mode 100644 index 000000000..104952480 --- /dev/null +++ b/tests/src/test_cases/test_area.c @@ -0,0 +1,121 @@ +#if LV_BUILD_TEST +#include "../lvgl.h" + +#include "unity/unity.h" + +#define PCT_MAX_VALUE 268435455 + +void setUp(void) +{ + /* Function run before every test */ +} + +void tearDown(void) +{ + /* Function run after every test */ + lv_obj_clean(lv_screen_active()); +} + +void test_pct(void) +{ + int32_t pct_val; + int32_t pct_coord; + + pct_val = 0; + pct_coord = lv_pct(pct_val); + TEST_ASSERT_TRUE(LV_COORD_IS_PCT(pct_coord)); + TEST_ASSERT_FALSE(LV_COORD_IS_PX(pct_coord)); + TEST_ASSERT_TRUE(LV_COORD_IS_SPEC(pct_coord)); + TEST_ASSERT_EQUAL_INT32(pct_val, LV_COORD_GET_PCT(pct_coord)); + + pct_val = 1; + pct_coord = lv_pct(pct_val); + TEST_ASSERT_TRUE(LV_COORD_IS_PCT(pct_coord)); + TEST_ASSERT_FALSE(LV_COORD_IS_PX(pct_coord)); + TEST_ASSERT_TRUE(LV_COORD_IS_SPEC(pct_coord)); + TEST_ASSERT_EQUAL_INT32(pct_val, LV_COORD_GET_PCT(pct_coord)); + + pct_val = 100; + pct_coord = lv_pct(pct_val); + TEST_ASSERT_TRUE(LV_COORD_IS_PCT(pct_coord)); + TEST_ASSERT_FALSE(LV_COORD_IS_PX(pct_coord)); + TEST_ASSERT_TRUE(LV_COORD_IS_SPEC(pct_coord)); + TEST_ASSERT_EQUAL_INT32(pct_val, LV_COORD_GET_PCT(pct_coord)); + + pct_val = 111111111; + pct_coord = lv_pct(pct_val); + TEST_ASSERT_TRUE(LV_COORD_IS_PCT(pct_coord)); + TEST_ASSERT_FALSE(LV_COORD_IS_PX(pct_coord)); + TEST_ASSERT_TRUE(LV_COORD_IS_SPEC(pct_coord)); + TEST_ASSERT_EQUAL_INT32(pct_val, LV_COORD_GET_PCT(pct_coord)); + + pct_val = PCT_MAX_VALUE; + pct_coord = lv_pct(pct_val); + TEST_ASSERT_TRUE(LV_COORD_IS_PCT(pct_coord)); + TEST_ASSERT_FALSE(LV_COORD_IS_PX(pct_coord)); + TEST_ASSERT_TRUE(LV_COORD_IS_SPEC(pct_coord)); + TEST_ASSERT_EQUAL_INT32(pct_val, LV_COORD_GET_PCT(pct_coord)); + + pct_val = -1; + pct_coord = lv_pct(pct_val); + TEST_ASSERT_TRUE(LV_COORD_IS_PCT(pct_coord)); + TEST_ASSERT_FALSE(LV_COORD_IS_PX(pct_coord)); + TEST_ASSERT_TRUE(LV_COORD_IS_SPEC(pct_coord)); + TEST_ASSERT_EQUAL_INT32(pct_val, LV_COORD_GET_PCT(pct_coord)); + + pct_val = -100; + pct_coord = lv_pct(pct_val); + TEST_ASSERT_TRUE(LV_COORD_IS_PCT(pct_coord)); + TEST_ASSERT_FALSE(LV_COORD_IS_PX(pct_coord)); + TEST_ASSERT_TRUE(LV_COORD_IS_SPEC(pct_coord)); + TEST_ASSERT_EQUAL_INT32(pct_val, LV_COORD_GET_PCT(pct_coord)); + + pct_val = -111111111; + pct_coord = lv_pct(pct_val); + TEST_ASSERT_TRUE(LV_COORD_IS_PCT(pct_coord)); + TEST_ASSERT_FALSE(LV_COORD_IS_PX(pct_coord)); + TEST_ASSERT_TRUE(LV_COORD_IS_SPEC(pct_coord)); + TEST_ASSERT_EQUAL_INT32(pct_val, LV_COORD_GET_PCT(pct_coord)); + + pct_val = -PCT_MAX_VALUE; + pct_coord = lv_pct(pct_val); + TEST_ASSERT_TRUE(LV_COORD_IS_PCT(pct_coord)); + TEST_ASSERT_FALSE(LV_COORD_IS_PX(pct_coord)); + TEST_ASSERT_TRUE(LV_COORD_IS_SPEC(pct_coord)); + TEST_ASSERT_EQUAL_INT32(pct_val, LV_COORD_GET_PCT(pct_coord)); + + /** + * Out of bounds behavior. + * The pct value will be clamped to the max/min value if it's out of bounds. + */ + + pct_val = PCT_MAX_VALUE + 1; + pct_coord = lv_pct(pct_val); + TEST_ASSERT_TRUE(LV_COORD_IS_PCT(pct_coord)); + TEST_ASSERT_FALSE(LV_COORD_IS_PX(pct_coord)); + TEST_ASSERT_TRUE(LV_COORD_IS_SPEC(pct_coord)); + TEST_ASSERT_EQUAL_INT32(PCT_MAX_VALUE, LV_COORD_GET_PCT(pct_coord)); + + pct_val = PCT_MAX_VALUE + 100; + pct_coord = lv_pct(pct_val); + TEST_ASSERT_TRUE(LV_COORD_IS_PCT(pct_coord)); + TEST_ASSERT_FALSE(LV_COORD_IS_PX(pct_coord)); + TEST_ASSERT_TRUE(LV_COORD_IS_SPEC(pct_coord)); + TEST_ASSERT_EQUAL_INT32(PCT_MAX_VALUE, LV_COORD_GET_PCT(pct_coord)); + + pct_val = -PCT_MAX_VALUE - 1; + pct_coord = lv_pct(pct_val); + TEST_ASSERT_TRUE(LV_COORD_IS_PCT(pct_coord)); + TEST_ASSERT_FALSE(LV_COORD_IS_PX(pct_coord)); + TEST_ASSERT_TRUE(LV_COORD_IS_SPEC(pct_coord)); + TEST_ASSERT_EQUAL_INT32(-PCT_MAX_VALUE, LV_COORD_GET_PCT(pct_coord)); + + pct_val = -PCT_MAX_VALUE - 100; + pct_coord = lv_pct(pct_val); + TEST_ASSERT_TRUE(LV_COORD_IS_PCT(pct_coord)); + TEST_ASSERT_FALSE(LV_COORD_IS_PX(pct_coord)); + TEST_ASSERT_TRUE(LV_COORD_IS_SPEC(pct_coord)); + TEST_ASSERT_EQUAL_INT32(-PCT_MAX_VALUE, LV_COORD_GET_PCT(pct_coord)); +} + +#endif