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