feat(vg_lite): add stroke path support (#5831)
Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com> Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com>
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
#include "lv_vg_lite_pending.h"
|
#include "lv_vg_lite_pending.h"
|
||||||
#include "lv_vg_lite_utils.h"
|
#include "lv_vg_lite_utils.h"
|
||||||
#include "lv_vg_lite_grad.h"
|
#include "lv_vg_lite_grad.h"
|
||||||
|
#include "lv_vg_lite_math.h"
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
@@ -32,9 +33,12 @@
|
|||||||
static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vector_draw_dsc_t * dsc);
|
static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vector_draw_dsc_t * dsc);
|
||||||
static void lv_matrix_to_vg(vg_lite_matrix_t * desy, const lv_matrix_t * src);
|
static void lv_matrix_to_vg(vg_lite_matrix_t * desy, const lv_matrix_t * src);
|
||||||
static void lv_path_to_vg(lv_vg_lite_path_t * dest, const lv_vector_path_t * src);
|
static void lv_path_to_vg(lv_vg_lite_path_t * dest, const lv_vector_path_t * src);
|
||||||
|
static void lv_stroke_to_vg(lv_vg_lite_path_t * dest, const lv_vector_stroke_dsc_t * dsc);
|
||||||
static vg_lite_blend_t lv_blend_to_vg(lv_vector_blend_t blend);
|
static vg_lite_blend_t lv_blend_to_vg(lv_vector_blend_t blend);
|
||||||
static vg_lite_fill_t lv_fill_to_vg(lv_vector_fill_t fill_rule);
|
static vg_lite_fill_t lv_fill_to_vg(lv_vector_fill_t fill_rule);
|
||||||
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);
|
||||||
|
static vg_lite_cap_style_t lv_stroke_cap_to_vg(lv_vector_stroke_cap_t cap);
|
||||||
|
static vg_lite_join_style_t lv_stroke_join_to_vg(lv_vector_stroke_join_t join);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC VARIABLES
|
* STATIC VARIABLES
|
||||||
@@ -114,6 +118,9 @@ static void task_draw_cb(void * ctx, const lv_vector_path_t * path, const lv_vec
|
|||||||
vg_lite_blend_t blend = lv_blend_to_vg(dsc->blend_mode);
|
vg_lite_blend_t blend = lv_blend_to_vg(dsc->blend_mode);
|
||||||
vg_lite_fill_t fill = lv_fill_to_vg(dsc->fill_dsc.fill_rule);
|
vg_lite_fill_t fill = lv_fill_to_vg(dsc->fill_dsc.fill_rule);
|
||||||
|
|
||||||
|
/* convert stroke style */
|
||||||
|
lv_stroke_to_vg(lv_vg_path, &dsc->stroke_dsc);
|
||||||
|
|
||||||
/* get path bounds */
|
/* get path bounds */
|
||||||
float min_x, min_y, max_x, max_y;
|
float min_x, min_y, max_x, max_y;
|
||||||
lv_vg_lite_path_get_bonding_box(lv_vg_path, &min_x, &min_y, &max_x, &max_y);
|
lv_vg_lite_path_get_bonding_box(lv_vg_path, &min_x, &min_y, &max_x, &max_y);
|
||||||
@@ -336,6 +343,36 @@ static void lv_path_to_vg(lv_vg_lite_path_t * dest, const lv_vector_path_t * src
|
|||||||
LV_PROFILER_END;
|
LV_PROFILER_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void lv_stroke_to_vg(lv_vg_lite_path_t * dest, const lv_vector_stroke_dsc_t * dsc)
|
||||||
|
{
|
||||||
|
LV_ASSERT_NULL(dest);
|
||||||
|
LV_ASSERT_NULL(dsc);
|
||||||
|
|
||||||
|
/* if width is 0, no need to set stroke */
|
||||||
|
if(math_zero(dsc->width)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vg_lite_path_t * path = lv_vg_lite_path_get_path(dest);
|
||||||
|
|
||||||
|
LV_VG_LITE_CHECK_ERROR(vg_lite_set_path_type(path, VG_LITE_DRAW_STROKE_PATH));
|
||||||
|
|
||||||
|
LV_VG_LITE_CHECK_ERROR(
|
||||||
|
vg_lite_set_stroke(
|
||||||
|
path,
|
||||||
|
lv_stroke_cap_to_vg(dsc->cap),
|
||||||
|
lv_stroke_join_to_vg(dsc->join),
|
||||||
|
dsc->width,
|
||||||
|
dsc->miter_limit,
|
||||||
|
lv_array_front(&dsc->dash_pattern),
|
||||||
|
dsc->dash_pattern.size,
|
||||||
|
dsc->width / 2,
|
||||||
|
lv_color32_to_vg(dsc->color, dsc->opa))
|
||||||
|
);
|
||||||
|
|
||||||
|
LV_VG_LITE_CHECK_ERROR(vg_lite_update_stroke(path));
|
||||||
|
}
|
||||||
|
|
||||||
static vg_lite_blend_t lv_blend_to_vg(lv_vector_blend_t blend)
|
static vg_lite_blend_t lv_blend_to_vg(lv_vector_blend_t blend)
|
||||||
{
|
{
|
||||||
switch(blend) {
|
switch(blend) {
|
||||||
@@ -388,4 +425,32 @@ static vg_lite_gradient_spreadmode_t lv_spread_to_vg(lv_vector_gradient_spread_t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static vg_lite_cap_style_t lv_stroke_cap_to_vg(lv_vector_stroke_cap_t cap)
|
||||||
|
{
|
||||||
|
switch(cap) {
|
||||||
|
case LV_VECTOR_STROKE_CAP_SQUARE:
|
||||||
|
return VG_LITE_CAP_SQUARE;
|
||||||
|
case LV_VECTOR_STROKE_CAP_ROUND:
|
||||||
|
return VG_LITE_CAP_ROUND;
|
||||||
|
case LV_VECTOR_STROKE_CAP_BUTT:
|
||||||
|
return VG_LITE_CAP_BUTT;
|
||||||
|
default:
|
||||||
|
return VG_LITE_CAP_SQUARE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static vg_lite_join_style_t lv_stroke_join_to_vg(lv_vector_stroke_join_t join)
|
||||||
|
{
|
||||||
|
switch(join) {
|
||||||
|
case LV_VECTOR_STROKE_JOIN_BEVEL:
|
||||||
|
return VG_LITE_JOIN_BEVEL;
|
||||||
|
case LV_VECTOR_STROKE_JOIN_ROUND:
|
||||||
|
return VG_LITE_JOIN_ROUND;
|
||||||
|
case LV_VECTOR_STROKE_JOIN_MITER:
|
||||||
|
return VG_LITE_JOIN_MITER;
|
||||||
|
default:
|
||||||
|
return VG_LITE_JOIN_BEVEL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif /*LV_USE_DRAW_VG_LITE && LV_USE_VECTOR_GRAPHIC*/
|
#endif /*LV_USE_DRAW_VG_LITE && LV_USE_VECTOR_GRAPHIC*/
|
||||||
|
|||||||
@@ -103,6 +103,10 @@ void lv_vg_lite_path_destroy(lv_vg_lite_path_t * path)
|
|||||||
if(path->base.path != NULL) {
|
if(path->base.path != NULL) {
|
||||||
lv_free(path->base.path);
|
lv_free(path->base.path);
|
||||||
path->base.path = NULL;
|
path->base.path = NULL;
|
||||||
|
|
||||||
|
if(path->base.stroke) {
|
||||||
|
LV_LOG_ERROR("can't free stroke path");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lv_free(path);
|
lv_free(path);
|
||||||
LV_PROFILER_END;
|
LV_PROFILER_END;
|
||||||
@@ -133,6 +137,7 @@ void lv_vg_lite_path_reset(lv_vg_lite_path_t * path, vg_lite_format_t data_forma
|
|||||||
path->base.path_length = 0;
|
path->base.path_length = 0;
|
||||||
path->base.format = data_format;
|
path->base.format = data_format;
|
||||||
path->base.quality = VG_LITE_MEDIUM;
|
path->base.quality = VG_LITE_MEDIUM;
|
||||||
|
path->base.path_type = VG_LITE_DRAW_ZERO;
|
||||||
path->format_len = lv_vg_lite_path_format_len(data_format);
|
path->format_len = lv_vg_lite_path_format_len(data_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -269,6 +269,8 @@ static vg_lite_error_t vg_lite_error_conv(Result result);
|
|||||||
static Matrix matrix_conv(const vg_lite_matrix_t * matrix);
|
static Matrix matrix_conv(const vg_lite_matrix_t * matrix);
|
||||||
static FillRule fill_rule_conv(vg_lite_fill_t fill);
|
static FillRule fill_rule_conv(vg_lite_fill_t fill);
|
||||||
static BlendMethod blend_method_conv(vg_lite_blend_t blend);
|
static BlendMethod blend_method_conv(vg_lite_blend_t blend);
|
||||||
|
static StrokeCap stroke_cap_conv(vg_lite_cap_style_t cap);
|
||||||
|
static StrokeJoin stroke_join_conv(vg_lite_join_style_t join);
|
||||||
static Result shape_append_path(std::unique_ptr<Shape> & shape, vg_lite_path_t * path, vg_lite_matrix_t * matrix);
|
static Result shape_append_path(std::unique_ptr<Shape> & shape, vg_lite_path_t * path, vg_lite_matrix_t * matrix);
|
||||||
static Result shape_append_rect(std::unique_ptr<Shape> & shape, const vg_lite_buffer_t * target,
|
static Result shape_append_rect(std::unique_ptr<Shape> & shape, const vg_lite_buffer_t * target,
|
||||||
const vg_lite_rectangle_t * rect);
|
const vg_lite_rectangle_t * rect);
|
||||||
@@ -711,6 +713,65 @@ extern "C" {
|
|||||||
return VG_LITE_SUCCESS;
|
return VG_LITE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vg_lite_error_t vg_lite_set_stroke(vg_lite_path_t * path,
|
||||||
|
vg_lite_cap_style_t cap_style,
|
||||||
|
vg_lite_join_style_t join_style,
|
||||||
|
vg_lite_float_t line_width,
|
||||||
|
vg_lite_float_t miter_limit,
|
||||||
|
vg_lite_float_t * dash_pattern,
|
||||||
|
vg_lite_uint32_t pattern_count,
|
||||||
|
vg_lite_float_t dash_phase,
|
||||||
|
vg_lite_color_t color)
|
||||||
|
{
|
||||||
|
if(!path || line_width <= 0) {
|
||||||
|
return VG_LITE_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(miter_limit < 1.0f) {
|
||||||
|
miter_limit = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!path->stroke) {
|
||||||
|
path->stroke = (vg_lite_stroke_t *)lv_malloc_zeroed(sizeof(vg_lite_stroke_t));
|
||||||
|
|
||||||
|
if(!path->stroke) {
|
||||||
|
return VG_LITE_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
path->stroke->cap_style = cap_style;
|
||||||
|
path->stroke->join_style = join_style;
|
||||||
|
path->stroke->line_width = line_width;
|
||||||
|
path->stroke->miter_limit = miter_limit;
|
||||||
|
path->stroke->half_width = line_width / 2.0f;
|
||||||
|
path->stroke->miter_square = path->stroke->miter_limit * path->stroke->miter_limit;
|
||||||
|
path->stroke->dash_pattern = dash_pattern;
|
||||||
|
path->stroke->pattern_count = pattern_count;
|
||||||
|
path->stroke->dash_phase = dash_phase;
|
||||||
|
path->stroke_color = color;
|
||||||
|
return VG_LITE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
vg_lite_error_t vg_lite_update_stroke(vg_lite_path_t * path)
|
||||||
|
{
|
||||||
|
LV_UNUSED(path);
|
||||||
|
return VG_LITE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
vg_lite_error_t vg_lite_set_path_type(vg_lite_path_t * path, vg_lite_path_type_t path_type)
|
||||||
|
{
|
||||||
|
if(!path ||
|
||||||
|
(path_type != VG_LITE_DRAW_FILL_PATH &&
|
||||||
|
path_type != VG_LITE_DRAW_STROKE_PATH &&
|
||||||
|
path_type != VG_LITE_DRAW_FILL_STROKE_PATH)
|
||||||
|
)
|
||||||
|
return VG_LITE_INVALID_ARGUMENT;
|
||||||
|
|
||||||
|
path->path_type = path_type;
|
||||||
|
|
||||||
|
return VG_LITE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
vg_lite_error_t vg_lite_get_register(vg_lite_uint32_t address, vg_lite_uint32_t * result)
|
vg_lite_error_t vg_lite_get_register(vg_lite_uint32_t address, vg_lite_uint32_t * result)
|
||||||
{
|
{
|
||||||
LV_UNUSED(address);
|
LV_UNUSED(address);
|
||||||
@@ -820,7 +881,13 @@ extern "C" {
|
|||||||
|
|
||||||
vg_lite_error_t vg_lite_clear_path(vg_lite_path_t * path)
|
vg_lite_error_t vg_lite_clear_path(vg_lite_path_t * path)
|
||||||
{
|
{
|
||||||
LV_UNUSED(path);
|
LV_ASSERT_NULL(path);
|
||||||
|
|
||||||
|
if(path->stroke) {
|
||||||
|
lv_free(path->stroke);
|
||||||
|
path->stroke = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return VG_LITE_NOT_SUPPORT;
|
return VG_LITE_NOT_SUPPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1880,6 +1947,38 @@ static BlendMethod blend_method_conv(vg_lite_blend_t blend)
|
|||||||
return BlendMethod::Normal;
|
return BlendMethod::Normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static StrokeCap stroke_cap_conv(vg_lite_cap_style_t cap)
|
||||||
|
{
|
||||||
|
switch(cap) {
|
||||||
|
case VG_LITE_CAP_SQUARE:
|
||||||
|
return StrokeCap::Square;
|
||||||
|
case VG_LITE_CAP_ROUND:
|
||||||
|
return StrokeCap::Round;
|
||||||
|
case VG_LITE_CAP_BUTT:
|
||||||
|
return StrokeCap::Butt;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return StrokeCap::Square;
|
||||||
|
}
|
||||||
|
|
||||||
|
static StrokeJoin stroke_join_conv(vg_lite_join_style_t join)
|
||||||
|
{
|
||||||
|
switch(join) {
|
||||||
|
case VG_LITE_JOIN_BEVEL:
|
||||||
|
return StrokeJoin::Bevel;
|
||||||
|
case VG_LITE_JOIN_ROUND:
|
||||||
|
return StrokeJoin::Round;
|
||||||
|
case VG_LITE_JOIN_MITER:
|
||||||
|
return StrokeJoin::Miter;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return StrokeJoin::Bevel;
|
||||||
|
}
|
||||||
|
|
||||||
static float vlc_get_arg(const void * data, vg_lite_format_t format)
|
static float vlc_get_arg(const void * data, vg_lite_format_t format)
|
||||||
{
|
{
|
||||||
switch(format) {
|
switch(format) {
|
||||||
@@ -1953,6 +2052,29 @@ static uint8_t vlc_op_arg_len(uint8_t vlc_op)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Result shape_set_stroke(std::unique_ptr<Shape> & shape, const vg_lite_path_t * path)
|
||||||
|
{
|
||||||
|
/* if path is not a stroke, return */
|
||||||
|
if(path->path_type == VG_LITE_DRAW_ZERO
|
||||||
|
|| path->path_type == VG_LITE_DRAW_FILL_PATH) {
|
||||||
|
return Result::Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
LV_ASSERT_NULL(path->stroke);
|
||||||
|
TVG_CHECK_RETURN_RESULT(shape->stroke(path->stroke->line_width));
|
||||||
|
TVG_CHECK_RETURN_RESULT(shape->strokeMiterlimit(path->stroke->miter_limit));
|
||||||
|
TVG_CHECK_RETURN_RESULT(shape->stroke(stroke_cap_conv(path->stroke->cap_style)));
|
||||||
|
TVG_CHECK_RETURN_RESULT(shape->stroke(stroke_join_conv(path->stroke->join_style)));
|
||||||
|
TVG_CHECK_RETURN_RESULT(shape->stroke(TVG_COLOR(path->stroke_color)));
|
||||||
|
|
||||||
|
if(path->stroke->pattern_count) {
|
||||||
|
LV_ASSERT_NULL(path->stroke->dash_pattern);
|
||||||
|
TVG_CHECK_RETURN_RESULT(shape->stroke(path->stroke->dash_pattern, path->stroke->pattern_count));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result::Success;
|
||||||
|
}
|
||||||
|
|
||||||
static Result shape_append_path(std::unique_ptr<Shape> & shape, vg_lite_path_t * path, vg_lite_matrix_t * matrix)
|
static Result shape_append_path(std::unique_ptr<Shape> & shape, vg_lite_path_t * path, vg_lite_matrix_t * matrix)
|
||||||
{
|
{
|
||||||
uint8_t fmt_len = vlc_format_len(path->format);
|
uint8_t fmt_len = vlc_format_len(path->format);
|
||||||
@@ -2036,6 +2158,8 @@ static Result shape_append_path(std::unique_ptr<Shape> & shape, vg_lite_path_t *
|
|||||||
return Result::Success;
|
return Result::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TVG_CHECK_RETURN_RESULT(shape_set_stroke(shape, path));
|
||||||
|
|
||||||
auto cilp = Shape::gen();
|
auto cilp = Shape::gen();
|
||||||
TVG_CHECK_RETURN_RESULT(cilp->appendRect(x_min, y_min, x_max - x_min, y_max - y_min, 0, 0));
|
TVG_CHECK_RETURN_RESULT(cilp->appendRect(x_min, y_min, x_max - x_min, y_max - y_min, 0, 0));
|
||||||
TVG_CHECK_RETURN_RESULT(cilp->transform(matrix_conv(matrix)));
|
TVG_CHECK_RETURN_RESULT(cilp->transform(matrix_conv(matrix)));
|
||||||
|
|||||||
Reference in New Issue
Block a user