fix(draw): SDL2 gradient support #3848 (#3856)

This commit is contained in:
Mariotaku
2022-12-08 18:36:03 +09:00
committed by GitHub
parent 1e3ca25fed
commit d2d886aae5
3 changed files with 274 additions and 13 deletions

View File

@@ -27,6 +27,8 @@
* DEFINES * DEFINES
*********************/ *********************/
#define FRAG_SPACING 3
/********************** /**********************
* TYPEDEFS * TYPEDEFS
**********************/ **********************/
@@ -37,6 +39,23 @@ typedef struct {
lv_coord_t size; lv_coord_t size;
} lv_draw_rect_bg_key_t; } lv_draw_rect_bg_key_t;
typedef struct {
lv_sdl_cache_key_magic_t magic;
lv_gradient_stop_t stops[LV_GRADIENT_MAX_STOPS];
uint8_t stops_count;
lv_grad_dir_t dir;
} lv_draw_rect_grad_strip_key_t;
typedef struct {
lv_sdl_cache_key_magic_t magic;
lv_gradient_stop_t stops[LV_GRADIENT_MAX_STOPS];
uint8_t stops_count;
lv_grad_dir_t dir;
lv_coord_t w;
lv_coord_t h;
lv_coord_t radius;
} lv_draw_rect_grad_frag_key_t;
typedef struct { typedef struct {
lv_sdl_cache_key_magic_t magic; lv_sdl_cache_key_magic_t magic;
lv_coord_t radius; lv_coord_t radius;
@@ -57,6 +76,12 @@ typedef struct {
static void draw_bg_color(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, const lv_area_t * draw_area, static void draw_bg_color(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, const lv_area_t * draw_area,
const lv_draw_rect_dsc_t * dsc); const lv_draw_rect_dsc_t * dsc);
static void draw_bg_grad_simple(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, const lv_area_t * draw_area,
const lv_grad_dsc_t * grad, bool blend_mod);
static void draw_bg_grad_radius(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, const lv_area_t * draw_area,
const lv_draw_rect_dsc_t * dsc);
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,
const lv_draw_rect_dsc_t * dsc); const lv_draw_rect_dsc_t * dsc);
@@ -81,6 +106,11 @@ static void frag_render_center(SDL_Renderer * renderer, SDL_Texture * frag, lv_c
static lv_draw_rect_bg_key_t rect_bg_key_create(lv_coord_t radius, lv_coord_t size); static lv_draw_rect_bg_key_t rect_bg_key_create(lv_coord_t radius, lv_coord_t size);
static lv_draw_rect_grad_frag_key_t rect_grad_frag_key_create(const lv_grad_dsc_t * grad, lv_coord_t w, lv_coord_t h,
lv_coord_t radius);
static lv_draw_rect_grad_strip_key_t rect_grad_strip_key_create(const lv_grad_dsc_t * grad);
static lv_draw_rect_shadow_key_t rect_shadow_key_create(lv_coord_t radius, lv_coord_t size, lv_coord_t blur); static lv_draw_rect_shadow_key_t rect_shadow_key_create(lv_coord_t radius, lv_coord_t size, lv_coord_t blur);
static lv_draw_rect_border_key_t rect_border_key_create(lv_coord_t rout, lv_coord_t rin, const lv_area_t * outer_area, static lv_draw_rect_border_key_t rect_border_key_create(lv_coord_t rout, lv_coord_t rin, const lv_area_t * outer_area,
@@ -148,16 +178,93 @@ void lv_draw_sdl_draw_rect(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t *
SDL_Texture * lv_draw_sdl_rect_bg_frag_obtain(lv_draw_sdl_ctx_t * ctx, lv_coord_t radius) 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_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); SDL_Texture * texture = lv_draw_sdl_texture_cache_get(ctx, &key, sizeof(key), NULL);
if(texture == NULL) { if(texture == NULL) {
lv_area_t coords = {0, 0, radius * 2 - 1, radius * 2 - 1};
lv_area_t coords_frag = {0, 0, radius - 1, radius - 1};
lv_draw_mask_radius_param_t mask_rout_param; lv_draw_mask_radius_param_t mask_rout_param;
lv_draw_mask_radius_init(&mask_rout_param, &coords, radius, false); lv_draw_mask_radius_init(&mask_rout_param, &coords, radius, false);
int16_t mask_id = lv_draw_mask_add(&mask_rout_param, NULL); 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); texture = lv_draw_sdl_mask_dump_texture(ctx->renderer, &coords_frag, &mask_id, 1);
SDL_assert(texture != NULL);
lv_draw_mask_remove_id(mask_id); lv_draw_mask_remove_id(mask_id);
SDL_assert(texture); lv_draw_sdl_texture_cache_put(ctx, &key, sizeof(key), texture);
}
return texture;
}
SDL_Texture * lv_draw_sdl_rect_grad_frag_obtain(lv_draw_sdl_ctx_t * ctx, const lv_grad_dsc_t * grad, lv_coord_t w,
lv_coord_t h, lv_coord_t radius)
{
lv_draw_rect_grad_frag_key_t key = rect_grad_frag_key_create(grad, w, h, radius);
SDL_Texture * texture = lv_draw_sdl_texture_cache_get(ctx, &key, sizeof(key), NULL);
if(texture == NULL) {
lv_area_t coords = {0, 0, radius * 2 + FRAG_SPACING - 1, radius * 2 + FRAG_SPACING - 1};
texture = SDL_CreateTexture(ctx->renderer, LV_DRAW_SDL_TEXTURE_FORMAT, SDL_TEXTUREACCESS_TARGET,
lv_area_get_width(&coords), lv_area_get_height(&coords));
SDL_assert(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);
SDL_Texture * mask = lv_draw_sdl_mask_dump_texture(ctx->renderer, &coords, &mask_id, 1);
SDL_assert(mask != NULL);
SDL_SetTextureBlendMode(mask, SDL_BLENDMODE_NONE);
lv_draw_mask_remove_id(mask_id);
SDL_Texture * target_backup = SDL_GetRenderTarget(ctx->renderer);
SDL_SetRenderTarget(ctx->renderer, texture);
SDL_RenderCopy(ctx->renderer, mask, NULL, NULL);
SDL_DestroyTexture(mask);
lv_area_t blend_coords = {.x1 = 0, .y1 = 0, .x2 = w - 1, .y2 = h - 1};
lv_area_t draw_area = {.x1 = 0, .y1 = 0, .x2 = radius - 1, .y2 = radius - 1};
/* Align to top left */
lv_area_align(&coords, &draw_area, LV_ALIGN_TOP_LEFT, 0, 0);
lv_area_align(&coords, &blend_coords, LV_ALIGN_TOP_LEFT, 0, 0);
draw_bg_grad_simple(ctx, &blend_coords, &draw_area, grad, true);
/* Align to top right */
lv_area_align(&coords, &draw_area, LV_ALIGN_TOP_RIGHT, 0, 0);
lv_area_align(&coords, &blend_coords, LV_ALIGN_TOP_RIGHT, 0, 0);
draw_bg_grad_simple(ctx, &blend_coords, &draw_area, grad, true);
/* Align to bottom right */
lv_area_align(&coords, &draw_area, LV_ALIGN_BOTTOM_RIGHT, 0, 0);
lv_area_align(&coords, &blend_coords, LV_ALIGN_BOTTOM_RIGHT, 0, 0);
draw_bg_grad_simple(ctx, &blend_coords, &draw_area, grad, true);
/* Align to bottom left */
lv_area_align(&coords, &draw_area, LV_ALIGN_BOTTOM_LEFT, 0, 0);
lv_area_align(&coords, &blend_coords, LV_ALIGN_BOTTOM_LEFT, 0, 0);
draw_bg_grad_simple(ctx, &blend_coords, &draw_area, grad, true);
SDL_SetRenderTarget(ctx->renderer, target_backup);
lv_draw_sdl_texture_cache_put(ctx, &key, sizeof(key), texture);
}
return texture;
}
SDL_Texture * lv_draw_sdl_rect_grad_strip_obtain(lv_draw_sdl_ctx_t * ctx, const lv_grad_dsc_t * grad)
{
lv_draw_rect_grad_strip_key_t key = rect_grad_strip_key_create(grad);
SDL_Texture * texture = lv_draw_sdl_texture_cache_get(ctx, &key, sizeof(key), NULL);
if(texture == NULL) {
Uint32 amask = 0xFF000000;
Uint32 rmask = 0x00FF0000;
Uint32 gmask = 0x0000FF00;
Uint32 bmask = 0x000000FF;
lv_color_t pixels[256];
for(int i = 0; i < 256; i++) {
pixels[i] = lv_gradient_calculate(grad, 256, i);
}
int width = grad->dir == LV_GRAD_DIR_VER ? 1 : 256;
int height = grad->dir == LV_GRAD_DIR_VER ? 256 : 1;
SDL_Surface * surface = SDL_CreateRGBSurfaceFrom(pixels, width, height, LV_COLOR_DEPTH, width * LV_COLOR_DEPTH / 8,
rmask, gmask, bmask, amask);
texture = SDL_CreateTextureFromSurface(ctx->renderer, surface);
SDL_assert(texture != NULL);
SDL_FreeSurface(surface);
lv_draw_sdl_texture_cache_put(ctx, &key, sizeof(key), texture); lv_draw_sdl_texture_cache_put(ctx, &key, sizeof(key), texture);
} }
return texture; return texture;
@@ -193,7 +300,7 @@ void lv_draw_sdl_rect_bg_frag_draw_corners(lv_draw_sdl_ctx_t * ctx, SDL_Texture
if(full) { if(full) {
lv_coord_t sx = (lv_coord_t)(dst_area.x1 - corner_area.x1), lv_coord_t sx = (lv_coord_t)(dst_area.x1 - corner_area.x1),
sy = (lv_coord_t)(dst_area.y1 - corner_area.y1); sy = (lv_coord_t)(dst_area.y1 - corner_area.y1);
SDL_Rect src_rect = {frag_size + 3 + sx, sy, dw, dh}; SDL_Rect src_rect = {frag_size + FRAG_SPACING + sx, sy, dw, dh};
SDL_RenderCopy(ctx->renderer, frag, &src_rect, &dst_rect); SDL_RenderCopy(ctx->renderer, frag, &src_rect, &dst_rect);
} }
else { else {
@@ -212,7 +319,7 @@ void lv_draw_sdl_rect_bg_frag_draw_corners(lv_draw_sdl_ctx_t * ctx, SDL_Texture
if(full) { if(full) {
lv_coord_t sx = (lv_coord_t)(dst_area.x1 - corner_area.x1), lv_coord_t sx = (lv_coord_t)(dst_area.x1 - corner_area.x1),
sy = (lv_coord_t)(dst_area.y1 - corner_area.y1); 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_Rect src_rect = {frag_size + FRAG_SPACING + sx, frag_size + FRAG_SPACING + sy, dw, dh};
SDL_RenderCopy(ctx->renderer, frag, &src_rect, &dst_rect); SDL_RenderCopy(ctx->renderer, frag, &src_rect, &dst_rect);
} }
else { else {
@@ -220,7 +327,7 @@ void lv_draw_sdl_rect_bg_frag_draw_corners(lv_draw_sdl_ctx_t * ctx, SDL_Texture
SDL_RenderCopyEx(ctx->renderer, frag, &src_rect, &dst_rect, 0, NULL, SDL_FLIP_HORIZONTAL | SDL_FLIP_VERTICAL); 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 */ /* Lower left, right edge should not be clipped */
corner_area.x1 = coords->x1; corner_area.x1 = coords->x1;
corner_area.x2 = coords->x1 + frag_size - 1; corner_area.x2 = coords->x1 + frag_size - 1;
if(_lv_area_intersect(&dst_area, &corner_area, clip)) { if(_lv_area_intersect(&dst_area, &corner_area, clip)) {
@@ -231,7 +338,7 @@ void lv_draw_sdl_rect_bg_frag_draw_corners(lv_draw_sdl_ctx_t * ctx, SDL_Texture
if(full) { if(full) {
lv_coord_t sx = (lv_coord_t)(dst_area.x1 - corner_area.x1), lv_coord_t sx = (lv_coord_t)(dst_area.x1 - corner_area.x1),
sy = (lv_coord_t)(dst_area.y1 - corner_area.y1); sy = (lv_coord_t)(dst_area.y1 - corner_area.y1);
SDL_Rect src_rect = {sx, frag_size + 3 + sy, dw, dh}; SDL_Rect src_rect = {sx, frag_size + FRAG_SPACING + sy, dw, dh};
SDL_RenderCopy(ctx->renderer, frag, &src_rect, &dst_rect); SDL_RenderCopy(ctx->renderer, frag, &src_rect, &dst_rect);
} }
else { else {
@@ -252,9 +359,23 @@ static void draw_bg_color(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, con
if(dsc->bg_opa == 0) { if(dsc->bg_opa == 0) {
return; return;
} }
SDL_Color bg_color;
lv_color_to_sdl_color(&dsc->bg_color, &bg_color);
lv_coord_t radius = dsc->radius; lv_coord_t radius = dsc->radius;
SDL_Color bg_color;
if(dsc->bg_grad.dir == LV_GRAD_DIR_NONE) {
lv_color_to_sdl_color(&dsc->bg_color, &bg_color);
}
else if(dsc->bg_grad.stops_count == 1) {
lv_color_to_sdl_color(&dsc->bg_grad.stops[0].color, &bg_color);
}
else {
if(radius <= 0) {
draw_bg_grad_simple(ctx, coords, draw_area, &dsc->bg_grad, false);
}
else {
draw_bg_grad_radius(ctx, coords, draw_area, dsc);
}
return;
}
if(radius <= 0) { if(radius <= 0) {
SDL_Rect rect; SDL_Rect rect;
lv_area_to_sdl_rect(draw_area, &rect); lv_area_to_sdl_rect(draw_area, &rect);
@@ -277,9 +398,111 @@ static void draw_bg_color(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, con
frag_render_center(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_grad_simple(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, const lv_area_t * draw_area,
const lv_grad_dsc_t * grad, bool blend_mod)
{
SDL_Rect dstrect;
lv_area_to_sdl_rect(draw_area, &dstrect);
SDL_Rect srcrect;
if(grad->dir == LV_GRAD_DIR_VER) {
lv_coord_t coords_h = lv_area_get_height(coords);
srcrect.x = 0;
srcrect.y = (draw_area->y1 - coords->y1) * 255 / coords_h;
srcrect.w = 1;
srcrect.h = dstrect.h * 256 / coords_h;
if(srcrect.y < 0 || srcrect.y > 255) {
return;
}
}
else {
lv_coord_t coords_w = lv_area_get_width(coords);
srcrect.x = (draw_area->x1 - coords->x1) * 255 / coords_w;
srcrect.y = 0;
srcrect.w = dstrect.w * 256 / coords_w;
srcrect.h = 1;
if(srcrect.x < 0 || srcrect.x > 255) {
return;
}
}
SDL_Texture * grad_texture = lv_draw_sdl_rect_grad_strip_obtain(ctx, grad);
if(blend_mod) {
SDL_SetTextureBlendMode(grad_texture, SDL_BLENDMODE_MOD);
}
else {
SDL_SetTextureBlendMode(grad_texture, SDL_BLENDMODE_BLEND);
}
SDL_RenderCopy(ctx->renderer, grad_texture, &srcrect, &dstrect);
}
static void draw_bg_grad_radius(lv_draw_sdl_ctx_t * ctx, const lv_area_t * coords, const lv_area_t * draw_area,
const lv_draw_rect_dsc_t * dsc)
{
lv_coord_t radius = dsc->radius;
/*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 real_radius = LV_MIN3(bg_w / 2, bg_h / 2, radius);
SDL_Texture * grad_texture = lv_draw_sdl_rect_grad_frag_obtain(ctx, &dsc->bg_grad, bg_w, bg_h, radius);
SDL_SetTextureBlendMode(grad_texture, SDL_BLENDMODE_BLEND);
lv_draw_sdl_rect_bg_frag_draw_corners(ctx, grad_texture, real_radius, coords, draw_area, true);
lv_area_t part_coords;
lv_area_t part_area;
if(bg_w > radius * 2) {
/*Draw left, middle, right*/
part_coords.x1 = 0;
part_coords.x2 = radius - 1;
part_coords.y1 = radius;
part_coords.y2 = bg_h - radius - 1;
lv_area_align(coords, &part_coords, LV_ALIGN_LEFT_MID, 0, 0);
_lv_area_intersect(&part_area, &part_coords, draw_area);
draw_bg_grad_simple(ctx, coords, &part_area, &dsc->bg_grad, false);
lv_area_align(coords, &part_coords, LV_ALIGN_RIGHT_MID, 0, 0);
_lv_area_intersect(&part_area, &part_coords, draw_area);
draw_bg_grad_simple(ctx, coords, &part_area, &dsc->bg_grad, false);
part_coords.x1 = radius;
part_coords.x2 = bg_w - radius - 1;
part_coords.y1 = 0;
part_coords.y2 = bg_h - 1;
lv_area_align(coords, &part_coords, LV_ALIGN_CENTER, 0, 0);
_lv_area_intersect(&part_area, &part_coords, draw_area);
draw_bg_grad_simple(ctx, coords, &part_area, &dsc->bg_grad, false);
}
else if(bg_h > radius * 2) {
/*Draw top, middle, bottom*/
part_coords.x1 = radius;
part_coords.x2 = bg_w - radius - 1;
part_coords.y1 = 0;
part_coords.y2 = radius - 1;
lv_area_align(coords, &part_coords, LV_ALIGN_TOP_MID, 0, 0);
_lv_area_intersect(&part_area, &part_coords, draw_area);
draw_bg_grad_simple(ctx, coords, &part_area, &dsc->bg_grad, false);
lv_area_align(coords, &part_coords, LV_ALIGN_BOTTOM_MID, 0, 0);
_lv_area_intersect(&part_area, &part_coords, draw_area);
draw_bg_grad_simple(ctx, coords, &part_area, &dsc->bg_grad, false);
part_coords.x1 = 0;
part_coords.x2 = bg_w - 1;
part_coords.y1 = radius;
part_coords.y2 = bg_h - radius - 1;
lv_area_align(coords, &part_coords, LV_ALIGN_CENTER, 0, 0);
_lv_area_intersect(&part_area, &part_coords, draw_area);
draw_bg_grad_simple(ctx, coords, &part_area, &dsc->bg_grad, 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,
const lv_draw_rect_dsc_t * dsc) const lv_draw_rect_dsc_t * dsc)
{ {
LV_UNUSED(draw_area);
if(SKIP_IMAGE(dsc)) return; if(SKIP_IMAGE(dsc)) return;
lv_img_src_t src_type = lv_img_src_get_type(dsc->bg_img_src); lv_img_src_t src_type = lv_img_src_get_type(dsc->bg_img_src);
@@ -521,8 +744,8 @@ static void draw_border_generic(lv_draw_sdl_ctx_t * ctx, const lv_area_t * outer
lv_coord_t frag_size = LV_MAX(radius, max_side); lv_coord_t frag_size = LV_MAX(radius, max_side);
SDL_Texture * texture = lv_draw_sdl_texture_cache_get(ctx, &key, sizeof(key), NULL); SDL_Texture * texture = lv_draw_sdl_texture_cache_get(ctx, &key, sizeof(key), NULL);
if(texture == NULL) { if(texture == NULL) {
/* Create a mask texture with size of (frag_size * 2 + 3) */ /* Create a mask texture with size of (frag_size * 2 + FRAG_SPACING) */
const lv_area_t frag_area = {0, 0, frag_size * 2 + 2, frag_size * 2 + 2}; const lv_area_t frag_area = {0, 0, frag_size * 2 + FRAG_SPACING - 1, frag_size * 2 + FRAG_SPACING - 1};
/*Create mask for the outer area*/ /*Create mask for the outer area*/
int16_t mask_ids[2] = {LV_MASK_ID_INV, LV_MASK_ID_INV}; int16_t mask_ids[2] = {LV_MASK_ID_INV, LV_MASK_ID_INV};
@@ -595,7 +818,7 @@ static void frag_render_borders(SDL_Renderer * renderer, SDL_Texture * frag, lv_
lv_coord_t dh = lv_area_get_height(&dst_area); lv_coord_t dh = lv_area_get_height(&dst_area);
if(full) { if(full) {
lv_coord_t sy = (lv_coord_t)(dst_area.y1 - border_area.y1); lv_coord_t sy = (lv_coord_t)(dst_area.y1 - border_area.y1);
SDL_Rect src_rect = {frag_size + 1, frag_size + 3 + sy, 1, dh}; SDL_Rect src_rect = {frag_size + 1, frag_size + FRAG_SPACING + sy, 1, dh};
SDL_RenderCopy(renderer, frag, &src_rect, &dst_rect); SDL_RenderCopy(renderer, frag, &src_rect, &dst_rect);
} }
else { else {
@@ -634,7 +857,7 @@ static void frag_render_borders(SDL_Renderer * renderer, SDL_Texture * frag, lv_
lv_coord_t dw = lv_area_get_width(&dst_area); lv_coord_t dw = lv_area_get_width(&dst_area);
if(full) { if(full) {
lv_coord_t sx = (lv_coord_t)(dst_area.x1 - border_area.x1); lv_coord_t sx = (lv_coord_t)(dst_area.x1 - border_area.x1);
SDL_Rect src_rect = {frag_size + 3 + sx, frag_size + 1, dw, 1}; SDL_Rect src_rect = {frag_size + FRAG_SPACING + sx, frag_size + 1, dw, 1};
SDL_RenderCopy(renderer, frag, &src_rect, &dst_rect); SDL_RenderCopy(renderer, frag, &src_rect, &dst_rect);
} }
else { else {
@@ -682,6 +905,38 @@ static lv_draw_rect_bg_key_t rect_bg_key_create(lv_coord_t radius, lv_coord_t si
return key; return key;
} }
static lv_draw_rect_grad_frag_key_t rect_grad_frag_key_create(const lv_grad_dsc_t * grad, lv_coord_t w, lv_coord_t h,
lv_coord_t radius)
{
lv_draw_rect_grad_frag_key_t key;
SDL_memset(&key, 0, sizeof(key));
key.magic = LV_GPU_CACHE_KEY_MAGIC_RECT_GRAD;
key.stops_count = grad->stops_count;
key.dir = grad->dir;
for(uint8_t i = 0; i < grad->stops_count; i++) {
key.stops[i].frac = grad->stops[i].frac;
key.stops[i].color = grad->stops[i].color;
}
key.w = w;
key.h = h;
key.radius = radius;
return key;
}
static lv_draw_rect_grad_strip_key_t rect_grad_strip_key_create(const lv_grad_dsc_t * grad)
{
lv_draw_rect_grad_strip_key_t key;
SDL_memset(&key, 0, sizeof(key));
key.magic = LV_GPU_CACHE_KEY_MAGIC_RECT_GRAD;
key.stops_count = grad->stops_count;
key.dir = grad->dir;
for(uint8_t i = 0; i < grad->stops_count; i++) {
key.stops[i].frac = grad->stops[i].frac;
key.stops[i].color = grad->stops[i].color;
}
return key;
}
static lv_draw_rect_shadow_key_t rect_shadow_key_create(lv_coord_t radius, lv_coord_t size, lv_coord_t blur) static lv_draw_rect_shadow_key_t rect_shadow_key_create(lv_coord_t radius, lv_coord_t size, lv_coord_t blur)
{ {
lv_draw_rect_shadow_key_t key; lv_draw_rect_shadow_key_t key;

View File

@@ -59,6 +59,11 @@ typedef struct lv_draw_sdl_rect_header_t {
SDL_Texture * lv_draw_sdl_rect_bg_frag_obtain(lv_draw_sdl_ctx_t * ctx, lv_coord_t radius); SDL_Texture * lv_draw_sdl_rect_bg_frag_obtain(lv_draw_sdl_ctx_t * ctx, lv_coord_t radius);
SDL_Texture * lv_draw_sdl_rect_grad_frag_obtain(lv_draw_sdl_ctx_t * ctx, const lv_grad_dsc_t * grad, lv_coord_t w,
lv_coord_t h, lv_coord_t radius);
SDL_Texture * lv_draw_sdl_rect_grad_strip_obtain(lv_draw_sdl_ctx_t * ctx, const lv_grad_dsc_t * grad);
void lv_draw_sdl_rect_bg_frag_draw_corners(lv_draw_sdl_ctx_t * ctx, SDL_Texture * frag, lv_coord_t frag_size, 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); const lv_area_t * coords, const lv_area_t * clip, bool full);

View File

@@ -50,6 +50,7 @@ typedef enum {
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,
LV_GPU_CACHE_KEY_MAGIC_RECT_BORDER = 0x33, LV_GPU_CACHE_KEY_MAGIC_RECT_BORDER = 0x33,
LV_GPU_CACHE_KEY_MAGIC_RECT_GRAD = 0x34,
LV_GPU_CACHE_KEY_MAGIC_FONT_GLYPH = 0x41, LV_GPU_CACHE_KEY_MAGIC_FONT_GLYPH = 0x41,
LV_GPU_CACHE_KEY_MAGIC_MASK = 0x51, LV_GPU_CACHE_KEY_MAGIC_MASK = 0x51,
} lv_sdl_cache_key_magic_t; } lv_sdl_cache_key_magic_t;