feat(barcode): add none tiled mode (#6462)

Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com>
Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com>
This commit is contained in:
VIFEX
2024-07-10 01:49:36 +08:00
committed by GitHub
parent ba7630ff53
commit ca70164c6b
9 changed files with 125 additions and 35 deletions
+93 -21
View File
@@ -28,6 +28,7 @@
static void lv_barcode_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
static void lv_barcode_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
static bool lv_barcode_change_buf_size(lv_obj_t * obj, int32_t w, int32_t h);
static void lv_barcode_clear(lv_obj_t * obj);
/**********************
* STATIC VARIABLES
@@ -94,16 +95,23 @@ void lv_barcode_set_direction(lv_obj_t * obj, lv_dir_t direction)
barcode->direction = direction;
}
void lv_barcode_set_tiled(lv_obj_t * obj, bool tiled)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_barcode_t * barcode = (lv_barcode_t *)obj;
barcode->tiled = tiled;
lv_image_set_inner_align(obj, tiled ? LV_IMAGE_ALIGN_TILE : LV_IMAGE_ALIGN_DEFAULT);
}
lv_result_t lv_barcode_update(lv_obj_t * obj, const char * data)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
LV_ASSERT_NULL(data);
lv_result_t res = LV_RESULT_INVALID;
lv_barcode_t * barcode = (lv_barcode_t *)obj;
if(data == NULL || lv_strlen(data) == 0) {
LV_LOG_WARN("data is empty");
lv_barcode_clear(obj);
return LV_RESULT_INVALID;
}
@@ -114,43 +122,92 @@ lv_result_t lv_barcode_update(lv_obj_t * obj, const char * data)
LV_ASSERT_MALLOC(out_buf);
if(!out_buf) {
LV_LOG_ERROR("malloc failed for out_buf");
lv_barcode_clear(obj);
return LV_RESULT_INVALID;
}
int32_t barcode_w = (int32_t) code128_encode_gs1(data, out_buf, len);
LV_LOG_INFO("barcode width = %d", (int)barcode_w);
LV_LOG_INFO("barcode width = %" LV_PRId32, barcode_w);
lv_barcode_t * barcode = (lv_barcode_t *)obj;
LV_ASSERT(barcode->scale > 0);
uint16_t scale = barcode->scale;
int32_t buf_w = (barcode->direction == LV_DIR_HOR) ? barcode_w * scale : 1;
int32_t buf_h = (barcode->direction == LV_DIR_VER) ? barcode_w * scale : 1;
int32_t buf_w;
int32_t buf_h;
if(!lv_barcode_change_buf_size(obj, buf_w, buf_h)) {
goto failed;
if(barcode->tiled) {
buf_w = (barcode->direction == LV_DIR_HOR) ? barcode_w * scale : 1;
buf_h = (barcode->direction == LV_DIR_VER) ? barcode_w * scale : 1;
}
else {
lv_obj_update_layout(obj);
buf_w = (barcode->direction == LV_DIR_HOR) ? barcode_w * scale : lv_obj_get_width(obj);
buf_h = (barcode->direction == LV_DIR_VER) ? barcode_w * scale : lv_obj_get_height(obj);
}
lv_canvas_set_palette(obj, 0, lv_color_to_32(barcode->dark_color, 0xff));
lv_canvas_set_palette(obj, 1, lv_color_to_32(barcode->light_color, 0xff));
if(!lv_barcode_change_buf_size(obj, buf_w, buf_h)) {
lv_barcode_clear(obj);
lv_free(out_buf);
return LV_RESULT_INVALID;
}
/* Temporarily disable invalidation to improve the efficiency of lv_canvas_set_px */
lv_display_enable_invalidation(lv_obj_get_display(obj), false);
lv_draw_buf_t * draw_buf = lv_canvas_get_draw_buf(obj);
uint32_t stride = draw_buf->header.stride;
const lv_color_t color = lv_color_hex(1);
/* Clear the canvas */
lv_draw_buf_clear(draw_buf, NULL);
/* Set the palette */
lv_canvas_set_palette(obj, 0, lv_color_to_32(barcode->light_color, LV_OPA_COVER));
lv_canvas_set_palette(obj, 1, lv_color_to_32(barcode->dark_color, LV_OPA_COVER));
for(int32_t x = 0; x < barcode_w; x++) {
lv_color_t color;
color = lv_color_hex(out_buf[x] ? 0 : 1);
/*skip empty data*/
if(out_buf[x] == 0) {
continue;
}
for(uint16_t i = 0; i < scale; i++) {
int32_t offset = x * scale + i;
if(barcode->direction == LV_DIR_HOR) {
lv_canvas_set_px(obj, x * scale + i, 0, color, LV_OPA_COVER);
lv_canvas_set_px(obj, offset, 0, color, LV_OPA_COVER);
}
else {
lv_canvas_set_px(obj, 0, x * scale + i, color, LV_OPA_COVER);
else { /*LV_DIR_VER*/
if(barcode->tiled) {
lv_canvas_set_px(obj, 0, offset, color, LV_OPA_COVER);
}
else {
uint8_t * dest = lv_draw_buf_goto_xy(draw_buf, 0, offset);
lv_memset(dest, 0xFF, stride);
}
}
}
}
res = LV_RESULT_OK;
/* Copy pixels by row */
if(!barcode->tiled && barcode->direction == LV_DIR_HOR && buf_h > 1) {
/* Skip the first row */
int32_t h = buf_h - 1;
const uint8_t * src = lv_draw_buf_goto_xy(draw_buf, 0, 0);
uint8_t * dest = lv_draw_buf_goto_xy(draw_buf, 0, 1);
while(h--) {
lv_memcpy(dest, src, stride);
dest += stride;
}
}
/* invalidate the canvas to refresh it */
lv_display_enable_invalidation(lv_obj_get_display(obj), true);
lv_obj_invalidate(obj);
failed:
lv_free(out_buf);
return res;
return LV_RESULT_OK;
}
lv_color_t lv_barcode_get_dark_color(lv_obj_t * obj)
@@ -190,7 +247,7 @@ static void lv_barcode_constructor(const lv_obj_class_t * class_p, lv_obj_t * ob
barcode->light_color = lv_color_white();
barcode->scale = 1;
barcode->direction = LV_DIR_HOR;
lv_image_set_inner_align(obj, LV_IMAGE_ALIGN_TILE);
lv_image_set_inner_align(obj, LV_IMAGE_ALIGN_DEFAULT);
}
static void lv_barcode_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
@@ -208,7 +265,10 @@ static void lv_barcode_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj
static bool lv_barcode_change_buf_size(lv_obj_t * obj, int32_t w, int32_t h)
{
LV_ASSERT_NULL(obj);
LV_ASSERT(w > 0);
if(w <= 0 || h <= 0) {
LV_LOG_WARN("invalid size: %" LV_PRId32 " x %" LV_PRId32, w, h);
return false;
}
lv_draw_buf_t * old_buf = lv_canvas_get_draw_buf(obj);
lv_draw_buf_t * new_buf = lv_draw_buf_create(w, h, LV_COLOR_FORMAT_I1, LV_STRIDE_AUTO);
@@ -218,10 +278,22 @@ static bool lv_barcode_change_buf_size(lv_obj_t * obj, int32_t w, int32_t h)
}
lv_canvas_set_draw_buf(obj, new_buf);
LV_LOG_INFO("set canvas buffer: %p, width = %d", (void *)new_buf, (int)w);
LV_LOG_INFO("set canvas buffer: %p, width = %" LV_PRId32, (void *)new_buf, w);
if(old_buf != NULL) lv_draw_buf_destroy(old_buf);
return true;
}
static void lv_barcode_clear(lv_obj_t * obj)
{
lv_draw_buf_t * draw_buf = lv_canvas_get_draw_buf(obj);
if(!draw_buf) {
return;
}
lv_draw_buf_clear(draw_buf, NULL);
lv_image_cache_drop(draw_buf);
lv_obj_invalidate(obj);
}
#endif /*LV_USE_BARCODE*/
+8
View File
@@ -35,6 +35,7 @@ typedef struct {
lv_color_t light_color;
uint16_t scale;
lv_dir_t direction;
bool tiled;
} lv_barcode_t;
LV_ATTRIBUTE_EXTERN_DATA extern const lv_obj_class_t lv_barcode_class;
@@ -78,6 +79,13 @@ void lv_barcode_set_scale(lv_obj_t * obj, uint16_t scale);
*/
void lv_barcode_set_direction(lv_obj_t * obj, lv_dir_t direction);
/**
* Set the tiled mode of a barcode object
* @param obj pointer to barcode object
* @param tiled true: tiled mode, false: normal mode (default)
*/
void lv_barcode_set_tiled(lv_obj_t * obj, bool tiled);
/**
* Set the data of a barcode object
* @param obj pointer to barcode object
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

+24 -14
View File
@@ -27,6 +27,7 @@ void test_barcode_normal(void)
lv_color_t dark_color = lv_color_black();
lv_color_t light_color = lv_color_white();
uint16_t scale = 2;
lv_result_t res;
lv_barcode_set_dark_color(barcode, dark_color);
lv_barcode_set_light_color(barcode, light_color);
@@ -36,26 +37,35 @@ void test_barcode_normal(void)
TEST_ASSERT_EQUAL_COLOR(lv_barcode_get_light_color(barcode), light_color);
TEST_ASSERT_EQUAL(lv_barcode_get_scale(barcode), scale);
/* Test horizontal mode */
lv_barcode_set_direction(barcode, LV_DIR_HOR);
lv_result_t res = lv_barcode_update(barcode, "https://lvgl.io");
TEST_ASSERT_EQUAL(res, LV_RESULT_OK);
lv_image_dsc_t * image_dsc = lv_canvas_get_image(barcode);
TEST_ASSERT_NOT_NULL(image_dsc);
lv_obj_set_size(barcode, image_dsc->header.w, 50);
TEST_ASSERT_EQUAL_SCREENSHOT("libs/barcode_1.png");
lv_barcode_set_direction(barcode, LV_DIR_VER);
lv_obj_set_height(barcode, 50);
res = lv_barcode_update(barcode, "https://lvgl.io");
TEST_ASSERT_EQUAL(res, LV_RESULT_OK);
TEST_ASSERT_EQUAL_SCREENSHOT("libs/barcode_1.png");
image_dsc = lv_canvas_get_image(barcode);
TEST_ASSERT_NOT_NULL(image_dsc);
lv_obj_set_size(barcode, 50, image_dsc->header.h);
/* Test vertical mode */
lv_barcode_set_direction(barcode, LV_DIR_VER);
lv_obj_set_size(barcode, 50, LV_SIZE_CONTENT);
res = lv_barcode_update(barcode, "https://lvgl.io");
TEST_ASSERT_EQUAL(res, LV_RESULT_OK);
TEST_ASSERT_EQUAL_SCREENSHOT("libs/barcode_2.png");
/* Test tiled + horizontal mode */
lv_barcode_set_tiled(barcode, true);
lv_barcode_set_direction(barcode, LV_DIR_HOR);
lv_obj_set_size(barcode, LV_SIZE_CONTENT, 50);
res = lv_barcode_update(barcode, "https://lvgl.io");
TEST_ASSERT_EQUAL(res, LV_RESULT_OK);
TEST_ASSERT_EQUAL_SCREENSHOT("libs/barcode_tiled_1.png");
/* Test tiled + vertical mode */
lv_barcode_set_direction(barcode, LV_DIR_VER);
lv_obj_set_size(barcode, 50, LV_SIZE_CONTENT);
res = lv_barcode_update(barcode, "https://lvgl.io");
TEST_ASSERT_EQUAL(res, LV_RESULT_OK);
TEST_ASSERT_EQUAL_SCREENSHOT("libs/barcode_tiled_2.png");
}
#else