mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-07 19:28:00 +08:00
feat(image): add LV_IMAGE_ALIGN_CONTAIN_DOWNSCALE (#10063)
Co-authored-by: Simon Stumm <simon.stumm@sartorius.com>
This commit is contained in:
@@ -55,6 +55,7 @@ typedef enum {
|
||||
LV_IMAGE_ALIGN_STRETCH, /**< Set X and Y scale to fill the Widget's area. */
|
||||
LV_IMAGE_ALIGN_TILE, /**< Tile image to fill Widget's area. Offset is applied to shift the tiling. */
|
||||
LV_IMAGE_ALIGN_CONTAIN, /**< The image keeps its aspect ratio, but is resized to the maximum size that fits within the Widget's area. */
|
||||
LV_IMAGE_ALIGN_CONTAIN_DOWNSCALE, /**< The image keeps its aspect ratio, but is resized to the maximum size that fits within the Widget's area if the image is bigger. */
|
||||
LV_IMAGE_ALIGN_COVER, /**< The image keeps its aspect ratio and fills the Widget's area. */
|
||||
} lv_image_align_t;
|
||||
|
||||
|
||||
@@ -464,7 +464,7 @@ void lv_image_set_inner_align(lv_obj_t * obj, lv_image_align_t align)
|
||||
|
||||
/*If we're removing STRETCH, reset the scale*/
|
||||
if(img->align == LV_IMAGE_ALIGN_STRETCH || img->align == LV_IMAGE_ALIGN_CONTAIN ||
|
||||
img->align == LV_IMAGE_ALIGN_COVER) {
|
||||
img->align == LV_IMAGE_ALIGN_COVER || img->align == LV_IMAGE_ALIGN_CONTAIN_DOWNSCALE) {
|
||||
lv_image_set_scale(obj, LV_SCALE_NONE);
|
||||
}
|
||||
|
||||
@@ -749,7 +749,7 @@ static void lv_image_event(const lv_obj_class_t * class_p, lv_event_t * e)
|
||||
}
|
||||
else if(code == LV_EVENT_SIZE_CHANGED) {
|
||||
if(img->align == LV_IMAGE_ALIGN_STRETCH || img->align == LV_IMAGE_ALIGN_CONTAIN ||
|
||||
img->align == LV_IMAGE_ALIGN_COVER) {
|
||||
img->align == LV_IMAGE_ALIGN_COVER || img->align == LV_IMAGE_ALIGN_CONTAIN_DOWNSCALE) {
|
||||
update_align(obj);
|
||||
if(img->rotation || img->scale_x != LV_SCALE_NONE || img->scale_y != LV_SCALE_NONE) {
|
||||
lv_obj_refresh_ext_draw_size(obj);
|
||||
@@ -890,7 +890,8 @@ static void draw_image(lv_event_t * e)
|
||||
lv_area_align(&obj->coords, &draw_dsc.image_area, img->align, img->offset.x, img->offset.y);
|
||||
coords = draw_dsc.image_area;
|
||||
}
|
||||
else if(img->align == LV_IMAGE_ALIGN_CONTAIN || img->align == LV_IMAGE_ALIGN_COVER) {
|
||||
else if(img->align == LV_IMAGE_ALIGN_CONTAIN || img->align == LV_IMAGE_ALIGN_COVER ||
|
||||
img->align == LV_IMAGE_ALIGN_CONTAIN_DOWNSCALE) {
|
||||
int32_t scale = lv_image_get_scale(obj);
|
||||
lv_point_t offset;
|
||||
offset.x = (lv_obj_get_width(obj) - img->w * scale / LV_SCALE_NONE) / 2;
|
||||
@@ -1004,7 +1005,7 @@ static void update_align(lv_obj_t * obj)
|
||||
scale_update(obj, scale_x, scale_y);
|
||||
}
|
||||
}
|
||||
else if(img->align == LV_IMAGE_ALIGN_CONTAIN) {
|
||||
else if(img->align == LV_IMAGE_ALIGN_CONTAIN || img->align == LV_IMAGE_ALIGN_CONTAIN_DOWNSCALE) {
|
||||
lv_image_set_rotation(obj, 0);
|
||||
lv_image_set_pivot(obj, 0, 0);
|
||||
if(img->w != 0 && img->h != 0) {
|
||||
@@ -1012,6 +1013,9 @@ static void update_align(lv_obj_t * obj)
|
||||
int32_t scale_x = lv_obj_get_width(obj) * LV_SCALE_NONE / img->w;
|
||||
int32_t scale_y = lv_obj_get_height(obj) * LV_SCALE_NONE / img->h;
|
||||
int32_t scale = LV_MIN(scale_x, scale_y);
|
||||
if(img->align == LV_IMAGE_ALIGN_CONTAIN_DOWNSCALE) {
|
||||
scale = LV_MIN(scale, LV_SCALE_NONE);
|
||||
}
|
||||
scale_update(obj, scale, scale);
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
@@ -320,6 +320,35 @@ void test_image_contain(void)
|
||||
TEST_ASSERT_EQUAL_SCREENSHOT("widgets/image_contain.png");
|
||||
}
|
||||
|
||||
void test_image_contain_downscale(void)
|
||||
{
|
||||
lv_obj_t * img;
|
||||
uint32_t i;
|
||||
|
||||
int32_t img_w = test_img_lvgl_logo_png.header.w;
|
||||
int32_t img_h = test_img_lvgl_logo_png.header.h;
|
||||
int32_t aspect_ratio = img_w / img_h;
|
||||
|
||||
int32_t w_array[] = {img_w / 2, img_w, img_w * 2};
|
||||
int32_t h_array[] = {img_h / 2, img_h, img_h * 2};
|
||||
|
||||
for(i = 0; i < 9; i++) {
|
||||
img = img_create();
|
||||
const int32_t w = w_array[i / 3];
|
||||
const int32_t h = h_array[i % 3];
|
||||
lv_obj_set_size(img, w, h);
|
||||
lv_obj_set_pos(img, 30 + (i % 3) * 260, 40 + (i / 3) * 150);
|
||||
lv_image_set_inner_align(img, LV_IMAGE_ALIGN_CONTAIN_DOWNSCALE);
|
||||
|
||||
const int32_t scale = lv_image_get_scale(img);
|
||||
TEST_ASSERT_EQUAL_INT(aspect_ratio, lv_image_get_transformed_width(img) / lv_image_get_transformed_height(img));
|
||||
TEST_ASSERT_EQUAL_INT((img_w * scale) >> 8, lv_image_get_transformed_width(img));
|
||||
TEST_ASSERT_EQUAL_INT((img_h * scale) >> 8, lv_image_get_transformed_height(img));
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL_SCREENSHOT("widgets/image_contain_downscale.png");
|
||||
}
|
||||
|
||||
void test_image_cover(void)
|
||||
{
|
||||
lv_obj_t * img;
|
||||
|
||||
Reference in New Issue
Block a user