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>
20
Kconfig
@@ -393,19 +393,14 @@ menu "LVGL configuration"
|
||||
which usually improves performance,
|
||||
but does not guarantee the same rendering quality as the software.
|
||||
|
||||
config LV_VG_LITE_LINEAR_GRAD_CACHE_CNT
|
||||
int "VG-Lite linear gradient image maximum cache number."
|
||||
config LV_VG_LITE_GRAD_CACHE_CNT
|
||||
int "VG-Lite gradient maximum cache number."
|
||||
default 32
|
||||
depends on LV_USE_DRAW_VG_LITE
|
||||
help
|
||||
The memory usage of a single gradient image is 4K bytes.
|
||||
|
||||
config LV_VG_LITE_RADIAL_GRAD_CACHE_CNT
|
||||
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.
|
||||
The memory usage of a single gradient:
|
||||
linear: 4K bytes.
|
||||
radial: radius * 4K bytes.
|
||||
|
||||
config LV_USE_VECTOR_GRAPHIC
|
||||
bool "Use Vector Graphic APIs"
|
||||
@@ -653,6 +648,11 @@ menu "LVGL configuration"
|
||||
default n
|
||||
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
|
||||
bool "Enable 16 pixels alignment"
|
||||
default y
|
||||
|
||||
@@ -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_close(path);
|
||||
|
||||
lv_grad_dsc_t grad;
|
||||
grad.dir = LV_GRAD_DIR_HOR;
|
||||
grad.stops_count = 2;
|
||||
grad.stops[0].color = lv_color_hex(0xff0000);
|
||||
grad.stops[0].opa = LV_OPA_COVER;
|
||||
grad.stops[0].frac = 0;
|
||||
grad.stops[1].color = lv_color_hex(0x00ff00);
|
||||
grad.stops[1].opa = LV_OPA_COVER;
|
||||
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_gradient_stop_t stops[2];
|
||||
lv_memzero(stops, sizeof(stops));
|
||||
stops[0].color = lv_color_hex(0xff0000);
|
||||
stops[0].opa = LV_OPA_COVER;
|
||||
stops[0].frac = 0;
|
||||
stops[1].color = lv_color_hex(0x00ff00);
|
||||
stops[1].opa = LV_OPA_COVER;
|
||||
stops[1].frac = 255;
|
||||
|
||||
lv_matrix_t mt;
|
||||
lv_matrix_identity(&mt);
|
||||
lv_matrix_rotate(&mt, 30);
|
||||
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
|
||||
}
|
||||
|
||||
@@ -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_close(path);
|
||||
|
||||
lv_grad_dsc_t grad;
|
||||
grad.dir = LV_GRAD_DIR_HOR;
|
||||
grad.stops_count = 2;
|
||||
grad.stops[0].color = lv_color_hex(0xff0000);
|
||||
grad.stops[0].opa = LV_OPA_COVER;
|
||||
grad.stops[0].frac = 0;
|
||||
grad.stops[1].color = lv_color_hex(0x0000ff);
|
||||
grad.stops[1].opa = LV_OPA_COVER;
|
||||
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_gradient_stop_t stops[2];
|
||||
lv_memzero(stops, sizeof(stops));
|
||||
stops[0].color = lv_color_hex(0xff0000);
|
||||
stops[0].opa = LV_OPA_COVER;
|
||||
stops[0].frac = 0;
|
||||
stops[1].color = lv_color_hex(0x0000ff);
|
||||
stops[1].opa = LV_OPA_COVER;
|
||||
stops[1].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
|
||||
}
|
||||
|
||||
|
||||
@@ -224,15 +224,10 @@
|
||||
* but does not guarantee the same rendering quality as the software. */
|
||||
#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.
|
||||
*/
|
||||
#define LV_VG_LITE_LINEAR_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
|
||||
#define LV_VG_LITE_GRAD_CACHE_CNT 32
|
||||
|
||||
#endif
|
||||
|
||||
@@ -382,6 +377,9 @@
|
||||
/*Enable YUV color format support*/
|
||||
#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*/
|
||||
#define LV_VG_LITE_THORVG_16PIXELS_ALIGN 1
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
dst->fill_dsc.style = src->fill_dsc.style;
|
||||
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));
|
||||
lv_memcpy(&(dst->fill_dsc), &(src->fill_dsc), sizeof(lv_vector_fill_dsc_t));
|
||||
|
||||
dst->stroke_dsc.style = src->stroke_dsc.style;
|
||||
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.cr = src->stroke_dsc.gradient.cr;
|
||||
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));
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_fill_linear_gradient(lv_vector_dsc_t * dsc, const lv_grad_dsc_t * grad,
|
||||
lv_vector_gradient_spread_t spread)
|
||||
void lv_vector_dsc_set_fill_linear_gradient(lv_vector_dsc_t * dsc, float x1, float y1, float x2, float y2)
|
||||
{
|
||||
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.spread = spread;
|
||||
lv_memcpy(&(dsc->current_dsc.fill_dsc.gradient.grad), grad, sizeof(lv_grad_dsc_t));
|
||||
dsc->current_dsc.fill_dsc.gradient.x1 = x1;
|
||||
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,
|
||||
float radius, lv_vector_gradient_spread_t spread)
|
||||
void lv_vector_dsc_set_fill_radial_gradient(lv_vector_dsc_t * dsc, float cx, float cy, float radius)
|
||||
{
|
||||
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.cx = cx;
|
||||
dsc->current_dsc.fill_dsc.gradient.cy = cy;
|
||||
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;
|
||||
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)
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_stroke_linear_gradient(lv_vector_dsc_t * dsc, const lv_grad_dsc_t * grad,
|
||||
lv_vector_gradient_spread_t spread)
|
||||
void lv_vector_dsc_set_stroke_linear_gradient(lv_vector_dsc_t * dsc, float x1, float y1, float x2, float y2)
|
||||
{
|
||||
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.spread = spread;
|
||||
lv_memcpy(&(dsc->current_dsc.stroke_dsc.gradient.grad), grad, sizeof(lv_grad_dsc_t));
|
||||
dsc->current_dsc.stroke_dsc.gradient.x1 = x1;
|
||||
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,
|
||||
float radius, lv_vector_gradient_spread_t spread)
|
||||
void lv_vector_dsc_set_stroke_radial_gradient(lv_vector_dsc_t * dsc, float cx, float cy, float radius)
|
||||
{
|
||||
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.cx = cx;
|
||||
dsc->current_dsc.stroke_dsc.gradient.cy = cy;
|
||||
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;
|
||||
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 */
|
||||
|
||||
@@ -107,7 +107,12 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
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 cy;
|
||||
float cr;
|
||||
@@ -392,23 +397,38 @@ void lv_vector_dsc_set_fill_image(lv_vector_dsc_t * dsc, const lv_draw_image_dsc
|
||||
/**
|
||||
* Set fill linear gradient for descriptor
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param grad pointer to a `lv_grad_dsc_t` variable
|
||||
* @param spread the gradient spread to be set in lv_vector_gradient_spread_t format
|
||||
* @param x1 the x for start point
|
||||
* @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,
|
||||
lv_vector_gradient_spread_t spread);
|
||||
void lv_vector_dsc_set_fill_linear_gradient(lv_vector_dsc_t * dsc, float x1, float y1, float x2, float y2);
|
||||
|
||||
/**
|
||||
* Set fill radial gradient for descriptor
|
||||
|
||||
* Set fill radial gradient radius for 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 cy the y for center of the circle
|
||||
* @param radius the radius for circle
|
||||
*/
|
||||
void lv_vector_dsc_set_fill_radial_gradient(lv_vector_dsc_t * dsc, float cx, float cy, float radius);
|
||||
|
||||
/**
|
||||
* 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_radial_gradient(lv_vector_dsc_t * dsc, const lv_grad_dsc_t * grad, float cx, float cy,
|
||||
float radius, lv_vector_gradient_spread_t spread);
|
||||
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
|
||||
@@ -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
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param grad pointer to a `lv_grad_dsc_t` variable
|
||||
* @param spread the gradient spread to be set in lv_vector_gradient_spread_t format
|
||||
* @param x1 the x for start point
|
||||
* @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,
|
||||
lv_vector_gradient_spread_t spread);
|
||||
void lv_vector_dsc_set_stroke_linear_gradient(lv_vector_dsc_t * dsc, float x1, float y1, float x2, float y2);
|
||||
/**
|
||||
* Set stroke radial gradient for 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 cy the y for center of the 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
|
||||
*/
|
||||
void lv_vector_dsc_set_stroke_radial_gradient(lv_vector_dsc_t * dsc, const lv_grad_dsc_t * grad, float cx, float cy,
|
||||
float radius, lv_vector_gradient_spread_t spread);
|
||||
void lv_vector_dsc_set_stroke_gradient_spread(lv_vector_dsc_t * dsc, 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
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
|
||||
@@ -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,
|
||||
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) * g->stops_count);
|
||||
for(uint8_t i = 0; i < g->stops_count; i++) {
|
||||
const lv_gradient_stop_t * s = &(g->stops[i]);
|
||||
Tvg_Color_Stop * stops = (Tvg_Color_Stop *)lv_malloc(sizeof(Tvg_Color_Stop) * grad->stops_count);
|
||||
LV_ASSERT_MALLOC(stops);
|
||||
for(uint16_t i = 0; i < grad->stops_count; i++) {
|
||||
const lv_gradient_stop_t * s = &(grad->stops[i]);
|
||||
|
||||
stops[i].offset = s->frac / 255.0f;
|
||||
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;
|
||||
}
|
||||
|
||||
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_Matrix mtx;
|
||||
_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)
|
||||
{
|
||||
float x, y, w, h;
|
||||
tvg_paint_get_bounds(obj, &x, &y, &w, &h, false);
|
||||
|
||||
Tvg_Gradient * grad = NULL;
|
||||
if(g->style == LV_VECTOR_GRADIENT_STYLE_RADIAL) {
|
||||
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);
|
||||
tvg_shape_set_stroke_radial_gradient(obj, grad);
|
||||
}
|
||||
else {
|
||||
grad = tvg_linear_gradient_new();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
tvg_linear_gradient_set(grad, g->x1, g->y1, g->x2, g->y2);
|
||||
_setup_gradient(grad, g, m);
|
||||
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)
|
||||
{
|
||||
float x, y, w, h;
|
||||
tvg_paint_get_bounds(obj, &x, &y, &w, &h, false);
|
||||
|
||||
Tvg_Gradient * grad = NULL;
|
||||
if(g->style == LV_VECTOR_GRADIENT_STYLE_RADIAL) {
|
||||
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);
|
||||
tvg_shape_set_radial_gradient(obj, grad);
|
||||
}
|
||||
else {
|
||||
grad = tvg_linear_gradient_new();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
tvg_linear_gradient_set(grad, g->x1, g->y1, g->x2, g->y2);
|
||||
_setup_gradient(grad, g, m);
|
||||
tvg_shape_set_linear_gradient(obj, grad);
|
||||
}
|
||||
|
||||
@@ -72,7 +72,9 @@ void lv_draw_vg_lite_init(void)
|
||||
unit->base_unit.delete_cb = draw_delete;
|
||||
|
||||
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_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_vg_lite_image_dsc_deinit(unit);
|
||||
#if LV_USE_VECTOR_GRAPHIC
|
||||
lv_vg_lite_grad_deinit(unit);
|
||||
#endif
|
||||
lv_vg_lite_path_deinit(unit);
|
||||
lv_vg_lite_decoder_deinit();
|
||||
return 1;
|
||||
|
||||
@@ -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);
|
||||
|
||||
if(dsc->grad.dir != LV_GRAD_DIR_NONE) {
|
||||
vg_lite_matrix_t grad_matrix;
|
||||
lv_vg_lite_grad_area_to_matrix(&grad_matrix, coords, dsc->grad.dir);
|
||||
lv_vg_lite_draw_linear_grad(
|
||||
#if LV_USE_VECTOR_GRAPHIC
|
||||
lv_vg_lite_draw_grad_helper(
|
||||
u,
|
||||
&u->target_buffer,
|
||||
vg_lite_path,
|
||||
coords,
|
||||
&dsc->grad,
|
||||
&grad_matrix,
|
||||
&matrix,
|
||||
VG_LITE_FILL_EVEN_ODD,
|
||||
VG_LITE_BLEND_SRC_OVER);
|
||||
#else
|
||||
LV_LOG_WARN("Gradient fill is not supported without VECTOR_GRAPHIC");
|
||||
#endif
|
||||
}
|
||||
else { /* normal fill */
|
||||
vg_lite_color_t color = lv_vg_lite_color(dsc->color, dsc->opa, true);
|
||||
|
||||
@@ -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);
|
||||
|
||||
if(dsc->bg_grad.dir != LV_GRAD_DIR_NONE) {
|
||||
vg_lite_matrix_t grad_matrix;
|
||||
lv_vg_lite_grad_area_to_matrix(&grad_matrix, &tri_area, dsc->bg_grad.dir);
|
||||
lv_vg_lite_draw_linear_grad(
|
||||
#if LV_USE_VECTOR_GRAPHIC
|
||||
lv_vg_lite_draw_grad_helper(
|
||||
u,
|
||||
&u->target_buffer,
|
||||
vg_lite_path,
|
||||
&tri_area,
|
||||
&dsc->bg_grad,
|
||||
&grad_matrix,
|
||||
&matrix,
|
||||
VG_LITE_FILL_EVEN_ODD,
|
||||
VG_LITE_BLEND_SRC_OVER);
|
||||
#else
|
||||
LV_LOG_WARN("Gradient fill is not supported without VECTOR_GRAPHIC");
|
||||
#endif
|
||||
}
|
||||
else { /* normal fill */
|
||||
vg_lite_color_t color = lv_vg_lite_color(dsc->bg_color, dsc->bg_opa, true);
|
||||
|
||||
@@ -43,11 +43,8 @@ struct _lv_draw_vg_lite_unit_t {
|
||||
|
||||
struct _lv_vg_lite_pending_t * image_dsc_pending;
|
||||
|
||||
lv_cache_t * linear_grad_cache;
|
||||
struct _lv_vg_lite_pending_t * linear_grad_pending;
|
||||
|
||||
lv_cache_t * radial_grad_cache;
|
||||
struct _lv_vg_lite_pending_t * radial_grad_pending;
|
||||
lv_cache_t * grad_cache;
|
||||
struct _lv_vg_lite_pending_t * grad_pending;
|
||||
|
||||
uint16_t flush_count;
|
||||
vg_lite_buffer_t target_buffer;
|
||||
|
||||
@@ -203,49 +203,19 @@ static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vec
|
||||
}
|
||||
break;
|
||||
case LV_VECTOR_DRAW_STYLE_GRADIENT: {
|
||||
/* draw gradient */
|
||||
lv_vector_gradient_style_t style = dsc->fill_dsc.gradient.style;
|
||||
|
||||
if(style == LV_VECTOR_GRADIENT_STYLE_LINEAR) {
|
||||
vg_lite_matrix_t grad_matrix, fill_matrix;
|
||||
lv_area_t grad_area;
|
||||
lv_area_set(&grad_area, (int32_t)min_x, (int32_t)min_y, (int32_t)max_x, (int32_t)max_y);
|
||||
lv_vg_lite_grad_area_to_matrix(&grad_matrix, &grad_area, LV_GRAD_DIR_HOR);
|
||||
|
||||
lv_matrix_to_vg(&fill_matrix, &dsc->fill_dsc.matrix);
|
||||
lv_vg_lite_matrix_multiply(&grad_matrix, &matrix);
|
||||
lv_vg_lite_matrix_multiply(&grad_matrix, &fill_matrix);
|
||||
|
||||
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(
|
||||
lv_vg_lite_draw_grad(
|
||||
u,
|
||||
&u->target_buffer,
|
||||
vg_path,
|
||||
&new_grad,
|
||||
&dsc->fill_dsc.gradient,
|
||||
&grad_matrix,
|
||||
&matrix,
|
||||
fill,
|
||||
blend);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LV_LOG_WARN("unknown style: %d", dsc->fill_dsc.style);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#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_vg_lite_pending.h"
|
||||
@@ -21,52 +21,47 @@
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define SQUARE(x) ((x)*(x))
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.1415926f
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct {
|
||||
lv_grad_dsc_t lv_grad;
|
||||
vg_lite_linear_gradient_t vg_grad;
|
||||
} linear_grad_item_t;
|
||||
|
||||
#if LV_USE_VECTOR_GRAPHIC
|
||||
typedef enum {
|
||||
GRAD_TYPE_UNKNOWN,
|
||||
GRAD_TYPE_LINEAR,
|
||||
GRAD_TYPE_LINEAR_EXT,
|
||||
GRAD_TYPE_RADIAL,
|
||||
} grad_type_t;
|
||||
|
||||
typedef struct {
|
||||
lv_vector_gradient_t lv_grad;
|
||||
vg_lite_radial_gradient_t vg_grad;
|
||||
} radial_grad_item_t;
|
||||
|
||||
#endif /* LV_USE_VECTOR_GRAPHIC */
|
||||
grad_type_t type;
|
||||
lv_vector_gradient_t lv;
|
||||
union {
|
||||
vg_lite_linear_gradient_t linear;
|
||||
vg_lite_ext_linear_gradient_t linear_ext;
|
||||
vg_lite_radial_gradient_t radial;
|
||||
} vg;
|
||||
} grad_item_t;
|
||||
|
||||
/**********************
|
||||
* 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 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 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 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_gradient_spreadmode_t lv_spread_to_vg(lv_vector_gradient_spread_t spread);
|
||||
|
||||
#endif /* LV_USE_VECTOR_GRAPHIC */
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
@@ -79,142 +74,33 @@ static vg_lite_gradient_spreadmode_t lv_spread_to_vg(lv_vector_gradient_spread_t
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
void lv_vg_lite_grad_init(
|
||||
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_init(struct _lv_draw_vg_lite_unit_t * u, uint32_t cache_cnt)
|
||||
{
|
||||
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)linear_grad_compare_cb,
|
||||
.create_cb = (lv_cache_create_cb_t)linear_grad_create_cb,
|
||||
.free_cb = (lv_cache_free_cb_t)linear_grad_free_cb,
|
||||
.compare_cb = (lv_cache_compare_cb_t)grad_compare_cb,
|
||||
.create_cb = (lv_cache_create_cb_t)grad_create_cb,
|
||||
.free_cb = (lv_cache_free_cb_t)grad_free_cb,
|
||||
};
|
||||
|
||||
u->linear_grad_cache = lv_cache_create(&lv_cache_class_lru_rb_count, sizeof(linear_grad_item_t),
|
||||
linear_grad_cache_cnt,
|
||||
ops);
|
||||
lv_cache_set_name(u->linear_grad_cache, "LINEAR_GRAD");
|
||||
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 */
|
||||
u->grad_cache = lv_cache_create(&lv_cache_class_lru_rb_count, sizeof(grad_item_t), cache_cnt, ops);
|
||||
lv_cache_set_name(u->grad_cache, "VG_GRAD");
|
||||
u->grad_pending = lv_vg_lite_pending_create(sizeof(lv_cache_entry_t *), 4);
|
||||
lv_vg_lite_pending_set_free_cb(u->grad_pending, grad_cache_release_cb, u->grad_cache);
|
||||
}
|
||||
|
||||
void lv_vg_lite_grad_deinit(struct _lv_draw_vg_lite_unit_t * u)
|
||||
{
|
||||
LV_ASSERT_NULL(u);
|
||||
lv_vg_lite_pending_destroy(u->linear_grad_pending);
|
||||
u->linear_grad_pending = NULL;
|
||||
lv_cache_destroy(u->linear_grad_cache, NULL);
|
||||
u->linear_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;
|
||||
}
|
||||
LV_ASSERT_NULL(u->grad_pending)
|
||||
lv_vg_lite_pending_destroy(u->grad_pending);
|
||||
u->grad_pending = NULL;
|
||||
lv_cache_destroy(u->grad_cache, NULL);
|
||||
u->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)
|
||||
{
|
||||
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(
|
||||
bool lv_vg_lite_draw_grad(
|
||||
struct _lv_draw_vg_lite_unit_t * u,
|
||||
vg_lite_buffer_t * buffer,
|
||||
vg_lite_path_t * path,
|
||||
@@ -225,37 +111,94 @@ void lv_vg_lite_draw_radial_grad(
|
||||
vg_lite_blend_t blend)
|
||||
{
|
||||
LV_ASSERT_NULL(u);
|
||||
LV_ASSERT_NULL(buffer);
|
||||
LV_ASSERT_NULL(path);
|
||||
LV_VG_LITE_ASSERT_DEST_BUFFER(buffer);
|
||||
LV_VG_LITE_ASSERT_PATH(path);
|
||||
LV_ASSERT_NULL(grad);
|
||||
LV_ASSERT_NULL(grad_matrix);
|
||||
LV_ASSERT_NULL(matrix);
|
||||
LV_VG_LITE_ASSERT_MATRIX(grad_matrix);
|
||||
LV_VG_LITE_ASSERT_MATRIX(matrix);
|
||||
|
||||
/* check radial gradient is supported */
|
||||
if(grad->style == LV_VECTOR_GRADIENT_STYLE_RADIAL) {
|
||||
if(!vg_lite_query_feature(gcFEATURE_BIT_VG_RADIAL_GRADIENT)) {
|
||||
LV_LOG_INFO("radial gradient is not supported");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* check if the radius is valid */
|
||||
if(grad->cr <= 0) {
|
||||
LV_LOG_INFO("radius: %f is not valid", grad->cr);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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", (int)grad->spread);
|
||||
return;
|
||||
LV_LOG_INFO("repeat/reflect spread(%d) is not supported", grad->spread);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LV_PROFILER_BEGIN;
|
||||
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_radial_gradient_t * radial_grad = radial_grad_get(u, grad);
|
||||
switch(grad_item->type) {
|
||||
case GRAD_TYPE_LINEAR: {
|
||||
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);
|
||||
|
||||
vg_lite_matrix_t * grad_mat_p = vg_lite_get_radial_grad_matrix(radial_grad);
|
||||
grad_point_to_matrix(grad_mat_p, grad->x1, grad->y1, grad->x2, grad->y2);
|
||||
lv_vg_lite_matrix_multiply(grad_mat_p, grad_matrix);
|
||||
|
||||
LV_VG_LITE_ASSERT_SRC_BUFFER(&linear_grad->image);
|
||||
|
||||
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_DEST_BUFFER(buffer);
|
||||
LV_VG_LITE_ASSERT_SRC_BUFFER(&radial_grad->image);
|
||||
LV_VG_LITE_ASSERT_PATH(path);
|
||||
LV_VG_LITE_ASSERT_MATRIX(grad_mat_p);
|
||||
LV_VG_LITE_ASSERT_MATRIX(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(
|
||||
@@ -264,42 +207,143 @@ void lv_vg_lite_draw_radial_grad(
|
||||
path,
|
||||
fill,
|
||||
(vg_lite_matrix_t *)matrix,
|
||||
radial_grad,
|
||||
&grad_item->vg.radial,
|
||||
0,
|
||||
blend,
|
||||
VG_LITE_FILTER_LINEAR));
|
||||
LV_PROFILER_END_TAG("vg_lite_draw_radial_grad");
|
||||
}
|
||||
break;
|
||||
|
||||
LV_PROFILER_END;
|
||||
default:
|
||||
LV_LOG_ERROR("Unsupported gradient type: %d", grad_item->type);
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif /* LV_USE_VECTOR_GRAPHIC */
|
||||
return true;
|
||||
}
|
||||
|
||||
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 void * grad_get(
|
||||
struct _lv_draw_vg_lite_unit_t * u,
|
||||
lv_cache_t * cache,
|
||||
lv_vg_lite_pending_t * pending,
|
||||
const void * key)
|
||||
static grad_item_t * grad_get(struct _lv_draw_vg_lite_unit_t * u, const lv_vector_gradient_t * grad)
|
||||
{
|
||||
LV_ASSERT_NULL(u);
|
||||
LV_ASSERT_NULL(cache);
|
||||
LV_ASSERT_NULL(pending);
|
||||
LV_ASSERT_NULL(key);
|
||||
LV_ASSERT_NULL(grad);
|
||||
|
||||
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) {
|
||||
/* 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) {
|
||||
LV_LOG_INFO("grad cache is full, release all pending cache entries");
|
||||
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) {
|
||||
LV_LOG_ERROR("grad cache creating failed");
|
||||
return NULL;
|
||||
@@ -307,7 +351,7 @@ static void * grad_get(
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
@@ -319,30 +363,35 @@ static void grad_cache_release_cb(void * entry, void * user_data)
|
||||
lv_cache_release(cache, * entry_p, NULL);
|
||||
}
|
||||
|
||||
/* Linear gradient */
|
||||
|
||||
static vg_lite_linear_gradient_t * linear_grad_get(struct _lv_draw_vg_lite_unit_t * u,
|
||||
const lv_grad_dsc_t * grad)
|
||||
static vg_lite_color_ramp_t * grad_create_color_ramp(const lv_vector_gradient_t * grad)
|
||||
{
|
||||
linear_grad_item_t search_key;
|
||||
lv_memzero(&search_key, sizeof(search_key));
|
||||
search_key.lv_grad = *grad;
|
||||
LV_ASSERT_NULL(grad);
|
||||
|
||||
linear_grad_item_t * item = grad_get(u, u->linear_grad_cache, u->linear_grad_pending, &search_key);
|
||||
if(!item) {
|
||||
vg_lite_color_ramp_t * color_ramp = lv_malloc(sizeof(vg_lite_color_ramp_t) * grad->stops_count);
|
||||
LV_ASSERT_MALLOC(color_ramp);
|
||||
if(!color_ramp) {
|
||||
LV_LOG_ERROR("malloc failed for color_ramp");
|
||||
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;
|
||||
}
|
||||
|
||||
static bool linear_grad_create_cb(linear_grad_item_t * item, void * user_data)
|
||||
{
|
||||
LV_UNUSED(user_data);
|
||||
return color_ramp;
|
||||
}
|
||||
|
||||
static bool linear_grad_create(grad_item_t * item)
|
||||
{
|
||||
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) {
|
||||
LV_PROFILER_END;
|
||||
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];
|
||||
|
||||
/* Gradient setup */
|
||||
uint8_t cnt = item->lv_grad.stops_count;
|
||||
LV_ASSERT(cnt < VLC_MAX_GRADIENT_STOPS);
|
||||
for(uint8_t i = 0; i < cnt; i++) {
|
||||
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;
|
||||
if(item->lv.stops_count > VLC_MAX_GRADIENT_STOPS) {
|
||||
LV_LOG_WARN("Too many gradient stops, max is %d", VLC_MAX_GRADIENT_STOPS);
|
||||
item->lv.stops_count = VLC_MAX_GRADIENT_STOPS;
|
||||
}
|
||||
|
||||
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 */
|
||||
lv_color_t grad_color = lv_color_make(c->blue, c->green, c->red);
|
||||
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_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;
|
||||
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_vector_gradient_t * grad = &item->lv_grad;
|
||||
uint8_t stops_count = grad->grad.stops_count;
|
||||
vg_lite_color_ramp_t * color_ramp = lv_malloc(sizeof(vg_lite_color_ramp_t) * stops_count);
|
||||
LV_ASSERT_MALLOC(color_ramp);
|
||||
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_LOG_ERROR("malloc failed for color_ramp");
|
||||
LV_PROFILER_END;
|
||||
return false;
|
||||
}
|
||||
|
||||
for(uint8_t i = 0; i < stops_count; i++) {
|
||||
color_ramp[i].stop = grad->grad.stops[i].frac / 255.0f;
|
||||
lv_color_t c = grad->grad.stops[i].color;
|
||||
const vg_lite_linear_gradient_parameter_t grad_param = {
|
||||
.X0 = item->lv.x1,
|
||||
.Y0 = item->lv.y1,
|
||||
.X1 = item->lv.x2,
|
||||
.Y1 = item->lv.y2,
|
||||
};
|
||||
|
||||
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->grad.stops[i].opa / 255.0f;
|
||||
vg_lite_ext_linear_gradient_t linear_grad;
|
||||
lv_memzero(&linear_grad, sizeof(linear_grad));
|
||||
|
||||
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 = {
|
||||
.cx = grad->cx,
|
||||
.cy = grad->cy,
|
||||
.r = grad->cr,
|
||||
.fx = grad->cx,
|
||||
.fy = grad->cy,
|
||||
.cx = item->lv.cx,
|
||||
.cy = item->lv.cy,
|
||||
.r = item->lv.cr,
|
||||
.fx = item->lv.cx,
|
||||
.fy = item->lv.cy,
|
||||
};
|
||||
|
||||
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(
|
||||
vg_lite_set_radial_grad(
|
||||
&radial_grad,
|
||||
stops_count,
|
||||
item->lv.stops_count,
|
||||
color_ramp,
|
||||
grad_param,
|
||||
lv_spread_to_vg(grad->spread),
|
||||
lv_spread_to_vg(item->lv.spread),
|
||||
1));
|
||||
LV_PROFILER_END_TAG("vg_lite_set_radial_grad");
|
||||
|
||||
LV_PROFILER_BEGIN_TAG("vg_lite_update_radial_grad");
|
||||
vg_lite_error_t err = vg_lite_update_radial_grad(&radial_grad);
|
||||
LV_PROFILER_END_TAG("vg_lite_update_radial_grad");
|
||||
if(!err) {
|
||||
item->vg_grad = radial_grad;
|
||||
if(err == VG_LITE_SUCCESS) {
|
||||
item->vg.radial = radial_grad;
|
||||
}
|
||||
else {
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
LV_VG_LITE_CHECK_ERROR(vg_lite_clear_radial_grad(&item->vg_grad));
|
||||
if(style == LV_VECTOR_GRADIENT_STYLE_LINEAR) {
|
||||
return vg_lite_query_feature(gcFEATURE_BIT_VG_LINEAR_GRADIENT_EXT) ? GRAD_TYPE_LINEAR_EXT : GRAD_TYPE_LINEAR;
|
||||
}
|
||||
|
||||
static lv_cache_compare_res_t radial_grad_compare_cb(const radial_grad_item_t * lhs, const radial_grad_item_t * rhs)
|
||||
if(style == LV_VECTOR_GRADIENT_STYLE_RADIAL) {
|
||||
return GRAD_TYPE_RADIAL;
|
||||
}
|
||||
|
||||
LV_LOG_WARN("unknown gradient style: %d", style);
|
||||
return GRAD_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
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)) {
|
||||
return lhs->lv_grad.cx > rhs->lv_grad.cx ? 1 : -1;
|
||||
}
|
||||
vg_lite_identity(grad_matrix);
|
||||
vg_lite_translate(x1, y1, grad_matrix);
|
||||
|
||||
if(!math_equal(lhs->lv_grad.cy, rhs->lv_grad.cy)) {
|
||||
return lhs->lv_grad.cy > rhs->lv_grad.cy ? 1 : -1;
|
||||
}
|
||||
|
||||
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;
|
||||
float angle = atan2f(y2 - y1, x2 - x1) * 180.0f / (float)M_PI;
|
||||
vg_lite_rotate(angle, grad_matrix);
|
||||
float length = sqrtf(SQUARE(x2 - x1) + SQUARE(y2 - y1));
|
||||
vg_lite_scale(length / 256.0f, 1, grad_matrix);
|
||||
}
|
||||
|
||||
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:
|
||||
return VG_LITE_GRADIENT_SPREAD_REFLECT;
|
||||
default:
|
||||
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;
|
||||
}
|
||||
|
||||
#endif /* LV_USE_VECTOR_GRAPHIC */
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif /*LV_USE_DRAW_VG_LITE*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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*/
|
||||
|
||||
@@ -16,7 +16,7 @@ extern "C" {
|
||||
|
||||
#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"
|
||||
|
||||
@@ -32,28 +32,11 @@ extern "C" {
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
void lv_vg_lite_grad_init(
|
||||
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_init(struct _lv_draw_vg_lite_unit_t * u, uint32_t cache_cnt);
|
||||
|
||||
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);
|
||||
|
||||
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(
|
||||
bool lv_vg_lite_draw_grad(
|
||||
struct _lv_draw_vg_lite_unit_t * u,
|
||||
vg_lite_buffer_t * buffer,
|
||||
vg_lite_path_t * path,
|
||||
@@ -63,13 +46,21 @@ void lv_vg_lite_draw_radial_grad(
|
||||
vg_lite_fill_t fill,
|
||||
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
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_DRAW_VG_LITE*/
|
||||
#endif /*LV_USE_DRAW_VG_LITE && LV_USE_VECTOR_GRAPHIC*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
|
||||
@@ -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());
|
||||
|
||||
/* Clear all gradient caches reference */
|
||||
lv_vg_lite_pending_remove_all(u->linear_grad_pending);
|
||||
|
||||
if(u->radial_grad_pending) {
|
||||
lv_vg_lite_pending_remove_all(u->radial_grad_pending);
|
||||
if(u->grad_pending) {
|
||||
lv_vg_lite_pending_remove_all(u->grad_pending);
|
||||
}
|
||||
|
||||
/* Clear image decoder dsc reference */
|
||||
|
||||
@@ -657,25 +657,14 @@
|
||||
#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.
|
||||
*/
|
||||
#ifndef LV_VG_LITE_LINEAR_GRAD_CACHE_CNT
|
||||
#ifdef CONFIG_LV_VG_LITE_LINEAR_GRAD_CACHE_CNT
|
||||
#define LV_VG_LITE_LINEAR_GRAD_CACHE_CNT CONFIG_LV_VG_LITE_LINEAR_GRAD_CACHE_CNT
|
||||
#ifndef LV_VG_LITE_GRAD_CACHE_CNT
|
||||
#ifdef CONFIG_LV_VG_LITE_GRAD_CACHE_CNT
|
||||
#define LV_VG_LITE_GRAD_CACHE_CNT CONFIG_LV_VG_LITE_GRAD_CACHE_CNT
|
||||
#else
|
||||
#define LV_VG_LITE_LINEAR_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
|
||||
#define LV_VG_LITE_GRAD_CACHE_CNT 32
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1121,6 +1110,15 @@
|
||||
#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*/
|
||||
#ifndef LV_VG_LITE_THORVG_16PIXELS_ALIGN
|
||||
#ifdef _LV_KCONFIG_PRESENT
|
||||
|
||||
@@ -463,10 +463,13 @@ extern "C" {
|
||||
vg_lite_uint32_t stride = VG_LITE_ALIGN((buffer->width * mul / div), align);
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
LV_ASSERT(buffer->memory);
|
||||
buffer->address = (vg_lite_uint32_t)(uintptr_t)buffer->memory;
|
||||
@@ -829,6 +832,10 @@ extern "C" {
|
||||
case gcFEATURE_BIT_VG_YUV_INPUT:
|
||||
#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
|
||||
case gcFEATURE_BIT_VG_16PIXELS_ALIGN:
|
||||
#endif
|
||||
@@ -1264,6 +1271,49 @@ Empty_sequence_handler:
|
||||
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_uint32_t count,
|
||||
vg_lite_color_ramp_t * color_ramp,
|
||||
@@ -1720,8 +1770,8 @@ Empty_sequence_handler:
|
||||
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);
|
||||
auto linearGrad = LinearGradient::gen();
|
||||
linearGrad->linear(x_min, y_min, x_max, y_max);
|
||||
linearGrad->spread(FillSpread::Pad);
|
||||
TVG_CHECK_RETURN_VG_ERROR(linearGrad->linear(x_min, y_min, x_max, y_max));
|
||||
TVG_CHECK_RETURN_VG_ERROR(linearGrad->spread(FillSpread::Pad));
|
||||
|
||||
tvg::Fill::ColorStop colorStops[VLC_MAX_GRADIENT_STOPS];
|
||||
for(vg_lite_uint32_t i = 0; i < grad->count; i++) {
|
||||
|
||||
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 43 KiB |
@@ -15,15 +15,10 @@
|
||||
* but does not guarantee the same rendering quality as the software. */
|
||||
#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.
|
||||
*/
|
||||
#define LV_VG_LITE_LINEAR_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
|
||||
#define LV_VG_LITE_GRAD_CACHE_CNT 32
|
||||
|
||||
/* Disable 16 pixels alignment */
|
||||
#define LV_VG_LITE_THORVG_16PIXELS_ALIGN 0
|
||||
|
||||
@@ -47,20 +47,21 @@ static void draw_shapes(lv_layer_t * layer)
|
||||
lv_vector_dsc_identity(ctx);
|
||||
lv_vector_dsc_translate(ctx, 0, 150);
|
||||
|
||||
lv_grad_dsc_t grad;
|
||||
grad.dir = LV_GRAD_DIR_HOR;
|
||||
grad.stops_count = 2;
|
||||
grad.stops[0].color = lv_color_hex(0xffffff);
|
||||
grad.stops[0].opa = LV_OPA_COVER;
|
||||
grad.stops[0].frac = 0;
|
||||
grad.stops[1].color = lv_color_hex(0x000000);
|
||||
grad.stops[1].opa = LV_OPA_COVER;
|
||||
grad.stops[1].frac = 255;
|
||||
lv_gradient_stop_t stops[2];
|
||||
lv_memzero(stops, sizeof(stops));
|
||||
stops[0].color = lv_color_hex(0xffffff);
|
||||
stops[0].opa = LV_OPA_COVER;
|
||||
stops[0].frac = 0;
|
||||
stops[1].color = lv_color_hex(0x000000);
|
||||
stops[1].opa = LV_OPA_COVER;
|
||||
stops[1].frac = 255;
|
||||
|
||||
lv_matrix_t mt;
|
||||
lv_matrix_identity(&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_identity(ctx);
|
||||
@@ -208,15 +209,14 @@ static void draw_lines(lv_layer_t * layer)
|
||||
lv_vector_path_clear(path);
|
||||
lv_vector_path_append_rect(path, &rect1, 0, 0);
|
||||
|
||||
lv_grad_dsc_t grad;
|
||||
grad.dir = LV_GRAD_DIR_HOR;
|
||||
grad.stops_count = 2;
|
||||
grad.stops[0].color = lv_color_hex(0xff0000);
|
||||
grad.stops[0].opa = LV_OPA_COVER;
|
||||
grad.stops[0].frac = 0;
|
||||
grad.stops[1].color = lv_color_hex(0x00ff00);
|
||||
grad.stops[1].opa = LV_OPA_COVER;
|
||||
grad.stops[1].frac = 255;
|
||||
lv_gradient_stop_t stops[2];
|
||||
lv_memzero(stops, sizeof(stops));
|
||||
stops[0].color = lv_color_hex(0xff0000);
|
||||
stops[0].opa = LV_OPA_COVER;
|
||||
stops[0].frac = 0;
|
||||
stops[1].color = lv_color_hex(0x00ff00);
|
||||
stops[1].opa = LV_OPA_COVER;
|
||||
stops[1].frac = 255;
|
||||
|
||||
lv_matrix_t mt;
|
||||
lv_matrix_identity(&mt);
|
||||
@@ -224,7 +224,9 @@ static void draw_lines(lv_layer_t * layer)
|
||||
lv_matrix_translate(&mt, 20, 20);
|
||||
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_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_draw_vector(ctx);
|
||||
|
||||