diff --git a/src/draw/sw/lv_draw_sw_arc.c b/src/draw/sw/lv_draw_sw_arc.c index 5a205c1739..5db127df51 100644 --- a/src/draw/sw/lv_draw_sw_arc.c +++ b/src/draw/sw/lv_draw_sw_arc.c @@ -118,22 +118,34 @@ void lv_draw_sw_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, c blend_dsc.opa = dsc->opa; blend_dsc.blend_area = &blend_area; blend_dsc.mask_area = &blend_area; + + const uint8_t * img_mask = NULL; lv_image_decoder_dsc_t decoder_dsc; if(dsc->img_src == NULL) { blend_dsc.color = dsc->color; } else { - lv_image_decoder_open(&decoder_dsc, dsc->img_src, NULL); - img_area.x1 = 0; - img_area.y1 = 0; - img_area.x2 = decoder_dsc.decoded->header.w - 1; - img_area.y2 = decoder_dsc.decoded->header.h - 1; - int32_t ofs = decoder_dsc.decoded->header.w / 2; - lv_area_move(&img_area, dsc->center.x - ofs, dsc->center.y - ofs); - blend_dsc.src_area = &img_area; - blend_dsc.src_buf = decoder_dsc.decoded->data; - blend_dsc.src_color_format = decoder_dsc.decoded->header.cf; - blend_dsc.src_stride = decoder_dsc.decoded->header.stride; + lv_result_t res = lv_image_decoder_open(&decoder_dsc, dsc->img_src, NULL); + if(res == LV_RESULT_INVALID || decoder_dsc.decoded == NULL) { + LV_LOG_WARN("Can't decode the background image"); + blend_dsc.color = dsc->color; + } + else { + img_area.x1 = 0; + img_area.y1 = 0; + img_area.x2 = decoder_dsc.decoded->header.w - 1; + img_area.y2 = decoder_dsc.decoded->header.h - 1; + int32_t ofs = decoder_dsc.decoded->header.w / 2; + lv_area_move(&img_area, dsc->center.x - ofs, dsc->center.y - ofs); + blend_dsc.src_area = &img_area; + blend_dsc.src_buf = decoder_dsc.decoded->data; + blend_dsc.src_stride = decoder_dsc.decoded->header.stride; + blend_dsc.src_color_format = decoder_dsc.decoded->header.cf; + if(blend_dsc.src_color_format == LV_COLOR_FORMAT_RGB565A8) { + blend_dsc.src_color_format = LV_COLOR_FORMAT_RGB565; + img_mask = (uint8_t *)blend_dsc.src_buf + blend_dsc.src_stride * lv_area_get_height(blend_dsc.src_area); + } + } } lv_opa_t * circle_mask = NULL; @@ -185,6 +197,21 @@ void lv_draw_sw_arc(lv_draw_unit_t * draw_unit, const lv_draw_arc_dsc_t * dsc, c } } + /*If it was an RGB565A8 image use consider its A8 part on the mask*/ + if(img_mask && blend_dsc.mask_res != LV_DRAW_SW_MASK_RES_TRANSP) { + const uint8_t * img_mask_tmp = img_mask; + img_mask_tmp += blend_dsc.src_stride / 2 * (blend_area.y1 - blend_dsc.src_area->y1); + img_mask_tmp += blend_area.x1 - blend_dsc.src_area->x1; + + int32_t i; + for(i = 0; i < blend_w; i++) { + mask_buf[i] = LV_OPA_MIX2(mask_buf[i], img_mask_tmp[i]); + } + if(blend_dsc.mask_res == LV_DRAW_SW_MASK_RES_FULL_COVER) { + blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED; + } + } + lv_draw_sw_blend(draw_unit, &blend_dsc); blend_area.y1 ++; diff --git a/src/misc/lv_log.c b/src/misc/lv_log.c index cf7da050df..d15fe27389 100644 --- a/src/misc/lv_log.c +++ b/src/misc/lv_log.c @@ -101,6 +101,7 @@ void _lv_log_add(lv_log_level_t level, const char * file, int line, const char * lvl_prefix[level], LOG_TIMESTAMP_EXPR func); vprintf(format, args); printf(LOG_FILE_LINE_FMT "\n" LOG_FILE_LINE_EXPR); + fflush(stdout); #else if(custom_print_cb) { char buf[512]; diff --git a/tests/ref_imgs/widgets/arc_1.png b/tests/ref_imgs/widgets/arc_1.png index f4deada394..cdb5979a47 100644 Binary files a/tests/ref_imgs/widgets/arc_1.png and b/tests/ref_imgs/widgets/arc_1.png differ diff --git a/tests/ref_imgs/widgets/arc_2.png b/tests/ref_imgs/widgets/arc_2.png index f75770052a..4af862ba35 100644 Binary files a/tests/ref_imgs/widgets/arc_2.png and b/tests/ref_imgs/widgets/arc_2.png differ diff --git a/tests/ref_imgs/widgets/arc_3.png b/tests/ref_imgs/widgets/arc_3.png new file mode 100644 index 0000000000..f75770052a Binary files /dev/null and b/tests/ref_imgs/widgets/arc_3.png differ diff --git a/tests/src/test_cases/widgets/test_arc.c b/tests/src/test_cases/widgets/test_arc.c index 968ce89b3f..7776f87c6e 100644 --- a/tests/src/test_cases/widgets/test_arc.c +++ b/tests/src/test_cases/widgets/test_arc.c @@ -28,7 +28,8 @@ void setUp(void) void tearDown(void) { - lv_obj_clean(lv_screen_active()); + lv_obj_clean(active_screen); + lv_obj_set_style_layout(active_screen, LV_LAYOUT_NONE, 0); } void test_arc_creation_successful(void) @@ -38,6 +39,34 @@ void test_arc_creation_successful(void) TEST_ASSERT_NOT_NULL(arc); } +void test_arc_basic_render(void) +{ + arc = lv_arc_create(active_screen); + lv_obj_set_size(arc, 100, 100); + lv_obj_center(arc); + lv_arc_set_value(arc, 70); + + TEST_ASSERT_EQUAL_SCREENSHOT("widgets/arc_1.png"); +} + +void test_arc_rgb565a8_image(void) +{ +#if LV_BIN_DECODER_RAM_LOAD + /*RGB565A8 image rendering requires special handling*/ + arc = lv_arc_create(active_screen); + lv_obj_set_size(arc, 100, 100); + lv_obj_center(arc); + lv_arc_set_value(arc, 70); + lv_obj_set_style_arc_width(arc, 30, 0); + lv_obj_set_style_arc_width(arc, 30, LV_PART_INDICATOR); + lv_obj_set_style_arc_image_src(arc, "A:src/test_files/binimages/cogwheel.RGB565A8.bin", LV_PART_INDICATOR); + lv_obj_set_style_arc_opa(arc, 150, LV_PART_INDICATOR); + lv_obj_set_style_bg_opa(arc, 0, LV_PART_KNOB); + + TEST_ASSERT_EQUAL_SCREENSHOT("widgets/arc_2.png"); +#endif +} + void test_arc_should_truncate_to_max_range_when_new_value_exceeds_it(void) { /* Default max range is 100 */ @@ -199,15 +228,7 @@ void test_arc_click_sustained_from_start_to_end_does_not_set_value_to_max(void) TEST_ASSERT_EQUAL_UINT32(1, event_cnt); TEST_ASSERT_EQUAL_INT32(lv_arc_get_min_value(arc), lv_arc_get_value(arc)); - TEST_ASSERT_EQUAL_SCREENSHOT("widgets/arc_2.png"); -} - -void test_arc_basic_render(void) -{ - arc = lv_arc_create(lv_screen_active()); - lv_obj_set_size(arc, 100, 100); - lv_obj_center(arc); - TEST_ASSERT_EQUAL_SCREENSHOT("widgets/arc_1.png"); + TEST_ASSERT_EQUAL_SCREENSHOT("widgets/arc_3.png"); } static void dummy_event_cb(lv_event_t * e)