Skip to content

Commit

Permalink
fix(canvas): lv_canvas_set_px for indexed images
Browse files Browse the repository at this point in the history
fixes lvgl#6196
  • Loading branch information
kisvegabor committed May 14, 2024
1 parent f575cd3 commit ddc9a02
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 10 deletions.
9 changes: 7 additions & 2 deletions src/draw/lv_draw_buf.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,15 @@ typedef struct {
*/

#define _LV_DRAW_BUF_STRIDE(w, cf) \
LV_ROUND_UP(((w) * LV_COLOR_FORMAT_GET_BPP(cf) + 7) / 8, LV_DRAW_BUF_STRIDE_ALIGN)
((LV_ROUND_UP(((w) * LV_COLOR_FORMAT_GET_BPP(cf) + 7), LV_DRAW_BUF_STRIDE_ALIGN * 8)) >> 3)

#define _LV_DRAW_BUF_PALETTE_SIZE(cf) (cf == LV_COLOR_FORMAT_I1 ? 8 : \
cf == LV_COLOR_FORMAT_I2 ? 16 : \
cf == LV_COLOR_FORMAT_I4 ? 64 : \
cf == LV_COLOR_FORMAT_I8 ? 1024 : 0)

/* Allocate a slightly larger buffer, so we can adjust the start address to meet alignment */
#define _LV_DRAW_BUF_SIZE(w, h, cf) (_LV_DRAW_BUF_STRIDE(w, cf) * (h) + LV_DRAW_BUF_ALIGN)
#define _LV_DRAW_BUF_SIZE(w, h, cf) (_LV_DRAW_BUF_STRIDE(w, cf) * (h) + LV_DRAW_BUF_ALIGN + _LV_DRAW_BUF_PALETTE_SIZE(cf))

/**
* Define a static draw buffer with the given width, height, and color format.
Expand Down
32 changes: 24 additions & 8 deletions src/widgets/canvas/lv_canvas.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,29 +111,45 @@ void lv_canvas_set_px(lv_obj_t * obj, int32_t x, int32_t y, lv_color_t color, lv
uint8_t * data = lv_draw_buf_goto_xy(draw_buf, x, y);

if(cf == LV_COLOR_FORMAT_I1) {
/*Indexed image bpp could be less than 8, calculate again*/
uint8_t * buf = (uint8_t *)canvas->draw_buf->data;
buf += 2 * sizeof(lv_color32_t); /*skip the palette*/
buf += y * stride;
buf += x >> 3;
uint32_t bit = 7 - (x & 0x7);
uint32_t bit = 0x7 - (x & 0x7);
uint32_t c_int = color.blue;

*buf &= ~(1 << bit);
*buf |= c_int << bit;
}
else if(cf == LV_COLOR_FORMAT_I1) {
/*Indexed image bpp could be less than 8, calculate again*/
else if(cf == LV_COLOR_FORMAT_I2) {
uint8_t * buf = (uint8_t *)canvas->draw_buf->data;
buf += 8;
buf += 4 * sizeof(lv_color32_t); /*skip the palette*/
buf += y * stride;
buf += x >> 3;
uint32_t bit = 7 - (x & 0x7);
buf += x >> 2;
uint32_t bit = (0x3 - (x & 0x3)) * 2;
uint32_t c_int = color.blue;

*buf &= ~(1 << bit);
*buf &= ~(3 << bit);
*buf |= c_int << bit;
}
else if(cf == LV_COLOR_FORMAT_I4) {
uint8_t * buf = (uint8_t *)canvas->draw_buf->data;
buf += 16 * sizeof(lv_color32_t); /*skip the palette*/
buf += y * stride;
buf += x >> 1;
uint32_t bit = (0x1 - (x & 0x1)) * 4;
uint32_t c_int = color.blue;

*buf &= ~(2 << bit);
*buf |= c_int << bit;
}
else if(cf == LV_COLOR_FORMAT_I8) {
uint8_t * buf = (uint8_t *)canvas->draw_buf->data;
buf += 256 * sizeof(lv_color32_t); /*skip the palette*/
buf += y * stride;
buf += x;
*buf = color.blue;
}
else if(cf == LV_COLOR_FORMAT_L8) {
*data = lv_color_luminance(color);
}
Expand Down
Binary file added tests/ref_imgs/widgets/canvas_1.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
70 changes: 70 additions & 0 deletions tests/src/test_cases/widgets/test_canvas.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,74 @@ void test_canvas_functions_invalidate(void)
TEST_ASSERT(draw_counter == 4);
}

void test_canvas_fill_and_set_px(void)
{
lv_obj_t * canvas = lv_canvas_create(lv_screen_active());
lv_obj_center(canvas);

LV_DRAW_BUF_DEFINE_STATIC(buf_i1, 10, 10, LV_COLOR_FORMAT_I1);
LV_DRAW_BUF_INIT_STATIC(buf_i1);
lv_canvas_set_draw_buf(canvas, &buf_i1);
lv_canvas_set_palette(canvas, 0, lv_color32_make(0x00, 0xff, 0x00, 0xff));
lv_canvas_set_palette(canvas, 1, lv_color32_make(0x00, 0x00, 0xff, 0xff));
lv_canvas_fill_bg(canvas, lv_color_hex(0), LV_OPA_COVER);
lv_canvas_set_px(canvas, 1, 7, lv_color_hex(1), 0);
TEST_ASSERT_EQUAL_SCREENSHOT("widgets/canvas_1.png");

LV_DRAW_BUF_DEFINE_STATIC(buf_i2, 10, 10, LV_COLOR_FORMAT_I2);
LV_DRAW_BUF_INIT_STATIC(buf_i2);
lv_canvas_set_draw_buf(canvas, &buf_i2);
lv_canvas_set_palette(canvas, 0, lv_color32_make(0x00, 0xff, 0x00, 0xff));
lv_canvas_set_palette(canvas, 3, lv_color32_make(0x00, 0x00, 0xff, 0xff));
lv_canvas_fill_bg(canvas, lv_color_hex(0), LV_OPA_COVER);
lv_canvas_set_px(canvas, 1, 7, lv_color_hex(3), 0);
TEST_ASSERT_EQUAL_SCREENSHOT("widgets/canvas_1.png");

LV_DRAW_BUF_DEFINE_STATIC(buf_i4, 10, 10, LV_COLOR_FORMAT_I4);
LV_DRAW_BUF_INIT_STATIC(buf_i4);
lv_canvas_set_draw_buf(canvas, &buf_i4);
lv_canvas_set_palette(canvas, 0, lv_color32_make(0x00, 0xff, 0x00, 0xff));
lv_canvas_set_palette(canvas, 15, lv_color32_make(0x00, 0x00, 0xff, 0xff));
lv_canvas_fill_bg(canvas, lv_color_hex(0), LV_OPA_COVER);
lv_canvas_set_px(canvas, 1, 7, lv_color_hex(15), 0);
TEST_ASSERT_EQUAL_SCREENSHOT("widgets/canvas_1.png");

LV_DRAW_BUF_DEFINE_STATIC(buf_i8, 10, 10, LV_COLOR_FORMAT_I8);
LV_DRAW_BUF_INIT_STATIC(buf_i8);
lv_canvas_set_draw_buf(canvas, &buf_i8);
lv_canvas_set_palette(canvas, 0, lv_color32_make(0x00, 0xff, 0x00, 0xff));
lv_canvas_set_palette(canvas, 255, lv_color32_make(0x00, 0x00, 0xff, 0xff));
lv_canvas_fill_bg(canvas, lv_color_hex(0), LV_OPA_COVER);
lv_canvas_set_px(canvas, 1, 7, lv_color_hex(255), 0);
TEST_ASSERT_EQUAL_SCREENSHOT("widgets/canvas_1.png");

LV_DRAW_BUF_DEFINE_STATIC(buf_rgb888, 10, 10, LV_COLOR_FORMAT_RGB888);
LV_DRAW_BUF_INIT_STATIC(buf_rgb888);
lv_canvas_set_draw_buf(canvas, &buf_rgb888);
lv_canvas_fill_bg(canvas, lv_color_hex(0x00ff00), LV_OPA_COVER);
lv_canvas_set_px(canvas, 1, 7, lv_color_hex(0x0000ff), 0);
TEST_ASSERT_EQUAL_SCREENSHOT("widgets/canvas_1.png");

LV_DRAW_BUF_DEFINE_STATIC(buf_rgb565, 10, 10, LV_COLOR_FORMAT_RGB565);
LV_DRAW_BUF_INIT_STATIC(buf_rgb565);
lv_canvas_set_draw_buf(canvas, &buf_rgb565);
lv_canvas_fill_bg(canvas, lv_color_hex(0x00ff00), LV_OPA_COVER);
lv_canvas_set_px(canvas, 1, 7, lv_color_hex(0x0000ff), 0);
TEST_ASSERT_EQUAL_SCREENSHOT("widgets/canvas_1.png");

LV_DRAW_BUF_DEFINE_STATIC(buf_xrgb8888, 10, 10, LV_COLOR_FORMAT_XRGB8888);
LV_DRAW_BUF_INIT_STATIC(buf_xrgb8888);
lv_canvas_set_draw_buf(canvas, &buf_xrgb8888);
lv_canvas_fill_bg(canvas, lv_color_hex(0x00ff00), LV_OPA_COVER);
lv_canvas_set_px(canvas, 1, 7, lv_color_hex(0x0000ff), 0);
TEST_ASSERT_EQUAL_SCREENSHOT("widgets/canvas_1.png");

LV_DRAW_BUF_DEFINE_STATIC(buf_argb8888, 10, 10, LV_COLOR_FORMAT_ARGB8888);
LV_DRAW_BUF_INIT_STATIC(buf_argb8888);
lv_canvas_set_draw_buf(canvas, &buf_argb8888);
lv_canvas_fill_bg(canvas, lv_color_hex(0x00ff00), LV_OPA_COVER);
lv_canvas_set_px(canvas, 1, 7, lv_color_hex(0x0000ff), LV_OPA_COVER);
TEST_ASSERT_EQUAL_SCREENSHOT("widgets/canvas_1.png");
}

#endif

0 comments on commit ddc9a02

Please sign in to comment.