fix(svg): adjust svg render node object for reduce memory usage. (#8013)

Signed-off-by: zhangjipeng <zhangjipeng@xiaomi.com>
Co-authored-by: zhangjipeng <zhangjipeng@xiaomi.com>
This commit is contained in:
Zhang Ji Peng
2025-03-29 01:47:22 +08:00
committed by GitHub
parent 8e65486b32
commit f55c8d4dbe
3 changed files with 170 additions and 99 deletions
+1 -1
View File
@@ -146,7 +146,7 @@ static lv_result_t svg_decoder_info(lv_image_decoder_t * decoder, lv_image_decod
lv_svg_render_obj_t * svg_header = lv_svg_render_create(svg_doc); lv_svg_render_obj_t * svg_header = lv_svg_render_create(svg_doc);
if(svg_header->tag == LV_SVG_TAG_SVG) { if(svg_header->tag == LV_SVG_TAG_SVG) {
lv_area_t bounds; lv_area_t bounds;
svg_header->get_bounds(svg_header, &bounds); svg_header->clz->get_bounds(svg_header, &bounds);
width = lv_area_get_width(&bounds) - 1; width = lv_area_get_width(&bounds) - 1;
height = lv_area_get_height(&bounds) - 1; height = lv_area_get_height(&bounds) - 1;
} }
+163 -97
View File
@@ -483,7 +483,7 @@ static void _set_polyline_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t *
} }
} }
static void _set_polygen_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr) static void _set_polygon_attr(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, const lv_svg_attr_t * attr)
{ {
_set_polyline_attr(obj, dsc, attr); _set_polyline_attr(obj, dsc, attr);
lv_svg_render_poly_t * poly = (lv_svg_render_poly_t *)obj; lv_svg_render_poly_t * poly = (lv_svg_render_poly_t *)obj;
@@ -899,7 +899,7 @@ static void _set_solid_ref(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc
static void _set_gradient_ref(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc, static void _set_gradient_ref(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t * dsc,
const lv_svg_render_obj_t * target_obj, bool fill) const lv_svg_render_obj_t * target_obj, bool fill)
{ {
if(!target_obj->get_bounds) { if(!target_obj->clz->get_bounds) {
return; return;
} }
@@ -921,7 +921,7 @@ static void _set_gradient_ref(lv_svg_render_obj_t * obj, lv_vector_draw_dsc_t *
lv_memcpy(grad_dsc, &grad->dsc, sizeof(lv_vector_gradient_t)); lv_memcpy(grad_dsc, &grad->dsc, sizeof(lv_vector_gradient_t));
lv_area_t bounds = {0, 0, 0, 0}; lv_area_t bounds = {0, 0, 0, 0};
target_obj->get_bounds(target_obj, &bounds); target_obj->clz->get_bounds(target_obj, &bounds);
int32_t w = bounds.x2 - bounds.x1; int32_t w = bounds.x2 - bounds.x1;
int32_t h = bounds.y2 - bounds.y1; int32_t h = bounds.y2 - bounds.y1;
@@ -998,7 +998,7 @@ static void _copy_draw_dsc_from_ref(lv_vector_dsc_t * dsc, const lv_svg_render_o
while(list) { while(list) {
if(list->id) { if(list->id) {
if(strcmp(obj->fill_ref, list->id) == 0) { if(strcmp(obj->fill_ref, list->id) == 0) {
list->set_paint_ref(list, dst, obj, true); list->clz->set_paint_ref(list, dst, obj, true);
break; break;
} }
} }
@@ -1011,7 +1011,7 @@ static void _copy_draw_dsc_from_ref(lv_vector_dsc_t * dsc, const lv_svg_render_o
while(list) { while(list) {
if(list->id) { if(list->id) {
if(strcmp(obj->stroke_ref, list->id) == 0) { if(strcmp(obj->stroke_ref, list->id) == 0) {
list->set_paint_ref(list, dst, obj, false); list->clz->set_paint_ref(list, dst, obj, false);
break; break;
} }
} }
@@ -1027,8 +1027,8 @@ static void _set_render_attrs(lv_svg_render_obj_t * obj, const lv_svg_node_t * n
if((node->type != LV_SVG_TAG_CONTENT) && node->xml_id) { if((node->type != LV_SVG_TAG_CONTENT) && node->xml_id) {
obj->id = lv_strdup(node->xml_id); obj->id = lv_strdup(node->xml_id);
} }
if(obj->init) { if(obj->clz->init) {
obj->init(obj, node); obj->clz->init(obj, node);
} }
if(state->draw_dsc->fill_ref) { if(state->draw_dsc->fill_ref) {
obj->fill_ref = lv_strdup(state->draw_dsc->fill_ref); obj->fill_ref = lv_strdup(state->draw_dsc->fill_ref);
@@ -1040,7 +1040,7 @@ static void _set_render_attrs(lv_svg_render_obj_t * obj, const lv_svg_node_t * n
uint32_t len = lv_array_size(&node->attrs); uint32_t len = lv_array_size(&node->attrs);
for(uint32_t i = 0; i < len; i++) { for(uint32_t i = 0; i < len; i++) {
lv_svg_attr_t * attr = lv_array_at(&node->attrs, i); lv_svg_attr_t * attr = lv_array_at(&node->attrs, i);
obj->set_attr(obj, &(state->draw_dsc->dsc), attr); obj->clz->set_attr(obj, &(state->draw_dsc->dsc), attr);
} }
if(node->type == LV_SVG_TAG_G) { // only <g> need store it if(node->type == LV_SVG_TAG_G) { // only <g> need store it
state->draw_dsc->fill_ref = obj->fill_ref; state->draw_dsc->fill_ref = obj->fill_ref;
@@ -1391,10 +1391,10 @@ static void _render_group(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc
for(uint32_t i = 0; i < group->items.size; i++) { for(uint32_t i = 0; i < group->items.size; i++) {
lv_svg_render_obj_t * list = *((lv_svg_render_obj_t **)lv_array_at(&group->items, i)); lv_svg_render_obj_t * list = *((lv_svg_render_obj_t **)lv_array_at(&group->items, i));
if(list->render && (list->flags & _RENDER_IN_GROUP)) { if(list->clz->render && (list->flags & _RENDER_IN_GROUP)) {
_copy_draw_dsc(&(save_dsc.dsc), &(dsc->current_dsc)); _copy_draw_dsc(&(save_dsc.dsc), &(dsc->current_dsc));
_special_render(list, dsc); _special_render(list, dsc);
list->render(list, dsc, matrix); list->clz->render(list, dsc, matrix);
_copy_draw_dsc(&(dsc->current_dsc), &(save_dsc.dsc)); _copy_draw_dsc(&(dsc->current_dsc), &(save_dsc.dsc));
} }
} }
@@ -1525,10 +1525,10 @@ static void _render_use(const lv_svg_render_obj_t * obj, lv_vector_dsc_t * dsc,
while(list) { while(list) {
if(list->id) { if(list->id) {
if(strcmp(use->xlink, list->id) == 0) { if(strcmp(use->xlink, list->id) == 0) {
if(list->render) { if(list->clz->render) {
_prepare_render(list, dsc); _prepare_render(list, dsc);
_special_render(obj, dsc); _special_render(obj, dsc);
list->render(list, dsc, &mtx); list->clz->render(list, dsc, &mtx);
} }
break; break;
} }
@@ -1951,6 +1951,135 @@ static void _destroy_tspan(lv_svg_render_obj_t * obj)
#endif #endif
static lv_svg_render_class svg_viewport_class = {
.init = _init_viewport,
.render = _render_viewport,
.set_attr = _set_viewport_attr,
.get_bounds = _get_viewport_bounds,
.get_size = _get_viewport_size,
};
static lv_svg_render_class svg_rect_class = {
.init = _init_obj,
.render = _render_rect,
.set_attr = _set_rect_attr,
.get_bounds = _get_rect_bounds,
.get_size = _get_rect_size,
};
static lv_svg_render_class svg_circle_class = {
.init = _init_obj,
.render = _render_circle,
.set_attr = _set_circle_attr,
.get_bounds = _get_circle_bounds,
.get_size = _get_circle_size,
};
static lv_svg_render_class svg_ellipse_class = {
.init = _init_obj,
.render = _render_ellipse,
.set_attr = _set_ellipse_attr,
.get_bounds = _get_ellipse_bounds,
.get_size = _get_ellipse_size,
};
static lv_svg_render_class svg_line_class = {
.init = _init_obj,
.render = _render_line,
.set_attr = _set_line_attr,
.get_bounds = _get_line_bounds,
.get_size = _get_line_size,
};
static lv_svg_render_class svg_polyline_class = {
.init = _init_poly,
.render = _render_poly,
.set_attr = _set_polyline_attr,
.get_bounds = _get_poly_bounds,
.destroy = _destroy_poly,
.get_size = _get_poly_size,
};
static lv_svg_render_class svg_polygon_class = {
.init = _init_poly,
.render = _render_poly,
.set_attr = _set_polygon_attr,
.get_bounds = _get_poly_bounds,
.destroy = _destroy_poly,
.get_size = _get_poly_size,
};
static lv_svg_render_class svg_path_class = {
.init = _init_poly,
.render = _render_poly,
.set_attr = _set_path_attr,
.get_bounds = _get_poly_bounds,
.destroy = _destroy_poly,
.get_size = _get_poly_size,
};
#if LV_USE_FREETYPE
static lv_svg_render_class svg_text_class = {
.init = _init_text,
.set_attr = _set_text_attr,
.render = _render_text,
.get_bounds = _get_text_bounds,
.destroy = _destroy_text,
.get_size = _get_txt_size,
};
static lv_svg_render_class svg_tspan_class = {
.init = _init_tspan,
.set_attr = _set_tspan_attr,
.get_bounds = _get_tspan_bounds,
.destroy = _destroy_tspan,
.get_size = _get_span_size,
};
static lv_svg_render_class svg_content_class = {
.init = _init_content,
.destroy = _destroy_content,
.get_size = _get_content_size,
};
#endif
static lv_svg_render_class svg_image_class = {
.init = _init_image,
.render = _render_image,
.set_attr = _set_image_attr,
.get_size = _get_image_size,
};
static lv_svg_render_class svg_use_class = {
.init = _init_obj,
.set_attr = _set_use_attr,
.render = _render_use,
.destroy = _destroy_use,
.get_size = _get_use_size,
};
static lv_svg_render_class svg_solid_class = {
.init = _init_obj,
.set_attr = _set_solid_attr,
.set_paint_ref = _set_solid_ref,
.get_size = _get_solid_size,
};
static lv_svg_render_class svg_grad_class = {
.init = _init_gradient,
.set_attr = _set_gradient_attr,
.set_paint_ref = _set_gradient_ref,
.get_size = _get_grad_size,
};
static lv_svg_render_class svg_group_class = {
.init = _init_group,
.set_attr = _set_attr,
.render = _render_group,
.destroy = _destroy_group,
.get_size = _get_group_size,
};
static lv_svg_render_obj_t * _lv_svg_render_create(const lv_svg_node_t * node, static lv_svg_render_obj_t * _lv_svg_render_create(const lv_svg_node_t * node,
struct _lv_svg_drawing_builder_state * state) struct _lv_svg_drawing_builder_state * state)
{ {
@@ -1958,91 +2087,56 @@ static lv_svg_render_obj_t * _lv_svg_render_create(const lv_svg_node_t * node,
case LV_SVG_TAG_SVG: { case LV_SVG_TAG_SVG: {
lv_svg_render_viewport_t * view = lv_zalloc(sizeof(lv_svg_render_viewport_t)); lv_svg_render_viewport_t * view = lv_zalloc(sizeof(lv_svg_render_viewport_t));
LV_ASSERT_MALLOC(view); LV_ASSERT_MALLOC(view);
view->base.init = _init_viewport; view->base.clz = &svg_viewport_class;
view->base.render = _render_viewport;
view->base.set_attr = _set_viewport_attr;
view->base.get_bounds = _get_viewport_bounds;
view->base.get_size = _get_viewport_size;
_set_render_attrs(LV_SVG_RENDER_OBJ(view), node, state); _set_render_attrs(LV_SVG_RENDER_OBJ(view), node, state);
return LV_SVG_RENDER_OBJ(view); return LV_SVG_RENDER_OBJ(view);
} }
case LV_SVG_TAG_RECT: { case LV_SVG_TAG_RECT: {
lv_svg_render_rect_t * rect = lv_zalloc(sizeof(lv_svg_render_rect_t)); lv_svg_render_rect_t * rect = lv_zalloc(sizeof(lv_svg_render_rect_t));
LV_ASSERT_MALLOC(rect); LV_ASSERT_MALLOC(rect);
rect->base.init = _init_obj; rect->base.clz = &svg_rect_class;
rect->base.render = _render_rect;
rect->base.set_attr = _set_rect_attr;
rect->base.get_bounds = _get_rect_bounds;
rect->base.get_size = _get_rect_size;
_set_render_attrs(LV_SVG_RENDER_OBJ(rect), node, state); _set_render_attrs(LV_SVG_RENDER_OBJ(rect), node, state);
return LV_SVG_RENDER_OBJ(rect); return LV_SVG_RENDER_OBJ(rect);
} }
case LV_SVG_TAG_CIRCLE: { case LV_SVG_TAG_CIRCLE: {
lv_svg_render_circle_t * circle = lv_zalloc(sizeof(lv_svg_render_circle_t)); lv_svg_render_circle_t * circle = lv_zalloc(sizeof(lv_svg_render_circle_t));
LV_ASSERT_MALLOC(circle); LV_ASSERT_MALLOC(circle);
circle->base.init = _init_obj; circle->base.clz = &svg_circle_class;
circle->base.render = _render_circle;
circle->base.set_attr = _set_circle_attr;
circle->base.get_bounds = _get_circle_bounds;
circle->base.get_size = _get_circle_size;
_set_render_attrs(LV_SVG_RENDER_OBJ(circle), node, state); _set_render_attrs(LV_SVG_RENDER_OBJ(circle), node, state);
return LV_SVG_RENDER_OBJ(circle); return LV_SVG_RENDER_OBJ(circle);
} }
case LV_SVG_TAG_ELLIPSE: { case LV_SVG_TAG_ELLIPSE: {
lv_svg_render_ellipse_t * ellipse = lv_zalloc(sizeof(lv_svg_render_ellipse_t)); lv_svg_render_ellipse_t * ellipse = lv_zalloc(sizeof(lv_svg_render_ellipse_t));
LV_ASSERT_MALLOC(ellipse); LV_ASSERT_MALLOC(ellipse);
ellipse->base.init = _init_obj; ellipse->base.clz = &svg_ellipse_class;
ellipse->base.render = _render_ellipse;
ellipse->base.set_attr = _set_ellipse_attr;
ellipse->base.get_bounds = _get_ellipse_bounds;
ellipse->base.get_size = _get_ellipse_size;
_set_render_attrs(LV_SVG_RENDER_OBJ(ellipse), node, state); _set_render_attrs(LV_SVG_RENDER_OBJ(ellipse), node, state);
return LV_SVG_RENDER_OBJ(ellipse); return LV_SVG_RENDER_OBJ(ellipse);
} }
case LV_SVG_TAG_LINE: { case LV_SVG_TAG_LINE: {
lv_svg_render_line_t * line = lv_zalloc(sizeof(lv_svg_render_line_t)); lv_svg_render_line_t * line = lv_zalloc(sizeof(lv_svg_render_line_t));
LV_ASSERT_MALLOC(line); LV_ASSERT_MALLOC(line);
line->base.init = _init_obj; line->base.clz = &svg_line_class;
line->base.render = _render_line;
line->base.set_attr = _set_line_attr;
line->base.get_bounds = _get_line_bounds;
line->base.get_size = _get_line_size;
_set_render_attrs(LV_SVG_RENDER_OBJ(line), node, state); _set_render_attrs(LV_SVG_RENDER_OBJ(line), node, state);
return LV_SVG_RENDER_OBJ(line); return LV_SVG_RENDER_OBJ(line);
} }
case LV_SVG_TAG_POLYLINE: { case LV_SVG_TAG_POLYLINE: {
lv_svg_render_poly_t * poly = lv_zalloc(sizeof(lv_svg_render_poly_t)); lv_svg_render_poly_t * poly = lv_zalloc(sizeof(lv_svg_render_poly_t));
LV_ASSERT_MALLOC(poly); LV_ASSERT_MALLOC(poly);
poly->base.init = _init_poly; poly->base.clz = &svg_polyline_class;
poly->base.render = _render_poly;
poly->base.set_attr = _set_polyline_attr;
poly->base.get_bounds = _get_poly_bounds;
poly->base.destroy = _destroy_poly;
poly->base.get_size = _get_poly_size;
_set_render_attrs(LV_SVG_RENDER_OBJ(poly), node, state); _set_render_attrs(LV_SVG_RENDER_OBJ(poly), node, state);
return LV_SVG_RENDER_OBJ(poly); return LV_SVG_RENDER_OBJ(poly);
} }
case LV_SVG_TAG_POLYGON: { case LV_SVG_TAG_POLYGON: {
lv_svg_render_poly_t * poly = lv_zalloc(sizeof(lv_svg_render_poly_t)); lv_svg_render_poly_t * poly = lv_zalloc(sizeof(lv_svg_render_poly_t));
LV_ASSERT_MALLOC(poly); LV_ASSERT_MALLOC(poly);
poly->base.init = _init_poly; poly->base.clz = &svg_polygon_class;
poly->base.render = _render_poly;
poly->base.set_attr = _set_polygen_attr;
poly->base.get_bounds = _get_poly_bounds;
poly->base.destroy = _destroy_poly;
poly->base.get_size = _get_poly_size;
_set_render_attrs(LV_SVG_RENDER_OBJ(poly), node, state); _set_render_attrs(LV_SVG_RENDER_OBJ(poly), node, state);
return LV_SVG_RENDER_OBJ(poly); return LV_SVG_RENDER_OBJ(poly);
} }
case LV_SVG_TAG_PATH: { case LV_SVG_TAG_PATH: {
lv_svg_render_poly_t * poly = lv_zalloc(sizeof(lv_svg_render_poly_t)); lv_svg_render_poly_t * poly = lv_zalloc(sizeof(lv_svg_render_poly_t));
LV_ASSERT_MALLOC(poly); LV_ASSERT_MALLOC(poly);
poly->base.init = _init_poly; poly->base.clz = &svg_path_class;
poly->base.render = _render_poly;
poly->base.set_attr = _set_path_attr;
poly->base.get_bounds = _get_poly_bounds;
poly->base.destroy = _destroy_poly;
poly->base.get_size = _get_poly_size;
_set_render_attrs(LV_SVG_RENDER_OBJ(poly), node, state); _set_render_attrs(LV_SVG_RENDER_OBJ(poly), node, state);
return LV_SVG_RENDER_OBJ(poly); return LV_SVG_RENDER_OBJ(poly);
} }
@@ -2050,12 +2144,7 @@ static lv_svg_render_obj_t * _lv_svg_render_create(const lv_svg_node_t * node,
case LV_SVG_TAG_TEXT: { case LV_SVG_TAG_TEXT: {
lv_svg_render_text_t * txt = lv_zalloc(sizeof(lv_svg_render_text_t)); lv_svg_render_text_t * txt = lv_zalloc(sizeof(lv_svg_render_text_t));
LV_ASSERT_MALLOC(txt); LV_ASSERT_MALLOC(txt);
txt->base.init = _init_text; txt->base.clz = &svg_text_class;
txt->base.set_attr = _set_text_attr;
txt->base.render = _render_text;
txt->base.get_bounds = _get_text_bounds;
txt->base.destroy = _destroy_text;
txt->base.get_size = _get_txt_size;
_set_render_attrs(LV_SVG_RENDER_OBJ(txt), node, state); _set_render_attrs(LV_SVG_RENDER_OBJ(txt), node, state);
return LV_SVG_RENDER_OBJ(txt); return LV_SVG_RENDER_OBJ(txt);
} }
@@ -2064,20 +2153,14 @@ static lv_svg_render_obj_t * _lv_svg_render_create(const lv_svg_node_t * node,
LV_ASSERT_MALLOC(span); LV_ASSERT_MALLOC(span);
lv_svg_render_content_t * content = (lv_svg_render_content_t *)span; lv_svg_render_content_t * content = (lv_svg_render_content_t *)span;
content->render_content = _render_span; content->render_content = _render_span;
content->base.init = _init_tspan; content->base.clz = &svg_tspan_class;
content->base.set_attr = _set_tspan_attr;
content->base.get_bounds = _get_tspan_bounds;
content->base.destroy = _destroy_tspan;
content->base.get_size = _get_span_size;
_set_render_attrs(LV_SVG_RENDER_OBJ(span), node, state); _set_render_attrs(LV_SVG_RENDER_OBJ(span), node, state);
return LV_SVG_RENDER_OBJ(span); return LV_SVG_RENDER_OBJ(span);
} }
case LV_SVG_TAG_CONTENT: { case LV_SVG_TAG_CONTENT: {
lv_svg_render_content_t * content = lv_zalloc(sizeof(lv_svg_render_content_t)); lv_svg_render_content_t * content = lv_zalloc(sizeof(lv_svg_render_content_t));
LV_ASSERT_MALLOC(content); LV_ASSERT_MALLOC(content);
content->base.init = _init_content; content->base.clz = &svg_content_class;
content->base.destroy = _destroy_content;
content->base.get_size = _get_content_size;
_set_render_attrs(LV_SVG_RENDER_OBJ(content), node, state); _set_render_attrs(LV_SVG_RENDER_OBJ(content), node, state);
return LV_SVG_RENDER_OBJ(content); return LV_SVG_RENDER_OBJ(content);
} }
@@ -2085,31 +2168,21 @@ static lv_svg_render_obj_t * _lv_svg_render_create(const lv_svg_node_t * node,
case LV_SVG_TAG_IMAGE: { case LV_SVG_TAG_IMAGE: {
lv_svg_render_image_t * image = lv_zalloc(sizeof(lv_svg_render_image_t)); lv_svg_render_image_t * image = lv_zalloc(sizeof(lv_svg_render_image_t));
LV_ASSERT_MALLOC(image); LV_ASSERT_MALLOC(image);
image->base.init = _init_image; image->base.clz = &svg_image_class;
image->base.render = _render_image;
image->base.set_attr = _set_image_attr;
image->base.get_size = _get_image_size;
_set_render_attrs(LV_SVG_RENDER_OBJ(image), node, state); _set_render_attrs(LV_SVG_RENDER_OBJ(image), node, state);
return LV_SVG_RENDER_OBJ(image); return LV_SVG_RENDER_OBJ(image);
} }
case LV_SVG_TAG_USE: { case LV_SVG_TAG_USE: {
lv_svg_render_use_t * use = lv_zalloc(sizeof(lv_svg_render_use_t)); lv_svg_render_use_t * use = lv_zalloc(sizeof(lv_svg_render_use_t));
LV_ASSERT_MALLOC(use); LV_ASSERT_MALLOC(use);
use->base.init = _init_obj; use->base.clz = &svg_use_class;
use->base.set_attr = _set_use_attr;
use->base.render = _render_use;
use->base.destroy = _destroy_use;
use->base.get_size = _get_use_size;
_set_render_attrs(LV_SVG_RENDER_OBJ(use), node, state); _set_render_attrs(LV_SVG_RENDER_OBJ(use), node, state);
return LV_SVG_RENDER_OBJ(use); return LV_SVG_RENDER_OBJ(use);
} }
case LV_SVG_TAG_SOLID_COLOR: { case LV_SVG_TAG_SOLID_COLOR: {
lv_svg_render_solid_t * solid = lv_zalloc(sizeof(lv_svg_render_solid_t)); lv_svg_render_solid_t * solid = lv_zalloc(sizeof(lv_svg_render_solid_t));
LV_ASSERT_MALLOC(solid); LV_ASSERT_MALLOC(solid);
solid->base.init = _init_obj; solid->base.clz = &svg_solid_class;
solid->base.set_attr = _set_solid_attr;
solid->base.set_paint_ref = _set_solid_ref;
solid->base.get_size = _get_solid_size;
_set_render_attrs(LV_SVG_RENDER_OBJ(solid), node, state); _set_render_attrs(LV_SVG_RENDER_OBJ(solid), node, state);
return LV_SVG_RENDER_OBJ(solid); return LV_SVG_RENDER_OBJ(solid);
} }
@@ -2117,27 +2190,20 @@ static lv_svg_render_obj_t * _lv_svg_render_create(const lv_svg_node_t * node,
case LV_SVG_TAG_LINEAR_GRADIENT: { case LV_SVG_TAG_LINEAR_GRADIENT: {
lv_svg_render_gradient_t * grad = lv_zalloc(sizeof(lv_svg_render_gradient_t)); lv_svg_render_gradient_t * grad = lv_zalloc(sizeof(lv_svg_render_gradient_t));
LV_ASSERT_MALLOC(grad); LV_ASSERT_MALLOC(grad);
grad->base.init = _init_gradient; grad->base.clz = &svg_grad_class;
grad->base.set_attr = _set_gradient_attr;
grad->base.set_paint_ref = _set_gradient_ref;
if(node->type == LV_SVG_TAG_LINEAR_GRADIENT) { if(node->type == LV_SVG_TAG_LINEAR_GRADIENT) {
grad->dsc.style = LV_VECTOR_GRADIENT_STYLE_LINEAR; grad->dsc.style = LV_VECTOR_GRADIENT_STYLE_LINEAR;
} }
else { // radial gradient else { // radial gradient
grad->dsc.style = LV_VECTOR_GRADIENT_STYLE_RADIAL; grad->dsc.style = LV_VECTOR_GRADIENT_STYLE_RADIAL;
} }
grad->base.get_size = _get_grad_size;
_set_render_attrs(LV_SVG_RENDER_OBJ(grad), node, state); _set_render_attrs(LV_SVG_RENDER_OBJ(grad), node, state);
return LV_SVG_RENDER_OBJ(grad); return LV_SVG_RENDER_OBJ(grad);
} }
case LV_SVG_TAG_G: { case LV_SVG_TAG_G: {
lv_svg_render_group_t * group = lv_zalloc(sizeof(lv_svg_render_group_t)); lv_svg_render_group_t * group = lv_zalloc(sizeof(lv_svg_render_group_t));
LV_ASSERT_MALLOC(group); LV_ASSERT_MALLOC(group);
group->base.init = _init_group; group->base.clz = &svg_group_class;
group->base.set_attr = _set_attr;
group->base.render = _render_group;
group->base.destroy = _destroy_group;
group->base.get_size = _get_group_size;
_set_render_attrs(LV_SVG_RENDER_OBJ(group), node, state); _set_render_attrs(LV_SVG_RENDER_OBJ(group), node, state);
return LV_SVG_RENDER_OBJ(group); return LV_SVG_RENDER_OBJ(group);
} }
@@ -2330,8 +2396,8 @@ void lv_svg_render_delete(lv_svg_render_obj_t * list)
_deinit_draw_dsc(&(obj->dsc)); _deinit_draw_dsc(&(obj->dsc));
if(obj->destroy) { if(obj->clz->destroy) {
obj->destroy(obj); obj->clz->destroy(obj);
} }
if(obj->id) { if(obj->id) {
lv_free(obj->id); lv_free(obj->id);
@@ -2355,8 +2421,8 @@ uint32_t lv_svg_render_get_size(const lv_svg_render_obj_t * render)
uint32_t size = 0; uint32_t size = 0;
const lv_svg_render_obj_t * cur = render; const lv_svg_render_obj_t * cur = render;
while(cur) { while(cur) {
if(cur->get_size) { if(cur->clz->get_size) {
cur->get_size(cur, &size); cur->clz->get_size(cur, &size);
} }
cur = cur->next; cur = cur->next;
} }
@@ -2371,9 +2437,9 @@ void lv_draw_svg_render(lv_vector_dsc_t * dsc, const lv_svg_render_obj_t * rende
const lv_svg_render_obj_t * cur = render; const lv_svg_render_obj_t * cur = render;
while(cur) { while(cur) {
if(cur->render && ((cur->flags & 3) == _RENDER_NORMAL)) { if(cur->clz->render && ((cur->flags & 3) == _RENDER_NORMAL)) {
_prepare_render(cur, dsc); _prepare_render(cur, dsc);
cur->render(cur, dsc, NULL); cur->clz->render(cur, dsc, NULL);
} }
cur = cur->next; cur = cur->next;
} }
+6 -1
View File
@@ -29,6 +29,7 @@
/********************** /**********************
* TYPEDEFS * TYPEDEFS
**********************/ **********************/
struct _lv_svg_render_class;
typedef struct _lv_svg_render_obj { typedef struct _lv_svg_render_obj {
struct _lv_svg_render_obj * next; struct _lv_svg_render_obj * next;
@@ -42,6 +43,10 @@ typedef struct _lv_svg_render_obj {
struct _lv_svg_render_obj * head; struct _lv_svg_render_obj * head;
char * fill_ref; char * fill_ref;
char * stroke_ref; char * stroke_ref;
struct _lv_svg_render_class * clz;
} lv_svg_render_obj_t;
typedef struct _lv_svg_render_class {
void (*set_paint_ref)(struct _lv_svg_render_obj * obj, lv_vector_draw_dsc_t * dsc, void (*set_paint_ref)(struct _lv_svg_render_obj * obj, lv_vector_draw_dsc_t * dsc,
const struct _lv_svg_render_obj * target_obj, bool fill); const struct _lv_svg_render_obj * target_obj, bool fill);
@@ -51,7 +56,7 @@ typedef struct _lv_svg_render_obj {
void (*get_bounds)(const struct _lv_svg_render_obj * obj, lv_area_t * area); void (*get_bounds)(const struct _lv_svg_render_obj * obj, lv_area_t * area);
void (*get_size)(const struct _lv_svg_render_obj * obj, uint32_t * size); void (*get_size)(const struct _lv_svg_render_obj * obj, uint32_t * size);
void (*destroy)(struct _lv_svg_render_obj * obj); void (*destroy)(struct _lv_svg_render_obj * obj);
} lv_svg_render_obj_t; } lv_svg_render_class;
typedef struct _lv_svg_render_hal { typedef struct _lv_svg_render_hal {
void (*load_image)(const char * image_url, lv_draw_image_dsc_t * img_dsc); void (*load_image)(const char * image_url, lv_draw_image_dsc_t * img_dsc);