fix(image): set the draw_task area correctly for tiled image (#6029)

Co-authored-by: Neo Xu <neo.xu1990@gmail.com>
This commit is contained in:
Gabor Kiss-Vamosi
2024-04-17 13:17:49 +02:00
committed by GitHub
parent 76df54db5a
commit bbab604278
5 changed files with 38 additions and 23 deletions

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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;
}