diff --git a/doc/releases/migration-guide-4.1.rst b/doc/releases/migration-guide-4.1.rst index 6fae5b1d4fe7..98b8476890ad 100644 --- a/doc/releases/migration-guide-4.1.rst +++ b/doc/releases/migration-guide-4.1.rst @@ -608,6 +608,13 @@ Networking Other Subsystems **************** +CFB +=== + +* Change using signed values to represent the coordinates. + As a result, :c:func:`cfb_print`, :c:func:`cfb_invert_area`, + and :c:struct:`cfb_position` definitions are changed. + Flash map ========= diff --git a/include/zephyr/display/cfb.h b/include/zephyr/display/cfb.h index 9cdf81e259af..d8f13f945c35 100644 --- a/include/zephyr/display/cfb.h +++ b/include/zephyr/display/cfb.h @@ -51,8 +51,8 @@ struct cfb_font { }; struct cfb_position { - uint16_t x; - uint16_t y; + int16_t x; + int16_t y; }; /** @@ -86,7 +86,7 @@ struct cfb_position { * * @return 0 on success, negative value otherwise */ -int cfb_print(const struct device *dev, const char *const str, uint16_t x, uint16_t y); +int cfb_print(const struct device *dev, const char *const str, int16_t x, int16_t y); /** * @brief Print a string into the framebuffer. @@ -166,7 +166,7 @@ int cfb_framebuffer_invert(const struct device *dev); * * @return 0 on success, negative value otherwise */ -int cfb_invert_area(const struct device *dev, uint16_t x, uint16_t y, +int cfb_invert_area(const struct device *dev, int16_t x, int16_t y, uint16_t width, uint16_t height); /** diff --git a/subsys/fb/cfb.c b/subsys/fb/cfb.c index c87a33c1b07b..42564b4ed644 100644 --- a/subsys/fb/cfb.c +++ b/subsys/fb/cfb.c @@ -121,7 +121,7 @@ static uint8_t draw_char_vtmono(const struct char_framebuffer *fb, const int16_t fb_y = y + g_y; const size_t fb_index = (fb_y / 8U) * fb->x_res + fb_x; - const size_t offset = y % 8; + const size_t offset = (y >= 0) ? y % 8 : (8 + (y % 8)); const uint8_t bottom_lines = ((offset + fptr->height) % 8); uint8_t bg_mask; uint8_t byte; @@ -331,41 +331,45 @@ int cfb_draw_text(const struct device *dev, const char *const str, int16_t x, in return draw_text(dev, str, x, y, false); } -int cfb_print(const struct device *dev, const char *const str, uint16_t x, uint16_t y) +int cfb_print(const struct device *dev, const char *const str, int16_t x, int16_t y) { return draw_text(dev, str, x, y, true); } -int cfb_invert_area(const struct device *dev, uint16_t x, uint16_t y, +int cfb_invert_area(const struct device *dev, int16_t x, int16_t y, uint16_t width, uint16_t height) { const struct char_framebuffer *fb = &char_fb; const bool need_reverse = ((fb->screen_info & SCREEN_INFO_MONO_MSB_FIRST) != 0); - if (x >= fb->x_res || y >= fb->y_res) { - LOG_ERR("Coordinates outside of framebuffer"); + if ((x + width) < 0 || x >= fb->x_res) { + return 0; + } - return -EINVAL; + if ((y + height) < 0 || y >= fb->y_res) { + return 0; } if ((fb->screen_info & SCREEN_INFO_MONO_VTILED)) { - if (x > fb->x_res) { - x = fb->x_res; + if (x < 0) { + width += x; + x = 0; } - if (y > fb->y_res) { - y = fb->y_res; + if (y < 0) { + height += y; + y = 0; } - if (x + width > fb->x_res) { + if (width > (fb->x_res - x)) { width = fb->x_res - x; } - if (y + height > fb->y_res) { + if (height > (fb->y_res - y)) { height = fb->y_res - y; } - for (size_t i = x; i < x + width; i++) { + for (size_t i = x; i < (x + width); i++) { for (size_t j = y; j < (y + height); j++) { /* * Process inversion in the y direction diff --git a/tests/subsys/display/cfb/basic/src/invert_area.c b/tests/subsys/display/cfb/basic/src/invert_area.c index 98b86559ff16..4db1674773d6 100644 --- a/tests/subsys/display/cfb/basic/src/invert_area.c +++ b/tests/subsys/display/cfb/basic/src/invert_area.c @@ -66,26 +66,29 @@ ZTEST(invert_area, test_invert_area_overlapped_2times) ZTEST(invert_area, test_invert_area_overlap_top_left) { - int err; + zassert_ok(cfb_invert_area(dev, -10, -10, 20, 20)); + zassert_ok(cfb_framebuffer_finalize(dev)); - err = cfb_invert_area(dev, -10, -10, 20, 20); - zassert_not_ok(err, "out of rect"); + zassert_true(verify_color_inside_rect(0, 0, 10, 10, 0xFFFFFF)); + zassert_true(verify_color_outside_rect(0, 0, 10, 10, 0x0)); } ZTEST(invert_area, test_invert_area_overlap_top_right) { - int err; + zassert_ok(cfb_invert_area(dev, display_width - 10, -10, 20, 20)); + zassert_ok(cfb_framebuffer_finalize(dev)); - err = cfb_invert_area(dev, 230, -10, 20, 20); - zassert_not_ok(err, "out of rect"); + zassert_true(verify_color_inside_rect(display_width - 10, 0, 10, 10, 0xFFFFFF)); + zassert_true(verify_color_outside_rect(display_width - 10, 0, 10, 10, 0x0)); } ZTEST(invert_area, test_invert_area_overlap_bottom_left) { - int err; + zassert_ok(cfb_invert_area(dev, -10, display_height - 10, 20, 20)); + zassert_ok(cfb_framebuffer_finalize(dev)); - err = cfb_invert_area(dev, -10, display_height - 10, 20, 20); - zassert_not_ok(err, "out of rect"); + zassert_true(verify_color_inside_rect(0, display_height - 10, 10, 10, 0xFFFFFF)); + zassert_true(verify_color_outside_rect(0, display_height - 10, 10, 10, 0x0)); } ZTEST(invert_area, test_invert_area_overlap_bottom_right) @@ -101,12 +104,18 @@ ZTEST(invert_area, test_invert_area_overlap_bottom_right) ZTEST(invert_area, test_invert_area_outside_top_left) { - zassert_not_ok(cfb_invert_area(dev, -10, -10, 10, 10), "out of rect"); + zassert_ok(cfb_invert_area(dev, -10, -10, 10, 10)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_color_inside_rect(0, 0, display_width, display_height, 0x0)); } ZTEST(invert_area, test_invert_area_outside_bottom_right) { - zassert_not_ok(cfb_invert_area(dev, display_width, display_height, 20, 20), "out of rect"); + zassert_ok(cfb_invert_area(dev, display_width, display_height, 20, 20)); + zassert_ok(cfb_framebuffer_finalize(dev)); + + zassert_true(verify_color_inside_rect(0, 0, display_width, display_height, 0x0)); } ZTEST_SUITE(invert_area, NULL, NULL, cfb_test_before, cfb_test_after, NULL);