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

img rotate fixes

This commit is contained in:
Gabor Kiss-Vamosi 2019-11-04 08:47:49 +01:00
parent b74e62edba
commit cbe780de14
2 changed files with 66 additions and 50 deletions

View File

@ -191,52 +191,6 @@ lv_img_src_t lv_img_src_get_type(const void * src)
static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mask, const void * src,
const lv_style_t * style, uint16_t angle, lv_opa_t opa_scale)
{
lv_area_t map_area_rot;
lv_area_copy(&map_area_rot, coords);
if(angle) {
/*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;
lv_area_t norm;
norm.x1 = + coords->x1 - pivot_x;
norm.y1 = + coords->y1 - pivot_y;
norm.x2 = + coords->x2 - pivot_x;
norm.y2 = + coords->y2 - pivot_y;
int16_t sinma = lv_trigo_sin(-angle);
int16_t cosma = lv_trigo_sin(-angle + 90);
lv_point_t lt;
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;
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;
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;
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);
}
lv_area_t mask_com; /*Common area of mask and coords*/
bool union_ok;
union_ok = lv_area_intersect(&mask_com, mask, &map_area_rot);
if(union_ok == false) {
return LV_RES_OK; /*Out of mask. There is nothing to draw so the image is drawn
successfully.*/
}
lv_opa_t opa =
opa_scale == LV_OPA_COVER ? style->image.opa : (uint16_t)((uint16_t)style->image.opa * opa_scale) >> 8;
@ -249,16 +203,70 @@ static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mas
if(cdsc->dec_dsc.error_msg != NULL) {
LV_LOG_WARN("Image draw error");
lv_draw_rect(coords, &mask_com, &lv_style_plain, LV_OPA_COVER);
lv_draw_label(coords, &mask_com, &lv_style_plain, LV_OPA_COVER, cdsc->dec_dsc.error_msg, LV_TXT_FLAG_NONE, NULL, NULL, NULL);
lv_draw_rect(coords, mask, &lv_style_plain, LV_OPA_COVER);
lv_draw_label(coords, mask, &lv_style_plain, LV_OPA_COVER, cdsc->dec_dsc.error_msg, LV_TXT_FLAG_NONE, NULL, NULL, NULL);
}
/* The decoder open could open the image and gave the entire uncompressed image.
* Just draw it!*/
else if(cdsc->dec_dsc.img_data) {
lv_area_t map_area_rot;
lv_area_copy(&map_area_rot, coords);
if(angle) {
/*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;
lv_area_t norm;
norm.x1 = + coords->x1 - pivot_x;
norm.y1 = + coords->y1 - pivot_y;
norm.x2 = + coords->x2 - pivot_x;
norm.y2 = + coords->y2 - pivot_y;
int16_t sinma = lv_trigo_sin(-angle);
int16_t cosma = lv_trigo_sin(-angle + 90);
lv_point_t lt;
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;
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;
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;
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);
}
lv_area_t mask_com; /*Common area of mask and coords*/
bool union_ok;
union_ok = lv_area_intersect(&mask_com, mask, &map_area_rot);
if(union_ok == false) {
return LV_RES_OK; /*Out of mask. There is nothing to draw so the image is drawn
successfully.*/
}
lv_draw_map(coords, &mask_com, cdsc->dec_dsc.img_data, opa, chroma_keyed, alpha_byte, style, angle);
}
/* The whole uncompressed image is not available. Try to read it line-by-line*/
else {
lv_area_t mask_com; /*Common area of mask and coords*/
bool union_ok;
union_ok = lv_area_intersect(&mask_com, mask, coords);
if(union_ok == false) {
return LV_RES_OK; /*Out of mask. There is nothing to draw so the image is drawn
successfully.*/
}
lv_coord_t width = lv_area_get_width(&mask_com);
uint8_t * buf = lv_draw_buf_get(lv_area_get_width(&mask_com) * LV_IMG_PX_SIZE_ALPHA_BYTE); /*+1 because of the possible alpha byte*/
@ -271,6 +279,10 @@ static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mas
lv_coord_t row;
lv_res_t read_res;
for(row = mask_com.y1; row <= mask_com.y2; row++) {
lv_area_t mask_line;
union_ok = lv_area_intersect(&mask_line, mask, &line);
if(union_ok == false) continue;
read_res = lv_img_decoder_read_line(&cdsc->dec_dsc, x, y, width, buf);
if(read_res != LV_RES_OK) {
lv_img_decoder_close(&cdsc->dec_dsc);
@ -278,7 +290,9 @@ static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mas
lv_draw_buf_release(buf);
return LV_RES_INV;
}
lv_draw_map(&line, &mask_com, buf, opa, chroma_keyed, alpha_byte, style, 0);
lv_draw_map(&line, &mask_line, buf, opa, chroma_keyed, alpha_byte, style, 0);
line.y1++;
line.y2++;
y++;

View File

@ -7,7 +7,9 @@
* INCLUDES
*********************/
#include <stddef.h>
#include <string.h>
#include "lv_img_buf.h"
#include "lv_draw_img.h"
#include "../lv_misc/lv_math.h"
#include "../lv_misc/lv_log.h"
@ -459,7 +461,7 @@ bool lv_img_buf_get_px_rotated(lv_img_rotate_dsc_t * dsc, lv_coord_t x, lv_coord
if(dsc->native_color) {
memcpy(&c_dest_yn, &src_u8[px - px_size * dsc->src_w], sizeof(lv_color_t));
if(dsc->has_alpha) opa_dest_yn = src_u8[px - px_size * dsc->src_w - 1];
if(dsc->has_alpha) opa_dest_yn = src_u8[px - px_size * dsc->src_w + px_size- 1];
} else {
c_dest_yn = lv_img_buf_get_px_color(&dsc->img_dsc, yn, y, dsc->color);
if(dsc->has_alpha) opa_dest_yn = lv_img_buf_get_px_alpha(&dsc->img_dsc, yn, y);