1 /**
2 * @file lv_svg.c
3 *
4 */
5
6 /*********************
7 * INCLUDES
8 *********************/
9 #include "lv_svg.h"
10 #if LV_USE_SVG
11
12 #include "../../misc/lv_assert.h"
13 #include "../../misc/lv_log.h"
14 #include "../../stdlib/lv_mem.h"
15
16 #include "lv_svg_token.h"
17 #include "lv_svg_parser.h"
18
19 /*********************
20 * DEFINES
21 *********************/
22
23 /**********************
24 * TYPEDEFS
25 **********************/
26
27 /**********************
28 * STATIC PROTOTYPES
29 **********************/
lv_svg_node_constructor(const lv_tree_class_t * class_p,lv_tree_node_t * node)30 static void lv_svg_node_constructor(const lv_tree_class_t * class_p, lv_tree_node_t * node)
31 {
32 LV_UNUSED(class_p);
33 lv_svg_node_t * t = (lv_svg_node_t *)node;
34 t->xml_id = NULL;
35 t->type = LV_SVG_TAG_INVALID;
36 lv_array_init(&t->attrs, 4, sizeof(lv_svg_attr_t));
37 t->render_obj = NULL;
38 }
39
lv_svg_node_destructor(const lv_tree_class_t * class_p,lv_tree_node_t * node)40 static void lv_svg_node_destructor(const lv_tree_class_t * class_p, lv_tree_node_t * node)
41 {
42 LV_UNUSED(class_p);
43 lv_svg_node_t * t = (lv_svg_node_t *)node;
44 if(t->xml_id) {
45 lv_free(t->xml_id);
46 }
47 for(uint32_t i = 0; i < lv_array_size(&t->attrs); i++) {
48 lv_svg_attr_t * attr = lv_array_at(&t->attrs, i);
49 if(attr->val_type == LV_SVG_ATTR_VALUE_PTR) {
50 lv_free(attr->value.val);
51 }
52 }
53 lv_array_deinit(&t->attrs);
54 }
55
svg_token_process_cb(_lv_svg_token_t * token,void * data)56 static bool svg_token_process_cb(_lv_svg_token_t * token, void * data)
57 {
58 _lv_svg_parser_t * parser = (_lv_svg_parser_t *)data;
59 return _lv_svg_parser_token(parser, token);
60 }
61
62 /**********************
63 * STATIC VARIABLES
64 **********************/
65 const lv_tree_class_t lv_svg_node_class = {
66 .base_class = &lv_tree_node_class,
67 .instance_size = sizeof(lv_svg_node_t),
68 .constructor_cb = lv_svg_node_constructor,
69 .destructor_cb = lv_svg_node_destructor,
70 };
71
72 /**********************
73 * MACROS
74 **********************/
75
76 /**********************
77 * GLOBAL FUNCTIONS
78 **********************/
lv_svg_load_data(const char * svg_data,uint32_t data_len)79 lv_svg_node_t * lv_svg_load_data(const char * svg_data, uint32_t data_len)
80 {
81 LV_ASSERT_NULL(svg_data);
82 LV_ASSERT(data_len > 0);
83
84 _lv_svg_parser_t parser;
85 _lv_svg_parser_init(&parser);
86
87 if(_lv_svg_tokenizer(svg_data, data_len, svg_token_process_cb, &parser)) {
88 if(_lv_svg_parser_is_finish(&parser)) {
89 lv_svg_node_t * doc = parser.doc_root;
90 parser.doc_root = NULL;
91 _lv_svg_parser_deinit(&parser);
92 #if LV_USE_SVG_DEBUG
93 _lv_svg_dump_tree(doc, 0);
94 #endif
95 return doc;
96 }
97 else {
98 _lv_svg_parser_deinit(&parser);
99 LV_LOG_ERROR("svg document parser raise errors!");
100 return NULL;
101 }
102 }
103 else {
104 _lv_svg_parser_deinit(&parser);
105 LV_LOG_ERROR("svg document tokenizer raise errors!");
106 return NULL;
107 }
108 }
109
lv_svg_node_create(lv_svg_node_t * parent)110 lv_svg_node_t * lv_svg_node_create(lv_svg_node_t * parent)
111 {
112 lv_tree_node_t * node = lv_tree_node_create(&lv_svg_node_class, (lv_tree_node_t *)parent);
113 return (lv_svg_node_t *)node;
114 }
115
lv_svg_node_delete(lv_svg_node_t * node)116 void lv_svg_node_delete(lv_svg_node_t * node)
117 {
118 lv_tree_node_delete((lv_tree_node_t *)node);
119 }
120
121 /**********************
122 * STATIC FUNCTIONS
123 **********************/
124 #endif /*LV_USE_SVG*/
125