mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-20 12:32:18 +08:00
feat(iamge) add scale_x and scale_y support
This commit is contained in:
+100
-49
@@ -27,6 +27,7 @@ static void lv_image_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
|
||||
static void lv_image_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
|
||||
static void lv_image_event(const lv_obj_class_t * class_p, lv_event_t * e);
|
||||
static void draw_image(lv_event_t * e);
|
||||
static void scale_update(lv_obj_t * obj, int32_t zoom_x, int32_t zoom_y);
|
||||
|
||||
#if LV_USE_OBJ_PROPERTY
|
||||
static const lv_property_ops_t properties[] = {
|
||||
@@ -198,7 +199,7 @@ void lv_image_set_src(lv_obj_t * obj, const void * src)
|
||||
lv_obj_refresh_self_size(obj);
|
||||
|
||||
/*Provide enough room for the rotated corners*/
|
||||
if(img->rotation || img->zoom != LV_SCALE_NONE) lv_obj_refresh_ext_draw_size(obj);
|
||||
if(img->rotation || img->zoom_x != LV_SCALE_NONE || img->zoom_y != LV_SCALE_NONE) lv_obj_refresh_ext_draw_size(obj);
|
||||
|
||||
lv_obj_invalidate(obj);
|
||||
}
|
||||
@@ -243,7 +244,7 @@ void lv_image_set_rotation(lv_obj_t * obj, int32_t angle)
|
||||
lv_area_t a;
|
||||
lv_point_t pivot_px;
|
||||
lv_image_get_pivot(obj, &pivot_px);
|
||||
_lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->zoom, img->zoom, &pivot_px);
|
||||
_lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->zoom_x, img->zoom_y, &pivot_px);
|
||||
a.x1 += obj->coords.x1;
|
||||
a.y1 += obj->coords.y1;
|
||||
a.x2 += obj->coords.x1;
|
||||
@@ -259,7 +260,7 @@ void lv_image_set_rotation(lv_obj_t * obj, int32_t angle)
|
||||
lv_obj_refresh_ext_draw_size(obj);
|
||||
lv_display_enable_invalidation(disp, true);
|
||||
|
||||
_lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->zoom, img->zoom, &pivot_px);
|
||||
_lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->zoom_x, img->zoom_y, &pivot_px);
|
||||
a.x1 += obj->coords.x1;
|
||||
a.y1 += obj->coords.y1;
|
||||
a.x2 += obj->coords.x1;
|
||||
@@ -285,7 +286,7 @@ void lv_image_set_pivot(lv_obj_t * obj, lv_coord_t x, lv_coord_t y)
|
||||
lv_area_t a;
|
||||
lv_point_t pivot_px;
|
||||
lv_image_get_pivot(obj, &pivot_px);
|
||||
_lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->zoom, img->zoom, &pivot_px);
|
||||
_lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->zoom_x, img->zoom_y, &pivot_px);
|
||||
a.x1 += obj->coords.x1;
|
||||
a.y1 += obj->coords.y1;
|
||||
a.x2 += obj->coords.x1;
|
||||
@@ -303,7 +304,7 @@ void lv_image_set_pivot(lv_obj_t * obj, lv_coord_t x, lv_coord_t y)
|
||||
lv_display_enable_invalidation(disp, true);
|
||||
|
||||
lv_image_get_pivot(obj, &pivot_px);
|
||||
_lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->zoom, img->zoom, &pivot_px);
|
||||
_lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->zoom_x, img->zoom_y, &pivot_px);
|
||||
a.x1 += obj->coords.x1;
|
||||
a.y1 += obj->coords.y1;
|
||||
a.x2 += obj->coords.x1;
|
||||
@@ -314,44 +315,31 @@ void lv_image_set_pivot(lv_obj_t * obj, lv_coord_t x, lv_coord_t y)
|
||||
void lv_image_set_scale(lv_obj_t * obj, uint32_t zoom)
|
||||
{
|
||||
lv_image_t * img = (lv_image_t *)obj;
|
||||
if(zoom == img->zoom) return;
|
||||
if(zoom == img->zoom_x && zoom == img->zoom_y) return;
|
||||
|
||||
if(zoom == 0) zoom = 1;
|
||||
|
||||
if(img->obj_size_mode == LV_IMAGE_SIZE_MODE_REAL) {
|
||||
img->zoom = zoom;
|
||||
lv_obj_invalidate_area(obj, &obj->coords);
|
||||
return;
|
||||
}
|
||||
scale_update(obj, zoom, zoom);
|
||||
}
|
||||
|
||||
lv_obj_update_layout(obj); /*Be sure the object's size is calculated*/
|
||||
lv_coord_t w = lv_obj_get_width(obj);
|
||||
lv_coord_t h = lv_obj_get_height(obj);
|
||||
lv_area_t a;
|
||||
lv_point_t pivot_px;
|
||||
lv_image_get_pivot(obj, &pivot_px);
|
||||
_lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->zoom, img->zoom, &pivot_px);
|
||||
a.x1 += obj->coords.x1 - 1;
|
||||
a.y1 += obj->coords.y1 - 1;
|
||||
a.x2 += obj->coords.x1 + 1;
|
||||
a.y2 += obj->coords.y1 + 1;
|
||||
lv_obj_invalidate_area(obj, &a);
|
||||
void lv_image_set_scale_x(lv_obj_t * obj, uint32_t zoom)
|
||||
{
|
||||
lv_image_t * img = (lv_image_t *)obj;
|
||||
if(zoom == img->zoom_x) return;
|
||||
|
||||
img->zoom = zoom;
|
||||
if(zoom == 0) zoom = 1;
|
||||
|
||||
/* Disable invalidations because lv_obj_refresh_ext_draw_size would invalidate
|
||||
* the whole ext draw area */
|
||||
lv_display_t * disp = lv_obj_get_disp(obj);
|
||||
lv_display_enable_invalidation(disp, false);
|
||||
lv_obj_refresh_ext_draw_size(obj);
|
||||
lv_display_enable_invalidation(disp, true);
|
||||
scale_update(obj, zoom, img->zoom_y);
|
||||
}
|
||||
|
||||
_lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->zoom, img->zoom, &pivot_px);
|
||||
a.x1 += obj->coords.x1 - 1;
|
||||
a.y1 += obj->coords.y1 - 1;
|
||||
a.x2 += obj->coords.x1 + 1;
|
||||
a.y2 += obj->coords.y1 + 1;
|
||||
lv_obj_invalidate_area(obj, &a);
|
||||
void lv_image_set_scale_y(lv_obj_t * obj, uint32_t zoom)
|
||||
{
|
||||
lv_image_t * img = (lv_image_t *)obj;
|
||||
if(zoom == img->zoom_y) return;
|
||||
|
||||
if(zoom == 0) zoom = 1;
|
||||
|
||||
scale_update(obj, img->zoom_y, zoom);
|
||||
}
|
||||
|
||||
void lv_image_set_antialias(lv_obj_t * obj, bool antialias)
|
||||
@@ -429,7 +417,25 @@ lv_coord_t lv_image_get_scale(lv_obj_t * obj)
|
||||
|
||||
lv_image_t * img = (lv_image_t *)obj;
|
||||
|
||||
return img->zoom;
|
||||
return img->zoom_x;
|
||||
}
|
||||
|
||||
lv_coord_t lv_image_get_scale_x(lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_image_t * img = (lv_image_t *)obj;
|
||||
|
||||
return img->zoom_x;
|
||||
}
|
||||
|
||||
lv_coord_t lv_image_get_scale_y(lv_obj_t * obj)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_image_t * img = (lv_image_t *)obj;
|
||||
|
||||
return img->zoom_y;
|
||||
}
|
||||
|
||||
bool lv_image_get_antialias(lv_obj_t * obj)
|
||||
@@ -465,7 +471,8 @@ static void lv_image_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
|
||||
img->w = lv_obj_get_width(obj);
|
||||
img->h = lv_obj_get_height(obj);
|
||||
img->rotation = 0;
|
||||
img->zoom = LV_SCALE_NONE;
|
||||
img->zoom_x = LV_SCALE_NONE;
|
||||
img->zoom_y = LV_SCALE_NONE;
|
||||
img->antialias = LV_COLOR_DEPTH > 8 ? 1 : 0;
|
||||
img->offset.x = 0;
|
||||
img->offset.y = 0;
|
||||
@@ -500,7 +507,7 @@ static lv_point_t lv_image_get_transformed_size(lv_obj_t * obj)
|
||||
lv_point_t pivot_px;
|
||||
lv_image_get_pivot(obj, &pivot_px);
|
||||
_lv_image_buf_get_transformed_area(&area_transform, img->w, img->h,
|
||||
img->rotation, img->zoom, img->zoom, &pivot_px);
|
||||
img->rotation, img->zoom_x, img->zoom_y, &pivot_px);
|
||||
|
||||
return (lv_point_t) {
|
||||
lv_area_get_width(&area_transform), lv_area_get_height(&area_transform)
|
||||
@@ -540,11 +547,11 @@ static void lv_image_event(const lv_obj_class_t * class_p, lv_event_t * e)
|
||||
lv_coord_t * s = lv_event_get_param(e);
|
||||
|
||||
/*If the image has angle provide enough room for the rotated corners*/
|
||||
if(img->rotation || img->zoom != LV_SCALE_NONE) {
|
||||
if(img->rotation || img->zoom_x != LV_SCALE_NONE || img->zoom_y != LV_SCALE_NONE) {
|
||||
lv_area_t a;
|
||||
lv_coord_t w = lv_obj_get_width(obj);
|
||||
lv_coord_t h = lv_obj_get_height(obj);
|
||||
_lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->zoom, img->zoom, &pivot_px);
|
||||
_lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->zoom_x, img->zoom_y, &pivot_px);
|
||||
*s = LV_MAX(*s, -a.x1);
|
||||
*s = LV_MAX(*s, -a.y1);
|
||||
*s = LV_MAX(*s, a.x2 - w);
|
||||
@@ -557,12 +564,13 @@ static void lv_image_event(const lv_obj_class_t * class_p, lv_event_t * e)
|
||||
/*If the object is exactly image sized (not cropped, not mosaic) and transformed
|
||||
*perform hit test on its transformed area*/
|
||||
if(img->w == lv_obj_get_width(obj) && img->h == lv_obj_get_height(obj) &&
|
||||
(img->zoom != LV_SCALE_NONE || img->rotation != 0 || img->pivot.x != img->w / 2 || img->pivot.y != img->h / 2)) {
|
||||
(img->zoom_x != LV_SCALE_NONE || img->zoom_y != LV_SCALE_NONE ||
|
||||
img->rotation != 0 || img->pivot.x != img->w / 2 || img->pivot.y != img->h / 2)) {
|
||||
|
||||
lv_coord_t w = lv_obj_get_width(obj);
|
||||
lv_coord_t h = lv_obj_get_height(obj);
|
||||
lv_area_t coords;
|
||||
_lv_image_buf_get_transformed_area(&coords, w, h, img->rotation, img->zoom, img->zoom, &pivot_px);
|
||||
_lv_image_buf_get_transformed_area(&coords, w, h, img->rotation, img->zoom_x, img->zoom_y, &pivot_px);
|
||||
coords.x1 += obj->coords.x1;
|
||||
coords.y1 += obj->coords.y1;
|
||||
coords.x2 += obj->coords.x1;
|
||||
@@ -622,7 +630,7 @@ static void draw_image(lv_event_t * e)
|
||||
}
|
||||
|
||||
const lv_area_t * clip_area = lv_event_get_param(e);
|
||||
if(img->zoom == LV_SCALE_NONE) {
|
||||
if(img->zoom_x == LV_SCALE_NONE && img->zoom_y == LV_SCALE_NONE) {
|
||||
if(_lv_area_is_in(clip_area, &obj->coords, 0) == false) {
|
||||
info->res = LV_COVER_RES_NOT_COVER;
|
||||
return;
|
||||
@@ -632,7 +640,7 @@ static void draw_image(lv_event_t * e)
|
||||
lv_area_t a;
|
||||
lv_point_t pivot_px;
|
||||
lv_image_get_pivot(obj, &pivot_px);
|
||||
_lv_image_buf_get_transformed_area(&a, lv_obj_get_width(obj), lv_obj_get_height(obj), 0, img->zoom, img->zoom,
|
||||
_lv_image_buf_get_transformed_area(&a, lv_obj_get_width(obj), lv_obj_get_height(obj), 0, img->zoom_x, img->zoom_y,
|
||||
&pivot_px);
|
||||
a.x1 += obj->coords.x1;
|
||||
a.y1 += obj->coords.y1;
|
||||
@@ -670,7 +678,7 @@ static void draw_image(lv_event_t * e)
|
||||
}
|
||||
else {
|
||||
_lv_image_buf_get_transformed_area(&bg_coords, obj_w, obj_h,
|
||||
img->rotation, img->zoom, img->zoom, &bg_pivot);
|
||||
img->rotation, img->zoom_x, img->zoom_y, &bg_pivot);
|
||||
|
||||
/*Modify the coordinates to draw the background for the rotated and scaled coordinates*/
|
||||
bg_coords.x1 += obj->coords.x1;
|
||||
@@ -690,7 +698,7 @@ static void draw_image(lv_event_t * e)
|
||||
|
||||
if(code == LV_EVENT_DRAW_MAIN) {
|
||||
if(img->h == 0 || img->w == 0) return;
|
||||
if(img->zoom == 0) return;
|
||||
if(img->zoom_x == 0 || img->zoom_y == 0) return;
|
||||
|
||||
lv_layer_t * layer = lv_event_get_layer(e);
|
||||
|
||||
@@ -720,8 +728,8 @@ static void draw_image(lv_event_t * e)
|
||||
lv_draw_image_dsc_init(&img_dsc);
|
||||
lv_obj_init_draw_image_dsc(obj, LV_PART_MAIN, &img_dsc);
|
||||
|
||||
img_dsc.zoom_x = img->zoom;
|
||||
img_dsc.zoom_y = img->zoom;
|
||||
img_dsc.zoom_x = img->zoom_x;
|
||||
img_dsc.zoom_y = img->zoom_y;
|
||||
img_dsc.rotation = img->rotation;
|
||||
img_dsc.pivot.x = pivot_px.x;
|
||||
img_dsc.pivot.y = pivot_px.y;
|
||||
@@ -775,4 +783,47 @@ static void draw_image(lv_event_t * e)
|
||||
}
|
||||
}
|
||||
|
||||
static void scale_update(lv_obj_t * obj, int32_t zoom_x, int32_t zoom_y)
|
||||
{
|
||||
lv_image_t * img = (lv_image_t *)obj;
|
||||
|
||||
if(img->obj_size_mode == LV_IMAGE_SIZE_MODE_REAL) {
|
||||
img->zoom_x = zoom_x;
|
||||
img->zoom_y = zoom_y;
|
||||
lv_obj_invalidate_area(obj, &obj->coords);
|
||||
return;
|
||||
}
|
||||
|
||||
lv_obj_update_layout(obj); /*Be sure the object's size is calculated*/
|
||||
lv_coord_t w = lv_obj_get_width(obj);
|
||||
lv_coord_t h = lv_obj_get_height(obj);
|
||||
lv_area_t a;
|
||||
lv_point_t pivot_px;
|
||||
lv_image_get_pivot(obj, &pivot_px);
|
||||
_lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->zoom_x, img->zoom_y, &pivot_px);
|
||||
a.x1 += obj->coords.x1 - 1;
|
||||
a.y1 += obj->coords.y1 - 1;
|
||||
a.x2 += obj->coords.x1 + 1;
|
||||
a.y2 += obj->coords.y1 + 1;
|
||||
lv_obj_invalidate_area(obj, &a);
|
||||
|
||||
img->zoom_x = zoom_x;
|
||||
img->zoom_y = zoom_y;
|
||||
|
||||
/* Disable invalidations because lv_obj_refresh_ext_draw_size would invalidate
|
||||
* the whole ext draw area */
|
||||
lv_display_t * disp = lv_obj_get_disp(obj);
|
||||
lv_display_enable_invalidation(disp, false);
|
||||
lv_obj_refresh_ext_draw_size(obj);
|
||||
lv_display_enable_invalidation(disp, true);
|
||||
|
||||
_lv_image_buf_get_transformed_area(&a, w, h, img->rotation, img->zoom_x, img->zoom_y, &pivot_px);
|
||||
a.x1 += obj->coords.x1 - 1;
|
||||
a.y1 += obj->coords.y1 - 1;
|
||||
a.x2 += obj->coords.x1 + 1;
|
||||
a.y2 += obj->coords.y1 + 1;
|
||||
lv_obj_invalidate_area(obj, &a);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -44,7 +44,8 @@ typedef struct {
|
||||
lv_coord_t w; /*Width of the image (Handled by the library)*/
|
||||
lv_coord_t h; /*Height of the image (Handled by the library)*/
|
||||
uint32_t rotation; /*rotation angle of the image*/
|
||||
uint32_t zoom; /*256 means no zoom, 512 double size, 128 half size*/
|
||||
uint32_t zoom_x; /*256 means no zoom, 512 double size, 128 half size*/
|
||||
uint32_t zoom_y; /*256 means no zoom, 512 double size, 128 half size*/
|
||||
lv_point_t pivot; /*rotation center of the image*/
|
||||
uint8_t src_type : 2; /*See: lv_image_src_t*/
|
||||
uint8_t cf : 5; /*Color format from `lv_color_format_t`*/
|
||||
@@ -170,6 +171,33 @@ static inline void _lv_image_set_pivot(lv_obj_t * obj, lv_point_t * pivot)
|
||||
*/
|
||||
void lv_image_set_scale(lv_obj_t * obj, uint32_t zoom);
|
||||
|
||||
/**
|
||||
* Set the horizontal zoom factor of the image.
|
||||
* Note that indexed and alpha only images can't be transformed.
|
||||
* @param img pointer to an image object
|
||||
* @param zoom the zoom factor.
|
||||
* @example 256 or LV_ZOOM_IMAGE_NONE for no zoom
|
||||
* @example <256: scale down
|
||||
* @example >256 scale up
|
||||
* @example 128 half size
|
||||
* @example 512 double size
|
||||
*/
|
||||
void lv_image_set_scale_x(lv_obj_t * obj, uint32_t zoom);
|
||||
|
||||
/**
|
||||
* Set the vertical zoom factor of the image.
|
||||
* Note that indexed and alpha only images can't be transformed.
|
||||
* @param img pointer to an image object
|
||||
* @param zoom the zoom factor.
|
||||
* @example 256 or LV_ZOOM_IMAGE_NONE for no zoom
|
||||
* @example <256: scale down
|
||||
* @example >256 scale up
|
||||
* @example 128 half size
|
||||
* @example 512 double size
|
||||
*/
|
||||
void lv_image_set_scale_y(lv_obj_t * obj, uint32_t zoom);
|
||||
|
||||
|
||||
/**
|
||||
* Enable/disable anti-aliasing for the transformations (rotate, zoom) or not.
|
||||
* The quality is better with anti-aliasing looks better but slower.
|
||||
@@ -232,6 +260,20 @@ void lv_image_get_pivot(lv_obj_t * obj, lv_point_t * pivot);
|
||||
*/
|
||||
lv_coord_t lv_image_get_scale(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the horizontal zoom factor of the image.
|
||||
* @param obj pointer to an image object
|
||||
* @return zoom factor (256: no zoom)
|
||||
*/
|
||||
lv_coord_t lv_image_get_scale_x(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get the vertical zoom factor of the image.
|
||||
* @param obj pointer to an image object
|
||||
* @return zoom factor (256: no zoom)
|
||||
*/
|
||||
lv_coord_t lv_image_get_scale_y(lv_obj_t * obj);
|
||||
|
||||
/**
|
||||
* Get whether the transformations (rotate, zoom) are anti-aliased or not
|
||||
* @param obj pointer to an image object
|
||||
|
||||
Reference in New Issue
Block a user