1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-14 06:42:58 +08:00

image invalidation fixes

This commit is contained in:
Gabor Kiss-Vamosi 2020-02-14 08:11:48 +01:00
parent b9697df3a1
commit 9d664b27ec
2 changed files with 85 additions and 36 deletions

View File

@ -215,24 +215,14 @@ static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mas
lv_area_t map_area_rot;
lv_area_copy(&map_area_rot, coords);
if(angle || zoom != LV_IMG_ZOOM_NONE) {
/*Get the exact area which is required to show the rotated image*/
lv_coord_t pivot_x = lv_area_get_width(coords) / 2 + coords->x1;
lv_coord_t pivot_y = lv_area_get_height(coords) / 2 + coords->y1;
if (pivot){
pivot_x = pivot->x + coords->x1;
pivot_y = pivot->y + coords->y1;
}
lv_coord_t w = lv_area_get_width(coords);
lv_coord_t w_zoom = (((w * zoom) >> 8) - w) / 2;
lv_coord_t h = lv_area_get_height(coords);
lv_coord_t h_zoom = (((h * zoom) >> 8) - h) / 2;
int32_t w = lv_area_get_width(coords);
int32_t h = lv_area_get_height(coords);
lv_area_t norm;
norm.x1 = coords->x1 - pivot_x - w_zoom;
norm.y1 = coords->y1 - pivot_y - h_zoom;
norm.x2 = coords->x2 - pivot_x + w_zoom;
norm.y2 = coords->y2 - pivot_y + h_zoom;
norm.x1 = 0 - pivot->x;
norm.y1 = 0 - pivot->y;
norm.x2 = w - pivot->x;
norm.y2 = h - pivot->y;
int16_t sinma = lv_trigo_sin(angle);
int16_t cosma = lv_trigo_sin(angle + 90);
@ -241,22 +231,40 @@ static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mas
lv_point_t rt;
lv_point_t lb;
lv_point_t rb;
lt.x = ((cosma * norm.x1 - sinma * norm.y1) >> (LV_TRIGO_SHIFT)) + pivot_x;
lt.y = ((sinma * norm.x1 + cosma * norm.y1) >> (LV_TRIGO_SHIFT)) + pivot_y;
rt.x = ((cosma * norm.x2 - sinma * norm.y1) >> (LV_TRIGO_SHIFT)) + pivot_x;
rt.y = ((sinma * norm.x2 + cosma * norm.y1) >> (LV_TRIGO_SHIFT)) + pivot_y;
lv_coord_t xt;
lv_coord_t yt;
lb.x = ((cosma * norm.x1 - sinma * norm.y2) >> (LV_TRIGO_SHIFT)) + pivot_x;
lb.y = ((sinma * norm.x1 + cosma * norm.y2) >> (LV_TRIGO_SHIFT)) + pivot_y;
xt = (norm.x1 * zoom) >> 8;
yt = (norm.y1 * zoom) >> 8;
lt.x = ((cosma * xt - sinma * yt) >> LV_TRIGO_SHIFT) + pivot->x;
lt.y = ((sinma * xt + cosma * yt) >> LV_TRIGO_SHIFT) + pivot->y;
rb.x = ((cosma * norm.x2 - sinma * norm.y2) >> (LV_TRIGO_SHIFT)) + pivot_x;
rb.y = ((sinma * norm.x2 + cosma * norm.y2) >> (LV_TRIGO_SHIFT)) + pivot_y;
xt = (norm.x2 * zoom) >> 8;
yt = (norm.y1 * zoom) >> 8;
rt.x = ((cosma * xt - sinma * yt) >> LV_TRIGO_SHIFT) + pivot->x;
rt.y = ((sinma * xt + cosma * yt) >> LV_TRIGO_SHIFT) + pivot->y;
map_area_rot.x1 = LV_MATH_MIN(LV_MATH_MIN(LV_MATH_MIN(lb.x, lt.x), rb.x), rt.x);
map_area_rot.x2 = LV_MATH_MAX(LV_MATH_MAX(LV_MATH_MAX(lb.x, lt.x), rb.x), rt.x);
map_area_rot.y1 = LV_MATH_MIN(LV_MATH_MIN(LV_MATH_MIN(lb.y, lt.y), rb.y), rt.y);
map_area_rot.y2 = LV_MATH_MAX(LV_MATH_MAX(LV_MATH_MAX(lb.y, lt.y), rb.y), rt.y);
xt = (norm.x1 * zoom) >> 8;
yt = (norm.y2 * zoom) >> 8;
lb.x = ((cosma * xt - sinma * yt) >> LV_TRIGO_SHIFT) + pivot->x;
lb.y = ((sinma * xt + cosma * yt) >> LV_TRIGO_SHIFT) + pivot->y;
xt = (norm.x2 * zoom) >> 8;
yt = (norm.y2 * zoom) >> 8;
rb.x = ((cosma * xt - sinma * yt) >> LV_TRIGO_SHIFT) + pivot->x;
rb.y = ((sinma * xt + cosma * yt) >> LV_TRIGO_SHIFT) + pivot->y;
map_area_rot.x1 = LV_MATH_MIN(lb.x, LV_MATH_MIN(lt.x, LV_MATH_MIN(rb.x, rt.x))) + coords->x1;
map_area_rot.x2 = LV_MATH_MAX(lb.x, LV_MATH_MAX(lt.x, LV_MATH_MAX(rb.x, rt.x))) + coords->x1;
map_area_rot.y1 = LV_MATH_MIN(lb.y, LV_MATH_MIN(lt.y, LV_MATH_MIN(rb.y, rt.y))) + coords->y1;
map_area_rot.y2 = LV_MATH_MAX(lb.y, LV_MATH_MAX(lt.y, LV_MATH_MAX(rb.y, rt.y))) + coords->y1;
// lv_draw_rect_dsc_t r;
// lv_draw_rect_dsc_init(&r);
// r.bg_color = LV_COLOR_BLUE;
// r.bg_opa = LV_OPA_50;
// lv_draw_rect(&map_area_rot, mask, &r);
}
lv_area_t mask_com; /*Common area of mask and coords*/

View File

@ -581,15 +581,56 @@ static lv_res_t lv_img_signal(lv_obj_t * img, lv_signal_t sign, void * param)
} else if(sign == LV_SIGNAL_REFR_EXT_DRAW_PAD) {
/*If the image has angle provide enough room for the rotated corners */
if(ext->angle || ext->zoom != LV_IMG_ZOOM_NONE) {
lv_sqrt_res_t ds;
lv_coord_t max_w = ext->w + LV_MATH_ABS(ext->pivot.x + ext->w / 2);
lv_coord_t max_h = ext->h + LV_MATH_ABS(ext->pivot.y + ext->h / 2);
lv_sqrt(max_w * max_w + max_h * max_h, &ds);/*Maximum diagonal length*/
lv_sqrt(ds.i * ds.i + ds.i * ds.i, &ds); /*Maximum side length of external rectangle*/
ds.i = (ds.i * ext->zoom ) >> 8; /*+10 to be sure anything won't be clipped*/
int32_t w = ext->w;
int32_t h = ext->h;
lv_coord_t d = ds.i / 2;
img->ext_draw_pad = LV_MATH_MAX(img->ext_draw_pad, d);
lv_area_t norm;
norm.x1 = 0 - ext->pivot.x;
norm.y1 = 0 - ext->pivot.y;
norm.x2 = w - ext->pivot.x;
norm.y2 = h - ext->pivot.y;
int16_t sinma = lv_trigo_sin(ext->angle);
int16_t cosma = lv_trigo_sin(ext->angle + 90);
lv_point_t lt;
lv_point_t rt;
lv_point_t lb;
lv_point_t rb;
lv_coord_t xt;
lv_coord_t yt;
xt = (norm.x1 * ext->zoom) >> 8;
yt = (norm.y1 * ext->zoom) >> 8;
lt.x = ((cosma * xt - sinma * yt) >> LV_TRIGO_SHIFT) + ext->pivot.x;
lt.y = ((sinma * xt + cosma * yt) >> LV_TRIGO_SHIFT) + ext->pivot.y;
xt = (norm.x2 * ext->zoom) >> 8;
yt = (norm.y1 * ext->zoom) >> 8;
rt.x = ((cosma * xt - sinma * yt) >> LV_TRIGO_SHIFT) + ext->pivot.x;
rt.y = ((sinma * xt + cosma * yt) >> LV_TRIGO_SHIFT) + ext->pivot.y;
xt = (norm.x1 * ext->zoom) >> 8;
yt = (norm.y2 * ext->zoom) >> 8;
lb.x = ((cosma * xt - sinma * yt) >> LV_TRIGO_SHIFT) + ext->pivot.x;
lb.y = ((sinma * xt + cosma * yt) >> LV_TRIGO_SHIFT) + ext->pivot.y;
xt = (norm.x2 * ext->zoom) >> 8;
yt = (norm.y2 * ext->zoom) >> 8;
rb.x = ((cosma * xt - sinma * yt) >> LV_TRIGO_SHIFT) + ext->pivot.x;
rb.y = ((sinma * xt + cosma * yt) >> LV_TRIGO_SHIFT) + ext->pivot.y;
lv_area_t a;
a.x1 = LV_MATH_MIN(lb.x, LV_MATH_MIN(lt.x, LV_MATH_MIN(rb.x, rt.x)));
a.x2 = LV_MATH_MAX(lb.x, LV_MATH_MAX(lt.x, LV_MATH_MAX(rb.x, rt.x)));
a.y1 = LV_MATH_MIN(lb.y, LV_MATH_MIN(lt.y, LV_MATH_MIN(rb.y, rt.y)));
a.y2 = LV_MATH_MAX(lb.y, LV_MATH_MAX(lt.y, LV_MATH_MAX(rb.y, rt.y)));
img->ext_draw_pad = LV_MATH_MAX(img->ext_draw_pad, - a.x1);
img->ext_draw_pad = LV_MATH_MAX(img->ext_draw_pad, - a.y1);
img->ext_draw_pad = LV_MATH_MAX(img->ext_draw_pad, a.x2 - ext->w);
img->ext_draw_pad = LV_MATH_MAX(img->ext_draw_pad, a.y2 - ext->h);
}
} else if(sign == LV_SIGNAL_HIT_TEST) {
lv_hit_test_info_t *info = param;