feat(sdl): support rounded images (#3012)
* added radius mask for rounded img * improved mask composite improved image zoom fidelity * implementing sdl image radius * low performance radius img drawing * improved rounded image performance * improved rounded image performance * improved rounded image blending * pixel perfect rounded image for SDL * accurate drawing only * supports rounded img for rect as well * fixed mask check when zoomed * surrounded rounded mask in lv_img with draw_complex check * updated docs * fixed build issue * aware of clip_corner property * reverted lv_img.c * updated docs
This commit is contained in:
@@ -102,6 +102,12 @@ If you need the object size to be updated to the transformed size set `lv_img_se
|
|||||||
In this case if the width/height of the object is set to `LV_SIZE_CONTENT` the object's size will be set to the zoomed and rotated size.
|
In this case if the width/height of the object is set to `LV_SIZE_CONTENT` the object's size will be set to the zoomed and rotated size.
|
||||||
If an explicit size is set then the overflowing content will be cropped.
|
If an explicit size is set then the overflowing content will be cropped.
|
||||||
|
|
||||||
|
### Rounded image
|
||||||
|
|
||||||
|
You can use `lv_obj_set_style_radius` to set radius to an image, and enable `lv_obj_set_style_clip_corner` to clip the
|
||||||
|
content to rounded rectangle or circular shape. Please note this will have some negative performance impact to CPU
|
||||||
|
based renderers.
|
||||||
|
|
||||||
## Events
|
## Events
|
||||||
No special events are sent by image objects.
|
No special events are sent by image objects.
|
||||||
|
|
||||||
|
|||||||
@@ -146,21 +146,21 @@ void lv_draw_sdl_composite_end(lv_draw_sdl_ctx_t * ctx, const lv_area_t * apply_
|
|||||||
SDL_SetTextureBlendMode(internals->composition, SDL_BLENDMODE_BLEND);
|
SDL_SetTextureBlendMode(internals->composition, SDL_BLENDMODE_BLEND);
|
||||||
break;
|
break;
|
||||||
case LV_BLEND_MODE_ADDITIVE:
|
case LV_BLEND_MODE_ADDITIVE:
|
||||||
SDL_SetRenderDrawBlendMode(ctx->renderer, SDL_BLENDMODE_ADD);
|
SDL_SetTextureBlendMode(internals->composition, SDL_BLENDMODE_ADD);
|
||||||
break;
|
break;
|
||||||
#if LV_GPU_SDL_CUSTOM_BLEND_MODE
|
#if LV_GPU_SDL_CUSTOM_BLEND_MODE
|
||||||
case LV_BLEND_MODE_SUBTRACTIVE: {
|
case LV_BLEND_MODE_SUBTRACTIVE: {
|
||||||
SDL_BlendMode mode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE,
|
SDL_BlendMode mode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE,
|
||||||
SDL_BLENDOPERATION_SUBTRACT, SDL_BLENDFACTOR_ONE,
|
SDL_BLENDOPERATION_SUBTRACT, SDL_BLENDFACTOR_ONE,
|
||||||
SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_SUBTRACT);
|
SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_SUBTRACT);
|
||||||
SDL_SetRenderDrawBlendMode(ctx->renderer, mode);
|
SDL_SetTextureBlendMode(internals->composition, mode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LV_BLEND_MODE_MULTIPLY: {
|
case LV_BLEND_MODE_MULTIPLY: {
|
||||||
SDL_BlendMode mode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ZERO, SDL_BLENDFACTOR_SRC_COLOR,
|
SDL_BlendMode mode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ZERO, SDL_BLENDFACTOR_SRC_COLOR,
|
||||||
SDL_BLENDOPERATION_ADD, SDL_BLENDFACTOR_ZERO,
|
SDL_BLENDOPERATION_ADD, SDL_BLENDFACTOR_ZERO,
|
||||||
SDL_BLENDFACTOR_DST_ALPHA, SDL_BLENDOPERATION_ADD);
|
SDL_BLENDFACTOR_DST_ALPHA, SDL_BLENDOPERATION_ADD);
|
||||||
SDL_SetRenderDrawBlendMode(ctx->renderer, mode);
|
SDL_SetTextureBlendMode(internals->composition, mode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ typedef enum lv_draw_sdl_composite_texture_id_t {
|
|||||||
LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_STREAM0,
|
LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_STREAM0,
|
||||||
LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_STREAM1,
|
LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_STREAM1,
|
||||||
LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_TARGET0,
|
LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_TARGET0,
|
||||||
|
LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_TARGET1,
|
||||||
} lv_draw_sdl_composite_texture_id_t;
|
} lv_draw_sdl_composite_texture_id_t;
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
|
|||||||
@@ -15,9 +15,13 @@
|
|||||||
#include "../lv_img_cache.h"
|
#include "../lv_img_cache.h"
|
||||||
#include "../lv_draw_mask.h"
|
#include "../lv_draw_mask.h"
|
||||||
#include "../../misc/lv_lru.h"
|
#include "../../misc/lv_lru.h"
|
||||||
|
#include "../../misc/lv_gc.h"
|
||||||
|
|
||||||
|
#include "lv_draw_sdl_img.h"
|
||||||
#include "lv_draw_sdl_utils.h"
|
#include "lv_draw_sdl_utils.h"
|
||||||
#include "lv_draw_sdl_texture_cache.h"
|
#include "lv_draw_sdl_texture_cache.h"
|
||||||
|
#include "lv_draw_sdl_composite.h"
|
||||||
|
#include "lv_draw_sdl_rect.h"
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
@@ -26,10 +30,28 @@
|
|||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
**********************/
|
**********************/
|
||||||
typedef struct sdl_img_header_t {
|
|
||||||
lv_img_header_t base;
|
typedef struct {
|
||||||
SDL_Rect rect;
|
lv_sdl_cache_key_magic_t magic;
|
||||||
} sdl_img_header_t;
|
const SDL_Texture * texture;
|
||||||
|
lv_coord_t w, h, radius;
|
||||||
|
} lv_draw_img_rounded_key_t;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ROUNDED_IMG_PART_LEFT = 0,
|
||||||
|
ROUNDED_IMG_PART_HCENTER = 1,
|
||||||
|
ROUNDED_IMG_PART_RIGHT = 2,
|
||||||
|
ROUNDED_IMG_PART_TOP = 3,
|
||||||
|
ROUNDED_IMG_PART_VCENTER = 4,
|
||||||
|
ROUNDED_IMG_PART_BOTTOM = 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ROUNDED_IMG_CORNER_TOP_LEFT = 0,
|
||||||
|
ROUNDED_IMG_CORNER_TOP_RIGHT = 1,
|
||||||
|
ROUNDED_IMG_CORNER_BOTTOM_RIGHT = 2,
|
||||||
|
ROUNDED_IMG_CORNER_BOTTOM_LEFT = 3,
|
||||||
|
};
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC PROTOTYPES
|
* STATIC PROTOTYPES
|
||||||
@@ -39,6 +61,23 @@ static SDL_Texture * upload_img_texture(SDL_Renderer * renderer, lv_img_decoder_
|
|||||||
|
|
||||||
static SDL_Texture * upload_img_texture_fallback(SDL_Renderer * renderer, lv_img_decoder_dsc_t * dsc);
|
static SDL_Texture * upload_img_texture_fallback(SDL_Renderer * renderer, lv_img_decoder_dsc_t * dsc);
|
||||||
|
|
||||||
|
static bool check_mask_simple_radius(const lv_area_t * coords, lv_coord_t * radius);
|
||||||
|
|
||||||
|
static void draw_img_simple(lv_draw_sdl_ctx_t * ctx, SDL_Texture * texture, const lv_draw_sdl_img_header_t * header,
|
||||||
|
const lv_draw_img_dsc_t * draw_dsc, const lv_area_t * coords, const lv_area_t * clip);
|
||||||
|
|
||||||
|
static void draw_img_rounded(lv_draw_sdl_ctx_t * ctx, SDL_Texture * texture, const lv_draw_sdl_img_header_t * header,
|
||||||
|
const lv_draw_img_dsc_t * draw_dsc, const lv_area_t * coords, const lv_area_t * clip,
|
||||||
|
lv_coord_t radius);
|
||||||
|
|
||||||
|
static SDL_Texture * img_rounded_frag_obtain(lv_draw_sdl_ctx_t * ctx, SDL_Texture * texture,
|
||||||
|
const lv_draw_sdl_img_header_t * header, int w, int h, lv_coord_t radius);
|
||||||
|
|
||||||
|
static lv_draw_img_rounded_key_t rounded_key_create(const SDL_Texture * texture, lv_coord_t w, lv_coord_t h,
|
||||||
|
lv_coord_t radius);
|
||||||
|
|
||||||
|
static void calc_draw_part(SDL_Texture * texture, const lv_draw_sdl_img_header_t * header, const lv_area_t * coords,
|
||||||
|
const lv_area_t * clip, SDL_Rect * clipped_src, SDL_Rect * clipped_dst);
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC VARIABLES
|
* STATIC VARIABLES
|
||||||
**********************/
|
**********************/
|
||||||
@@ -47,6 +86,9 @@ static SDL_Texture * upload_img_texture_fallback(SDL_Renderer * renderer, lv_img
|
|||||||
* MACROS
|
* MACROS
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
|
|
||||||
|
static void apply_recolor_opa(SDL_Texture * texture, const lv_draw_img_dsc_t * draw_dsc);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* GLOBAL FUNCTIONS
|
* GLOBAL FUNCTIONS
|
||||||
**********************/
|
**********************/
|
||||||
@@ -56,16 +98,91 @@ lv_res_t lv_draw_sdl_img_core(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t
|
|||||||
{
|
{
|
||||||
const lv_area_t * clip = draw_ctx->clip_area;
|
const lv_area_t * clip = draw_ctx->clip_area;
|
||||||
lv_draw_sdl_ctx_t * ctx = (lv_draw_sdl_ctx_t *) draw_ctx;
|
lv_draw_sdl_ctx_t * ctx = (lv_draw_sdl_ctx_t *) draw_ctx;
|
||||||
SDL_Renderer * renderer = ctx->renderer;
|
|
||||||
|
|
||||||
size_t key_size;
|
size_t key_size;
|
||||||
lv_draw_sdl_cache_key_head_img_t * key = lv_draw_sdl_texture_img_key_create(src, draw_dsc->frame_id, &key_size);
|
lv_draw_sdl_cache_key_head_img_t * key = lv_draw_sdl_texture_img_key_create(src, draw_dsc->frame_id, &key_size);
|
||||||
bool texture_found = false;
|
bool texture_found = false;
|
||||||
sdl_img_header_t * header = NULL;
|
lv_draw_sdl_img_header_t * header = NULL;
|
||||||
SDL_Texture * texture = lv_draw_sdl_texture_cache_get_with_userdata(ctx, key, key_size, &texture_found,
|
SDL_Texture * texture = lv_draw_sdl_texture_cache_get_with_userdata(ctx, key, key_size, &texture_found,
|
||||||
(void **) &header);
|
(void **) &header);
|
||||||
if(!texture_found) {
|
if(!texture_found) {
|
||||||
_lv_img_cache_entry_t * cdsc = _lv_img_cache_open(src, draw_dsc->recolor, draw_dsc->frame_id);
|
lv_draw_sdl_img_load_texture(ctx, key, key_size, src, draw_dsc->frame_id, &texture, &header);
|
||||||
|
}
|
||||||
|
SDL_free(key);
|
||||||
|
if(!texture) {
|
||||||
|
return LV_RES_INV;
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_area_t zoomed_cords;
|
||||||
|
_lv_img_buf_get_transformed_area(&zoomed_cords, lv_area_get_width(coords), lv_area_get_height(coords), 0,
|
||||||
|
draw_dsc->zoom, &draw_dsc->pivot);
|
||||||
|
lv_area_move(&zoomed_cords, coords->x1, coords->y1);
|
||||||
|
|
||||||
|
/* When in > 0, draw simple radius */
|
||||||
|
lv_coord_t radius = 0;
|
||||||
|
/* Coords will be translated so coords will start at (0,0) */
|
||||||
|
lv_area_t t_coords = zoomed_cords, t_clip = *clip, apply_area;
|
||||||
|
|
||||||
|
if(!check_mask_simple_radius(&t_coords, &radius)) {
|
||||||
|
lv_draw_sdl_composite_begin(ctx, &zoomed_cords, clip, NULL, draw_dsc->blend_mode,
|
||||||
|
&t_coords, &t_clip, &apply_area);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Rect clip_rect, coords_rect;
|
||||||
|
lv_area_to_sdl_rect(&t_clip, &clip_rect);
|
||||||
|
lv_area_to_sdl_rect(&t_coords, &coords_rect);
|
||||||
|
|
||||||
|
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
||||||
|
|
||||||
|
if(radius > 0) {
|
||||||
|
draw_img_rounded(ctx, texture, header, draw_dsc, &t_coords, &t_clip, radius);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
draw_img_simple(ctx, texture, header, draw_dsc, &t_coords, &t_clip);
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_draw_sdl_composite_end(ctx, &apply_area, draw_dsc->blend_mode);
|
||||||
|
|
||||||
|
return LV_RES_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void calc_draw_part(SDL_Texture * texture, const lv_draw_sdl_img_header_t * header, const lv_area_t * coords,
|
||||||
|
const lv_area_t * clip, SDL_Rect * clipped_src, SDL_Rect * clipped_dst)
|
||||||
|
{
|
||||||
|
double x = 0, y = 0, w, h;
|
||||||
|
if(SDL_RectEmpty(&header->rect)) {
|
||||||
|
Uint32 format = 0;
|
||||||
|
int access = 0, tw, th;
|
||||||
|
SDL_QueryTexture(texture, &format, &access, &tw, &th);
|
||||||
|
w = tw;
|
||||||
|
h = th;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x = header->rect.x;
|
||||||
|
y = header->rect.y;
|
||||||
|
w = header->rect.w;
|
||||||
|
h = header->rect.h;
|
||||||
|
}
|
||||||
|
if(clip) {
|
||||||
|
lv_area_t clipped_area;
|
||||||
|
_lv_area_intersect(&clipped_area, coords, clip);
|
||||||
|
lv_area_to_sdl_rect(&clipped_area, clipped_dst);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lv_area_to_sdl_rect(coords, clipped_dst);
|
||||||
|
}
|
||||||
|
lv_coord_t coords_w = lv_area_get_width(coords), coords_h = lv_area_get_height(coords);
|
||||||
|
clipped_src->x = (int)(x + (clipped_dst->x - coords->x1) * w / coords_w);
|
||||||
|
clipped_src->y = (int)(y + (clipped_dst->y - coords->y1) * h / coords_h);
|
||||||
|
clipped_src->w = (int)(w - (coords_w - clipped_dst->w) * w / coords_w);
|
||||||
|
clipped_src->h = (int)(h - (coords_h - clipped_dst->h) * h / coords_h);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool lv_draw_sdl_img_load_texture(lv_draw_sdl_ctx_t * ctx, lv_draw_sdl_cache_key_head_img_t * key, size_t key_size,
|
||||||
|
const void * src, int32_t frame_id, SDL_Texture ** texture,
|
||||||
|
lv_draw_sdl_img_header_t ** header)
|
||||||
|
{
|
||||||
|
_lv_img_cache_entry_t * cdsc = _lv_img_cache_open(src, lv_color_white(), frame_id);
|
||||||
lv_draw_sdl_cache_flag_t tex_flags = 0;
|
lv_draw_sdl_cache_flag_t tex_flags = 0;
|
||||||
SDL_Rect rect;
|
SDL_Rect rect;
|
||||||
SDL_memset(&rect, 0, sizeof(SDL_Rect));
|
SDL_memset(&rect, 0, sizeof(SDL_Rect));
|
||||||
@@ -73,7 +190,7 @@ lv_res_t lv_draw_sdl_img_core(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t
|
|||||||
lv_img_decoder_dsc_t * dsc = &cdsc->dec_dsc;
|
lv_img_decoder_dsc_t * dsc = &cdsc->dec_dsc;
|
||||||
if(dsc->user_data && SDL_memcmp(dsc->user_data, LV_DRAW_SDL_DEC_DSC_TEXTURE_HEAD, 8) == 0) {
|
if(dsc->user_data && SDL_memcmp(dsc->user_data, LV_DRAW_SDL_DEC_DSC_TEXTURE_HEAD, 8) == 0) {
|
||||||
lv_draw_sdl_dec_dsc_userdata_t * ptr = (lv_draw_sdl_dec_dsc_userdata_t *) dsc->user_data;
|
lv_draw_sdl_dec_dsc_userdata_t * ptr = (lv_draw_sdl_dec_dsc_userdata_t *) dsc->user_data;
|
||||||
texture = ptr->texture;
|
*texture = ptr->texture;
|
||||||
rect = ptr->rect;
|
rect = ptr->rect;
|
||||||
if(ptr->texture_managed) {
|
if(ptr->texture_managed) {
|
||||||
tex_flags |= LV_DRAW_SDL_CACHE_FLAG_MANAGED;
|
tex_flags |= LV_DRAW_SDL_CACHE_FLAG_MANAGED;
|
||||||
@@ -81,89 +198,23 @@ lv_res_t lv_draw_sdl_img_core(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t
|
|||||||
ptr->texture_referenced = true;
|
ptr->texture_referenced = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
texture = upload_img_texture(renderer, dsc);
|
*texture = upload_img_texture(ctx->renderer, dsc);
|
||||||
}
|
}
|
||||||
#if LV_IMG_CACHE_DEF_SIZE == 0
|
#if LV_IMG_CACHE_DEF_SIZE == 0
|
||||||
lv_img_decoder_close(dsc);
|
lv_img_decoder_close(dsc);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if(texture && cdsc) {
|
if(texture && cdsc) {
|
||||||
header = SDL_malloc(sizeof(sdl_img_header_t));
|
*header = SDL_malloc(sizeof(lv_draw_sdl_img_header_t));
|
||||||
SDL_memcpy(&header->base, &cdsc->dec_dsc.header, sizeof(lv_img_header_t));
|
SDL_memcpy(&(*header)->base, &cdsc->dec_dsc.header, sizeof(lv_img_header_t));
|
||||||
header->rect = rect;
|
(*header)->rect = rect;
|
||||||
lv_draw_sdl_texture_cache_put_advanced(ctx, key, key_size, texture, header, SDL_free, tex_flags);
|
lv_draw_sdl_texture_cache_put_advanced(ctx, key, key_size, *texture, *header, SDL_free, tex_flags);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lv_draw_sdl_texture_cache_put(ctx, key, key_size, NULL);
|
lv_draw_sdl_texture_cache_put(ctx, key, key_size, NULL);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
return true;
|
||||||
SDL_free(key);
|
|
||||||
if(!texture) {
|
|
||||||
return LV_RES_INV;
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_Rect clip_rect, coords_rect;
|
|
||||||
lv_area_to_sdl_rect(clip, &clip_rect);
|
|
||||||
lv_area_to_sdl_rect(coords, &coords_rect);
|
|
||||||
lv_area_zoom_to_sdl_rect(coords, &coords_rect, draw_dsc->zoom, &draw_dsc->pivot);
|
|
||||||
|
|
||||||
SDL_Point pivot = {.x = draw_dsc->pivot.x, .y = draw_dsc->pivot.y};
|
|
||||||
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
|
||||||
SDL_Rect clipped_src = {0, 0, 0, 0}, clipped_dst = coords_rect;
|
|
||||||
const SDL_Rect * src_rect = NULL, *dst_rect = &clipped_dst;
|
|
||||||
|
|
||||||
if(_lv_area_is_in(coords, clip, 0)) {
|
|
||||||
/*Image needs to be fully drawn*/
|
|
||||||
src_rect = SDL_RectEmpty(&header->rect) ? NULL : &header->rect;
|
|
||||||
}
|
|
||||||
else if(draw_dsc->angle == 0) {
|
|
||||||
/*Image needs to be partly drawn, and we calculate the area to draw manually*/
|
|
||||||
Uint32 format = 0;
|
|
||||||
int access = 0, w, h;
|
|
||||||
if(SDL_RectEmpty(&header->rect)) {
|
|
||||||
SDL_QueryTexture(texture, &format, &access, &w, &h);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
w = header->rect.w;
|
|
||||||
h = header->rect.h;
|
|
||||||
}
|
|
||||||
SDL_IntersectRect(&clip_rect, &coords_rect, &clipped_dst);
|
|
||||||
clipped_src.x = header->rect.x + (clipped_dst.x - coords_rect.x) * w / coords_rect.w;
|
|
||||||
clipped_src.y = header->rect.y + (clipped_dst.y - coords_rect.y) * h / coords_rect.h;
|
|
||||||
clipped_src.w = w - (coords_rect.w - clipped_dst.w) * w / coords_rect.w;
|
|
||||||
clipped_src.h = h - (coords_rect.h - clipped_dst.h) * h / coords_rect.h;
|
|
||||||
src_rect = &clipped_src;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/*Image needs to be rotated, so we have to use clip rect which is slower*/
|
|
||||||
SDL_RenderSetClipRect(renderer, &clip_rect);
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_Color recolor;
|
|
||||||
lv_color_to_sdl_color(&draw_dsc->recolor, &recolor);
|
|
||||||
if(draw_dsc->recolor_opa == LV_OPA_COVER) {
|
|
||||||
/* Draw fully recolored image*/
|
|
||||||
SDL_SetTextureColorMod(texture, draw_dsc->recolor.ch.red, recolor.g, recolor.b);
|
|
||||||
SDL_SetTextureAlphaMod(texture, draw_dsc->opa);
|
|
||||||
SDL_RenderCopyEx(renderer, texture, src_rect, dst_rect, draw_dsc->angle, &pivot, SDL_FLIP_NONE);
|
|
||||||
}
|
|
||||||
else if(draw_dsc->recolor_opa > LV_OPA_TRANSP) {
|
|
||||||
/* Draw blended. src: origA, dst: origA * recolorA */
|
|
||||||
SDL_SetTextureColorMod(texture, 0xFF, 0xFF, 0xFF);
|
|
||||||
SDL_SetTextureAlphaMod(texture, draw_dsc->opa);
|
|
||||||
SDL_RenderCopyEx(renderer, texture, src_rect, dst_rect, draw_dsc->angle, &pivot, SDL_FLIP_NONE);
|
|
||||||
SDL_SetTextureColorMod(texture, recolor.r, recolor.g, recolor.b);
|
|
||||||
SDL_SetTextureAlphaMod(texture, draw_dsc->opa * draw_dsc->recolor_opa / 255);
|
|
||||||
SDL_RenderCopyEx(renderer, texture, src_rect, dst_rect, draw_dsc->angle, &pivot, SDL_FLIP_NONE);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* Draw with no recolor */
|
|
||||||
SDL_SetTextureColorMod(texture, 0xFF, 0xFF, 0xFF);
|
|
||||||
SDL_SetTextureAlphaMod(texture, draw_dsc->opa);
|
|
||||||
SDL_RenderCopyEx(renderer, texture, src_rect, dst_rect, draw_dsc->angle, &pivot, SDL_FLIP_NONE);
|
|
||||||
}
|
|
||||||
SDL_RenderSetClipRect(renderer, NULL);
|
|
||||||
return LV_RES_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
@@ -175,9 +226,9 @@ static SDL_Texture * upload_img_texture(SDL_Renderer * renderer, lv_img_decoder_
|
|||||||
if(!dsc->img_data) {
|
if(!dsc->img_data) {
|
||||||
return upload_img_texture_fallback(renderer, dsc);
|
return upload_img_texture_fallback(renderer, dsc);
|
||||||
}
|
}
|
||||||
bool chroma_keyed = dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED;
|
bool chroma_keyed = dsc->header.cf == (uint32_t) LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED;
|
||||||
uint32_t h = dsc->header.h;
|
int h = (int) dsc->header.h;
|
||||||
uint32_t w = dsc->header.w;
|
int w = (int) dsc->header.w;
|
||||||
void * data = (void *) dsc->img_data;
|
void * data = (void *) dsc->img_data;
|
||||||
Uint32 rmask = 0x00FF0000;
|
Uint32 rmask = 0x00FF0000;
|
||||||
Uint32 gmask = 0x0000FF00;
|
Uint32 gmask = 0x0000FF00;
|
||||||
@@ -196,8 +247,8 @@ static SDL_Texture * upload_img_texture(SDL_Renderer * renderer, lv_img_decoder_
|
|||||||
|
|
||||||
static SDL_Texture * upload_img_texture_fallback(SDL_Renderer * renderer, lv_img_decoder_dsc_t * dsc)
|
static SDL_Texture * upload_img_texture_fallback(SDL_Renderer * renderer, lv_img_decoder_dsc_t * dsc)
|
||||||
{
|
{
|
||||||
lv_coord_t h = dsc->header.h;
|
lv_coord_t h = (lv_coord_t) dsc->header.h;
|
||||||
lv_coord_t w = dsc->header.w;
|
lv_coord_t w = (lv_coord_t) dsc->header.w;
|
||||||
uint8_t * data = lv_mem_buf_get(w * h * sizeof(lv_color_t));
|
uint8_t * data = lv_mem_buf_get(w * h * sizeof(lv_color_t));
|
||||||
for(lv_coord_t y = 0; y < h; y++) {
|
for(lv_coord_t y = 0; y < h; y++) {
|
||||||
lv_img_decoder_read_line(dsc, 0, y, w, &data[y * w * sizeof(lv_color_t)]);
|
lv_img_decoder_read_line(dsc, 0, y, w, &data[y * w * sizeof(lv_color_t)]);
|
||||||
@@ -215,5 +266,194 @@ static SDL_Texture * upload_img_texture_fallback(SDL_Renderer * renderer, lv_img
|
|||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if there is only one radius mask
|
||||||
|
* @param radius Set to radius value if the only mask is a radius mask
|
||||||
|
* @return true if the only mask is a radius mask
|
||||||
|
*/
|
||||||
|
static bool check_mask_simple_radius(const lv_area_t * coords, lv_coord_t * radius)
|
||||||
|
{
|
||||||
|
if(lv_draw_mask_get_cnt() != 1) return false;
|
||||||
|
for(uint8_t i = 0; i < _LV_MASK_MAX_NUM; i++) {
|
||||||
|
_lv_draw_mask_common_dsc_t * param = LV_GC_ROOT(_lv_draw_mask_list[i]).param;
|
||||||
|
if(param->type == LV_DRAW_MASK_TYPE_RADIUS) {
|
||||||
|
lv_draw_mask_radius_param_t * rparam = (lv_draw_mask_radius_param_t *) param;
|
||||||
|
if(rparam->cfg.outer) return false;
|
||||||
|
if(!_lv_area_is_equal(&rparam->cfg.rect, coords)) return false;
|
||||||
|
*radius = rparam->cfg.radius;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void draw_img_simple(lv_draw_sdl_ctx_t * ctx, SDL_Texture * texture, const lv_draw_sdl_img_header_t * header,
|
||||||
|
const lv_draw_img_dsc_t * draw_dsc, const lv_area_t * coords, const lv_area_t * clip)
|
||||||
|
{
|
||||||
|
apply_recolor_opa(texture, draw_dsc);
|
||||||
|
SDL_Point pivot = {.x = draw_dsc->pivot.x, .y = draw_dsc->pivot.y};
|
||||||
|
|
||||||
|
/*Image needs to be rotated, so we have to use clip rect which is slower*/
|
||||||
|
if(draw_dsc->angle != 0) {
|
||||||
|
/* No radius, set clip here */
|
||||||
|
SDL_Rect clip_rect;
|
||||||
|
lv_area_to_sdl_rect(clip, &clip_rect);
|
||||||
|
SDL_RenderSetClipRect(ctx->renderer, &clip_rect);
|
||||||
|
}
|
||||||
|
SDL_Rect src_rect, dst_rect;
|
||||||
|
calc_draw_part(texture, header, coords, clip, &src_rect, &dst_rect);
|
||||||
|
SDL_RenderCopyEx(ctx->renderer, texture, &src_rect, &dst_rect, draw_dsc->angle, &pivot, SDL_FLIP_NONE);
|
||||||
|
if(draw_dsc->angle != 0) {
|
||||||
|
SDL_RenderSetClipRect(ctx->renderer, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void draw_img_rounded(lv_draw_sdl_ctx_t * ctx, SDL_Texture * texture, const lv_draw_sdl_img_header_t * header,
|
||||||
|
const lv_draw_img_dsc_t * draw_dsc, const lv_area_t * coords, const lv_area_t * clip,
|
||||||
|
lv_coord_t radius)
|
||||||
|
{
|
||||||
|
const int w = lv_area_get_width(coords), h = lv_area_get_height(coords);
|
||||||
|
lv_coord_t real_radius = LV_MIN3(radius, w, h);
|
||||||
|
SDL_Texture * frag = img_rounded_frag_obtain(ctx, texture, header, w, h, real_radius);
|
||||||
|
apply_recolor_opa(frag, draw_dsc);
|
||||||
|
lv_draw_sdl_rect_bg_frag_draw_corners(ctx, frag, real_radius, coords, clip, true);
|
||||||
|
|
||||||
|
apply_recolor_opa(texture, draw_dsc);
|
||||||
|
|
||||||
|
SDL_Rect src_rect, dst_rect;
|
||||||
|
/* Draw 3 parts */
|
||||||
|
lv_area_t clip_tmp, part;
|
||||||
|
calc_draw_part(texture, header, coords, NULL, &src_rect, &dst_rect);
|
||||||
|
for(int i = w > h ? ROUNDED_IMG_PART_LEFT : ROUNDED_IMG_PART_TOP, j = i + 3; i <= j; i++) {
|
||||||
|
switch(i) {
|
||||||
|
case ROUNDED_IMG_PART_LEFT:
|
||||||
|
lv_area_set(&part, coords->x1, coords->y1 + radius, coords->x1 + radius - 1, coords->y2 - radius);
|
||||||
|
break;
|
||||||
|
case ROUNDED_IMG_PART_HCENTER:
|
||||||
|
lv_area_set(&part, coords->x1 + radius, coords->y1, coords->x2 - radius, coords->y2);
|
||||||
|
break;
|
||||||
|
case ROUNDED_IMG_PART_RIGHT:
|
||||||
|
lv_area_set(&part, coords->x2 - radius + 1, coords->y1 + radius, coords->x2, coords->y2 - radius);
|
||||||
|
break;
|
||||||
|
case ROUNDED_IMG_PART_TOP:
|
||||||
|
lv_area_set(&part, coords->x1 + radius, coords->y1, coords->x2 - radius, coords->y1 + radius - 1);
|
||||||
|
break;
|
||||||
|
case ROUNDED_IMG_PART_VCENTER:
|
||||||
|
lv_area_set(&part, coords->x1 + radius, coords->y2 - radius + 1, coords->x2 - radius, coords->y2);
|
||||||
|
break;
|
||||||
|
case ROUNDED_IMG_PART_BOTTOM:
|
||||||
|
lv_area_set(&part, coords->x1, coords->y1 + radius, coords->x2, coords->y2 - radius);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(!_lv_area_intersect(&clip_tmp, &part, clip)) continue;
|
||||||
|
SDL_Rect clip_rect;
|
||||||
|
lv_area_to_sdl_rect(&clip_tmp, &clip_rect);
|
||||||
|
SDL_RenderSetClipRect(ctx->renderer, &clip_rect);
|
||||||
|
SDL_RenderCopy(ctx->renderer, texture, &src_rect, &dst_rect);
|
||||||
|
}
|
||||||
|
SDL_RenderSetClipRect(ctx->renderer, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void apply_recolor_opa(SDL_Texture * texture, const lv_draw_img_dsc_t * draw_dsc)
|
||||||
|
{
|
||||||
|
if(draw_dsc->recolor_opa > LV_OPA_TRANSP) {
|
||||||
|
/* Draw with mixed recolor */
|
||||||
|
lv_color_t recolor = lv_color_mix(draw_dsc->recolor, lv_color_white(), draw_dsc->recolor_opa);
|
||||||
|
SDL_SetTextureColorMod(texture, recolor.ch.red, recolor.ch.green, recolor.ch.blue);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Draw with no recolor */
|
||||||
|
SDL_SetTextureColorMod(texture, 0xFF, 0xFF, 0xFF);
|
||||||
|
}
|
||||||
|
SDL_SetTextureAlphaMod(texture, draw_dsc->opa);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SDL_Texture * img_rounded_frag_obtain(lv_draw_sdl_ctx_t * ctx, SDL_Texture * texture,
|
||||||
|
const lv_draw_sdl_img_header_t * header, int w, int h, lv_coord_t radius)
|
||||||
|
{
|
||||||
|
lv_draw_img_rounded_key_t key = rounded_key_create(texture, w, h, radius);
|
||||||
|
SDL_Texture * mask_frag = lv_draw_sdl_rect_bg_frag_obtain(ctx, radius);
|
||||||
|
SDL_Texture * img_frag = lv_draw_sdl_texture_cache_get(ctx, &key, sizeof(key), NULL);
|
||||||
|
if(img_frag == NULL) {
|
||||||
|
const lv_coord_t full_frag_size = radius * 2 + 3;
|
||||||
|
img_frag = SDL_CreateTexture(ctx->renderer, LV_DRAW_SDL_TEXTURE_FORMAT, SDL_TEXTUREACCESS_TARGET,
|
||||||
|
full_frag_size, full_frag_size);
|
||||||
|
SDL_SetTextureBlendMode(img_frag, SDL_BLENDMODE_BLEND);
|
||||||
|
SDL_Texture * old_target = SDL_GetRenderTarget(ctx->renderer);
|
||||||
|
SDL_SetRenderTarget(ctx->renderer, img_frag);
|
||||||
|
SDL_SetRenderDrawColor(ctx->renderer, 0, 0, 0, 0);
|
||||||
|
SDL_RenderClear(ctx->renderer);
|
||||||
|
|
||||||
|
lv_area_t coords = {0, 0, w - 1, h - 1}, clip;
|
||||||
|
lv_area_t frag_coords = {0, 0, full_frag_size - 1, full_frag_size - 1};
|
||||||
|
lv_draw_sdl_rect_bg_frag_draw_corners(ctx, mask_frag, radius, &frag_coords, NULL, false);
|
||||||
|
|
||||||
|
SDL_SetTextureAlphaMod(texture, 0xFF);
|
||||||
|
SDL_SetTextureColorMod(texture, 0xFF, 0xFF, 0xFF);
|
||||||
|
#if LV_GPU_SDL_CUSTOM_BLEND_MODE
|
||||||
|
SDL_BlendMode blend_mode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ZERO,
|
||||||
|
SDL_BLENDOPERATION_ADD, SDL_BLENDFACTOR_DST_ALPHA,
|
||||||
|
SDL_BLENDFACTOR_ZERO, SDL_BLENDOPERATION_ADD);
|
||||||
|
SDL_SetTextureBlendMode(texture, blend_mode);
|
||||||
|
#else
|
||||||
|
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_MOD);
|
||||||
|
#endif
|
||||||
|
SDL_Rect srcrect, cliprect, dstrect = {0, 0, radius, radius};
|
||||||
|
|
||||||
|
cliprect.w = cliprect.h = radius;
|
||||||
|
for(int i = 0; i <= ROUNDED_IMG_CORNER_BOTTOM_LEFT; i++) {
|
||||||
|
switch(i) {
|
||||||
|
case ROUNDED_IMG_CORNER_TOP_LEFT:
|
||||||
|
cliprect.x = 0;
|
||||||
|
cliprect.y = 0;
|
||||||
|
lv_area_align(&frag_coords, &coords, LV_ALIGN_TOP_LEFT, 0, 0);
|
||||||
|
break;
|
||||||
|
case ROUNDED_IMG_CORNER_TOP_RIGHT:
|
||||||
|
cliprect.x = full_frag_size - radius;
|
||||||
|
cliprect.y = 0;
|
||||||
|
lv_area_align(&frag_coords, &coords, LV_ALIGN_TOP_RIGHT, 0, 0);
|
||||||
|
break;
|
||||||
|
case ROUNDED_IMG_CORNER_BOTTOM_RIGHT:
|
||||||
|
cliprect.x = full_frag_size - radius;
|
||||||
|
cliprect.y = full_frag_size - radius;
|
||||||
|
lv_area_align(&frag_coords, &coords, LV_ALIGN_BOTTOM_RIGHT, 0, 0);
|
||||||
|
break;
|
||||||
|
case ROUNDED_IMG_CORNER_BOTTOM_LEFT:
|
||||||
|
cliprect.x = 0;
|
||||||
|
cliprect.y = full_frag_size - radius;
|
||||||
|
lv_area_align(&frag_coords, &coords, LV_ALIGN_BOTTOM_LEFT, 0, 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
calc_draw_part(texture, header, &coords, NULL, &srcrect, &dstrect);
|
||||||
|
SDL_RenderSetClipRect(ctx->renderer, &cliprect);
|
||||||
|
SDL_RenderCopy(ctx->renderer, texture, &srcrect, &dstrect);
|
||||||
|
}
|
||||||
|
SDL_RenderSetClipRect(ctx->renderer, NULL);
|
||||||
|
|
||||||
|
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
||||||
|
|
||||||
|
SDL_SetRenderTarget(ctx->renderer, old_target);
|
||||||
|
lv_draw_sdl_texture_cache_put(ctx, &key, sizeof(key), img_frag);
|
||||||
|
}
|
||||||
|
return img_frag;
|
||||||
|
}
|
||||||
|
|
||||||
|
static lv_draw_img_rounded_key_t rounded_key_create(const SDL_Texture * texture, lv_coord_t w, lv_coord_t h,
|
||||||
|
lv_coord_t radius)
|
||||||
|
{
|
||||||
|
lv_draw_img_rounded_key_t key;
|
||||||
|
SDL_memset(&key, 0, sizeof(key));
|
||||||
|
key.magic = LV_GPU_CACHE_KEY_MAGIC_IMG_ROUNDED_CORNERS;
|
||||||
|
key.texture = texture;
|
||||||
|
key.w = w;
|
||||||
|
key.h = h;
|
||||||
|
key.radius = radius;
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /*LV_USE_GPU_SDL*/
|
#endif /*LV_USE_GPU_SDL*/
|
||||||
|
|||||||
72
src/draw/sdl/lv_draw_sdl_img.h
Normal file
72
src/draw/sdl/lv_draw_sdl_img.h
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/**
|
||||||
|
* @file lv_draw_sdl_img.h
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LV_DRAW_SDL_IMG_H
|
||||||
|
#define LV_DRAW_SDL_IMG_H
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* INCLUDES
|
||||||
|
*********************/
|
||||||
|
#include "../../lv_conf_internal.h"
|
||||||
|
|
||||||
|
#if LV_USE_GPU_SDL
|
||||||
|
|
||||||
|
#include LV_GPU_SDL_INCLUDE_PATH
|
||||||
|
|
||||||
|
#include "../lv_draw.h"
|
||||||
|
|
||||||
|
#include "lv_draw_sdl_texture_cache.h"
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* DEFINES
|
||||||
|
*********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* TYPEDEFS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
typedef struct lv_draw_sdl_img_header_t {
|
||||||
|
lv_img_header_t base;
|
||||||
|
SDL_Rect rect;
|
||||||
|
} lv_draw_sdl_img_header_t;
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* GLOBAL PROTOTYPES
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/*======================
|
||||||
|
* Add/remove functions
|
||||||
|
*=====================*/
|
||||||
|
|
||||||
|
/*=====================
|
||||||
|
* Setter functions
|
||||||
|
*====================*/
|
||||||
|
|
||||||
|
/*=====================
|
||||||
|
* Getter functions
|
||||||
|
*====================*/
|
||||||
|
|
||||||
|
/*=====================
|
||||||
|
* Other functions
|
||||||
|
*====================*/
|
||||||
|
bool lv_draw_sdl_img_load_texture(lv_draw_sdl_ctx_t * ctx, lv_draw_sdl_cache_key_head_img_t * key, size_t key_size,
|
||||||
|
const void * src, int32_t frame_id, SDL_Texture ** texture,
|
||||||
|
lv_draw_sdl_img_header_t ** header);
|
||||||
|
/**********************
|
||||||
|
* MACROS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
#endif /*LV_USE_GPU_SDL*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /*extern "C"*/
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*LV_DRAW_SDL_IMG_H*/
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "lv_draw_sdl_composite.h"
|
#include "lv_draw_sdl_composite.h"
|
||||||
#include "lv_draw_sdl_mask.h"
|
#include "lv_draw_sdl_mask.h"
|
||||||
#include "lv_draw_sdl_stack_blur.h"
|
#include "lv_draw_sdl_stack_blur.h"
|
||||||
|
#include "lv_draw_sdl_img.h"
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
@@ -72,9 +73,6 @@ static void draw_border_generic(lv_draw_sdl_ctx_t * ctx, const lv_area_t * outer
|
|||||||
const lv_area_t * clip, lv_coord_t rout, lv_coord_t rin, lv_color_t color, lv_opa_t opa,
|
const lv_area_t * clip, lv_coord_t rout, lv_coord_t rin, lv_color_t color, lv_opa_t opa,
|
||||||
lv_blend_mode_t blend_mode);
|
lv_blend_mode_t blend_mode);
|
||||||
|
|
||||||
static void frag_render_corners(SDL_Renderer * renderer, SDL_Texture * frag, lv_coord_t frag_size,
|
|
||||||
const lv_area_t * coords, const lv_area_t * clip, bool full);
|
|
||||||
|
|
||||||
static void frag_render_borders(SDL_Renderer * renderer, SDL_Texture * frag, lv_coord_t frag_size,
|
static void frag_render_borders(SDL_Renderer * renderer, SDL_Texture * frag, lv_coord_t frag_size,
|
||||||
const lv_area_t * coords, const lv_area_t * clipped, bool full);
|
const lv_area_t * coords, const lv_area_t * clipped, bool full);
|
||||||
|
|
||||||
@@ -143,6 +141,103 @@ void lv_draw_sdl_draw_rect(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t *
|
|||||||
lv_draw_sdl_composite_end(ctx, &apply_area, dsc->blend_mode);
|
lv_draw_sdl_composite_end(ctx, &apply_area, dsc->blend_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDL_Texture * lv_draw_sdl_rect_bg_frag_obtain(lv_draw_sdl_ctx_t * ctx, lv_coord_t radius)
|
||||||
|
{
|
||||||
|
lv_draw_rect_bg_key_t key = rect_bg_key_create(radius, radius);
|
||||||
|
lv_area_t coords = {0, 0, radius * 2 - 1, radius * 2 - 1};
|
||||||
|
lv_area_t coords_frag = {0, 0, radius - 1, radius - 1};
|
||||||
|
SDL_Texture * texture = lv_draw_sdl_texture_cache_get(ctx, &key, sizeof(key), NULL);
|
||||||
|
if(texture == NULL) {
|
||||||
|
lv_draw_mask_radius_param_t mask_rout_param;
|
||||||
|
lv_draw_mask_radius_init(&mask_rout_param, &coords, radius, false);
|
||||||
|
int16_t mask_id = lv_draw_mask_add(&mask_rout_param, NULL);
|
||||||
|
texture = lv_draw_sdl_mask_dump_texture(ctx->renderer, &coords_frag, &mask_id, 1);
|
||||||
|
lv_draw_mask_remove_id(mask_id);
|
||||||
|
SDL_assert(texture);
|
||||||
|
lv_draw_sdl_texture_cache_put(ctx, &key, sizeof(key), texture);
|
||||||
|
}
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lv_draw_sdl_rect_bg_frag_draw_corners(lv_draw_sdl_ctx_t * ctx, SDL_Texture * frag, lv_coord_t frag_size,
|
||||||
|
const lv_area_t * coords, const lv_area_t * clip, bool full)
|
||||||
|
{
|
||||||
|
if(!clip) clip = coords;
|
||||||
|
lv_area_t corner_area, dst_area;
|
||||||
|
/* Upper left */
|
||||||
|
corner_area.x1 = coords->x1;
|
||||||
|
corner_area.y1 = coords->y1;
|
||||||
|
corner_area.x2 = coords->x1 + frag_size - 1;
|
||||||
|
corner_area.y2 = coords->y1 + frag_size - 1;
|
||||||
|
if(_lv_area_intersect(&dst_area, &corner_area, clip)) {
|
||||||
|
SDL_Rect dst_rect;
|
||||||
|
lv_area_to_sdl_rect(&dst_area, &dst_rect);
|
||||||
|
|
||||||
|
lv_coord_t dw = lv_area_get_width(&dst_area), dh = lv_area_get_height(&dst_area);
|
||||||
|
lv_coord_t sx = (lv_coord_t)(dst_area.x1 - corner_area.x1), sy = (lv_coord_t)(dst_area.y1 - corner_area.y1);
|
||||||
|
SDL_Rect src_rect = {sx, sy, dw, dh};
|
||||||
|
SDL_RenderCopy(ctx->renderer, frag, &src_rect, &dst_rect);
|
||||||
|
}
|
||||||
|
/* Upper right, clip right edge if too big */
|
||||||
|
corner_area.x1 = LV_MAX(coords->x2 - frag_size + 1, coords->x1 + frag_size);
|
||||||
|
corner_area.x2 = coords->x2;
|
||||||
|
if(_lv_area_intersect(&dst_area, &corner_area, clip)) {
|
||||||
|
SDL_Rect dst_rect;
|
||||||
|
lv_area_to_sdl_rect(&dst_area, &dst_rect);
|
||||||
|
|
||||||
|
lv_coord_t dw = lv_area_get_width(&dst_area), dh = lv_area_get_height(&dst_area);
|
||||||
|
if(full) {
|
||||||
|
lv_coord_t sx = (lv_coord_t)(dst_area.x1 - corner_area.x1),
|
||||||
|
sy = (lv_coord_t)(dst_area.y1 - corner_area.y1);
|
||||||
|
SDL_Rect src_rect = {frag_size + 3 + sx, sy, dw, dh};
|
||||||
|
SDL_RenderCopy(ctx->renderer, frag, &src_rect, &dst_rect);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SDL_Rect src_rect = {corner_area.x2 - dst_area.x2, dst_area.y1 - corner_area.y1, dw, dh};
|
||||||
|
SDL_RenderCopyEx(ctx->renderer, frag, &src_rect, &dst_rect, 0, NULL, SDL_FLIP_HORIZONTAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Lower right, clip bottom edge if too big */
|
||||||
|
corner_area.y1 = LV_MAX(coords->y2 - frag_size + 1, coords->y1 + frag_size);
|
||||||
|
corner_area.y2 = coords->y2;
|
||||||
|
if(_lv_area_intersect(&dst_area, &corner_area, clip)) {
|
||||||
|
SDL_Rect dst_rect;
|
||||||
|
lv_area_to_sdl_rect(&dst_area, &dst_rect);
|
||||||
|
|
||||||
|
lv_coord_t dw = lv_area_get_width(&dst_area), dh = lv_area_get_height(&dst_area);
|
||||||
|
if(full) {
|
||||||
|
lv_coord_t sx = (lv_coord_t)(dst_area.x1 - corner_area.x1),
|
||||||
|
sy = (lv_coord_t)(dst_area.y1 - corner_area.y1);
|
||||||
|
SDL_Rect src_rect = {frag_size + 3 + sx, frag_size + 3 + sy, dw, dh};
|
||||||
|
SDL_RenderCopy(ctx->renderer, frag, &src_rect, &dst_rect);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SDL_Rect src_rect = {corner_area.x2 - dst_area.x2, corner_area.y2 - dst_area.y2, dw, dh};
|
||||||
|
SDL_RenderCopyEx(ctx->renderer, frag, &src_rect, &dst_rect, 0, NULL, SDL_FLIP_HORIZONTAL | SDL_FLIP_VERTICAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Lower left, right edge should not be clip */
|
||||||
|
corner_area.x1 = coords->x1;
|
||||||
|
corner_area.x2 = coords->x1 + frag_size - 1;
|
||||||
|
if(_lv_area_intersect(&dst_area, &corner_area, clip)) {
|
||||||
|
SDL_Rect dst_rect;
|
||||||
|
lv_area_to_sdl_rect(&dst_area, &dst_rect);
|
||||||
|
|
||||||
|
lv_coord_t dw = lv_area_get_width(&dst_area), dh = lv_area_get_height(&dst_area);
|
||||||
|
if(full) {
|
||||||
|
lv_coord_t sx = (lv_coord_t)(dst_area.x1 - corner_area.x1),
|
||||||
|
sy = (lv_coord_t)(dst_area.y1 - corner_area.y1);
|
||||||
|
SDL_Rect src_rect = {sx, frag_size + 3 + sy, dw, dh};
|
||||||
|
SDL_RenderCopy(ctx->renderer, frag, &src_rect, &dst_rect);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SDL_Rect src_rect = {dst_area.x1 - corner_area.x1, corner_area.y2 - dst_area.y2, dw, dh};
|
||||||
|
SDL_RenderCopyEx(ctx->renderer, frag, &src_rect, &dst_rect, 0, NULL, SDL_FLIP_VERTICAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC FUNCTIONS
|
* STATIC FUNCTIONS
|
||||||
**********************/
|
**********************/
|
||||||
@@ -167,29 +262,15 @@ static void draw_bg_color(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, con
|
|||||||
|
|
||||||
/*A small texture with a quarter of the rect is enough*/
|
/*A small texture with a quarter of the rect is enough*/
|
||||||
lv_coord_t bg_w = lv_area_get_width(coords), bg_h = lv_area_get_height(coords);
|
lv_coord_t bg_w = lv_area_get_width(coords), bg_h = lv_area_get_height(coords);
|
||||||
lv_coord_t frag_size = LV_MIN3(bg_w / 2, bg_h / 2, radius);
|
lv_coord_t real_radius = LV_MIN3(bg_w / 2, bg_h / 2, radius);
|
||||||
lv_draw_rect_bg_key_t key = rect_bg_key_create(radius, frag_size);
|
SDL_Texture * texture = lv_draw_sdl_rect_bg_frag_obtain(ctx, real_radius);
|
||||||
lv_area_t coords_frag;
|
|
||||||
lv_area_copy(&coords_frag, coords);
|
|
||||||
lv_area_set_width(&coords_frag, frag_size);
|
|
||||||
lv_area_set_height(&coords_frag, frag_size);
|
|
||||||
SDL_Texture * texture = lv_draw_sdl_texture_cache_get(ctx, &key, sizeof(key), NULL);
|
|
||||||
if(texture == NULL) {
|
|
||||||
lv_draw_mask_radius_param_t mask_rout_param;
|
|
||||||
lv_draw_mask_radius_init(&mask_rout_param, coords, radius, false);
|
|
||||||
int16_t mask_id = lv_draw_mask_add(&mask_rout_param, NULL);
|
|
||||||
texture = lv_draw_sdl_mask_dump_texture(ctx->renderer, &coords_frag, &mask_id, 1);
|
|
||||||
lv_draw_mask_remove_id(mask_id);
|
|
||||||
SDL_assert(texture);
|
|
||||||
lv_draw_sdl_texture_cache_put(ctx, &key, sizeof(key), texture);
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
||||||
SDL_SetTextureAlphaMod(texture, dsc->bg_opa);
|
SDL_SetTextureAlphaMod(texture, dsc->bg_opa);
|
||||||
SDL_SetTextureColorMod(texture, bg_color.r, bg_color.g, bg_color.b);
|
SDL_SetTextureColorMod(texture, bg_color.r, bg_color.g, bg_color.b);
|
||||||
frag_render_corners(ctx->renderer, texture, frag_size, coords, draw_area, false);
|
lv_draw_sdl_rect_bg_frag_draw_corners(ctx, texture, real_radius, coords, draw_area, false);
|
||||||
frag_render_borders(ctx->renderer, texture, frag_size, coords, draw_area, false);
|
frag_render_borders(ctx->renderer, texture, real_radius, coords, draw_area, false);
|
||||||
frag_render_center(ctx->renderer, texture, frag_size, coords, draw_area, false);
|
frag_render_center(ctx->renderer, texture, real_radius, coords, draw_area, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void draw_bg_img(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, const lv_area_t * draw_area,
|
static void draw_bg_img(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, const lv_area_t * draw_area,
|
||||||
@@ -238,6 +319,14 @@ static void draw_bg_img(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, const
|
|||||||
img_dsc.recolor = dsc->bg_img_recolor;
|
img_dsc.recolor = dsc->bg_img_recolor;
|
||||||
img_dsc.recolor_opa = dsc->bg_img_recolor_opa;
|
img_dsc.recolor_opa = dsc->bg_img_recolor_opa;
|
||||||
img_dsc.opa = dsc->bg_img_opa;
|
img_dsc.opa = dsc->bg_img_opa;
|
||||||
|
img_dsc.frame_id = 0;
|
||||||
|
|
||||||
|
int16_t radius_mask_id = LV_MASK_ID_INV;
|
||||||
|
lv_draw_mask_radius_param_t radius_param;
|
||||||
|
if(dsc->radius > 0) {
|
||||||
|
lv_draw_mask_radius_init(&radius_param, coords, dsc->radius, false);
|
||||||
|
radius_mask_id = lv_draw_mask_add(&radius_param, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/*Center align*/
|
/*Center align*/
|
||||||
if(dsc->bg_img_tiled == false) {
|
if(dsc->bg_img_tiled == false) {
|
||||||
@@ -263,6 +352,11 @@ static void draw_bg_img(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(radius_mask_id != LV_MASK_ID_INV) {
|
||||||
|
lv_draw_mask_remove_id(radius_mask_id);
|
||||||
|
lv_draw_mask_free_param(&radius_param);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,7 +432,7 @@ static void draw_shadow(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, const
|
|||||||
SDL_SetTextureAlphaMod(texture, opa);
|
SDL_SetTextureAlphaMod(texture, opa);
|
||||||
SDL_SetTextureColorMod(texture, shadow_color.r, shadow_color.g, shadow_color.b);
|
SDL_SetTextureColorMod(texture, shadow_color.r, shadow_color.g, shadow_color.b);
|
||||||
|
|
||||||
frag_render_corners(ctx->renderer, texture, blur_frag_size, &shadow_area, clip, false);
|
lv_draw_sdl_rect_bg_frag_draw_corners(ctx, texture, blur_frag_size, &shadow_area, clip, false);
|
||||||
frag_render_borders(ctx->renderer, texture, blur_frag_size, &shadow_area, clip, false);
|
frag_render_borders(ctx->renderer, texture, blur_frag_size, &shadow_area, clip, false);
|
||||||
frag_render_center(ctx->renderer, texture, blur_frag_size, &shadow_area, clip, false);
|
frag_render_center(ctx->renderer, texture, blur_frag_size, &shadow_area, clip, false);
|
||||||
}
|
}
|
||||||
@@ -460,87 +554,10 @@ static void draw_border_generic(lv_draw_sdl_ctx_t * ctx, const lv_area_t * outer
|
|||||||
SDL_SetTextureAlphaMod(texture, opa);
|
SDL_SetTextureAlphaMod(texture, opa);
|
||||||
SDL_SetTextureColorMod(texture, color_sdl.r, color_sdl.g, color_sdl.b);
|
SDL_SetTextureColorMod(texture, color_sdl.r, color_sdl.g, color_sdl.b);
|
||||||
|
|
||||||
frag_render_corners(renderer, texture, frag_size, outer_area, clip, true);
|
lv_draw_sdl_rect_bg_frag_draw_corners(ctx, texture, frag_size, outer_area, clip, true);
|
||||||
frag_render_borders(renderer, texture, frag_size, outer_area, clip, true);
|
frag_render_borders(renderer, texture, frag_size, outer_area, clip, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void frag_render_corners(SDL_Renderer * renderer, SDL_Texture * frag, lv_coord_t frag_size,
|
|
||||||
const lv_area_t * coords, const lv_area_t * clipped, bool full)
|
|
||||||
{
|
|
||||||
lv_area_t corner_area, dst_area;
|
|
||||||
/* Upper left */
|
|
||||||
corner_area.x1 = coords->x1;
|
|
||||||
corner_area.y1 = coords->y1;
|
|
||||||
corner_area.x2 = coords->x1 + frag_size - 1;
|
|
||||||
corner_area.y2 = coords->y1 + frag_size - 1;
|
|
||||||
if(_lv_area_intersect(&dst_area, &corner_area, clipped)) {
|
|
||||||
SDL_Rect dst_rect;
|
|
||||||
lv_area_to_sdl_rect(&dst_area, &dst_rect);
|
|
||||||
|
|
||||||
lv_coord_t dw = lv_area_get_width(&dst_area), dh = lv_area_get_height(&dst_area);
|
|
||||||
lv_coord_t sx = (lv_coord_t)(dst_area.x1 - corner_area.x1), sy = (lv_coord_t)(dst_area.y1 - corner_area.y1);
|
|
||||||
SDL_Rect src_rect = {sx, sy, dw, dh};
|
|
||||||
SDL_RenderCopy(renderer, frag, &src_rect, &dst_rect);
|
|
||||||
}
|
|
||||||
/* Upper right, clip right edge if too big */
|
|
||||||
corner_area.x1 = LV_MAX(coords->x2 - frag_size + 1, coords->x1 + frag_size);
|
|
||||||
corner_area.x2 = coords->x2;
|
|
||||||
if(_lv_area_intersect(&dst_area, &corner_area, clipped)) {
|
|
||||||
SDL_Rect dst_rect;
|
|
||||||
lv_area_to_sdl_rect(&dst_area, &dst_rect);
|
|
||||||
|
|
||||||
lv_coord_t dw = lv_area_get_width(&dst_area), dh = lv_area_get_height(&dst_area);
|
|
||||||
if(full) {
|
|
||||||
lv_coord_t sx = (lv_coord_t)(dst_area.x1 - corner_area.x1),
|
|
||||||
sy = (lv_coord_t)(dst_area.y1 - corner_area.y1);
|
|
||||||
SDL_Rect src_rect = {frag_size + 3 + sx, sy, dw, dh};
|
|
||||||
SDL_RenderCopy(renderer, frag, &src_rect, &dst_rect);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SDL_Rect src_rect = {corner_area.x2 - dst_area.x2, dst_area.y1 - corner_area.y1, dw, dh};
|
|
||||||
SDL_RenderCopyEx(renderer, frag, &src_rect, &dst_rect, 0, NULL, SDL_FLIP_HORIZONTAL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Lower right, clip bottom edge if too big */
|
|
||||||
corner_area.y1 = LV_MAX(coords->y2 - frag_size + 1, coords->y1 + frag_size);
|
|
||||||
corner_area.y2 = coords->y2;
|
|
||||||
if(_lv_area_intersect(&dst_area, &corner_area, clipped)) {
|
|
||||||
SDL_Rect dst_rect;
|
|
||||||
lv_area_to_sdl_rect(&dst_area, &dst_rect);
|
|
||||||
|
|
||||||
lv_coord_t dw = lv_area_get_width(&dst_area), dh = lv_area_get_height(&dst_area);
|
|
||||||
if(full) {
|
|
||||||
lv_coord_t sx = (lv_coord_t)(dst_area.x1 - corner_area.x1),
|
|
||||||
sy = (lv_coord_t)(dst_area.y1 - corner_area.y1);
|
|
||||||
SDL_Rect src_rect = {frag_size + 3 + sx, frag_size + 3 + sy, dw, dh};
|
|
||||||
SDL_RenderCopy(renderer, frag, &src_rect, &dst_rect);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SDL_Rect src_rect = {corner_area.x2 - dst_area.x2, corner_area.y2 - dst_area.y2, dw, dh};
|
|
||||||
SDL_RenderCopyEx(renderer, frag, &src_rect, &dst_rect, 0, NULL, SDL_FLIP_HORIZONTAL | SDL_FLIP_VERTICAL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Lower left, right edge should not be clipped */
|
|
||||||
corner_area.x1 = coords->x1;
|
|
||||||
corner_area.x2 = coords->x1 + frag_size - 1;
|
|
||||||
if(_lv_area_intersect(&dst_area, &corner_area, clipped)) {
|
|
||||||
SDL_Rect dst_rect;
|
|
||||||
lv_area_to_sdl_rect(&dst_area, &dst_rect);
|
|
||||||
|
|
||||||
lv_coord_t dw = lv_area_get_width(&dst_area), dh = lv_area_get_height(&dst_area);
|
|
||||||
if(full) {
|
|
||||||
lv_coord_t sx = (lv_coord_t)(dst_area.x1 - corner_area.x1),
|
|
||||||
sy = (lv_coord_t)(dst_area.y1 - corner_area.y1);
|
|
||||||
SDL_Rect src_rect = {sx, frag_size + 3 + sy, dw, dh};
|
|
||||||
SDL_RenderCopy(renderer, frag, &src_rect, &dst_rect);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SDL_Rect src_rect = {dst_area.x1 - corner_area.x1, corner_area.y2 - dst_area.y2, dw, dh};
|
|
||||||
SDL_RenderCopyEx(renderer, frag, &src_rect, &dst_rect, 0, NULL, SDL_FLIP_VERTICAL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void frag_render_borders(SDL_Renderer * renderer, SDL_Texture * frag, lv_coord_t frag_size,
|
static void frag_render_borders(SDL_Renderer * renderer, SDL_Texture * frag, lv_coord_t frag_size,
|
||||||
const lv_area_t * coords, const lv_area_t * clipped, bool full)
|
const lv_area_t * coords, const lv_area_t * clipped, bool full)
|
||||||
{
|
{
|
||||||
|
|||||||
75
src/draw/sdl/lv_draw_sdl_rect.h
Normal file
75
src/draw/sdl/lv_draw_sdl_rect.h
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
/**
|
||||||
|
* @file lv_draw_sdl_rect.h
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LV_DRAW_SDL_RECT_H
|
||||||
|
#define LV_DRAW_SDL_RECT_H
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* INCLUDES
|
||||||
|
*********************/
|
||||||
|
#include "../../lv_conf_internal.h"
|
||||||
|
|
||||||
|
#if LV_USE_GPU_SDL
|
||||||
|
|
||||||
|
#include LV_GPU_SDL_INCLUDE_PATH
|
||||||
|
|
||||||
|
#include "../lv_draw.h"
|
||||||
|
|
||||||
|
#include "lv_draw_sdl_texture_cache.h"
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* DEFINES
|
||||||
|
*********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* TYPEDEFS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
typedef struct lv_draw_sdl_rect_header_t {
|
||||||
|
lv_img_header_t base;
|
||||||
|
SDL_Rect rect;
|
||||||
|
} lv_draw_sdl_rect_header_t;
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* GLOBAL PROTOTYPES
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/*======================
|
||||||
|
* Add/remove functions
|
||||||
|
*=====================*/
|
||||||
|
|
||||||
|
/*=====================
|
||||||
|
* Setter functions
|
||||||
|
*====================*/
|
||||||
|
|
||||||
|
/*=====================
|
||||||
|
* Getter functions
|
||||||
|
*====================*/
|
||||||
|
|
||||||
|
/*=====================
|
||||||
|
* Other functions
|
||||||
|
*====================*/
|
||||||
|
|
||||||
|
SDL_Texture * lv_draw_sdl_rect_bg_frag_obtain(lv_draw_sdl_ctx_t * ctx, lv_coord_t radius);
|
||||||
|
|
||||||
|
void lv_draw_sdl_rect_bg_frag_draw_corners(lv_draw_sdl_ctx_t * ctx, SDL_Texture * frag, lv_coord_t frag_size,
|
||||||
|
const lv_area_t * coords, const lv_area_t * clip, bool full);
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* MACROS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
#endif /*LV_USE_GPU_SDL*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /*extern "C"*/
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*LV_DRAW_SDL_RECT_H*/
|
||||||
@@ -45,6 +45,7 @@ typedef struct {
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
LV_GPU_CACHE_KEY_MAGIC_ARC = 0x01,
|
LV_GPU_CACHE_KEY_MAGIC_ARC = 0x01,
|
||||||
LV_GPU_CACHE_KEY_MAGIC_IMG = 0x11,
|
LV_GPU_CACHE_KEY_MAGIC_IMG = 0x11,
|
||||||
|
LV_GPU_CACHE_KEY_MAGIC_IMG_ROUNDED_CORNERS = 0x12,
|
||||||
LV_GPU_CACHE_KEY_MAGIC_LINE = 0x21,
|
LV_GPU_CACHE_KEY_MAGIC_LINE = 0x21,
|
||||||
LV_GPU_CACHE_KEY_MAGIC_RECT_BG = 0x31,
|
LV_GPU_CACHE_KEY_MAGIC_RECT_BG = 0x31,
|
||||||
LV_GPU_CACHE_KEY_MAGIC_RECT_SHADOW = 0x32,
|
LV_GPU_CACHE_KEY_MAGIC_RECT_SHADOW = 0x32,
|
||||||
|
|||||||
@@ -98,14 +98,10 @@ void lv_area_zoom_to_sdl_rect(const lv_area_t * in, SDL_Rect * out, uint16_t zoo
|
|||||||
lv_area_to_sdl_rect(in, out);
|
lv_area_to_sdl_rect(in, out);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int h = in->y2 - in->y1 + 1;
|
lv_area_t tmp;
|
||||||
int w = in->x2 - in->x1 + 1;
|
_lv_img_buf_get_transformed_area(&tmp, lv_area_get_width(in), lv_area_get_height(in), 0, zoom, pivot);
|
||||||
int sh = h * zoom >> 8;
|
lv_area_move(&tmp, in->x1, in->y1);
|
||||||
int sw = w * zoom >> 8;
|
lv_area_to_sdl_rect(&tmp, out);
|
||||||
out->x = in->x1 - (sw / 2 - pivot->x);
|
|
||||||
out->y = in->y1 - (sh / 2 - pivot->y);
|
|
||||||
out->w = sw;
|
|
||||||
out->h = sh;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Palette * lv_sdl_alloc_palette_for_bpp(const uint8_t * mapping, uint8_t bpp)
|
SDL_Palette * lv_sdl_alloc_palette_for_bpp(const uint8_t * mapping, uint8_t bpp)
|
||||||
|
|||||||
@@ -319,6 +319,11 @@ bool _lv_area_is_out(const lv_area_t * aout_p, const lv_area_t * aholder_p, lv_c
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _lv_area_is_equal(const lv_area_t * a, const lv_area_t * b)
|
||||||
|
{
|
||||||
|
return a->x1 == b->x1 && a->x2 == b->x2 && a->y1 == b->y1 && a->y2 == b->y2;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Align an area to an other
|
* Align an area to an other
|
||||||
* @param base an are where the other will be aligned
|
* @param base an are where the other will be aligned
|
||||||
|
|||||||
@@ -221,6 +221,13 @@ bool _lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p, lv_coo
|
|||||||
*/
|
*/
|
||||||
bool _lv_area_is_out(const lv_area_t * aout_p, const lv_area_t * aholder_p, lv_coord_t radius);
|
bool _lv_area_is_out(const lv_area_t * aout_p, const lv_area_t * aholder_p, lv_coord_t radius);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if 2 area is the same
|
||||||
|
* @param a pointer to an area
|
||||||
|
* @param b pointer to another area
|
||||||
|
*/
|
||||||
|
bool _lv_area_is_equal(const lv_area_t * a, const lv_area_t * b);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Align an area to an other
|
* Align an area to an other
|
||||||
* @param base an are where the other will be aligned
|
* @param base an are where the other will be aligned
|
||||||
|
|||||||
Reference in New Issue
Block a user