feat(draw_vector): add fill units support (#7774)
Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com> Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com>
@@ -541,6 +541,11 @@ void lv_vector_dsc_set_fill_rule(lv_vector_dsc_t * dsc, lv_vector_fill_t rule)
|
||||
dsc->current_dsc.fill_dsc.fill_rule = rule;
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_fill_units(lv_vector_dsc_t * dsc, const lv_vector_fill_units_t units)
|
||||
{
|
||||
dsc->current_dsc.fill_dsc.fill_units = units;
|
||||
}
|
||||
|
||||
void lv_vector_dsc_set_fill_image(lv_vector_dsc_t * dsc, const lv_draw_image_dsc_t * img_dsc)
|
||||
{
|
||||
dsc->current_dsc.fill_dsc.style = LV_VECTOR_DRAW_STYLE_PATTERN;
|
||||
|
||||
@@ -86,6 +86,11 @@ typedef enum {
|
||||
LV_VECTOR_GRADIENT_STYLE_RADIAL,
|
||||
} lv_vector_gradient_style_t;
|
||||
|
||||
typedef enum {
|
||||
LV_VECTOR_FILL_UNITS_OBJECT_BOUNDING_BOX = 0, /** Relative coordinates relative to the object bounding box. */
|
||||
LV_VECTOR_FILL_UNITS_USER_SPACE_ON_USE, /** Absolute coordinates relative to the layer's coordinate system */
|
||||
} lv_vector_fill_units_t;
|
||||
|
||||
struct _lv_fpoint_t {
|
||||
float x;
|
||||
float y;
|
||||
@@ -272,6 +277,15 @@ void lv_vector_dsc_set_fill_opa(lv_vector_dsc_t * dsc, lv_opa_t opa);
|
||||
*/
|
||||
void lv_vector_dsc_set_fill_rule(lv_vector_dsc_t * dsc, lv_vector_fill_t rule);
|
||||
|
||||
/**
|
||||
* Set the fill units for descriptor.
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
* @param units the units to be set in lv_vector_fill_units_t format
|
||||
* @note The units can be either relative to the object bounding box or absolute in user space.
|
||||
* This API specifically affects the drawing position of the fill image and does not impact other elements.
|
||||
*/
|
||||
void lv_vector_dsc_set_fill_units(lv_vector_dsc_t * dsc, const lv_vector_fill_units_t units);
|
||||
|
||||
/**
|
||||
* Set fill image for descriptor
|
||||
* @param dsc pointer to a vector graphic descriptor
|
||||
|
||||
@@ -51,6 +51,7 @@ struct _lv_vector_fill_dsc_t {
|
||||
lv_color32_t color;
|
||||
lv_opa_t opa;
|
||||
lv_vector_fill_t fill_rule;
|
||||
lv_vector_fill_units_t fill_units;
|
||||
lv_draw_image_dsc_t img_dsc;
|
||||
lv_vector_gradient_t gradient;
|
||||
lv_matrix_t matrix;
|
||||
|
||||
@@ -330,13 +330,22 @@ static void _set_paint_fill(Tvg_Paint * obj, Tvg_Canvas * canvas, const lv_vecto
|
||||
tvg_shape_set_fill_color(obj, c.r, c.g, c.b, c.a);
|
||||
}
|
||||
else if(dsc->style == LV_VECTOR_DRAW_STYLE_PATTERN) {
|
||||
float x, y, w, h;
|
||||
tvg_paint_get_bounds(obj, &x, &y, &w, &h, false);
|
||||
|
||||
lv_matrix_t imx;
|
||||
lv_memcpy(&imx, matrix, sizeof(lv_matrix_t));
|
||||
lv_matrix_translate(&imx, x, y);
|
||||
lv_matrix_multiply(&imx, &dsc->matrix);
|
||||
|
||||
if(dsc->fill_units == LV_VECTOR_FILL_UNITS_OBJECT_BOUNDING_BOX) {
|
||||
/* Convert to object bounding box coordinates */
|
||||
imx = *matrix;
|
||||
|
||||
float x, y, w, h;
|
||||
tvg_paint_get_bounds(obj, &x, &y, &w, &h, false);
|
||||
lv_matrix_translate(&imx, x, y);
|
||||
lv_matrix_multiply(&imx, &dsc->matrix);
|
||||
}
|
||||
else {
|
||||
/* Copy fill matrix directly, no need to convert */
|
||||
imx = dsc->matrix;
|
||||
}
|
||||
|
||||
_set_paint_fill_pattern(obj, canvas, &dsc->img_dsc, &imx);
|
||||
}
|
||||
else if(dsc->style == LV_VECTOR_DRAW_STYLE_GRADIENT) {
|
||||
|
||||
@@ -230,7 +230,12 @@ static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vec
|
||||
if(lv_vg_lite_buffer_open_image(&image_buffer, &decoder_dsc, dsc->fill_dsc.img_dsc.src, false, true)) {
|
||||
/* Calculate pattern matrix. Should start from path bond box, and also apply fill matrix. */
|
||||
lv_matrix_t m = dsc->matrix;
|
||||
lv_matrix_translate(&m, min_x, min_y);
|
||||
|
||||
if(dsc->fill_dsc.fill_units == LV_VECTOR_FILL_UNITS_OBJECT_BOUNDING_BOX) {
|
||||
/* Convert to object bounding box coordinates */
|
||||
lv_matrix_translate(&m, min_x, min_y);
|
||||
}
|
||||
|
||||
lv_matrix_multiply(&m, &dsc->fill_dsc.matrix);
|
||||
|
||||
vg_lite_matrix_t pattern_matrix;
|
||||
|
||||
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 31 KiB |
@@ -128,6 +128,22 @@ static void draw_shapes(lv_layer_t * layer)
|
||||
lv_vector_path_append_arc(path, &p, 50, 45, 45, true);
|
||||
lv_vector_dsc_add_path(ctx, path); // draw a path
|
||||
|
||||
/* Test image filling with absolute coordinates */
|
||||
lv_vector_dsc_identity(ctx);
|
||||
lv_vector_dsc_set_fill_units(ctx, LV_VECTOR_FILL_UNITS_USER_SPACE_ON_USE);
|
||||
lv_vector_dsc_set_fill_image(ctx, &img_dsc);
|
||||
lv_vector_dsc_set_fill_opa(ctx, LV_OPA_50);
|
||||
lv_vector_dsc_set_stroke_opa(ctx, LV_OPA_TRANSP);
|
||||
lv_matrix_identity(&mt);
|
||||
lv_matrix_translate(&mt, 50, 350);
|
||||
lv_vector_dsc_set_fill_transform(ctx, &mt);
|
||||
|
||||
lv_vector_path_clear(path);
|
||||
/* Aligned with translate. Image resolution is 100x100, cropped to 50% of width and height */
|
||||
lv_area_t img_area = {50, 350, 50 + 50, 350 + 50};
|
||||
lv_vector_path_append_rect(path, &img_area, 0, 0);
|
||||
lv_vector_dsc_add_path(ctx, path);
|
||||
|
||||
lv_draw_vector(ctx);
|
||||
lv_vector_path_delete(path);
|
||||
lv_vector_dsc_delete(ctx);
|
||||
|
||||