mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-14 06:42:58 +08:00
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:
parent
1f76eabadd
commit
d53b9145a2
@ -16,6 +16,7 @@
|
||||
#include "lv_vg_lite_pending.h"
|
||||
#include "lv_vg_lite_utils.h"
|
||||
#include "lv_vg_lite_grad.h"
|
||||
#include "lv_vg_lite_math.h"
|
||||
|
||||
/*********************
|
||||
* 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 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_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_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_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
|
||||
@ -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_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 */
|
||||
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);
|
||||
@ -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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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*/
|
||||
|
@ -103,6 +103,10 @@ void lv_vg_lite_path_destroy(lv_vg_lite_path_t * path)
|
||||
if(path->base.path != NULL) {
|
||||
lv_free(path->base.path);
|
||||
path->base.path = NULL;
|
||||
|
||||
if(path->base.stroke) {
|
||||
LV_LOG_ERROR("can't free stroke path");
|
||||
}
|
||||
}
|
||||
lv_free(path);
|
||||
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.format = data_format;
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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 FillRule fill_rule_conv(vg_lite_fill_t fill);
|
||||
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_rect(std::unique_ptr<Shape> & shape, const vg_lite_buffer_t * target,
|
||||
const vg_lite_rectangle_t * rect);
|
||||
@ -711,6 +713,65 @@ extern "C" {
|
||||
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)
|
||||
{
|
||||
LV_UNUSED(address);
|
||||
@ -820,7 +881,13 @@ extern "C" {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1880,6 +1947,38 @@ static BlendMethod blend_method_conv(vg_lite_blend_t blend)
|
||||
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)
|
||||
{
|
||||
switch(format) {
|
||||
@ -1953,6 +2052,29 @@ static uint8_t vlc_op_arg_len(uint8_t vlc_op)
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
TVG_CHECK_RETURN_RESULT(shape_set_stroke(shape, path));
|
||||
|
||||
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->transform(matrix_conv(matrix)));
|
||||
|
Loading…
x
Reference in New Issue
Block a user