refact(draw_vector): standardized draw gradient API (#6344)

Signed-off-by: FASTSHIFT <vifextech@foxmail.com>
Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com>
Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com>
This commit is contained in:
VIFEX
2024-06-20 18:31:21 +08:00
committed by GitHub
parent 37e4e4b4d0
commit e1547a126f
43 changed files with 767 additions and 574 deletions

20
Kconfig
View File

@@ -393,19 +393,14 @@ menu "LVGL configuration"
which usually improves performance, which usually improves performance,
but does not guarantee the same rendering quality as the software. but does not guarantee the same rendering quality as the software.
config LV_VG_LITE_LINEAR_GRAD_CACHE_CNT config LV_VG_LITE_GRAD_CACHE_CNT
int "VG-Lite linear gradient image maximum cache number." int "VG-Lite gradient maximum cache number."
default 32 default 32
depends on LV_USE_DRAW_VG_LITE depends on LV_USE_DRAW_VG_LITE
help help
The memory usage of a single gradient image is 4K bytes. The memory usage of a single gradient:
linear: 4K bytes.
config LV_VG_LITE_RADIAL_GRAD_CACHE_CNT radial: radius * 4K bytes.
int "VG-Lite radial gradient image maximum cache number."
default 32
depends on LV_USE_DRAW_VG_LITE
help
The memory usage of a single gradient image is radial grad radius * 4 bytes.
config LV_USE_VECTOR_GRAPHIC config LV_USE_VECTOR_GRAPHIC
bool "Use Vector Graphic APIs" bool "Use Vector Graphic APIs"
@@ -653,6 +648,11 @@ menu "LVGL configuration"
default n default n
depends on LV_USE_VG_LITE_THORVG depends on LV_USE_VG_LITE_THORVG
config LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT
bool "Enable linear gradient extension support"
default n
depends on LV_USE_VG_LITE_THORVG
config LV_VG_LITE_THORVG_16PIXELS_ALIGN config LV_VG_LITE_THORVG_16PIXELS_ALIGN
bool "Enable 16 pixels alignment" bool "Enable 16 pixels alignment"
default y default y

View File

@@ -58,25 +58,23 @@ static void draw_gradient(lv_vector_dsc_t * ctx, lv_vector_path_t * path)
lv_vector_path_quad_to(path, &pts[1], &pts[2]); lv_vector_path_quad_to(path, &pts[1], &pts[2]);
lv_vector_path_close(path); lv_vector_path_close(path);
lv_grad_dsc_t grad; lv_gradient_stop_t stops[2];
grad.dir = LV_GRAD_DIR_HOR; lv_memzero(stops, sizeof(stops));
grad.stops_count = 2; stops[0].color = lv_color_hex(0xff0000);
grad.stops[0].color = lv_color_hex(0xff0000); stops[0].opa = LV_OPA_COVER;
grad.stops[0].opa = LV_OPA_COVER; stops[0].frac = 0;
grad.stops[0].frac = 0; stops[1].color = lv_color_hex(0x00ff00);
grad.stops[1].color = lv_color_hex(0x00ff00); stops[1].opa = LV_OPA_COVER;
grad.stops[1].opa = LV_OPA_COVER; stops[1].frac = 255;
grad.stops[1].frac = 255;
// grad.stops[2].color = lv_color_hex(0x0000ff);
// grad.stops[2].opa = LV_OPA_COVER;
// grad.stops[2].frac = 255;
lv_matrix_t mt; lv_matrix_t mt;
lv_matrix_identity(&mt); lv_matrix_identity(&mt);
lv_matrix_rotate(&mt, 30); lv_matrix_rotate(&mt, 30);
lv_vector_dsc_set_fill_transform(ctx, &mt); lv_vector_dsc_set_fill_transform(ctx, &mt);
lv_vector_dsc_set_fill_linear_gradient(ctx, &grad, LV_VECTOR_GRADIENT_SPREAD_PAD); lv_vector_dsc_set_fill_linear_gradient(ctx, 200, 200, 400, 400);
lv_vector_dsc_set_fill_gradient_color_stops(ctx, stops, 2);
lv_vector_dsc_set_fill_gradient_spread(ctx, LV_VECTOR_GRADIENT_SPREAD_PAD);
lv_vector_dsc_add_path(ctx, path); // draw a path lv_vector_dsc_add_path(ctx, path); // draw a path
} }
@@ -92,20 +90,18 @@ static void draw_radial_gradient(lv_vector_dsc_t * ctx, lv_vector_path_t * path)
lv_vector_path_line_to(path, &pts[3]); lv_vector_path_line_to(path, &pts[3]);
lv_vector_path_close(path); lv_vector_path_close(path);
lv_grad_dsc_t grad; lv_gradient_stop_t stops[2];
grad.dir = LV_GRAD_DIR_HOR; lv_memzero(stops, sizeof(stops));
grad.stops_count = 2; stops[0].color = lv_color_hex(0xff0000);
grad.stops[0].color = lv_color_hex(0xff0000); stops[0].opa = LV_OPA_COVER;
grad.stops[0].opa = LV_OPA_COVER; stops[0].frac = 0;
grad.stops[0].frac = 0; stops[1].color = lv_color_hex(0x0000ff);
grad.stops[1].color = lv_color_hex(0x0000ff); stops[1].opa = LV_OPA_COVER;
grad.stops[1].opa = LV_OPA_COVER; stops[1].frac = 255;
grad.stops[1].frac = 255;
// grad.stops[2].color = lv_color_hex(0x0000ff);
// grad.stops[2].opa = LV_OPA_COVER;
// grad.stops[2].frac = 255;
lv_vector_dsc_set_fill_radial_gradient(ctx, &grad, 50, 50, 20, LV_VECTOR_GRADIENT_SPREAD_REFLECT); lv_vector_dsc_set_fill_radial_gradient(ctx, 450, 100, 20);
lv_vector_dsc_set_fill_gradient_color_stops(ctx, stops, 2);
lv_vector_dsc_set_fill_gradient_spread(ctx, LV_VECTOR_GRADIENT_SPREAD_REFLECT);
lv_vector_dsc_add_path(ctx, path); // draw a path lv_vector_dsc_add_path(ctx, path); // draw a path
} }

View File

@@ -224,15 +224,10 @@
* but does not guarantee the same rendering quality as the software. */ * but does not guarantee the same rendering quality as the software. */
#define LV_VG_LITE_USE_BOX_SHADOW 0 #define LV_VG_LITE_USE_BOX_SHADOW 0
/* VG-Lite linear gradient image maximum cache number. /* VG-Lite gradient maximum cache number.
* NOTE: The memory usage of a single gradient image is 4K bytes. * NOTE: The memory usage of a single gradient image is 4K bytes.
*/ */
#define LV_VG_LITE_LINEAR_GRAD_CACHE_CNT 32 #define LV_VG_LITE_GRAD_CACHE_CNT 32
/* VG-Lite radial gradient image maximum cache size.
* NOTE: The memory usage of a single gradient image is radial grad radius * 4 bytes.
*/
#define LV_VG_LITE_RADIAL_GRAD_CACHE_CNT 32
#endif #endif
@@ -382,6 +377,9 @@
/*Enable YUV color format support*/ /*Enable YUV color format support*/
#define LV_VG_LITE_THORVG_YUV_SUPPORT 0 #define LV_VG_LITE_THORVG_YUV_SUPPORT 0
/*Enable Linear gradient extension support*/
#define LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT 0
/*Enable 16 pixels alignment*/ /*Enable 16 pixels alignment*/
#define LV_VG_LITE_THORVG_16PIXELS_ALIGN 1 #define LV_VG_LITE_THORVG_16PIXELS_ALIGN 1

View File

@@ -85,18 +85,7 @@ static void _multiply_matrix(lv_matrix_t * matrix, const lv_matrix_t * mul)
static void _copy_draw_dsc(lv_vector_draw_dsc_t * dst, const lv_vector_draw_dsc_t * src) static void _copy_draw_dsc(lv_vector_draw_dsc_t * dst, const lv_vector_draw_dsc_t * src)
{ {
dst->fill_dsc.style = src->fill_dsc.style; lv_memcpy(&(dst->fill_dsc), &(src->fill_dsc), sizeof(lv_vector_fill_dsc_t));
dst->fill_dsc.color = src->fill_dsc.color;
dst->fill_dsc.opa = src->fill_dsc.opa;
dst->fill_dsc.fill_rule = src->fill_dsc.fill_rule;
dst->fill_dsc.gradient.style = src->fill_dsc.gradient.style;
dst->fill_dsc.gradient.cx = src->fill_dsc.gradient.cx;
dst->fill_dsc.gradient.cy = src->fill_dsc.gradient.cy;
dst->fill_dsc.gradient.cr = src->fill_dsc.gradient.cr;
dst->fill_dsc.gradient.spread = src->fill_dsc.gradient.spread;
lv_memcpy(&(dst->fill_dsc.gradient.grad), &(src->fill_dsc.gradient.grad), sizeof(lv_grad_dsc_t));
lv_memcpy(&(dst->fill_dsc.img_dsc), &(src->fill_dsc.img_dsc), sizeof(lv_draw_image_dsc_t));
lv_memcpy(&(dst->fill_dsc.matrix), &(src->fill_dsc.matrix), sizeof(lv_matrix_t));
dst->stroke_dsc.style = src->stroke_dsc.style; dst->stroke_dsc.style = src->stroke_dsc.style;
dst->stroke_dsc.color = src->stroke_dsc.color; dst->stroke_dsc.color = src->stroke_dsc.color;
@@ -111,7 +100,7 @@ static void _copy_draw_dsc(lv_vector_draw_dsc_t * dst, const lv_vector_draw_dsc_
dst->stroke_dsc.gradient.cy = src->stroke_dsc.gradient.cy; dst->stroke_dsc.gradient.cy = src->stroke_dsc.gradient.cy;
dst->stroke_dsc.gradient.cr = src->stroke_dsc.gradient.cr; dst->stroke_dsc.gradient.cr = src->stroke_dsc.gradient.cr;
dst->stroke_dsc.gradient.spread = src->fill_dsc.gradient.spread; dst->stroke_dsc.gradient.spread = src->fill_dsc.gradient.spread;
lv_memcpy(&(dst->stroke_dsc.gradient.grad), &(src->stroke_dsc.gradient.grad), sizeof(lv_grad_dsc_t)); lv_memcpy(&(dst->stroke_dsc.gradient), &(src->stroke_dsc.gradient), sizeof(lv_vector_gradient_t));
lv_memcpy(&(dst->stroke_dsc.matrix), &(src->stroke_dsc.matrix), sizeof(lv_matrix_t)); lv_memcpy(&(dst->stroke_dsc.matrix), &(src->stroke_dsc.matrix), sizeof(lv_matrix_t));
dst->blend_mode = src->blend_mode; dst->blend_mode = src->blend_mode;
@@ -666,25 +655,40 @@ void lv_vector_dsc_set_fill_image(lv_vector_dsc_t * dsc, const lv_draw_image_dsc
lv_memcpy(&(dsc->current_dsc.fill_dsc.img_dsc), img_dsc, sizeof(lv_draw_image_dsc_t)); lv_memcpy(&(dsc->current_dsc.fill_dsc.img_dsc), img_dsc, sizeof(lv_draw_image_dsc_t));
} }
void lv_vector_dsc_set_fill_linear_gradient(lv_vector_dsc_t * dsc, const lv_grad_dsc_t * grad, void lv_vector_dsc_set_fill_linear_gradient(lv_vector_dsc_t * dsc, float x1, float y1, float x2, float y2)
lv_vector_gradient_spread_t spread)
{ {
dsc->current_dsc.fill_dsc.style = LV_VECTOR_DRAW_STYLE_GRADIENT; dsc->current_dsc.fill_dsc.style = LV_VECTOR_DRAW_STYLE_GRADIENT;
dsc->current_dsc.fill_dsc.gradient.style = LV_VECTOR_GRADIENT_STYLE_LINEAR; dsc->current_dsc.fill_dsc.gradient.style = LV_VECTOR_GRADIENT_STYLE_LINEAR;
dsc->current_dsc.fill_dsc.gradient.spread = spread; dsc->current_dsc.fill_dsc.gradient.x1 = x1;
lv_memcpy(&(dsc->current_dsc.fill_dsc.gradient.grad), grad, sizeof(lv_grad_dsc_t)); dsc->current_dsc.fill_dsc.gradient.y1 = y1;
dsc->current_dsc.fill_dsc.gradient.x2 = x2;
dsc->current_dsc.fill_dsc.gradient.y2 = y2;
} }
void lv_vector_dsc_set_fill_radial_gradient(lv_vector_dsc_t * dsc, const lv_grad_dsc_t * grad, float cx, float cy, void lv_vector_dsc_set_fill_radial_gradient(lv_vector_dsc_t * dsc, float cx, float cy, float radius)
float radius, lv_vector_gradient_spread_t spread)
{ {
dsc->current_dsc.fill_dsc.style = LV_VECTOR_DRAW_STYLE_GRADIENT; dsc->current_dsc.fill_dsc.style = LV_VECTOR_DRAW_STYLE_GRADIENT;
dsc->current_dsc.fill_dsc.gradient.style = LV_VECTOR_GRADIENT_STYLE_RADIAL; dsc->current_dsc.fill_dsc.gradient.style = LV_VECTOR_GRADIENT_STYLE_RADIAL;
dsc->current_dsc.fill_dsc.gradient.cx = cx; dsc->current_dsc.fill_dsc.gradient.cx = cx;
dsc->current_dsc.fill_dsc.gradient.cy = cy; dsc->current_dsc.fill_dsc.gradient.cy = cy;
dsc->current_dsc.fill_dsc.gradient.cr = radius; dsc->current_dsc.fill_dsc.gradient.cr = radius;
}
void lv_vector_dsc_set_fill_gradient_spread(lv_vector_dsc_t * dsc, lv_vector_gradient_spread_t spread)
{
dsc->current_dsc.fill_dsc.gradient.spread = spread; dsc->current_dsc.fill_dsc.gradient.spread = spread;
lv_memcpy(&(dsc->current_dsc.fill_dsc.gradient.grad), grad, sizeof(lv_grad_dsc_t)); }
void lv_vector_dsc_set_fill_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_gradient_stop_t * stops,
uint16_t count)
{
if(count > LV_GRADIENT_MAX_STOPS) {
LV_LOG_WARN("Too many gradient stops. Truncating to %d", LV_GRADIENT_MAX_STOPS);
count = LV_GRADIENT_MAX_STOPS;
}
lv_memcpy(&(dsc->current_dsc.fill_dsc.gradient.stops), stops, sizeof(lv_gradient_stop_t) * count);
dsc->current_dsc.fill_dsc.gradient.stops_count = count;
} }
void lv_vector_dsc_set_fill_transform(lv_vector_dsc_t * dsc, const lv_matrix_t * matrix) void lv_vector_dsc_set_fill_transform(lv_vector_dsc_t * dsc, const lv_matrix_t * matrix)
@@ -754,25 +758,40 @@ void lv_vector_dsc_set_stroke_miter_limit(lv_vector_dsc_t * dsc, uint16_t miter_
dsc->current_dsc.stroke_dsc.miter_limit = miter_limit; dsc->current_dsc.stroke_dsc.miter_limit = miter_limit;
} }
void lv_vector_dsc_set_stroke_linear_gradient(lv_vector_dsc_t * dsc, const lv_grad_dsc_t * grad, void lv_vector_dsc_set_stroke_linear_gradient(lv_vector_dsc_t * dsc, float x1, float y1, float x2, float y2)
lv_vector_gradient_spread_t spread)
{ {
dsc->current_dsc.stroke_dsc.style = LV_VECTOR_DRAW_STYLE_GRADIENT; dsc->current_dsc.stroke_dsc.style = LV_VECTOR_DRAW_STYLE_GRADIENT;
dsc->current_dsc.stroke_dsc.gradient.style = LV_VECTOR_GRADIENT_STYLE_LINEAR; dsc->current_dsc.stroke_dsc.gradient.style = LV_VECTOR_GRADIENT_STYLE_LINEAR;
dsc->current_dsc.stroke_dsc.gradient.spread = spread; dsc->current_dsc.stroke_dsc.gradient.x1 = x1;
lv_memcpy(&(dsc->current_dsc.stroke_dsc.gradient.grad), grad, sizeof(lv_grad_dsc_t)); dsc->current_dsc.stroke_dsc.gradient.y1 = y1;
dsc->current_dsc.stroke_dsc.gradient.x2 = x2;
dsc->current_dsc.stroke_dsc.gradient.y2 = y2;
} }
void lv_vector_dsc_set_stroke_radial_gradient(lv_vector_dsc_t * dsc, const lv_grad_dsc_t * grad, float cx, float cy, void lv_vector_dsc_set_stroke_radial_gradient(lv_vector_dsc_t * dsc, float cx, float cy, float radius)
float radius, lv_vector_gradient_spread_t spread)
{ {
dsc->current_dsc.stroke_dsc.style = LV_VECTOR_DRAW_STYLE_GRADIENT; dsc->current_dsc.stroke_dsc.style = LV_VECTOR_DRAW_STYLE_GRADIENT;
dsc->current_dsc.stroke_dsc.gradient.style = LV_VECTOR_GRADIENT_STYLE_RADIAL; dsc->current_dsc.stroke_dsc.gradient.style = LV_VECTOR_GRADIENT_STYLE_RADIAL;
dsc->current_dsc.stroke_dsc.gradient.cx = cx; dsc->current_dsc.stroke_dsc.gradient.cx = cx;
dsc->current_dsc.stroke_dsc.gradient.cy = cy; dsc->current_dsc.stroke_dsc.gradient.cy = cy;
dsc->current_dsc.stroke_dsc.gradient.cr = radius; dsc->current_dsc.stroke_dsc.gradient.cr = radius;
}
void lv_vector_dsc_set_stroke_gradient_spread(lv_vector_dsc_t * dsc, lv_vector_gradient_spread_t spread)
{
dsc->current_dsc.stroke_dsc.gradient.spread = spread; dsc->current_dsc.stroke_dsc.gradient.spread = spread;
lv_memcpy(&(dsc->current_dsc.stroke_dsc.gradient.grad), grad, sizeof(lv_grad_dsc_t)); }
void lv_vector_dsc_set_stroke_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_gradient_stop_t * stops,
uint16_t count)
{
if(count > LV_GRADIENT_MAX_STOPS) {
LV_LOG_WARN("Too many gradient stops. Truncating to %d", LV_GRADIENT_MAX_STOPS);
count = LV_GRADIENT_MAX_STOPS;
}
lv_memcpy(&(dsc->current_dsc.stroke_dsc.gradient.stops), stops, sizeof(lv_gradient_stop_t) * count);
dsc->current_dsc.stroke_dsc.gradient.stops_count = count;
} }
/* draw functions */ /* draw functions */

View File

@@ -107,7 +107,12 @@ typedef struct {
typedef struct { typedef struct {
lv_vector_gradient_style_t style; lv_vector_gradient_style_t style;
lv_grad_dsc_t grad; lv_gradient_stop_t stops[LV_GRADIENT_MAX_STOPS]; /**< A gradient stop array */
uint16_t stops_count; /**< The number of used stops in the array */
float x1;
float y1;
float x2;
float y2;
float cx; float cx;
float cy; float cy;
float cr; float cr;
@@ -391,24 +396,39 @@ void lv_vector_dsc_set_fill_image(lv_vector_dsc_t * dsc, const lv_draw_image_dsc
/** /**
* Set fill linear gradient for descriptor * Set fill linear gradient for descriptor
* @param dsc pointer to a vector graphic descriptor * @param dsc pointer to a vector graphic descriptor
* @param grad pointer to a `lv_grad_dsc_t` variable * @param x1 the x for start point
* @param spread the gradient spread to be set in lv_vector_gradient_spread_t format * @param y1 the y for start point
* @param x2 the x for end point
* @param y2 the y for end point
*/ */
void lv_vector_dsc_set_fill_linear_gradient(lv_vector_dsc_t * dsc, const lv_grad_dsc_t * grad, void lv_vector_dsc_set_fill_linear_gradient(lv_vector_dsc_t * dsc, float x1, float y1, float x2, float y2);
lv_vector_gradient_spread_t spread);
/** /**
* Set fill radial gradient for descriptor
* @param dsc pointer to a vector graphic descriptor * Set fill radial gradient radius for descriptor
* @param grad pointer to a `lv_grad_dsc_t` variable * @param dsc pointer to a vector graphic descriptor
* @param cx the x for center of the circle * @param cx the x for center of the circle
* @param cy the y for center of the circle * @param cy the y for center of the circle
* @param radius the radius for circle * @param radius the radius for circle
* @param spread the gradient spread to be set in lv_vector_gradient_spread_t format
*/ */
void lv_vector_dsc_set_fill_radial_gradient(lv_vector_dsc_t * dsc, const lv_grad_dsc_t * grad, float cx, float cy, void lv_vector_dsc_set_fill_radial_gradient(lv_vector_dsc_t * dsc, float cx, float cy, float radius);
float radius, lv_vector_gradient_spread_t spread);
/**
* Set fill radial gradient spread for descriptor
* @param dsc pointer to a vector graphic descriptor
* @param spread the gradient spread to be set in lv_vector_gradient_spread_t format
*/
void lv_vector_dsc_set_fill_gradient_spread(lv_vector_dsc_t * dsc, lv_vector_gradient_spread_t spread);
/**
* Set fill gradient color stops for descriptor
* @param dsc pointer to a vector graphic descriptor
* @param stops an array of `lv_gradient_stop_t` variables
* @param count the number of stops in the array
*/
void lv_vector_dsc_set_fill_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_gradient_stop_t * stops,
uint16_t count);
/** /**
* Set a matrix to current fill transformation matrix * Set a matrix to current fill transformation matrix
@@ -477,22 +497,37 @@ void lv_vector_dsc_set_stroke_miter_limit(lv_vector_dsc_t * dsc, uint16_t miter_
/** /**
* Set stroke linear gradient for descriptor * Set stroke linear gradient for descriptor
* @param dsc pointer to a vector graphic descriptor * @param dsc pointer to a vector graphic descriptor
* @param grad pointer to a `lv_grad_dsc_t` variable * @param x1 the x for start point
* @param spread the gradient spread to be set in lv_vector_gradient_spread_t format * @param y1 the y for start point
* @param x2 the x for end point
* @param y2 the y for end point
*/ */
void lv_vector_dsc_set_stroke_linear_gradient(lv_vector_dsc_t * dsc, const lv_grad_dsc_t * grad, void lv_vector_dsc_set_stroke_linear_gradient(lv_vector_dsc_t * dsc, float x1, float y1, float x2, float y2);
lv_vector_gradient_spread_t spread);
/** /**
* Set stroke radial gradient for descriptor * Set stroke radial gradient for descriptor
* @param dsc pointer to a vector graphic descriptor * @param dsc pointer to a vector graphic descriptor
* @param grad pointer to a `lv_grad_dsc_t` variable
* @param cx the x for center of the circle * @param cx the x for center of the circle
* @param cy the y for center of the circle * @param cy the y for center of the circle
* @param radius the radius for circle * @param radius the radius for circle
*/
void lv_vector_dsc_set_stroke_radial_gradient(lv_vector_dsc_t * dsc, float cx, float cy, float radius);
/**
* Set stroke color stops for descriptor
* @param dsc pointer to a vector graphic descriptor
* @param spread the gradient spread to be set in lv_vector_gradient_spread_t format * @param spread the gradient spread to be set in lv_vector_gradient_spread_t format
*/ */
void lv_vector_dsc_set_stroke_radial_gradient(lv_vector_dsc_t * dsc, const lv_grad_dsc_t * grad, float cx, float cy, void lv_vector_dsc_set_stroke_gradient_spread(lv_vector_dsc_t * dsc, lv_vector_gradient_spread_t spread);
float radius, lv_vector_gradient_spread_t spread);
/**
* Set stroke color stops for descriptor
* @param dsc pointer to a vector graphic descriptor
* @param stops an array of `lv_gradient_stop_t` variables
* @param count the number of stops in the array
*/
void lv_vector_dsc_set_stroke_gradient_color_stops(lv_vector_dsc_t * dsc, const lv_gradient_stop_t * stops,
uint16_t count);
/** /**
* Set a matrix to current stroke transformation matrix * Set a matrix to current stroke transformation matrix
* @param dsc pointer to a vector graphic descriptor * @param dsc pointer to a vector graphic descriptor

View File

@@ -180,10 +180,10 @@ static Tvg_Stroke_Fill _lv_spread_to_tvg(lv_vector_gradient_spread_t sp)
static void _setup_gradient(Tvg_Gradient * gradient, const lv_vector_gradient_t * grad, static void _setup_gradient(Tvg_Gradient * gradient, const lv_vector_gradient_t * grad,
const lv_matrix_t * matrix) const lv_matrix_t * matrix)
{ {
const lv_grad_dsc_t * g = &grad->grad; Tvg_Color_Stop * stops = (Tvg_Color_Stop *)lv_malloc(sizeof(Tvg_Color_Stop) * grad->stops_count);
Tvg_Color_Stop * stops = (Tvg_Color_Stop *)lv_malloc(sizeof(Tvg_Color_Stop) * g->stops_count); LV_ASSERT_MALLOC(stops);
for(uint8_t i = 0; i < g->stops_count; i++) { for(uint16_t i = 0; i < grad->stops_count; i++) {
const lv_gradient_stop_t * s = &(g->stops[i]); const lv_gradient_stop_t * s = &(grad->stops[i]);
stops[i].offset = s->frac / 255.0f; stops[i].offset = s->frac / 255.0f;
stops[i].r = s->color.red; stops[i].r = s->color.red;
@@ -192,7 +192,7 @@ static void _setup_gradient(Tvg_Gradient * gradient, const lv_vector_gradient_t
stops[i].a = s->opa; stops[i].a = s->opa;
} }
tvg_gradient_set_color_stops(gradient, stops, g->stops_count); tvg_gradient_set_color_stops(gradient, stops, grad->stops_count);
tvg_gradient_set_spread(gradient, _lv_spread_to_tvg(grad->spread)); tvg_gradient_set_spread(gradient, _lv_spread_to_tvg(grad->spread));
Tvg_Matrix mtx; Tvg_Matrix mtx;
_lv_matrix_to_tvg(&mtx, matrix); _lv_matrix_to_tvg(&mtx, matrix);
@@ -202,26 +202,16 @@ static void _setup_gradient(Tvg_Gradient * gradient, const lv_vector_gradient_t
static void _set_paint_stroke_gradient(Tvg_Paint * obj, const lv_vector_gradient_t * g, const lv_matrix_t * m) static void _set_paint_stroke_gradient(Tvg_Paint * obj, const lv_vector_gradient_t * g, const lv_matrix_t * m)
{ {
float x, y, w, h;
tvg_paint_get_bounds(obj, &x, &y, &w, &h, false);
Tvg_Gradient * grad = NULL; Tvg_Gradient * grad = NULL;
if(g->style == LV_VECTOR_GRADIENT_STYLE_RADIAL) { if(g->style == LV_VECTOR_GRADIENT_STYLE_RADIAL) {
grad = tvg_radial_gradient_new(); grad = tvg_radial_gradient_new();
tvg_radial_gradient_set(grad, g->cx + x, g->cy + y, g->cr); tvg_radial_gradient_set(grad, g->cx, g->cy, g->cr);
_setup_gradient(grad, g, m); _setup_gradient(grad, g, m);
tvg_shape_set_stroke_radial_gradient(obj, grad); tvg_shape_set_stroke_radial_gradient(obj, grad);
} }
else { else {
grad = tvg_linear_gradient_new(); grad = tvg_linear_gradient_new();
tvg_linear_gradient_set(grad, g->x1, g->y1, g->x2, g->y2);
if(g->grad.dir == LV_GRAD_DIR_VER) {
tvg_linear_gradient_set(grad, x, y, x, y + h);
}
else {
tvg_linear_gradient_set(grad, x, y, x + w, y);
}
_setup_gradient(grad, g, m); _setup_gradient(grad, g, m);
tvg_shape_set_stroke_linear_gradient(obj, grad); tvg_shape_set_stroke_linear_gradient(obj, grad);
} }
@@ -263,26 +253,16 @@ static Tvg_Fill_Rule _lv_fill_rule_to_tvg(lv_vector_fill_t rule)
static void _set_paint_fill_gradient(Tvg_Paint * obj, const lv_vector_gradient_t * g, const lv_matrix_t * m) static void _set_paint_fill_gradient(Tvg_Paint * obj, const lv_vector_gradient_t * g, const lv_matrix_t * m)
{ {
float x, y, w, h;
tvg_paint_get_bounds(obj, &x, &y, &w, &h, false);
Tvg_Gradient * grad = NULL; Tvg_Gradient * grad = NULL;
if(g->style == LV_VECTOR_GRADIENT_STYLE_RADIAL) { if(g->style == LV_VECTOR_GRADIENT_STYLE_RADIAL) {
grad = tvg_radial_gradient_new(); grad = tvg_radial_gradient_new();
tvg_radial_gradient_set(grad, g->cx + x, g->cy + y, g->cr); tvg_radial_gradient_set(grad, g->cx, g->cy, g->cr);
_setup_gradient(grad, g, m); _setup_gradient(grad, g, m);
tvg_shape_set_radial_gradient(obj, grad); tvg_shape_set_radial_gradient(obj, grad);
} }
else { else {
grad = tvg_linear_gradient_new(); grad = tvg_linear_gradient_new();
tvg_linear_gradient_set(grad, g->x1, g->y1, g->x2, g->y2);
if(g->grad.dir == LV_GRAD_DIR_VER) {
tvg_linear_gradient_set(grad, x, y, x, y + h);
}
else {
tvg_linear_gradient_set(grad, x, y, x + w, y);
}
_setup_gradient(grad, g, m); _setup_gradient(grad, g, m);
tvg_shape_set_linear_gradient(obj, grad); tvg_shape_set_linear_gradient(obj, grad);
} }

View File

@@ -72,7 +72,9 @@ void lv_draw_vg_lite_init(void)
unit->base_unit.delete_cb = draw_delete; unit->base_unit.delete_cb = draw_delete;
lv_vg_lite_image_dsc_init(unit); lv_vg_lite_image_dsc_init(unit);
lv_vg_lite_grad_init(unit, LV_VG_LITE_LINEAR_GRAD_CACHE_CNT, LV_VG_LITE_RADIAL_GRAD_CACHE_CNT); #if LV_USE_VECTOR_GRAPHIC
lv_vg_lite_grad_init(unit, LV_VG_LITE_GRAD_CACHE_CNT);
#endif
lv_vg_lite_path_init(unit); lv_vg_lite_path_init(unit);
lv_vg_lite_decoder_init(); lv_vg_lite_decoder_init();
} }
@@ -250,7 +252,9 @@ static int32_t draw_delete(lv_draw_unit_t * draw_unit)
lv_draw_vg_lite_unit_t * unit = (lv_draw_vg_lite_unit_t *)draw_unit; lv_draw_vg_lite_unit_t * unit = (lv_draw_vg_lite_unit_t *)draw_unit;
lv_vg_lite_image_dsc_deinit(unit); lv_vg_lite_image_dsc_deinit(unit);
#if LV_USE_VECTOR_GRAPHIC
lv_vg_lite_grad_deinit(unit); lv_vg_lite_grad_deinit(unit);
#endif
lv_vg_lite_path_deinit(unit); lv_vg_lite_path_deinit(unit);
lv_vg_lite_decoder_deinit(); lv_vg_lite_decoder_deinit();
return 1; return 1;

View File

@@ -81,17 +81,19 @@ void lv_draw_vg_lite_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t *
LV_VG_LITE_ASSERT_MATRIX(&matrix); LV_VG_LITE_ASSERT_MATRIX(&matrix);
if(dsc->grad.dir != LV_GRAD_DIR_NONE) { if(dsc->grad.dir != LV_GRAD_DIR_NONE) {
vg_lite_matrix_t grad_matrix; #if LV_USE_VECTOR_GRAPHIC
lv_vg_lite_grad_area_to_matrix(&grad_matrix, coords, dsc->grad.dir); lv_vg_lite_draw_grad_helper(
lv_vg_lite_draw_linear_grad(
u, u,
&u->target_buffer, &u->target_buffer,
vg_lite_path, vg_lite_path,
coords,
&dsc->grad, &dsc->grad,
&grad_matrix,
&matrix, &matrix,
VG_LITE_FILL_EVEN_ODD, VG_LITE_FILL_EVEN_ODD,
VG_LITE_BLEND_SRC_OVER); VG_LITE_BLEND_SRC_OVER);
#else
LV_LOG_WARN("Gradient fill is not supported without VECTOR_GRAPHIC");
#endif
} }
else { /* normal fill */ else { /* normal fill */
vg_lite_color_t color = lv_vg_lite_color(dsc->color, dsc->opa, true); vg_lite_color_t color = lv_vg_lite_color(dsc->color, dsc->opa, true);

View File

@@ -76,17 +76,19 @@ void lv_draw_vg_lite_triangle(lv_draw_unit_t * draw_unit, const lv_draw_triangle
LV_VG_LITE_ASSERT_MATRIX(&matrix); LV_VG_LITE_ASSERT_MATRIX(&matrix);
if(dsc->bg_grad.dir != LV_GRAD_DIR_NONE) { if(dsc->bg_grad.dir != LV_GRAD_DIR_NONE) {
vg_lite_matrix_t grad_matrix; #if LV_USE_VECTOR_GRAPHIC
lv_vg_lite_grad_area_to_matrix(&grad_matrix, &tri_area, dsc->bg_grad.dir); lv_vg_lite_draw_grad_helper(
lv_vg_lite_draw_linear_grad(
u, u,
&u->target_buffer, &u->target_buffer,
vg_lite_path, vg_lite_path,
&tri_area,
&dsc->bg_grad, &dsc->bg_grad,
&grad_matrix,
&matrix, &matrix,
VG_LITE_FILL_EVEN_ODD, VG_LITE_FILL_EVEN_ODD,
VG_LITE_BLEND_SRC_OVER); VG_LITE_BLEND_SRC_OVER);
#else
LV_LOG_WARN("Gradient fill is not supported without VECTOR_GRAPHIC");
#endif
} }
else { /* normal fill */ else { /* normal fill */
vg_lite_color_t color = lv_vg_lite_color(dsc->bg_color, dsc->bg_opa, true); vg_lite_color_t color = lv_vg_lite_color(dsc->bg_color, dsc->bg_opa, true);

View File

@@ -43,11 +43,8 @@ struct _lv_draw_vg_lite_unit_t {
struct _lv_vg_lite_pending_t * image_dsc_pending; struct _lv_vg_lite_pending_t * image_dsc_pending;
lv_cache_t * linear_grad_cache; lv_cache_t * grad_cache;
struct _lv_vg_lite_pending_t * linear_grad_pending; struct _lv_vg_lite_pending_t * grad_pending;
lv_cache_t * radial_grad_cache;
struct _lv_vg_lite_pending_t * radial_grad_pending;
uint16_t flush_count; uint16_t flush_count;
vg_lite_buffer_t target_buffer; vg_lite_buffer_t target_buffer;

View File

@@ -203,48 +203,18 @@ static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vec
} }
break; break;
case LV_VECTOR_DRAW_STYLE_GRADIENT: { case LV_VECTOR_DRAW_STYLE_GRADIENT: {
/* draw gradient */ vg_lite_matrix_t grad_matrix;
lv_vector_gradient_style_t style = dsc->fill_dsc.gradient.style; lv_matrix_to_vg(&grad_matrix, &dsc->fill_dsc.matrix);
if(style == LV_VECTOR_GRADIENT_STYLE_LINEAR) { lv_vg_lite_draw_grad(
vg_lite_matrix_t grad_matrix, fill_matrix; u,
lv_area_t grad_area; &u->target_buffer,
lv_area_set(&grad_area, (int32_t)min_x, (int32_t)min_y, (int32_t)max_x, (int32_t)max_y); vg_path,
lv_vg_lite_grad_area_to_matrix(&grad_matrix, &grad_area, LV_GRAD_DIR_HOR); &dsc->fill_dsc.gradient,
&grad_matrix,
lv_matrix_to_vg(&fill_matrix, &dsc->fill_dsc.matrix); &matrix,
lv_vg_lite_matrix_multiply(&grad_matrix, &matrix); fill,
lv_vg_lite_matrix_multiply(&grad_matrix, &fill_matrix); blend);
lv_vg_lite_draw_linear_grad(
u,
&u->target_buffer,
vg_path,
&dsc->fill_dsc.gradient.grad,
&grad_matrix,
&matrix,
fill,
blend);
}
else if(style == LV_VECTOR_GRADIENT_STYLE_RADIAL) {
vg_lite_matrix_t grad_matrix;
lv_matrix_to_vg(&grad_matrix, &dsc->fill_dsc.matrix);
/* add min_x, min_y to gradient center */
lv_vector_gradient_t new_grad = dsc->fill_dsc.gradient;
new_grad.cx += min_x;
new_grad.cy += min_y;
lv_vg_lite_draw_radial_grad(
u,
&u->target_buffer,
vg_path,
&new_grad,
&grad_matrix,
&matrix,
fill,
blend);
}
} }
break; break;
default: default:

View File

@@ -9,7 +9,7 @@
#include "lv_vg_lite_grad.h" #include "lv_vg_lite_grad.h"
#if LV_USE_DRAW_VG_LITE #if LV_USE_DRAW_VG_LITE && LV_USE_VECTOR_GRAPHIC
#include "lv_draw_vg_lite_type.h" #include "lv_draw_vg_lite_type.h"
#include "lv_vg_lite_pending.h" #include "lv_vg_lite_pending.h"
@@ -21,52 +21,47 @@
* DEFINES * DEFINES
*********************/ *********************/
#define SQUARE(x) ((x)*(x))
#ifndef M_PI
#define M_PI 3.1415926f
#endif
/********************** /**********************
* TYPEDEFS * TYPEDEFS
**********************/ **********************/
typedef struct { typedef enum {
lv_grad_dsc_t lv_grad; GRAD_TYPE_UNKNOWN,
vg_lite_linear_gradient_t vg_grad; GRAD_TYPE_LINEAR,
} linear_grad_item_t; GRAD_TYPE_LINEAR_EXT,
GRAD_TYPE_RADIAL,
#if LV_USE_VECTOR_GRAPHIC } grad_type_t;
typedef struct { typedef struct {
lv_vector_gradient_t lv_grad; grad_type_t type;
vg_lite_radial_gradient_t vg_grad; lv_vector_gradient_t lv;
} radial_grad_item_t; union {
vg_lite_linear_gradient_t linear;
#endif /* LV_USE_VECTOR_GRAPHIC */ vg_lite_ext_linear_gradient_t linear_ext;
vg_lite_radial_gradient_t radial;
} vg;
} grad_item_t;
/********************** /**********************
* STATIC PROTOTYPES * STATIC PROTOTYPES
**********************/ **********************/
static grad_item_t * grad_get(struct _lv_draw_vg_lite_unit_t * u, const lv_vector_gradient_t * grad);
static void grad_cache_release_cb(void * entry, void * user_data); static void grad_cache_release_cb(void * entry, void * user_data);
static bool grad_create_cb(grad_item_t * item, void * user_data);
static void grad_free_cb(grad_item_t * item, void * user_data);
static lv_cache_compare_res_t grad_compare_cb(const grad_item_t * lhs, const grad_item_t * rhs);
/* Linear gradient */ static grad_type_t lv_grad_style_to_type(lv_vector_gradient_style_t style);
static void grad_point_to_matrix(vg_lite_matrix_t * grad_matrix, float x1, float y1, float x2, float y2);
static vg_lite_linear_gradient_t * linear_grad_get(struct _lv_draw_vg_lite_unit_t * u,
const lv_grad_dsc_t * grad);
static bool linear_grad_create_cb(linear_grad_item_t * item, void * user_data);
static void linear_grad_free_cb(linear_grad_item_t * item, void * user_data);
static lv_cache_compare_res_t linear_grad_compare_cb(const linear_grad_item_t * lhs, const linear_grad_item_t * rhs);
#if LV_USE_VECTOR_GRAPHIC
/* Radial gradient */
static vg_lite_radial_gradient_t * radial_grad_get(struct _lv_draw_vg_lite_unit_t * u,
const lv_vector_gradient_t * grad);
static bool radial_grad_create_cb(radial_grad_item_t * item, void * user_data);
static void radial_grad_free_cb(radial_grad_item_t * item, void * user_data);
static lv_cache_compare_res_t radial_grad_compare_cb(const radial_grad_item_t * lhs, const radial_grad_item_t * rhs);
static vg_lite_gradient_spreadmode_t lv_spread_to_vg(lv_vector_gradient_spread_t spread); static vg_lite_gradient_spreadmode_t lv_spread_to_vg(lv_vector_gradient_spread_t spread);
#endif /* LV_USE_VECTOR_GRAPHIC */
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
**********************/ **********************/
@@ -79,142 +74,33 @@ static vg_lite_gradient_spreadmode_t lv_spread_to_vg(lv_vector_gradient_spread_t
* GLOBAL FUNCTIONS * GLOBAL FUNCTIONS
**********************/ **********************/
void lv_vg_lite_grad_init( void lv_vg_lite_grad_init(struct _lv_draw_vg_lite_unit_t * u, uint32_t cache_cnt)
struct _lv_draw_vg_lite_unit_t * u,
uint32_t linear_grad_cache_cnt,
uint32_t radial_grad_cache_cnt)
{ {
LV_ASSERT_NULL(u); LV_ASSERT_NULL(u);
LV_UNUSED(radial_grad_cache_cnt);
/* Create the cache for linear gradients */ lv_cache_ops_t ops = {
{ .compare_cb = (lv_cache_compare_cb_t)grad_compare_cb,
lv_cache_ops_t ops = { .create_cb = (lv_cache_create_cb_t)grad_create_cb,
.compare_cb = (lv_cache_compare_cb_t)linear_grad_compare_cb, .free_cb = (lv_cache_free_cb_t)grad_free_cb,
.create_cb = (lv_cache_create_cb_t)linear_grad_create_cb, };
.free_cb = (lv_cache_free_cb_t)linear_grad_free_cb,
};
u->linear_grad_cache = lv_cache_create(&lv_cache_class_lru_rb_count, sizeof(linear_grad_item_t), u->grad_cache = lv_cache_create(&lv_cache_class_lru_rb_count, sizeof(grad_item_t), cache_cnt, ops);
linear_grad_cache_cnt, lv_cache_set_name(u->grad_cache, "VG_GRAD");
ops); u->grad_pending = lv_vg_lite_pending_create(sizeof(lv_cache_entry_t *), 4);
lv_cache_set_name(u->linear_grad_cache, "LINEAR_GRAD"); lv_vg_lite_pending_set_free_cb(u->grad_pending, grad_cache_release_cb, u->grad_cache);
u->linear_grad_pending = lv_vg_lite_pending_create(sizeof(lv_cache_entry_t *), 4);
lv_vg_lite_pending_set_free_cb(u->linear_grad_pending, grad_cache_release_cb, u->linear_grad_cache);
}
#if LV_USE_VECTOR_GRAPHIC
/* Create the cache for radial gradients */
if(vg_lite_query_feature(gcFEATURE_BIT_VG_RADIAL_GRADIENT)) {
lv_cache_ops_t ops = {
.compare_cb = (lv_cache_compare_cb_t)radial_grad_compare_cb,
.create_cb = (lv_cache_create_cb_t)radial_grad_create_cb,
.free_cb = (lv_cache_free_cb_t)radial_grad_free_cb,
};
u->radial_grad_cache = lv_cache_create(&lv_cache_class_lru_rb_count, sizeof(radial_grad_item_t),
radial_grad_cache_cnt,
ops);
u->radial_grad_pending = lv_vg_lite_pending_create(sizeof(lv_cache_entry_t *), 4);
lv_vg_lite_pending_set_free_cb(u->radial_grad_pending, grad_cache_release_cb, u->radial_grad_cache);
}
#endif /* LV_USE_VECTOR_GRAPHIC */
} }
void lv_vg_lite_grad_deinit(struct _lv_draw_vg_lite_unit_t * u) void lv_vg_lite_grad_deinit(struct _lv_draw_vg_lite_unit_t * u)
{ {
LV_ASSERT_NULL(u); LV_ASSERT_NULL(u);
lv_vg_lite_pending_destroy(u->linear_grad_pending); LV_ASSERT_NULL(u->grad_pending)
u->linear_grad_pending = NULL; lv_vg_lite_pending_destroy(u->grad_pending);
lv_cache_destroy(u->linear_grad_cache, NULL); u->grad_pending = NULL;
u->linear_grad_cache = NULL; lv_cache_destroy(u->grad_cache, NULL);
u->grad_cache = NULL;
if(u->radial_grad_pending) {
lv_vg_lite_pending_destroy(u->radial_grad_pending);
u->radial_grad_pending = NULL;
lv_cache_destroy(u->radial_grad_cache, NULL);
u->radial_grad_cache = NULL;
}
} }
void lv_vg_lite_grad_area_to_matrix(vg_lite_matrix_t * grad_matrix, const lv_area_t * area, lv_grad_dir_t dir) bool lv_vg_lite_draw_grad(
{
LV_ASSERT_NULL(grad_matrix);
LV_ASSERT_NULL(area);
vg_lite_identity(grad_matrix);
vg_lite_translate(area->x1, area->y1, grad_matrix);
switch(dir) {
case LV_GRAD_DIR_VER:
vg_lite_scale(1, lv_area_get_height(area) / 256.0f, grad_matrix);
vg_lite_rotate(90, grad_matrix);
break;
case LV_GRAD_DIR_HOR:
vg_lite_scale(lv_area_get_width(area) / 256.0f, 1, grad_matrix);
break;
default:
break;
}
}
void lv_vg_lite_draw_linear_grad(
struct _lv_draw_vg_lite_unit_t * u,
vg_lite_buffer_t * buffer,
vg_lite_path_t * path,
const lv_grad_dsc_t * grad,
const vg_lite_matrix_t * grad_matrix,
const vg_lite_matrix_t * matrix,
vg_lite_fill_t fill,
vg_lite_blend_t blend)
{
LV_ASSERT_NULL(u);
LV_ASSERT_NULL(buffer);
LV_ASSERT_NULL(path);
LV_ASSERT_NULL(grad);
LV_ASSERT_NULL(grad_matrix);
LV_ASSERT_NULL(matrix);
LV_PROFILER_BEGIN;
vg_lite_linear_gradient_t * linear_grad = linear_grad_get(u, grad);
LV_ASSERT_NULL(linear_grad);
if(!linear_grad) {
LV_LOG_ERROR("Failed to get linear gradient");
LV_PROFILER_END;
return;
}
vg_lite_matrix_t * grad_mat_p = vg_lite_get_grad_matrix(linear_grad);
LV_ASSERT_NULL(grad_mat_p);
*grad_mat_p = *grad_matrix;
LV_VG_LITE_ASSERT_DEST_BUFFER(buffer);
LV_VG_LITE_ASSERT_SRC_BUFFER(&linear_grad->image);
LV_VG_LITE_ASSERT_PATH(path);
LV_VG_LITE_ASSERT_MATRIX(grad_mat_p);
LV_VG_LITE_ASSERT_MATRIX(matrix);
LV_PROFILER_BEGIN_TAG("vg_lite_draw_grad");
LV_VG_LITE_CHECK_ERROR(vg_lite_draw_grad(
buffer,
path,
fill,
(vg_lite_matrix_t *)matrix,
linear_grad,
blend));
LV_PROFILER_END_TAG("vg_lite_draw_grad");
LV_PROFILER_END;
}
#if LV_USE_VECTOR_GRAPHIC
void lv_vg_lite_draw_radial_grad(
struct _lv_draw_vg_lite_unit_t * u, struct _lv_draw_vg_lite_unit_t * u,
vg_lite_buffer_t * buffer, vg_lite_buffer_t * buffer,
vg_lite_path_t * path, vg_lite_path_t * path,
@@ -225,81 +111,239 @@ void lv_vg_lite_draw_radial_grad(
vg_lite_blend_t blend) vg_lite_blend_t blend)
{ {
LV_ASSERT_NULL(u); LV_ASSERT_NULL(u);
LV_ASSERT_NULL(buffer); LV_VG_LITE_ASSERT_DEST_BUFFER(buffer);
LV_ASSERT_NULL(path); LV_VG_LITE_ASSERT_PATH(path);
LV_ASSERT_NULL(grad); LV_ASSERT_NULL(grad);
LV_ASSERT_NULL(grad_matrix); LV_VG_LITE_ASSERT_MATRIX(grad_matrix);
LV_ASSERT_NULL(matrix); LV_VG_LITE_ASSERT_MATRIX(matrix);
if(!vg_lite_query_feature(gcFEATURE_BIT_VG_RADIAL_GRADIENT)) { /* check radial gradient is supported */
LV_LOG_INFO("radial gradient is not supported"); if(grad->style == LV_VECTOR_GRADIENT_STYLE_RADIAL) {
return; if(!vg_lite_query_feature(gcFEATURE_BIT_VG_RADIAL_GRADIENT)) {
} LV_LOG_INFO("radial gradient is not supported");
return false;
}
if(grad->spread == LV_VECTOR_GRADIENT_SPREAD_REPEAT || grad->spread == LV_VECTOR_GRADIENT_SPREAD_REFLECT) { /* check if the radius is valid */
if(!vg_lite_query_feature(gcFEATURE_BIT_VG_IM_REPEAT_REFLECT)) { if(grad->cr <= 0) {
LV_LOG_INFO("repeat/reflect spread(%d) is not supported", (int)grad->spread); LV_LOG_INFO("radius: %f is not valid", grad->cr);
return; return false;
} }
} }
LV_PROFILER_BEGIN; /* check spread mode is supported */
if(grad->spread == LV_VECTOR_GRADIENT_SPREAD_REPEAT || grad->spread == LV_VECTOR_GRADIENT_SPREAD_REFLECT) {
if(!vg_lite_query_feature(gcFEATURE_BIT_VG_IM_REPEAT_REFLECT)) {
LV_LOG_INFO("repeat/reflect spread(%d) is not supported", grad->spread);
return false;
}
}
vg_lite_radial_gradient_t * radial_grad = radial_grad_get(u, grad); LV_PROFILER_BEGIN_TAG("grad_get");
grad_item_t * grad_item = grad_get(u, grad);
LV_PROFILER_END_TAG("grad_get");
if(!grad_item) {
LV_LOG_WARN("Failed to get gradient, style: %d", grad->style);
return false;
}
LV_ASSERT(grad_item->lv.style == grad->style);
vg_lite_matrix_t * grad_mat_p = vg_lite_get_radial_grad_matrix(radial_grad); switch(grad_item->type) {
LV_ASSERT_NULL(grad_mat_p); case GRAD_TYPE_LINEAR: {
*grad_mat_p = *grad_matrix; vg_lite_linear_gradient_t * linear_grad = &grad_item->vg.linear;
vg_lite_matrix_t * grad_mat_p = vg_lite_get_grad_matrix(linear_grad);
LV_ASSERT_NULL(grad_mat_p);
LV_VG_LITE_ASSERT_DEST_BUFFER(buffer); grad_point_to_matrix(grad_mat_p, grad->x1, grad->y1, grad->x2, grad->y2);
LV_VG_LITE_ASSERT_SRC_BUFFER(&radial_grad->image); lv_vg_lite_matrix_multiply(grad_mat_p, grad_matrix);
LV_VG_LITE_ASSERT_PATH(path);
LV_VG_LITE_ASSERT_MATRIX(grad_mat_p);
LV_VG_LITE_ASSERT_MATRIX(matrix);
LV_PROFILER_BEGIN_TAG("vg_lite_draw_radial_grad"); LV_VG_LITE_ASSERT_SRC_BUFFER(&linear_grad->image);
LV_VG_LITE_CHECK_ERROR(
vg_lite_draw_radial_grad(
buffer,
path,
fill,
(vg_lite_matrix_t *)matrix,
radial_grad,
0,
blend,
VG_LITE_FILTER_LINEAR));
LV_PROFILER_END_TAG("vg_lite_draw_radial_grad");
LV_PROFILER_END; LV_PROFILER_BEGIN_TAG("vg_lite_draw_grad");
LV_VG_LITE_CHECK_ERROR(vg_lite_draw_grad(
buffer,
path,
fill,
(vg_lite_matrix_t *)matrix,
linear_grad,
blend));
LV_PROFILER_END_TAG("vg_lite_draw_grad");
}
break;
case GRAD_TYPE_LINEAR_EXT: {
vg_lite_ext_linear_gradient_t * linear_grad = &grad_item->vg.linear_ext;
vg_lite_matrix_t * grad_mat_p = vg_lite_get_linear_grad_matrix(linear_grad);
LV_ASSERT_NULL(grad_mat_p);
*grad_mat_p = *grad_matrix;
LV_VG_LITE_ASSERT_SRC_BUFFER(&linear_grad->image);
LV_PROFILER_BEGIN_TAG("vg_lite_draw_linear_grad");
LV_VG_LITE_CHECK_ERROR(vg_lite_draw_linear_grad(
buffer,
path,
fill,
(vg_lite_matrix_t *)matrix,
linear_grad,
0,
blend,
VG_LITE_FILTER_LINEAR));
LV_PROFILER_END_TAG("vg_lite_draw_linear_grad");
}
break;
case GRAD_TYPE_RADIAL: {
vg_lite_radial_gradient_t * radial = &grad_item->vg.radial;
vg_lite_matrix_t * grad_mat_p = vg_lite_get_radial_grad_matrix(radial);
LV_ASSERT_NULL(grad_mat_p);
*grad_mat_p = *grad_matrix;
LV_VG_LITE_ASSERT_SRC_BUFFER(&grad_item->vg.radial.image);
LV_PROFILER_BEGIN_TAG("vg_lite_draw_radial_grad");
LV_VG_LITE_CHECK_ERROR(
vg_lite_draw_radial_grad(
buffer,
path,
fill,
(vg_lite_matrix_t *)matrix,
&grad_item->vg.radial,
0,
blend,
VG_LITE_FILTER_LINEAR));
LV_PROFILER_END_TAG("vg_lite_draw_radial_grad");
}
break;
default:
LV_LOG_ERROR("Unsupported gradient type: %d", grad_item->type);
return false;
}
return true;
} }
#endif /* LV_USE_VECTOR_GRAPHIC */ bool lv_vg_lite_draw_grad_helper(
struct _lv_draw_vg_lite_unit_t * u,
vg_lite_buffer_t * buffer,
vg_lite_path_t * path,
const lv_area_t * area,
const lv_grad_dsc_t * grad_dsc,
const vg_lite_matrix_t * matrix,
vg_lite_fill_t fill,
vg_lite_blend_t blend)
{
LV_ASSERT_NULL(u);
LV_VG_LITE_ASSERT_DEST_BUFFER(buffer);
LV_VG_LITE_ASSERT_PATH(path);
LV_ASSERT_NULL(area);
LV_ASSERT_NULL(grad_dsc);
LV_VG_LITE_ASSERT_MATRIX(matrix);
lv_vector_gradient_t grad;
lv_memzero(&grad, sizeof(grad));
grad.style = LV_VECTOR_GRADIENT_STYLE_LINEAR;
grad.stops_count = grad_dsc->stops_count;
lv_memcpy(grad.stops, grad_dsc->stops, sizeof(lv_gradient_stop_t) * grad_dsc->stops_count);
/*convert to spread mode*/
#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS
switch(grad_dsc->extend) {
case LV_GRAD_EXTEND_PAD:
grad.spread = LV_VECTOR_GRADIENT_SPREAD_PAD;
break;
case LV_GRAD_EXTEND_REPEAT:
grad.spread = LV_VECTOR_GRADIENT_SPREAD_REPEAT;
break;
case LV_GRAD_EXTEND_REFLECT:
grad.spread = LV_VECTOR_GRADIENT_SPREAD_REFLECT;
break;
default:
LV_LOG_WARN("Unsupported gradient extend mode: %d", grad_dsc->extend);
grad.spread = LV_VECTOR_GRADIENT_SPREAD_PAD;
break;
}
#else
grad.spread = LV_VECTOR_GRADIENT_SPREAD_PAD;
#endif
switch(grad_dsc->dir) {
case LV_GRAD_DIR_VER:
grad.x1 = area->x1;
grad.y1 = area->y1;
grad.x2 = area->x1;
grad.y2 = area->y2 + 1;
break;
case LV_GRAD_DIR_HOR:
grad.x1 = area->x1;
grad.y1 = area->y1;
grad.x2 = area->x2 + 1;
grad.y2 = area->y1;
break;
#if LV_USE_DRAW_SW_COMPLEX_GRADIENTS
case LV_GRAD_DIR_LINEAR: {
int32_t w = lv_area_get_width(area);
int32_t h = lv_area_get_height(area);
grad.x1 = lv_pct_to_px(grad_dsc->params.linear.start.x, w) + area->x1;
grad.y1 = lv_pct_to_px(grad_dsc->params.linear.start.y, h) + area->y1;
grad.x2 = lv_pct_to_px(grad_dsc->params.linear.end.x, w) + area->x1;
grad.y2 = lv_pct_to_px(grad_dsc->params.linear.end.y, h) + area->y1;
}
break;
case LV_GRAD_DIR_RADIAL: {
grad.style = LV_VECTOR_GRADIENT_STYLE_RADIAL;
int32_t w = lv_area_get_width(area);
int32_t h = lv_area_get_height(area);
grad.cx = lv_pct_to_px(grad_dsc->params.radial.focal.x, w) + area->x1;
grad.cy = lv_pct_to_px(grad_dsc->params.radial.focal.y, h) + area->y1;
int32_t end_extent_x = lv_pct_to_px(grad_dsc->params.radial.end_extent.x, w) + area->x1;
int32_t end_extent_y = lv_pct_to_px(grad_dsc->params.radial.end_extent.y, h) + area->y1;
grad.cr = LV_MAX(end_extent_x - grad.cx, end_extent_y - grad.cy);
}
break;
#endif
default:
LV_LOG_WARN("Unsupported gradient direction: %d", grad_dsc->dir);
return false;
}
vg_lite_matrix_t grad_matrix;
vg_lite_identity(&grad_matrix);
return lv_vg_lite_draw_grad(u, buffer, path, &grad, &grad_matrix, matrix, fill, blend);
}
/********************** /**********************
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/
static void * grad_get( static grad_item_t * grad_get(struct _lv_draw_vg_lite_unit_t * u, const lv_vector_gradient_t * grad)
struct _lv_draw_vg_lite_unit_t * u,
lv_cache_t * cache,
lv_vg_lite_pending_t * pending,
const void * key)
{ {
LV_ASSERT_NULL(u); LV_ASSERT_NULL(u);
LV_ASSERT_NULL(cache); LV_ASSERT_NULL(grad);
LV_ASSERT_NULL(pending);
LV_ASSERT_NULL(key);
lv_cache_entry_t * cache_node_entry = lv_cache_acquire(cache, key, NULL); grad_item_t search_key;
lv_memzero(&search_key, sizeof(search_key));
search_key.type = lv_grad_style_to_type(grad->style);
search_key.lv = *grad;
lv_cache_entry_t * cache_node_entry = lv_cache_acquire(u->grad_cache, &search_key, NULL);
if(cache_node_entry == NULL) { if(cache_node_entry == NULL) {
/* check if the cache is full */ /* check if the cache is full */
size_t free_size = lv_cache_get_free_size(cache, NULL); size_t free_size = lv_cache_get_free_size(u->grad_cache, NULL);
if(free_size == 0) { if(free_size == 0) {
LV_LOG_INFO("grad cache is full, release all pending cache entries"); LV_LOG_INFO("grad cache is full, release all pending cache entries");
lv_vg_lite_finish(u); lv_vg_lite_finish(u);
} }
cache_node_entry = lv_cache_acquire_or_create(cache, key, NULL); cache_node_entry = lv_cache_acquire_or_create(u->grad_cache, &search_key, NULL);
if(cache_node_entry == NULL) { if(cache_node_entry == NULL) {
LV_LOG_ERROR("grad cache creating failed"); LV_LOG_ERROR("grad cache creating failed");
return NULL; return NULL;
@@ -307,7 +351,7 @@ static void * grad_get(
} }
/* Add the new entry to the pending list */ /* Add the new entry to the pending list */
lv_vg_lite_pending_add(pending, &cache_node_entry); lv_vg_lite_pending_add(u->grad_pending, &cache_node_entry);
return lv_cache_entry_get_data(cache_node_entry); return lv_cache_entry_get_data(cache_node_entry);
} }
@@ -316,33 +360,38 @@ static void grad_cache_release_cb(void * entry, void * user_data)
{ {
lv_cache_entry_t ** entry_p = entry; lv_cache_entry_t ** entry_p = entry;
lv_cache_t * cache = user_data; lv_cache_t * cache = user_data;
lv_cache_release(cache, *entry_p, NULL); lv_cache_release(cache, * entry_p, NULL);
} }
/* Linear gradient */ static vg_lite_color_ramp_t * grad_create_color_ramp(const lv_vector_gradient_t * grad)
static vg_lite_linear_gradient_t * linear_grad_get(struct _lv_draw_vg_lite_unit_t * u,
const lv_grad_dsc_t * grad)
{ {
linear_grad_item_t search_key; LV_ASSERT_NULL(grad);
lv_memzero(&search_key, sizeof(search_key));
search_key.lv_grad = *grad;
linear_grad_item_t * item = grad_get(u, u->linear_grad_cache, u->linear_grad_pending, &search_key); vg_lite_color_ramp_t * color_ramp = lv_malloc(sizeof(vg_lite_color_ramp_t) * grad->stops_count);
if(!item) { LV_ASSERT_MALLOC(color_ramp);
if(!color_ramp) {
LV_LOG_ERROR("malloc failed for color_ramp");
return NULL; return NULL;
} }
return &item->vg_grad; for(uint16_t i = 0; i < grad->stops_count; i++) {
color_ramp[i].stop = grad->stops[i].frac / 255.0f;
lv_color_t c = grad->stops[i].color;
color_ramp[i].red = c.red / 255.0f;
color_ramp[i].green = c.green / 255.0f;
color_ramp[i].blue = c.blue / 255.0f;
color_ramp[i].alpha = grad->stops[i].opa / 255.0f;
}
return color_ramp;
} }
static bool linear_grad_create_cb(linear_grad_item_t * item, void * user_data) static bool linear_grad_create(grad_item_t * item)
{ {
LV_UNUSED(user_data);
LV_PROFILER_BEGIN; LV_PROFILER_BEGIN;
vg_lite_error_t err = vg_lite_init_grad(&item->vg_grad); vg_lite_error_t err = vg_lite_init_grad(&item->vg.linear);
if(err != VG_LITE_SUCCESS) { if(err != VG_LITE_SUCCESS) {
LV_PROFILER_END; LV_PROFILER_END;
LV_LOG_ERROR("init grad error(%d): %s", (int)err, lv_vg_lite_error_string(err)); LV_LOG_ERROR("init grad error(%d): %s", (int)err, lv_vg_lite_error_string(err));
@@ -353,99 +402,104 @@ static bool linear_grad_create_cb(linear_grad_item_t * item, void * user_data)
vg_lite_uint32_t stops[VLC_MAX_GRADIENT_STOPS]; vg_lite_uint32_t stops[VLC_MAX_GRADIENT_STOPS];
/* Gradient setup */ /* Gradient setup */
uint8_t cnt = item->lv_grad.stops_count; if(item->lv.stops_count > VLC_MAX_GRADIENT_STOPS) {
LV_ASSERT(cnt < VLC_MAX_GRADIENT_STOPS); LV_LOG_WARN("Too many gradient stops, max is %d", VLC_MAX_GRADIENT_STOPS);
for(uint8_t i = 0; i < cnt; i++) { item->lv.stops_count = VLC_MAX_GRADIENT_STOPS;
stops[i] = item->lv_grad.stops[i].frac; }
const lv_color_t * c = &item->lv_grad.stops[i].color;
lv_opa_t opa = item->lv_grad.stops[i].opa; for(uint16_t i = 0; i < item->lv.stops_count; i++) {
stops[i] = item->lv.stops[i].frac;
const lv_color_t * c = &item->lv.stops[i].color;
lv_opa_t opa = item->lv.stops[i].opa;
/* lvgl color -> gradient color */ /* lvgl color -> gradient color */
lv_color_t grad_color = lv_color_make(c->blue, c->green, c->red); lv_color_t grad_color = lv_color_make(c->blue, c->green, c->red);
colors[i] = lv_vg_lite_color(grad_color, opa, true); colors[i] = lv_vg_lite_color(grad_color, opa, true);
} }
LV_VG_LITE_CHECK_ERROR(vg_lite_set_grad(&item->vg_grad, cnt, colors, stops)); LV_VG_LITE_CHECK_ERROR(vg_lite_set_grad(&item->vg.linear, item->lv.stops_count, colors, stops));
LV_PROFILER_BEGIN_TAG("vg_lite_update_grad"); LV_PROFILER_BEGIN_TAG("vg_lite_update_grad");
LV_VG_LITE_CHECK_ERROR(vg_lite_update_grad(&item->vg_grad)); LV_VG_LITE_CHECK_ERROR(vg_lite_update_grad(&item->vg.linear));
LV_PROFILER_END_TAG("vg_lite_update_grad"); LV_PROFILER_END_TAG("vg_lite_update_grad");
LV_PROFILER_END; LV_PROFILER_END;
return true; return true;
} }
static void linear_grad_free_cb(linear_grad_item_t * item, void * user_data) static bool linear_ext_grad_create(grad_item_t * item)
{ {
LV_UNUSED(user_data);
LV_VG_LITE_CHECK_ERROR(vg_lite_clear_grad(&item->vg_grad));
}
static lv_cache_compare_res_t linear_grad_compare_cb(const linear_grad_item_t * lhs, const linear_grad_item_t * rhs)
{
if(lhs->lv_grad.stops_count != rhs->lv_grad.stops_count) {
return lhs->lv_grad.stops_count > rhs->lv_grad.stops_count ? 1 : -1;
}
int cmp_res = lv_memcmp(lhs->lv_grad.stops, rhs->lv_grad.stops,
sizeof(lv_gradient_stop_t) * lhs->lv_grad.stops_count);
if(cmp_res != 0) {
return cmp_res > 0 ? 1 : -1;
}
return 0;
}
#if LV_USE_VECTOR_GRAPHIC
/* Radial gradient */
static vg_lite_radial_gradient_t * radial_grad_get(struct _lv_draw_vg_lite_unit_t * u,
const lv_vector_gradient_t * grad)
{
radial_grad_item_t search_key;
lv_memzero(&search_key, sizeof(search_key));
search_key.lv_grad = *grad;
radial_grad_item_t * item = grad_get(u, u->radial_grad_cache, u->radial_grad_pending, &search_key);
if(!item) {
return NULL;
}
return &item->vg_grad;
}
static bool radial_grad_create_cb(radial_grad_item_t * item, void * user_data)
{
LV_UNUSED(user_data);
LV_PROFILER_BEGIN; LV_PROFILER_BEGIN;
lv_vector_gradient_t * grad = &item->lv_grad; if(item->lv.stops_count > VLC_MAX_COLOR_RAMP_STOPS) {
uint8_t stops_count = grad->grad.stops_count; LV_LOG_WARN("Too many gradient stops, max is %d", VLC_MAX_COLOR_RAMP_STOPS);
vg_lite_color_ramp_t * color_ramp = lv_malloc(sizeof(vg_lite_color_ramp_t) * stops_count); item->lv.stops_count = VLC_MAX_COLOR_RAMP_STOPS;
LV_ASSERT_MALLOC(color_ramp); }
vg_lite_color_ramp_t * color_ramp = grad_create_color_ramp(&item->lv);
if(!color_ramp) { if(!color_ramp) {
LV_LOG_ERROR("malloc failed for color_ramp"); LV_PROFILER_END;
return false; return false;
} }
for(uint8_t i = 0; i < stops_count; i++) { const vg_lite_linear_gradient_parameter_t grad_param = {
color_ramp[i].stop = grad->grad.stops[i].frac / 255.0f; .X0 = item->lv.x1,
lv_color_t c = grad->grad.stops[i].color; .Y0 = item->lv.y1,
.X1 = item->lv.x2,
.Y1 = item->lv.y2,
};
color_ramp[i].red = c.red / 255.0f; vg_lite_ext_linear_gradient_t linear_grad;
color_ramp[i].green = c.green / 255.0f; lv_memzero(&linear_grad, sizeof(linear_grad));
color_ramp[i].blue = c.blue / 255.0f;
color_ramp[i].alpha = grad->grad.stops[i].opa / 255.0f; LV_PROFILER_BEGIN_TAG("vg_lite_set_linear_grad");
LV_VG_LITE_CHECK_ERROR(
vg_lite_set_linear_grad(
&linear_grad,
item->lv.stops_count,
color_ramp,
grad_param,
lv_spread_to_vg(item->lv.spread),
1));
LV_PROFILER_END_TAG("vg_lite_set_linear_grad");
LV_PROFILER_BEGIN_TAG("vg_lite_update_linear_grad");
vg_lite_error_t err = vg_lite_update_linear_grad(&linear_grad);
LV_PROFILER_END_TAG("vg_lite_update_linear_grad");
if(err == VG_LITE_SUCCESS) {
item->vg.linear_ext = linear_grad;
}
else {
LV_LOG_ERROR("update grad error(%d): %s", (int)err, lv_vg_lite_error_string(err));
}
lv_free(color_ramp);
LV_PROFILER_END;
return err == VG_LITE_SUCCESS;
}
static bool radial_grad_create(grad_item_t * item)
{
LV_PROFILER_BEGIN;
if(item->lv.stops_count > VLC_MAX_COLOR_RAMP_STOPS) {
LV_LOG_WARN("Too many gradient stops, max is %d", VLC_MAX_COLOR_RAMP_STOPS);
item->lv.stops_count = VLC_MAX_COLOR_RAMP_STOPS;
}
vg_lite_color_ramp_t * color_ramp = grad_create_color_ramp(&item->lv);
if(!color_ramp) {
LV_PROFILER_END;
return false;
} }
const vg_lite_radial_gradient_parameter_t grad_param = { const vg_lite_radial_gradient_parameter_t grad_param = {
.cx = grad->cx, .cx = item->lv.cx,
.cy = grad->cy, .cy = item->lv.cy,
.r = grad->cr, .r = item->lv.cr,
.fx = grad->cx, .fx = item->lv.cx,
.fy = grad->cy, .fy = item->lv.cy,
}; };
vg_lite_radial_gradient_t radial_grad; vg_lite_radial_gradient_t radial_grad;
@@ -455,18 +509,18 @@ static bool radial_grad_create_cb(radial_grad_item_t * item, void * user_data)
LV_VG_LITE_CHECK_ERROR( LV_VG_LITE_CHECK_ERROR(
vg_lite_set_radial_grad( vg_lite_set_radial_grad(
&radial_grad, &radial_grad,
stops_count, item->lv.stops_count,
color_ramp, color_ramp,
grad_param, grad_param,
lv_spread_to_vg(grad->spread), lv_spread_to_vg(item->lv.spread),
1)); 1));
LV_PROFILER_END_TAG("vg_lite_set_radial_grad"); LV_PROFILER_END_TAG("vg_lite_set_radial_grad");
LV_PROFILER_BEGIN_TAG("vg_lite_update_radial_grad"); LV_PROFILER_BEGIN_TAG("vg_lite_update_radial_grad");
vg_lite_error_t err = vg_lite_update_radial_grad(&radial_grad); vg_lite_error_t err = vg_lite_update_radial_grad(&radial_grad);
LV_PROFILER_END_TAG("vg_lite_update_radial_grad"); LV_PROFILER_END_TAG("vg_lite_update_radial_grad");
if(!err) { if(err == VG_LITE_SUCCESS) {
item->vg_grad = radial_grad; item->vg.radial = radial_grad;
} }
else { else {
LV_LOG_ERROR("update radial grad error(%d): %s", (int)err, lv_vg_lite_error_string(err)); LV_LOG_ERROR("update radial grad error(%d): %s", (int)err, lv_vg_lite_error_string(err));
@@ -478,41 +532,29 @@ static bool radial_grad_create_cb(radial_grad_item_t * item, void * user_data)
return err == VG_LITE_SUCCESS; return err == VG_LITE_SUCCESS;
} }
static void radial_grad_free_cb(radial_grad_item_t * item, void * user_data) static grad_type_t lv_grad_style_to_type(lv_vector_gradient_style_t style)
{ {
LV_UNUSED(user_data); if(style == LV_VECTOR_GRADIENT_STYLE_LINEAR) {
LV_VG_LITE_CHECK_ERROR(vg_lite_clear_radial_grad(&item->vg_grad)); return vg_lite_query_feature(gcFEATURE_BIT_VG_LINEAR_GRADIENT_EXT) ? GRAD_TYPE_LINEAR_EXT : GRAD_TYPE_LINEAR;
}
if(style == LV_VECTOR_GRADIENT_STYLE_RADIAL) {
return GRAD_TYPE_RADIAL;
}
LV_LOG_WARN("unknown gradient style: %d", style);
return GRAD_TYPE_UNKNOWN;
} }
static lv_cache_compare_res_t radial_grad_compare_cb(const radial_grad_item_t * lhs, const radial_grad_item_t * rhs) static void grad_point_to_matrix(vg_lite_matrix_t * grad_matrix, float x1, float y1, float x2, float y2)
{ {
if(!math_equal(lhs->lv_grad.cx, rhs->lv_grad.cx)) { vg_lite_identity(grad_matrix);
return lhs->lv_grad.cx > rhs->lv_grad.cx ? 1 : -1; vg_lite_translate(x1, y1, grad_matrix);
}
if(!math_equal(lhs->lv_grad.cy, rhs->lv_grad.cy)) { float angle = atan2f(y2 - y1, x2 - x1) * 180.0f / (float)M_PI;
return lhs->lv_grad.cy > rhs->lv_grad.cy ? 1 : -1; vg_lite_rotate(angle, grad_matrix);
} float length = sqrtf(SQUARE(x2 - x1) + SQUARE(y2 - y1));
vg_lite_scale(length / 256.0f, 1, grad_matrix);
if(!math_equal(lhs->lv_grad.cr, rhs->lv_grad.cr)) {
return lhs->lv_grad.cr > rhs->lv_grad.cr ? 1 : -1;
}
if(lhs->lv_grad.spread != rhs->lv_grad.spread) {
return lhs->lv_grad.spread > rhs->lv_grad.spread ? 1 : -1;
}
if(lhs->lv_grad.grad.stops_count != rhs->lv_grad.grad.stops_count) {
return lhs->lv_grad.grad.stops_count > rhs->lv_grad.grad.stops_count ? 1 : -1;
}
int cmp_res = lv_memcmp(lhs->lv_grad.grad.stops, rhs->lv_grad.grad.stops,
sizeof(lv_gradient_stop_t) * lhs->lv_grad.grad.stops_count);
if(cmp_res != 0) {
return cmp_res > 0 ? 1 : -1;
}
return 0;
} }
static vg_lite_gradient_spreadmode_t lv_spread_to_vg(lv_vector_gradient_spread_t spread) static vg_lite_gradient_spreadmode_t lv_spread_to_vg(lv_vector_gradient_spread_t spread)
@@ -525,10 +567,124 @@ static vg_lite_gradient_spreadmode_t lv_spread_to_vg(lv_vector_gradient_spread_t
case LV_VECTOR_GRADIENT_SPREAD_REFLECT: case LV_VECTOR_GRADIENT_SPREAD_REFLECT:
return VG_LITE_GRADIENT_SPREAD_REFLECT; return VG_LITE_GRADIENT_SPREAD_REFLECT;
default: default:
return VG_LITE_GRADIENT_SPREAD_FILL; LV_LOG_WARN("unknown spread mode: %d", spread);
break;
}
return VG_LITE_GRADIENT_SPREAD_FILL;
}
static bool grad_create_cb(grad_item_t * item, void * user_data)
{
LV_UNUSED(user_data);
item->type = lv_grad_style_to_type(item->lv.style);
switch(item->type) {
case GRAD_TYPE_LINEAR:
return linear_grad_create(item);
case GRAD_TYPE_LINEAR_EXT:
return linear_ext_grad_create(item);
case GRAD_TYPE_RADIAL:
return radial_grad_create(item);
default:
LV_LOG_ERROR("unknown gradient type: %d", item->type);
break;
}
return false;
}
static void grad_free_cb(grad_item_t * item, void * user_data)
{
LV_UNUSED(user_data);
switch(item->type) {
case GRAD_TYPE_LINEAR:
LV_VG_LITE_CHECK_ERROR(vg_lite_clear_grad(&item->vg.linear));
break;
case GRAD_TYPE_LINEAR_EXT:
LV_VG_LITE_CHECK_ERROR(vg_lite_clear_linear_grad(&item->vg.linear_ext));
break;
case GRAD_TYPE_RADIAL:
LV_VG_LITE_CHECK_ERROR(vg_lite_clear_radial_grad(&item->vg.radial));
break;
default:
LV_LOG_ERROR("unknown gradient type: %d", item->type);
break;
} }
} }
#endif /* LV_USE_VECTOR_GRAPHIC */ static lv_cache_compare_res_t grad_compare_cb(const grad_item_t * lhs, const grad_item_t * rhs)
{
/* compare type first */
if(lhs->type != rhs->type) {
return lhs->type > rhs->type ? 1 : -1;
}
#endif /*LV_USE_DRAW_VG_LITE*/ /* compare spread mode */
if(lhs->lv.spread != rhs->lv.spread) {
return lhs->lv.spread > rhs->lv.spread ? 1 : -1;
}
/* compare gradient parameters */
switch(lhs->type) {
case GRAD_TYPE_LINEAR:
/* no extra compare needed */
break;
case GRAD_TYPE_LINEAR_EXT:
if(!math_equal(lhs->lv.x1, rhs->lv.x1)) {
return lhs->lv.x1 > rhs->lv.x1 ? 1 : -1;
}
if(!math_equal(lhs->lv.y1, rhs->lv.y1)) {
return lhs->lv.y1 > rhs->lv.y1 ? 1 : -1;
}
if(!math_equal(lhs->lv.x2, rhs->lv.x2)) {
return lhs->lv.x2 > rhs->lv.x2 ? 1 : -1;
}
if(!math_equal(lhs->lv.y2, rhs->lv.y2)) {
return lhs->lv.y2 > rhs->lv.y2 ? 1 : -1;
}
break;
case GRAD_TYPE_RADIAL:
if(!math_equal(lhs->lv.cx, rhs->lv.cx)) {
return lhs->lv.cx > rhs->lv.cx ? 1 : -1;
}
if(!math_equal(lhs->lv.cy, rhs->lv.cy)) {
return lhs->lv.cy > rhs->lv.cy ? 1 : -1;
}
if(!math_equal(lhs->lv.cr, rhs->lv.cr)) {
return lhs->lv.cr > rhs->lv.cr ? 1 : -1;
}
break;
default:
LV_LOG_ERROR("unknown gradient type: %d", lhs->type);
break;
}
/* compare stops count and stops */
if(lhs->lv.stops_count != rhs->lv.stops_count) {
return lhs->lv.stops_count > rhs->lv.stops_count ? 1 : -1;
}
int cmp_res = lv_memcmp(lhs->lv.stops, rhs->lv.stops,
sizeof(lv_gradient_stop_t) * lhs->lv.stops_count);
if(cmp_res != 0) {
return cmp_res > 0 ? 1 : -1;
}
return 0;
}
#endif /*LV_USE_DRAW_VG_LITE && LV_USE_VECTOR_GRAPHIC*/

View File

@@ -16,7 +16,7 @@ extern "C" {
#include "../../lvgl.h" #include "../../lvgl.h"
#if LV_USE_DRAW_VG_LITE #if LV_USE_DRAW_VG_LITE && LV_USE_VECTOR_GRAPHIC
#include "lv_vg_lite_utils.h" #include "lv_vg_lite_utils.h"
@@ -32,28 +32,11 @@ extern "C" {
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
**********************/ **********************/
void lv_vg_lite_grad_init( void lv_vg_lite_grad_init(struct _lv_draw_vg_lite_unit_t * u, uint32_t cache_cnt);
struct _lv_draw_vg_lite_unit_t * u,
uint32_t linear_grad_cache_cnt,
uint32_t radial_grad_cache_cnt);
void lv_vg_lite_grad_deinit(struct _lv_draw_vg_lite_unit_t * u); void lv_vg_lite_grad_deinit(struct _lv_draw_vg_lite_unit_t * u);
void lv_vg_lite_grad_area_to_matrix(vg_lite_matrix_t * grad_matrix, const lv_area_t * area, lv_grad_dir_t dir); bool lv_vg_lite_draw_grad(
void lv_vg_lite_draw_linear_grad(
struct _lv_draw_vg_lite_unit_t * u,
vg_lite_buffer_t * buffer,
vg_lite_path_t * path,
const lv_grad_dsc_t * grad,
const vg_lite_matrix_t * grad_matrix,
const vg_lite_matrix_t * matrix,
vg_lite_fill_t fill,
vg_lite_blend_t blend);
#if LV_USE_VECTOR_GRAPHIC
void lv_vg_lite_draw_radial_grad(
struct _lv_draw_vg_lite_unit_t * u, struct _lv_draw_vg_lite_unit_t * u,
vg_lite_buffer_t * buffer, vg_lite_buffer_t * buffer,
vg_lite_path_t * path, vg_lite_path_t * path,
@@ -63,13 +46,21 @@ void lv_vg_lite_draw_radial_grad(
vg_lite_fill_t fill, vg_lite_fill_t fill,
vg_lite_blend_t blend); vg_lite_blend_t blend);
#endif /* LV_USE_VECTOR_GRAPHIC */ bool lv_vg_lite_draw_grad_helper(
struct _lv_draw_vg_lite_unit_t * u,
vg_lite_buffer_t * buffer,
vg_lite_path_t * path,
const lv_area_t * area,
const lv_grad_dsc_t * grad_dsc,
const vg_lite_matrix_t * matrix,
vg_lite_fill_t fill,
vg_lite_blend_t blend);
/********************** /**********************
* MACROS * MACROS
**********************/ **********************/
#endif /*LV_USE_DRAW_VG_LITE*/ #endif /*LV_USE_DRAW_VG_LITE && LV_USE_VECTOR_GRAPHIC*/
#ifdef __cplusplus #ifdef __cplusplus
} /*extern "C"*/ } /*extern "C"*/

View File

@@ -1079,10 +1079,8 @@ void lv_vg_lite_finish(struct _lv_draw_vg_lite_unit_t * u)
LV_VG_LITE_CHECK_ERROR(vg_lite_finish()); LV_VG_LITE_CHECK_ERROR(vg_lite_finish());
/* Clear all gradient caches reference */ /* Clear all gradient caches reference */
lv_vg_lite_pending_remove_all(u->linear_grad_pending); if(u->grad_pending) {
lv_vg_lite_pending_remove_all(u->grad_pending);
if(u->radial_grad_pending) {
lv_vg_lite_pending_remove_all(u->radial_grad_pending);
} }
/* Clear image decoder dsc reference */ /* Clear image decoder dsc reference */

View File

@@ -657,25 +657,14 @@
#endif #endif
#endif #endif
/* VG-Lite linear gradient image maximum cache number. /* VG-Lite gradient maximum cache number.
* NOTE: The memory usage of a single gradient image is 4K bytes. * NOTE: The memory usage of a single gradient image is 4K bytes.
*/ */
#ifndef LV_VG_LITE_LINEAR_GRAD_CACHE_CNT #ifndef LV_VG_LITE_GRAD_CACHE_CNT
#ifdef CONFIG_LV_VG_LITE_LINEAR_GRAD_CACHE_CNT #ifdef CONFIG_LV_VG_LITE_GRAD_CACHE_CNT
#define LV_VG_LITE_LINEAR_GRAD_CACHE_CNT CONFIG_LV_VG_LITE_LINEAR_GRAD_CACHE_CNT #define LV_VG_LITE_GRAD_CACHE_CNT CONFIG_LV_VG_LITE_GRAD_CACHE_CNT
#else #else
#define LV_VG_LITE_LINEAR_GRAD_CACHE_CNT 32 #define LV_VG_LITE_GRAD_CACHE_CNT 32
#endif
#endif
/* VG-Lite radial gradient image maximum cache size.
* NOTE: The memory usage of a single gradient image is radial grad radius * 4 bytes.
*/
#ifndef LV_VG_LITE_RADIAL_GRAD_CACHE_CNT
#ifdef CONFIG_LV_VG_LITE_RADIAL_GRAD_CACHE_CNT
#define LV_VG_LITE_RADIAL_GRAD_CACHE_CNT CONFIG_LV_VG_LITE_RADIAL_GRAD_CACHE_CNT
#else
#define LV_VG_LITE_RADIAL_GRAD_CACHE_CNT 32
#endif #endif
#endif #endif
@@ -1121,6 +1110,15 @@
#endif #endif
#endif #endif
/*Enable Linear gradient extension support*/
#ifndef LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT
#ifdef CONFIG_LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT
#define LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT CONFIG_LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT
#else
#define LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT 0
#endif
#endif
/*Enable 16 pixels alignment*/ /*Enable 16 pixels alignment*/
#ifndef LV_VG_LITE_THORVG_16PIXELS_ALIGN #ifndef LV_VG_LITE_THORVG_16PIXELS_ALIGN
#ifdef _LV_KCONFIG_PRESENT #ifdef _LV_KCONFIG_PRESENT

View File

@@ -463,10 +463,13 @@ extern "C" {
vg_lite_uint32_t stride = VG_LITE_ALIGN((buffer->width * mul / div), align); vg_lite_uint32_t stride = VG_LITE_ALIGN((buffer->width * mul / div), align);
buffer->stride = stride; buffer->stride = stride;
/* Size must be multiple of align, See: https://en.cppreference.com/w/c/memory/aligned_alloc */
size_t size = VG_LITE_ALIGN(buffer->height * stride, LV_VG_LITE_THORVG_BUF_ADDR_ALIGN);
#ifndef _WIN32 #ifndef _WIN32
buffer->memory = aligned_alloc(LV_VG_LITE_THORVG_BUF_ADDR_ALIGN, stride * buffer->height); buffer->memory = aligned_alloc(LV_VG_LITE_THORVG_BUF_ADDR_ALIGN, size);
#else #else
buffer->memory = _aligned_malloc(stride * buffer->height, LV_VG_LITE_THORVG_BUF_ADDR_ALIGN); buffer->memory = _aligned_malloc(size, LV_VG_LITE_THORVG_BUF_ADDR_ALIGN);
#endif #endif
LV_ASSERT(buffer->memory); LV_ASSERT(buffer->memory);
buffer->address = (vg_lite_uint32_t)(uintptr_t)buffer->memory; buffer->address = (vg_lite_uint32_t)(uintptr_t)buffer->memory;
@@ -829,6 +832,10 @@ extern "C" {
case gcFEATURE_BIT_VG_YUV_INPUT: case gcFEATURE_BIT_VG_YUV_INPUT:
#endif #endif
#if LV_VG_LITE_THORVG_LINEAR_GRADIENT_EXT_SUPPORT
case gcFEATURE_BIT_VG_LINEAR_GRADIENT_EXT:
#endif
#if LV_VG_LITE_THORVG_16PIXELS_ALIGN #if LV_VG_LITE_THORVG_16PIXELS_ALIGN
case gcFEATURE_BIT_VG_16PIXELS_ALIGN: case gcFEATURE_BIT_VG_16PIXELS_ALIGN:
#endif #endif
@@ -1264,6 +1271,49 @@ Empty_sequence_handler:
return VG_LITE_SUCCESS; return VG_LITE_SUCCESS;
} }
vg_lite_error_t vg_lite_draw_linear_grad(vg_lite_buffer_t * target,
vg_lite_path_t * path,
vg_lite_fill_t fill_rule,
vg_lite_matrix_t * path_matrix,
vg_lite_ext_linear_gradient_t * grad,
vg_lite_color_t paint_color,
vg_lite_blend_t blend,
vg_lite_filter_t filter)
{
LV_UNUSED(paint_color);
LV_UNUSED(filter);
auto ctx = vg_lite_ctx::get_instance();
TVG_CHECK_RETURN_VG_ERROR(canvas_set_target(ctx, target));
auto shape = Shape::gen();
TVG_CHECK_RETURN_VG_ERROR(shape_append_path(shape, path, path_matrix));
TVG_CHECK_RETURN_VG_ERROR(shape->transform(matrix_conv(path_matrix)));
TVG_CHECK_RETURN_VG_ERROR(shape->fill(fill_rule_conv(fill_rule)););
TVG_CHECK_RETURN_VG_ERROR(shape->blend(blend_method_conv(blend)));
auto linearGrad = LinearGradient::gen();
TVG_CHECK_RETURN_VG_ERROR(linearGrad->linear(grad->linear_grad.X0, grad->linear_grad.Y0, grad->linear_grad.X1,
grad->linear_grad.Y1));
TVG_CHECK_RETURN_VG_ERROR(linearGrad->transform(matrix_conv(&grad->matrix)));
TVG_CHECK_RETURN_VG_ERROR(linearGrad->spread(fill_spread_conv(grad->spread_mode)));
tvg::Fill::ColorStop colorStops[VLC_MAX_COLOR_RAMP_STOPS];
for(vg_lite_uint32_t i = 0; i < grad->ramp_length; i++) {
colorStops[i].offset = grad->color_ramp[i].stop;
colorStops[i].r = grad->color_ramp[i].red * 255.0f;
colorStops[i].g = grad->color_ramp[i].green * 255.0f;
colorStops[i].b = grad->color_ramp[i].blue * 255.0f;
colorStops[i].a = grad->color_ramp[i].alpha * 255.0f;
}
TVG_CHECK_RETURN_VG_ERROR(linearGrad->colorStops(colorStops, grad->ramp_length));
TVG_CHECK_RETURN_VG_ERROR(shape->fill(std::move(linearGrad)));
TVG_CHECK_RETURN_VG_ERROR(ctx->canvas->push(std::move(shape)));
return VG_LITE_SUCCESS;
}
vg_lite_error_t vg_lite_set_radial_grad(vg_lite_radial_gradient_t * grad, vg_lite_error_t vg_lite_set_radial_grad(vg_lite_radial_gradient_t * grad,
vg_lite_uint32_t count, vg_lite_uint32_t count,
vg_lite_color_ramp_t * color_ramp, vg_lite_color_ramp_t * color_ramp,
@@ -1720,8 +1770,8 @@ Empty_sequence_handler:
float y_max = y_min + dlen * sinf(angle); float y_max = y_min + dlen * sinf(angle);
LV_LOG_TRACE("linear gradient {%.2f, %.2f} ~ {%.2f, %.2f}", x_min, y_min, x_max, y_max); LV_LOG_TRACE("linear gradient {%.2f, %.2f} ~ {%.2f, %.2f}", x_min, y_min, x_max, y_max);
auto linearGrad = LinearGradient::gen(); auto linearGrad = LinearGradient::gen();
linearGrad->linear(x_min, y_min, x_max, y_max); TVG_CHECK_RETURN_VG_ERROR(linearGrad->linear(x_min, y_min, x_max, y_max));
linearGrad->spread(FillSpread::Pad); TVG_CHECK_RETURN_VG_ERROR(linearGrad->spread(FillSpread::Pad));
tvg::Fill::ColorStop colorStops[VLC_MAX_GRADIENT_STOPS]; tvg::Fill::ColorStop colorStops[VLC_MAX_GRADIENT_STOPS];
for(vg_lite_uint32_t i = 0; i < grad->count; i++) { for(vg_lite_uint32_t i = 0; i < grad->count; i++) {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 43 KiB

View File

@@ -15,15 +15,10 @@
* but does not guarantee the same rendering quality as the software. */ * but does not guarantee the same rendering quality as the software. */
#define LV_VG_LITE_USE_BOX_SHADOW 1 #define LV_VG_LITE_USE_BOX_SHADOW 1
/* VG-Lite linear gradient image maximum cache number. /* VG-Lite gradient maximum cache number.
* NOTE: The memory usage of a single gradient image is 4K bytes. * NOTE: The memory usage of a single gradient image is 4K bytes.
*/ */
#define LV_VG_LITE_LINEAR_GRAD_CACHE_CNT 32 #define LV_VG_LITE_GRAD_CACHE_CNT 32
/* VG-Lite radial gradient image maximum cache size.
* NOTE: The memory usage of a single gradient image is radial grad radius * 4 bytes.
*/
#define LV_VG_LITE_RADIAL_GRAD_CACHE_CNT 32
/* Disable 16 pixels alignment */ /* Disable 16 pixels alignment */
#define LV_VG_LITE_THORVG_16PIXELS_ALIGN 0 #define LV_VG_LITE_THORVG_16PIXELS_ALIGN 0

View File

@@ -47,20 +47,21 @@ static void draw_shapes(lv_layer_t * layer)
lv_vector_dsc_identity(ctx); lv_vector_dsc_identity(ctx);
lv_vector_dsc_translate(ctx, 0, 150); lv_vector_dsc_translate(ctx, 0, 150);
lv_grad_dsc_t grad; lv_gradient_stop_t stops[2];
grad.dir = LV_GRAD_DIR_HOR; lv_memzero(stops, sizeof(stops));
grad.stops_count = 2; stops[0].color = lv_color_hex(0xffffff);
grad.stops[0].color = lv_color_hex(0xffffff); stops[0].opa = LV_OPA_COVER;
grad.stops[0].opa = LV_OPA_COVER; stops[0].frac = 0;
grad.stops[0].frac = 0; stops[1].color = lv_color_hex(0x000000);
grad.stops[1].color = lv_color_hex(0x000000); stops[1].opa = LV_OPA_COVER;
grad.stops[1].opa = LV_OPA_COVER; stops[1].frac = 255;
grad.stops[1].frac = 255;
lv_matrix_t mt; lv_matrix_t mt;
lv_matrix_identity(&mt); lv_matrix_identity(&mt);
lv_vector_dsc_set_fill_transform(ctx, &mt); lv_vector_dsc_set_fill_transform(ctx, &mt);
lv_vector_dsc_set_fill_radial_gradient(ctx, &grad, 50, 50, 50, LV_VECTOR_GRADIENT_SPREAD_PAD); lv_vector_dsc_set_fill_radial_gradient(ctx, 100, 100, 50);
lv_vector_dsc_set_fill_gradient_color_stops(ctx, stops, 2);
lv_vector_dsc_set_fill_gradient_spread(ctx, LV_VECTOR_GRADIENT_SPREAD_PAD);
lv_vector_dsc_add_path(ctx, path); lv_vector_dsc_add_path(ctx, path);
lv_vector_dsc_identity(ctx); lv_vector_dsc_identity(ctx);
@@ -208,15 +209,14 @@ static void draw_lines(lv_layer_t * layer)
lv_vector_path_clear(path); lv_vector_path_clear(path);
lv_vector_path_append_rect(path, &rect1, 0, 0); lv_vector_path_append_rect(path, &rect1, 0, 0);
lv_grad_dsc_t grad; lv_gradient_stop_t stops[2];
grad.dir = LV_GRAD_DIR_HOR; lv_memzero(stops, sizeof(stops));
grad.stops_count = 2; stops[0].color = lv_color_hex(0xff0000);
grad.stops[0].color = lv_color_hex(0xff0000); stops[0].opa = LV_OPA_COVER;
grad.stops[0].opa = LV_OPA_COVER; stops[0].frac = 0;
grad.stops[0].frac = 0; stops[1].color = lv_color_hex(0x00ff00);
grad.stops[1].color = lv_color_hex(0x00ff00); stops[1].opa = LV_OPA_COVER;
grad.stops[1].opa = LV_OPA_COVER; stops[1].frac = 255;
grad.stops[1].frac = 255;
lv_matrix_t mt; lv_matrix_t mt;
lv_matrix_identity(&mt); lv_matrix_identity(&mt);
@@ -224,7 +224,9 @@ static void draw_lines(lv_layer_t * layer)
lv_matrix_translate(&mt, 20, 20); lv_matrix_translate(&mt, 20, 20);
lv_vector_dsc_set_stroke_transform(ctx, &mt); lv_vector_dsc_set_stroke_transform(ctx, &mt);
lv_vector_dsc_set_stroke_join(ctx, LV_VECTOR_STROKE_JOIN_MITER); lv_vector_dsc_set_stroke_join(ctx, LV_VECTOR_STROKE_JOIN_MITER);
lv_vector_dsc_set_stroke_linear_gradient(ctx, &grad, LV_VECTOR_GRADIENT_SPREAD_REFLECT); lv_vector_dsc_set_stroke_linear_gradient(ctx, 250, 300, 350, 300);
lv_vector_dsc_set_stroke_gradient_color_stops(ctx, stops, 2);
lv_vector_dsc_set_stroke_gradient_spread(ctx, LV_VECTOR_GRADIENT_SPREAD_REFLECT);
lv_vector_dsc_add_path(ctx, path); // draw a path lv_vector_dsc_add_path(ctx, path); // draw a path
lv_draw_vector(ctx); lv_draw_vector(ctx);