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:
committed by
GitHub
parent
76df54db5a
commit
bbab604278
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user