mirror of
https://github.com/lvgl/lvgl.git
synced 2026-09-23 03:35:30 +08:00
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:
@@ -100,7 +100,13 @@ It also means the layouts are not affected the by the transformations.
|
||||
|
||||
If you need the object size to be updated to the transformed size set `lv_img_set_size_mode(img, LV_IMG_SIZE_MODE_REAL)`. (The previous mode is the default and called `LV_IMG_SIZE_MODE_VIRTUAL`).
|
||||
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
|
||||
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);
|
||||
break;
|
||||
case LV_BLEND_MODE_ADDITIVE:
|
||||
SDL_SetRenderDrawBlendMode(ctx->renderer, SDL_BLENDMODE_ADD);
|
||||
SDL_SetTextureBlendMode(internals->composition, SDL_BLENDMODE_ADD);
|
||||
break;
|
||||
#if LV_GPU_SDL_CUSTOM_BLEND_MODE
|
||||
case LV_BLEND_MODE_SUBTRACTIVE: {
|
||||
SDL_BlendMode mode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE,
|
||||
SDL_BLENDOPERATION_SUBTRACT, SDL_BLENDFACTOR_ONE,
|
||||
SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_SUBTRACT);
|
||||
SDL_SetRenderDrawBlendMode(ctx->renderer, mode);
|
||||
SDL_SetTextureBlendMode(internals->composition, mode);
|
||||
break;
|
||||
}
|
||||
case LV_BLEND_MODE_MULTIPLY: {
|
||||
SDL_BlendMode mode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_ZERO, SDL_BLENDFACTOR_SRC_COLOR,
|
||||
SDL_BLENDOPERATION_ADD, SDL_BLENDFACTOR_ZERO,
|
||||
SDL_BLENDFACTOR_DST_ALPHA, SDL_BLENDOPERATION_ADD);
|
||||
SDL_SetRenderDrawBlendMode(ctx->renderer, mode);
|
||||
SDL_SetTextureBlendMode(internals->composition, mode);
|
||||
break;
|
||||
}
|
||||
#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_STREAM1,
|
||||
LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_TARGET0,
|
||||
LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_TARGET1,
|
||||
} lv_draw_sdl_composite_texture_id_t;
|
||||
|
||||
/**********************
|
||||
|
||||
+334
-94
File diff suppressed because it is too large
Load Diff
@@ -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*/
|
||||
+118
-101
@@ -21,6 +21,7 @@
|
||||
#include "lv_draw_sdl_composite.h"
|
||||
#include "lv_draw_sdl_mask.h"
|
||||
#include "lv_draw_sdl_stack_blur.h"
|
||||
#include "lv_draw_sdl_img.h"
|
||||
|
||||
/*********************
|
||||
* 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,
|
||||
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,
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
**********************/
|
||||
@@ -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*/
|
||||
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_draw_rect_bg_key_t key = rect_bg_key_create(radius, frag_size);
|
||||
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);
|
||||
}
|
||||
lv_coord_t real_radius = LV_MIN3(bg_w / 2, bg_h / 2, radius);
|
||||
SDL_Texture * texture = lv_draw_sdl_rect_bg_frag_obtain(ctx, real_radius);
|
||||
|
||||
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetTextureAlphaMod(texture, dsc->bg_opa);
|
||||
SDL_SetTextureColorMod(texture, bg_color.r, bg_color.g, bg_color.b);
|
||||
frag_render_corners(ctx->renderer, texture, frag_size, coords, draw_area, false);
|
||||
frag_render_borders(ctx->renderer, texture, frag_size, coords, draw_area, false);
|
||||
frag_render_center(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, real_radius, 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,
|
||||
@@ -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_opa = dsc->bg_img_recolor_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*/
|
||||
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_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_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_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);
|
||||
}
|
||||
|
||||
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,
|
||||
const lv_area_t * coords, const lv_area_t * clipped, bool full)
|
||||
{
|
||||
|
||||
@@ -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 {
|
||||
LV_GPU_CACHE_KEY_MAGIC_ARC = 0x01,
|
||||
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_RECT_BG = 0x31,
|
||||
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);
|
||||
return;
|
||||
}
|
||||
int h = in->y2 - in->y1 + 1;
|
||||
int w = in->x2 - in->x1 + 1;
|
||||
int sh = h * zoom >> 8;
|
||||
int sw = w * zoom >> 8;
|
||||
out->x = in->x1 - (sw / 2 - pivot->x);
|
||||
out->y = in->y1 - (sh / 2 - pivot->y);
|
||||
out->w = sw;
|
||||
out->h = sh;
|
||||
lv_area_t tmp;
|
||||
_lv_img_buf_get_transformed_area(&tmp, lv_area_get_width(in), lv_area_get_height(in), 0, zoom, pivot);
|
||||
lv_area_move(&tmp, in->x1, in->y1);
|
||||
lv_area_to_sdl_rect(&tmp, out);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param base an are where the other will be aligned
|
||||
|
||||
Reference in New Issue
Block a user