From 84a70d16175b0d089f70e337fa12ee4742500f85 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Fri, 1 Nov 2019 06:00:04 +0100 Subject: [PATCH] add lv_img_get_px_rotated --- src/lv_draw/lv_draw_img.c | 228 +++++++++++++++++++++++++++----------- src/lv_draw/lv_draw_img.h | 13 ++- src/lv_objx/lv_canvas.c | 114 ++++--------------- 3 files changed, 189 insertions(+), 166 deletions(-) diff --git a/src/lv_draw/lv_draw_img.c b/src/lv_draw/lv_draw_img.c index 2bb8c95b5..1b2bd8563 100644 --- a/src/lv_draw/lv_draw_img.c +++ b/src/lv_draw/lv_draw_img.c @@ -10,6 +10,7 @@ #include "lv_img_cache.h" #include "../lv_misc/lv_log.h" #include "../lv_misc/lv_mem.h" +#include "../lv_misc/lv_math.h" /********************* * DEFINES @@ -23,7 +24,7 @@ * STATIC PROTOTYPES **********************/ 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, lv_opa_t opa_scale); + const lv_style_t * style, lv_opa_t opa_scale); /********************** * STATIC VARIABLES @@ -46,7 +47,7 @@ static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mas * @param opa_scale scale down all opacities by the factor */ void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * src, const lv_style_t * style, - lv_opa_t opa_scale) + lv_opa_t opa_scale) { if(src == NULL) { LV_LOG_WARN("Image draw: src is NULL"); @@ -71,12 +72,11 @@ void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * * @param dsc an image descriptor * @param x x coordinate of the point to get * @param y x coordinate of the point to get - * @param style style of the image. In case of `LV_IMG_CF_ALPHA_1/2/4/8` `style->image.color` shows - * the color. Can be `NULL` but for `ALPHA` images black will be returned. In other cases it is not - * used. + * @param color the color of the image. In case of `LV_IMG_CF_ALPHA_1/2/4/8` this color is used. + * Not used in other cases. * @return color of the point */ -lv_color_t lv_img_buf_get_px_color(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, const lv_style_t * style) +lv_color_t lv_img_buf_get_px_color(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_color_t color) { lv_color_t p_color = LV_COLOR_BLACK; if(x >= dsc->header.w) { @@ -98,7 +98,7 @@ lv_color_t lv_img_buf_get_px_color(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t uint8_t * buf_u8 = (uint8_t *)dsc->data; if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR || dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED || - dsc->header.cf == LV_IMG_CF_TRUE_COLOR_ALPHA) { + dsc->header.cf == LV_IMG_CF_TRUE_COLOR_ALPHA) { uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf) >> 3; uint32_t px = dsc->header.w * y * px_size + x * px_size; memcpy(&p_color, &buf_u8[px], sizeof(lv_color_t)); @@ -140,11 +140,8 @@ lv_color_t lv_img_buf_get_px_color(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t uint32_t px = dsc->header.w * y + x; p_color.full = buf_u8[px]; } else if(dsc->header.cf == LV_IMG_CF_ALPHA_1BIT || dsc->header.cf == LV_IMG_CF_ALPHA_2BIT || - dsc->header.cf == LV_IMG_CF_ALPHA_4BIT || dsc->header.cf == LV_IMG_CF_ALPHA_8BIT) { - if(style) - p_color = style->image.color; - else - p_color = LV_COLOR_BLACK; + dsc->header.cf == LV_IMG_CF_ALPHA_4BIT || dsc->header.cf == LV_IMG_CF_ALPHA_8BIT) { + p_color = color; } return p_color; } @@ -203,7 +200,7 @@ lv_opa_t lv_img_buf_get_px_alpha(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y) return opa_table[px_opa]; } else if(dsc->header.cf == LV_IMG_CF_ALPHA_4BIT) { const uint8_t opa_table[16] = {0, 17, 34, 51, /*Opacity mapping with bpp = 4*/ - 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255}; + 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255}; uint8_t bit = (x & 0x1) * 4; x = x >> 1; @@ -337,6 +334,103 @@ void lv_img_buf_set_px_alpha(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_ } } +bool lv_img_get_px_rotated(lv_img_dsc_t * img, uint16_t angle, lv_color_t color, lv_point_t * point, lv_point_t * pivot, lv_color_t * res_color, lv_opa_t * res_opa) +{ + + int32_t sinma = lv_trigo_sin(-angle); + int32_t cosma = lv_trigo_sin(-angle + 90); /* cos */ + + /*Get the target point relative coordinates to the pivot*/ + int32_t xt = point->x - pivot->x; + int32_t yt = point->y - pivot->y; + + /*Get the source pixel from the upscaled image*/ + int32_t xs = ((cosma * xt - sinma * yt) >> (LV_TRIGO_SHIFT - 8)) + pivot->x * 256; + int32_t ys = ((sinma * xt + cosma * yt) >> (LV_TRIGO_SHIFT - 8)) + pivot->y * 256; + + /*Get the integer part of the source pixel*/ + int xs_int = xs >> 8; + int ys_int = ys >> 8; + + if(xs_int >= img->header.w) return false; + else if(xs_int < 0) return false; + + if(ys_int >= img->header.h) return false; + else if(ys_int < 0) return false; + + /*Get the fractional part of the source pixel*/ + int xs_fract = xs & 0xff; + int ys_fract = ys & 0xff; + + /* If the fractional < 0x70 mix the source pixel with the left/top pixel + * If the fractional > 0x90 mix the source pixel with the right/bottom pixel + * In the 0x70..0x90 range use the unchanged source pixel */ + + int xn; /*x neightboor*/ + lv_opa_t xr; /*x mix ratio*/ + if(xs_fract < 0x70) { + xn = xs_int - 1; + xr = xs_fract * 2; + } else if(xs_fract > 0x90) { + xn = xs_int + 1; + xr = (0xFF - xs_fract) * 2; + } else { + xn = xs_int; + xr = 0xFF; + } + + /*Handle under/overflow*/ + if(xn >= img->header.w) return false; + else if(xn < 0) return false; + + int yn; /*y neightboor*/ + lv_opa_t yr; /*y mix ratio*/ + if(ys_fract < 0x70) { + yn = ys_int - 1; + yr = ys_fract * 2; + } else if(ys_fract > 0x90) { + yn = ys_int + 1; + yr = (0xFF - ys_fract) * 2; + } else { + yn = ys_int; + yr = 0xFF; + } + + /*Handle under/overflow*/ + if(yn >= img->header.h) return false; + else if(yn < 0) return false; + + /*Get the mixture of the original source and the neightboor pixels in both directions*/ + /*Get the mixture of the original source and the neightboor pixels in both directions*/ + lv_color_t c_dest_int = lv_img_buf_get_px_color(img, xs_int, ys_int, color); + + if(lv_img_color_format_is_chroma_keyed(img->header.cf)) { + lv_color_t ct = LV_COLOR_TRANSP; + if(c_dest_int.full == ct.full) return false; + } + + lv_color_t c_dest_xn = lv_img_buf_get_px_color(img, xn, ys_int, color); + lv_color_t c_dest_yn = lv_img_buf_get_px_color(img, xs_int, yn, color); + + lv_color_t x_dest = lv_color_mix(c_dest_int, c_dest_xn, xr); + lv_color_t y_dest = lv_color_mix(c_dest_int, c_dest_yn, yr); + *res_color = lv_color_mix(x_dest, y_dest, LV_OPA_50); + + /*Get result pixel opacity*/ + if(lv_img_color_format_has_alpha(img->header.cf)) { + lv_opa_t opa_int = lv_img_buf_get_px_alpha(img, xs_int, ys_int); + lv_opa_t opa_xn = lv_img_buf_get_px_alpha(img, xn, ys_int); + lv_opa_t opa_yn = lv_img_buf_get_px_alpha(img, xs_int, yn); + lv_opa_t opa_x = (opa_int * xr + (opa_xn * (255 - xr))) >> 8; + lv_opa_t opa_y = (opa_int * yr + (opa_yn * (255 - yr))) >> 8; + + *res_opa = (opa_x + opa_y) / 2; + if(*res_opa <= LV_OPA_MIN) return false; + } + + return true; +} + /** * Set the palette color of an indexed image. Valid only for `LV_IMG_CF_INDEXED1/2/4/8` * @param dsc pointer to an image descriptor @@ -350,7 +444,7 @@ void lv_img_buf_set_px_alpha(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_ void lv_img_buf_set_palette(lv_img_dsc_t * dsc, uint8_t id, lv_color_t c) { if((dsc->header.cf == LV_IMG_CF_ALPHA_1BIT && id > 1) || (dsc->header.cf == LV_IMG_CF_ALPHA_2BIT && id > 3) || - (dsc->header.cf == LV_IMG_CF_ALPHA_4BIT && id > 15) || (dsc->header.cf == LV_IMG_CF_ALPHA_8BIT)) { + (dsc->header.cf == LV_IMG_CF_ALPHA_4BIT && id > 15) || (dsc->header.cf == LV_IMG_CF_ALPHA_8BIT)) { LV_LOG_WARN("lv_img_buf_set_px_alpha: invalid 'id'"); return; } @@ -371,20 +465,20 @@ uint8_t lv_img_color_format_get_px_size(lv_img_cf_t cf) uint8_t px_size = 0; switch(cf) { - case LV_IMG_CF_UNKNOWN: - case LV_IMG_CF_RAW: px_size = 0; break; - case LV_IMG_CF_TRUE_COLOR: - case LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED: px_size = LV_COLOR_SIZE; break; - case LV_IMG_CF_TRUE_COLOR_ALPHA: px_size = LV_IMG_PX_SIZE_ALPHA_BYTE << 3; break; - case LV_IMG_CF_INDEXED_1BIT: - case LV_IMG_CF_ALPHA_1BIT: px_size = 1; break; - case LV_IMG_CF_INDEXED_2BIT: - case LV_IMG_CF_ALPHA_2BIT: px_size = 2; break; - case LV_IMG_CF_INDEXED_4BIT: - case LV_IMG_CF_ALPHA_4BIT: px_size = 4; break; - case LV_IMG_CF_INDEXED_8BIT: - case LV_IMG_CF_ALPHA_8BIT: px_size = 8; break; - default: px_size = 0; break; + case LV_IMG_CF_UNKNOWN: + case LV_IMG_CF_RAW: px_size = 0; break; + case LV_IMG_CF_TRUE_COLOR: + case LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED: px_size = LV_COLOR_SIZE; break; + case LV_IMG_CF_TRUE_COLOR_ALPHA: px_size = LV_IMG_PX_SIZE_ALPHA_BYTE << 3; break; + case LV_IMG_CF_INDEXED_1BIT: + case LV_IMG_CF_ALPHA_1BIT: px_size = 1; break; + case LV_IMG_CF_INDEXED_2BIT: + case LV_IMG_CF_ALPHA_2BIT: px_size = 2; break; + case LV_IMG_CF_INDEXED_4BIT: + case LV_IMG_CF_ALPHA_4BIT: px_size = 4; break; + case LV_IMG_CF_INDEXED_8BIT: + case LV_IMG_CF_ALPHA_8BIT: px_size = 8; break; + default: px_size = 0; break; } return px_size; @@ -400,17 +494,17 @@ bool lv_img_color_format_is_chroma_keyed(lv_img_cf_t cf) bool is_chroma_keyed = false; switch(cf) { - case LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED: - case LV_IMG_CF_RAW_CHROMA_KEYED: + case LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED: + case LV_IMG_CF_RAW_CHROMA_KEYED: #if LV_INDEXED_CHROMA - case LV_IMG_CF_INDEXED_1BIT: - case LV_IMG_CF_INDEXED_2BIT: - case LV_IMG_CF_INDEXED_4BIT: - case LV_IMG_CF_INDEXED_8BIT: + case LV_IMG_CF_INDEXED_1BIT: + case LV_IMG_CF_INDEXED_2BIT: + case LV_IMG_CF_INDEXED_4BIT: + case LV_IMG_CF_INDEXED_8BIT: #endif - is_chroma_keyed = true; break; + is_chroma_keyed = true; break; - default: is_chroma_keyed = false; break; + default: is_chroma_keyed = false; break; } return is_chroma_keyed; @@ -426,17 +520,17 @@ bool lv_img_color_format_has_alpha(lv_img_cf_t cf) bool has_alpha = false; switch(cf) { - case LV_IMG_CF_TRUE_COLOR_ALPHA: - case LV_IMG_CF_RAW_ALPHA: - case LV_IMG_CF_INDEXED_1BIT: - case LV_IMG_CF_INDEXED_2BIT: - case LV_IMG_CF_INDEXED_4BIT: - case LV_IMG_CF_INDEXED_8BIT: - case LV_IMG_CF_ALPHA_1BIT: - case LV_IMG_CF_ALPHA_2BIT: - case LV_IMG_CF_ALPHA_4BIT: - case LV_IMG_CF_ALPHA_8BIT: has_alpha = true; break; - default: has_alpha = false; break; + case LV_IMG_CF_TRUE_COLOR_ALPHA: + case LV_IMG_CF_RAW_ALPHA: + case LV_IMG_CF_INDEXED_1BIT: + case LV_IMG_CF_INDEXED_2BIT: + case LV_IMG_CF_INDEXED_4BIT: + case LV_IMG_CF_INDEXED_8BIT: + case LV_IMG_CF_ALPHA_1BIT: + case LV_IMG_CF_ALPHA_2BIT: + case LV_IMG_CF_ALPHA_4BIT: + case LV_IMG_CF_ALPHA_8BIT: has_alpha = true; break; + default: has_alpha = false; break; } return has_alpha; @@ -479,16 +573,16 @@ lv_img_dsc_t *lv_img_buf_alloc(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf) lv_img_dsc_t *dsc = lv_mem_alloc(sizeof(lv_img_dsc_t)); if(dsc == NULL) return NULL; - + memset(dsc, 0, sizeof(lv_img_dsc_t)); - + /* Get image data size */ dsc->data_size = lv_img_buf_get_img_size(w, h, cf); if(dsc->data_size == 0) { lv_mem_free(dsc); return NULL; } - + /* Allocate raw buffer */ dsc->data = lv_mem_alloc(dsc->data_size); if(dsc->data == NULL) { @@ -496,7 +590,7 @@ lv_img_dsc_t *lv_img_buf_alloc(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf) return NULL; } memset((uint8_t *)dsc->data, 0, dsc->data_size); - + /* Fill in header */ dsc->header.always_zero = 0; dsc->header.w = w; @@ -510,7 +604,7 @@ void lv_img_buf_free(lv_img_dsc_t *dsc) if(dsc != NULL) { if(dsc->data != NULL) lv_mem_free(dsc->data); - + lv_mem_free(dsc); } } @@ -518,18 +612,18 @@ void lv_img_buf_free(lv_img_dsc_t *dsc) uint32_t lv_img_buf_get_img_size(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf) { switch(cf) { - case LV_IMG_CF_TRUE_COLOR: return LV_IMG_BUF_SIZE_TRUE_COLOR(w, h); - case LV_IMG_CF_TRUE_COLOR_ALPHA: return LV_IMG_BUF_SIZE_TRUE_COLOR_ALPHA(w, h); - case LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED: return LV_IMG_BUF_SIZE_TRUE_COLOR_CHROMA_KEYED(w, h); - case LV_IMG_CF_ALPHA_1BIT: return LV_IMG_BUF_SIZE_ALPHA_1BIT(w, h); - case LV_IMG_CF_ALPHA_2BIT: return LV_IMG_BUF_SIZE_ALPHA_2BIT(w, h); - case LV_IMG_CF_ALPHA_4BIT: return LV_IMG_BUF_SIZE_ALPHA_4BIT(w, h); - case LV_IMG_CF_ALPHA_8BIT: return LV_IMG_BUF_SIZE_ALPHA_8BIT(w, h); - case LV_IMG_CF_INDEXED_1BIT: return LV_IMG_BUF_SIZE_INDEXED_1BIT(w, h); - case LV_IMG_CF_INDEXED_2BIT: return LV_IMG_BUF_SIZE_INDEXED_2BIT(w, h); - case LV_IMG_CF_INDEXED_4BIT: return LV_IMG_BUF_SIZE_INDEXED_4BIT(w, h); - case LV_IMG_CF_INDEXED_8BIT: return LV_IMG_BUF_SIZE_INDEXED_8BIT(w, h); - default: return 0; + case LV_IMG_CF_TRUE_COLOR: return LV_IMG_BUF_SIZE_TRUE_COLOR(w, h); + case LV_IMG_CF_TRUE_COLOR_ALPHA: return LV_IMG_BUF_SIZE_TRUE_COLOR_ALPHA(w, h); + case LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED: return LV_IMG_BUF_SIZE_TRUE_COLOR_CHROMA_KEYED(w, h); + case LV_IMG_CF_ALPHA_1BIT: return LV_IMG_BUF_SIZE_ALPHA_1BIT(w, h); + case LV_IMG_CF_ALPHA_2BIT: return LV_IMG_BUF_SIZE_ALPHA_2BIT(w, h); + case LV_IMG_CF_ALPHA_4BIT: return LV_IMG_BUF_SIZE_ALPHA_4BIT(w, h); + case LV_IMG_CF_ALPHA_8BIT: return LV_IMG_BUF_SIZE_ALPHA_8BIT(w, h); + case LV_IMG_CF_INDEXED_1BIT: return LV_IMG_BUF_SIZE_INDEXED_1BIT(w, h); + case LV_IMG_CF_INDEXED_2BIT: return LV_IMG_BUF_SIZE_INDEXED_2BIT(w, h); + case LV_IMG_CF_INDEXED_4BIT: return LV_IMG_BUF_SIZE_INDEXED_4BIT(w, h); + case LV_IMG_CF_INDEXED_8BIT: return LV_IMG_BUF_SIZE_INDEXED_8BIT(w, h); + default: return 0; } } @@ -538,7 +632,7 @@ uint32_t lv_img_buf_get_img_size(lv_coord_t w, lv_coord_t h, lv_img_cf_t cf) **********************/ 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, lv_opa_t opa_scale) + const lv_style_t * style, lv_opa_t opa_scale) { lv_area_t mask_com; /*Common area of mask and coords*/ @@ -550,7 +644,7 @@ static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mas } lv_opa_t opa = - opa_scale == LV_OPA_COVER ? style->image.opa : (uint16_t)((uint16_t)style->image.opa * opa_scale) >> 8; + opa_scale == LV_OPA_COVER ? style->image.opa : (uint16_t)((uint16_t)style->image.opa * opa_scale) >> 8; lv_img_cache_entry_t * cdsc = lv_img_cache_open(src, style); @@ -568,7 +662,7 @@ static lv_res_t lv_img_draw_core(const lv_area_t * coords, const lv_area_t * mas * Just draw it!*/ else if(cdsc->dec_dsc.img_data) { lv_draw_map(coords, mask, cdsc->dec_dsc.img_data, opa, chroma_keyed, alpha_byte, style->image.color, - style->image.intense); + style->image.intense); } /* The whole uncompressed image is not available. Try to read it line-by-line*/ else { diff --git a/src/lv_draw/lv_draw_img.h b/src/lv_draw/lv_draw_img.h index 794dd79e6..8e8088b00 100644 --- a/src/lv_draw/lv_draw_img.h +++ b/src/lv_draw/lv_draw_img.h @@ -69,17 +69,19 @@ void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask, const void * */ lv_img_src_t lv_img_src_get_type(const void * src); + /** * Get the color of an image's pixel * @param dsc an image descriptor * @param x x coordinate of the point to get * @param y x coordinate of the point to get - * @param style style of the image. In case of `LV_IMG_CF_ALPHA_1/2/4/8` `style->image.color` shows - * the color. Can be `NULL` but for `ALPHA` images black will be returned. In other cases it is not - * used. + * @param color the color of the image. In case of `LV_IMG_CF_ALPHA_1/2/4/8` this color is used. + * Not used in other cases. * @return color of the point */ -lv_color_t lv_img_buf_get_px_color(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, const lv_style_t * style); +lv_color_t lv_img_buf_get_px_color(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_color_t color); + + /** * Get the alpha value of an image's pixel * @param dsc pointer to an image descriptor @@ -89,6 +91,9 @@ lv_color_t lv_img_buf_get_px_color(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t */ lv_opa_t lv_img_buf_get_px_alpha(lv_img_dsc_t * dsc, lv_coord_t x, lv_coord_t y); + +bool lv_img_get_px_rotated(lv_img_dsc_t * img, uint16_t angle, lv_color_t color, lv_point_t * point, lv_point_t * pivot, lv_color_t * res_color, lv_opa_t * res_opa); + /** * Set the color of a pixel of an image. The alpha channel won't be affected. * @param dsc pointer to an image descriptor diff --git a/src/lv_objx/lv_canvas.c b/src/lv_objx/lv_canvas.c index 453b06a86..28924f41f 100644 --- a/src/lv_objx/lv_canvas.c +++ b/src/lv_objx/lv_canvas.c @@ -197,7 +197,9 @@ lv_color_t lv_canvas_get_px(lv_obj_t * canvas, lv_coord_t x, lv_coord_t y) lv_canvas_ext_t * ext = lv_obj_get_ext_attr(canvas); const lv_style_t * style = lv_canvas_get_style(canvas, LV_CANVAS_STYLE_MAIN); - return lv_img_buf_get_px_color(&ext->dsc, x, y, style); + if(style == NULL) style = &lv_style_scr; + + return lv_img_buf_get_px_color(&ext->dsc, x, y, style->image.color); } /** @@ -291,115 +293,37 @@ void lv_canvas_rotate(lv_obj_t * canvas, lv_img_dsc_t * img, int16_t angle, lv_c lv_canvas_ext_t * ext_dst = lv_obj_get_ext_attr(canvas); const lv_style_t * style = lv_canvas_get_style(canvas, LV_CANVAS_STYLE_MAIN); - int32_t sinma = lv_trigo_sin(-angle); - int32_t cosma = lv_trigo_sin(-angle + 90); /* cos */ - int32_t img_width = img->header.w; - int32_t img_height = img->header.h; int32_t dest_width = ext_dst->dsc.header.w; int32_t dest_height = ext_dst->dsc.header.h; int32_t x; int32_t y; + lv_point_t point_p; + + lv_point_t pivot_p; + pivot_p.x = pivot_x; + pivot_p.y = pivot_y; + + lv_color_t color_res; + lv_opa_t opa_res; + + bool ret; + for(x = -offset_x; x < dest_width - offset_x; x++) { for(y = -offset_y; y < dest_height - offset_y; y++) { - /*Get the target point relative coordinates to the pivot*/ - int32_t xt = x - pivot_x; - int32_t yt = y - pivot_y; + point_p.x = x; + point_p.y = y; - /*Get the source pixel from the upscaled image*/ - int32_t xs = ((cosma * xt - sinma * yt) >> (LV_TRIGO_SHIFT - 8)) + pivot_x * 256; - int32_t ys = ((sinma * xt + cosma * yt) >> (LV_TRIGO_SHIFT - 8)) + pivot_y * 256; - - /*Get the integer part of the source pixel*/ - int xs_int = xs >> 8; - int ys_int = ys >> 8; - - if(xs_int >= img_width) - continue; - else if(xs_int < 0) - continue; - - if(ys_int >= img_height) - continue; - else if(ys_int < 0) - continue; - - /*Get the fractional part of the source pixel*/ - int xs_fract = xs & 0xff; - int ys_fract = ys & 0xff; - - /* If the fractional < 0x70 mix the source pixel with the left/top pixel - * If the fractional > 0x90 mix the source pixel with the right/bottom pixel - * In the 0x70..0x90 range use the unchanged source pixel */ - - int xn; /*x neightboor*/ - lv_opa_t xr; /*x mix ratio*/ - if(xs_fract < 0x70) { - xn = xs_int - 1; - xr = xs_fract * 2; - } else if(xs_fract > 0x90) { - xn = xs_int + 1; - xr = (0xFF - xs_fract) * 2; - } else { - xn = xs_int; - xr = 0xFF; - } - - /*Handle under/overflow*/ - if(xn >= img_width) - continue; - else if(xn < 0) - continue; - - int yn; /*y neightboor*/ - lv_opa_t yr; /*y mix ratio*/ - if(ys_fract < 0x70) { - yn = ys_int - 1; - yr = ys_fract * 2; - } else if(ys_fract > 0x90) { - yn = ys_int + 1; - yr = (0xFF - ys_fract) * 2; - } else { - yn = ys_int; - yr = 0xFF; - } - - /*Handle under/overflow*/ - if(yn >= img_height) - continue; - else if(yn < 0) - continue; - - /*Get the mixture of the original source and the neightboor pixels in both directions*/ - lv_color_t c_dest_int = lv_img_buf_get_px_color(img, xs_int, ys_int, style); - - if(lv_img_color_format_is_chroma_keyed(img->header.cf)) { - lv_color_t ct = LV_COLOR_TRANSP; - if(c_dest_int.full == ct.full) continue; - } - - lv_color_t c_dest_xn = lv_img_buf_get_px_color(img, xn, ys_int, style); - lv_color_t c_dest_yn = lv_img_buf_get_px_color(img, xs_int, yn, style); - lv_color_t x_dest = lv_color_mix(c_dest_int, c_dest_xn, xr); - lv_color_t y_dest = lv_color_mix(c_dest_int, c_dest_yn, yr); - lv_color_t color_res = lv_color_mix(x_dest, y_dest, LV_OPA_50); + ret = lv_img_get_px_rotated(img, angle, style->image.color, &point_p, &pivot_p, &color_res, &opa_res); + if(ret == false) continue; if(x + offset_x >= 0 && x + offset_x < dest_width && y + offset_y >= 0 && y + offset_y < dest_height) { /*If the image has no alpha channel just simple set the result color on the canvas*/ if(lv_img_color_format_has_alpha(img->header.cf) == false) { lv_img_buf_set_px_color(&ext_dst->dsc, x + offset_x, y + offset_y, color_res); } else { - /*Get result pixel opacity*/ - lv_opa_t opa_int = lv_img_buf_get_px_alpha(img, xs_int, ys_int); - lv_opa_t opa_xn = lv_img_buf_get_px_alpha(img, xn, ys_int); - lv_opa_t opa_yn = lv_img_buf_get_px_alpha(img, xs_int, yn); - lv_opa_t opa_x = (opa_int * xr + (opa_xn * (255 - xr))) >> 8; - lv_opa_t opa_y = (opa_int * yr + (opa_yn * (255 - yr))) >> 8; - lv_opa_t opa_res = (opa_x + opa_y) / 2; - if(opa_res <= LV_OPA_MIN) continue; - - lv_color_t bg_color = lv_img_buf_get_px_color(&ext_dst->dsc, x + offset_x, y + offset_y, style); + lv_color_t bg_color = lv_img_buf_get_px_color(&ext_dst->dsc, x + offset_x, y + offset_y, style->image.color); /*If the canvas has no alpha but the image has mix the image's color with * canvas*/