diff --git a/src/draw/lv_draw_image.h b/src/draw/lv_draw_image.h index 0a63f3ea3..a11e1dacd 100644 --- a/src/draw/lv_draw_image.h +++ b/src/draw/lv_draw_image.h @@ -65,6 +65,9 @@ typedef struct _lv_draw_image_dsc_t { * 2. Tiled images, where the target draw area is larger than the image to be tiled. */ lv_area_t image_area; + + int32_t clip_radius; + const lv_image_dsc_t * bitmap_mask_src; } lv_draw_image_dsc_t; diff --git a/src/draw/vg_lite/lv_draw_vg_lite_img.c b/src/draw/vg_lite/lv_draw_vg_lite_img.c index 809909dc0..8f58369bc 100644 --- a/src/draw/vg_lite/lv_draw_vg_lite_img.c +++ b/src/draw/vg_lite/lv_draw_vg_lite_img.c @@ -99,7 +99,7 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * LV_VG_LITE_ASSERT_DEST_BUFFER(&u->target_buffer); /* If clipping is not required, blit directly */ - if(_lv_area_is_in(&image_tf_area, draw_unit->clip_area, false)) { + if(_lv_area_is_in(&image_tf_area, draw_unit->clip_area, false) && dsc->clip_radius <= 0) { /* The image area is the coordinates relative to the image itself */ lv_area_t src_area = *coords; lv_area_move(&src_area, -coords->x1, -coords->y1); @@ -121,11 +121,31 @@ void lv_draw_vg_lite_img(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t * } else { lv_vg_lite_path_t * path = lv_vg_lite_path_get(u, VG_LITE_FP32); - lv_vg_lite_path_append_rect( - path, - clip_area.x1, clip_area.y1, - lv_area_get_width(&clip_area), lv_area_get_height(&clip_area), - 0, 0); + + if(dsc->clip_radius) { + int32_t width = lv_area_get_width(coords); + int32_t height = lv_area_get_height(coords); + float r_short = LV_MIN(width, height) / 2.0f; + float radius = LV_MIN(dsc->clip_radius, r_short); + + /** + * When clip_radius is enabled, the clipping edges + * are aligned with the image edges + */ + lv_vg_lite_path_append_rect( + path, + coords->x1, coords->y1, + width, height, + radius, radius); + } + else { + lv_vg_lite_path_append_rect( + path, + clip_area.x1, clip_area.y1, + lv_area_get_width(&clip_area), lv_area_get_height(&clip_area), + 0, 0); + } + lv_vg_lite_path_set_bonding_box_area(path, &clip_area); lv_vg_lite_path_end(path); diff --git a/src/widgets/image/lv_image.c b/src/widgets/image/lv_image.c index 9bd93d2b7..24ebf71f6 100644 --- a/src/widgets/image/lv_image.c +++ b/src/widgets/image/lv_image.c @@ -749,6 +749,9 @@ static void draw_image(lv_event_t * e) obj->coords.y1, obj->coords.x1 + img->w - 1, obj->coords.y1 + img->h - 1); + + draw_dsc.clip_radius = lv_obj_get_style_radius(obj, LV_PART_MAIN); + lv_area_t coords; if(img->align < _LV_IMAGE_ALIGN_AUTO_TRANSFORM) { lv_area_align(&obj->coords, &draw_dsc.image_area, img->align, img->offset.x, img->offset.y); diff --git a/tests/ref_imgs/widgets/image_clip_radius_10.png b/tests/ref_imgs/widgets/image_clip_radius_10.png new file mode 100644 index 000000000..e6688217a Binary files /dev/null and b/tests/ref_imgs/widgets/image_clip_radius_10.png differ diff --git a/tests/ref_imgs/widgets/image_clip_radius_circle.png b/tests/ref_imgs/widgets/image_clip_radius_circle.png new file mode 100644 index 000000000..e6688217a Binary files /dev/null and b/tests/ref_imgs/widgets/image_clip_radius_circle.png differ diff --git a/tests/ref_imgs_vg_lite/widgets/image_clip_radius_10.png b/tests/ref_imgs_vg_lite/widgets/image_clip_radius_10.png new file mode 100644 index 000000000..3eb05987d Binary files /dev/null and b/tests/ref_imgs_vg_lite/widgets/image_clip_radius_10.png differ diff --git a/tests/ref_imgs_vg_lite/widgets/image_clip_radius_circle.png b/tests/ref_imgs_vg_lite/widgets/image_clip_radius_circle.png new file mode 100644 index 000000000..ffa28153d Binary files /dev/null and b/tests/ref_imgs_vg_lite/widgets/image_clip_radius_circle.png differ diff --git a/tests/src/test_cases/widgets/test_image.c b/tests/src/test_cases/widgets/test_image.c index 17a4d8d32..5ede0725f 100644 --- a/tests/src/test_cases/widgets/test_image.c +++ b/tests/src/test_cases/widgets/test_image.c @@ -4,6 +4,7 @@ #include "unity/unity.h" LV_IMAGE_DECLARE(test_img_lvgl_logo_png); +LV_IMAGE_DECLARE(test_arc_bg); void setUp(void) { @@ -361,4 +362,17 @@ void test_image_ignore_transformation_settings_when_tiled(void) TEST_ASSERT_EQUAL_INT(LV_SCALE_NONE, lv_image_get_scale_y(img)); } +void test_image_clip_radius(void) +{ + lv_obj_t * img = lv_img_create(lv_screen_active()); + lv_image_set_src(img, &test_arc_bg); + lv_obj_center(img); + + lv_obj_set_style_radius(img, 10, 0); + TEST_ASSERT_EQUAL_SCREENSHOT("widgets/image_clip_radius_10.png"); + + lv_obj_set_style_radius(img, LV_RADIUS_CIRCLE, 0); + TEST_ASSERT_EQUAL_SCREENSHOT("widgets/image_clip_radius_circle.png"); +} + #endif