aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabor Kiss-Vamosi <kisvegabor@gmail.com>2024-04-17 13:17:49 +0200
committerGitHub <noreply@github.com>2024-04-17 13:17:49 +0200
commitbbab604278337998ec2341a0f05717fde5da1603 (patch)
treef733d134fef149595842ae22d20511e637d0460b
parent76df54db5a5453647de01515a133721b36078857 (diff)
downloadlvgl-bbab604278337998ec2341a0f05717fde5da1603.tar.gz
lvgl-bbab604278337998ec2341a0f05717fde5da1603.zip
fix(image): set the draw_task area correctly for tiled image (#6029)
Co-authored-by: Neo Xu <neo.xu1990@gmail.com>
-rw-r--r--src/core/lv_refr.c2
-rw-r--r--src/draw/lv_draw_image.c10
-rw-r--r--src/draw/lv_draw_image.h16
-rw-r--r--src/draw/sw/lv_draw_sw_img.c8
-rw-r--r--src/widgets/image/lv_image.c25
5 files changed, 38 insertions, 23 deletions
diff --git a/src/core/lv_refr.c b/src/core/lv_refr.c
index 1dfbab79f..027484d06 100644
--- a/src/core/lv_refr.c
+++ b/src/core/lv_refr.c
@@ -959,7 +959,7 @@ void refr_obj(lv_layer_t * layer, lv_obj_t * obj)
layer_draw_dsc.blend_mode = lv_obj_get_style_blend_mode(obj, 0);
layer_draw_dsc.antialias = disp_refr->antialiasing;
layer_draw_dsc.bitmap_mask_src = lv_obj_get_style_bitmap_mask_src(obj, 0);
- layer_draw_dsc.original_area = obj_draw_size;
+ layer_draw_dsc.image_area = obj_draw_size;
layer_draw_dsc.src = new_layer;
lv_draw_layer(layer, &layer_draw_dsc, &layer_area_act);
diff --git a/src/draw/lv_draw_image.c b/src/draw/lv_draw_image.c
index 941b631c1..263260613 100644
--- a/src/draw/lv_draw_image.c
+++ b/src/draw/lv_draw_image.c
@@ -51,7 +51,7 @@ void lv_draw_image_dsc_init(lv_draw_image_dsc_t * dsc)
dsc->scale_x = LV_SCALE_NONE;
dsc->scale_y = LV_SCALE_NONE;
dsc->antialias = LV_COLOR_DEPTH > 8 ? 1 : 0;
- dsc->original_area.x2 = LV_COORD_MIN; /*Indicate invalid area by default by setting a negative size*/
+ dsc->image_area.x2 = LV_COORD_MIN; /*Indicate invalid area by default by setting a negative size*/
dsc->base.dsc_size = sizeof(lv_draw_image_dsc_t);
}
@@ -185,7 +185,7 @@ void _lv_draw_image_tiled_helper(lv_draw_unit_t * draw_unit, const lv_draw_image
int32_t img_w = draw_dsc->header.w;
int32_t img_h = draw_dsc->header.h;
- lv_area_t tile_area = *coords;
+ lv_area_t tile_area = draw_dsc->image_area;
lv_area_set_width(&tile_area, img_w);
lv_area_set_height(&tile_area, img_h);
@@ -198,11 +198,11 @@ void _lv_draw_image_tiled_helper(lv_draw_unit_t * draw_unit, const lv_draw_image
.y2 = LV_COORD_MIN,
};
- while(tile_area.y1 <= draw_unit->clip_area->y2) {
- while(tile_area.x1 <= draw_unit->clip_area->x2) {
+ while(tile_area.y1 <= coords->y2) {
+ while(tile_area.x1 <= coords->x2) {
lv_area_t clipped_img_area;
- if(_lv_area_intersect(&clipped_img_area, &tile_area, draw_unit->clip_area)) {
+ if(_lv_area_intersect(&clipped_img_area, &tile_area, coords)) {
img_decode_and_draw(draw_unit, draw_dsc, &decoder_dsc, &relative_decoded_area, &tile_area, &clipped_img_area,
draw_core_cb);
}
diff --git a/src/draw/lv_draw_image.h b/src/draw/lv_draw_image.h
index a6a9be568..0a63f3ea3 100644
--- a/src/draw/lv_draw_image.h
+++ b/src/draw/lv_draw_image.h
@@ -59,9 +59,12 @@ typedef struct _lv_draw_image_dsc_t {
uint16_t tile : 1;
lv_draw_image_sup_t * sup;
- /** Might be used to indicate the original size of the image if only a small portion is rendered now.
- * Used when a part of a layer is rendered to show the total layer size*/
- lv_area_t original_area;
+ /** Used to indicate the entire original, non-clipped area where the image is to be drawn.
+ * This is important for:
+ * 1. Layer rendering, where it might happen that only a smaller area of the layer is rendered.
+ * 2. Tiled images, where the target draw area is larger than the image to be tiled.
+ */
+ lv_area_t image_area;
const lv_image_dsc_t * bitmap_mask_src;
} lv_draw_image_dsc_t;
@@ -100,6 +103,9 @@ lv_draw_image_dsc_t * lv_draw_task_get_image_dsc(lv_draw_task_t * task);
* @param layer pointer to a layer
* @param dsc pointer to an initialized draw descriptor
* @param coords the coordinates of the image
+ * @note `coords` can be small than the real image area
+ * (if only a part of the image is rendered)
+ * or can be larger (in case of tiled images). .
*/
void lv_draw_image(lv_layer_t * layer, const lv_draw_image_dsc_t * dsc, const lv_area_t * coords);
@@ -107,7 +113,9 @@ void lv_draw_image(lv_layer_t * layer, const lv_draw_image_dsc_t * dsc, const lv
* Create a draw task to blend a layer to an other layer
* @param layer pointer to a layer
* @param dsc pointer to an initialized draw descriptor
- * @param coords the coordinates of the layer
+ * @param coords the coordinates of the layer.
+ * @note `coords` can be small than the total widget area from which the layer is created
+ * (if only a part of the widget was rendered to a layer)
*/
void lv_draw_layer(lv_layer_t * layer, const lv_draw_image_dsc_t * dsc, const lv_area_t * coords);
diff --git a/src/draw/sw/lv_draw_sw_img.c b/src/draw/sw/lv_draw_sw_img.c
index 167cdeddc..b84085979 100644
--- a/src/draw/sw/lv_draw_sw_img.c
+++ b/src/draw/sw/lv_draw_sw_img.c
@@ -245,11 +245,11 @@ static void img_draw_core(lv_draw_unit_t * draw_unit, const lv_draw_image_dsc_t
blend_dsc.mask_buf = mask_img->data;
blend_dsc.mask_stride = mask_img->header.stride;
- const lv_area_t * original_area;
- if(lv_area_get_width(&draw_dsc->original_area) < 0) original_area = img_coords;
- else original_area = &draw_dsc->original_area;
+ const lv_area_t * image_area;
+ if(lv_area_get_width(&draw_dsc->image_area) < 0) image_area = img_coords;
+ else image_area = &draw_dsc->image_area;
lv_area_set(&mask_area, 0, 0, mask_img->header.w - 1, mask_img->header.h - 1);
- lv_area_align(original_area, &mask_area, LV_ALIGN_CENTER, 0, 0);
+ lv_area_align(image_area, &mask_area, LV_ALIGN_CENTER, 0, 0);
blend_dsc.mask_area = &mask_area;
blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED;
}
diff --git a/src/widgets/image/lv_image.c b/src/widgets/image/lv_image.c
index 8bd70caf1..9bd93d2b7 100644
--- a/src/widgets/image/lv_image.c
+++ b/src/widgets/image/lv_image.c
@@ -745,23 +745,30 @@ static void draw_image(lv_event_t * e)
draw_dsc.bitmap_mask_src = img->bitmap_mask_src;
draw_dsc.src = img->src;
- lv_area_t img_area = {obj->coords.x1, obj->coords.y1,
- obj->coords.x1 + img->w - 1, obj->coords.y1 + img->h - 1
- };
+ lv_area_set(&draw_dsc.image_area, obj->coords.x1,
+ obj->coords.y1,
+ obj->coords.x1 + img->w - 1,
+ obj->coords.y1 + img->h - 1);
+ lv_area_t coords;
if(img->align < _LV_IMAGE_ALIGN_AUTO_TRANSFORM) {
- lv_area_align(&obj->coords, &img_area, img->align, img->offset.x, img->offset.y);
+ 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_TILE) {
_lv_area_intersect(&layer->_clip_area, &layer->_clip_area, &obj->coords);
- lv_area_move(&img_area, img->offset.x, img->offset.y);
+ lv_area_move(&draw_dsc.image_area, img->offset.x, img->offset.y);
- lv_area_move(&img_area,
- ((layer->_clip_area.x1 - img_area.x1 - (img->w - 1)) / img->w) * img->w,
- ((layer->_clip_area.y1 - img_area.y1 - (img->h - 1)) / img->h) * img->h);
+ lv_area_move(&draw_dsc.image_area,
+ ((layer->_clip_area.x1 - draw_dsc.image_area.x1 - (img->w - 1)) / img->w) * img->w,
+ ((layer->_clip_area.y1 - draw_dsc.image_area.y1 - (img->h - 1)) / img->h) * img->h);
+ coords = layer->_clip_area;
draw_dsc.tile = 1;
}
+ else {
+ coords = draw_dsc.image_area;
+ }
- lv_draw_image(layer, &draw_dsc, &img_area);
+ lv_draw_image(layer, &draw_dsc, &coords);
layer->_clip_area = clip_area_ori;
}