1 /**
2  * @file lv_svg.h
3  *
4  */
5 
6 #ifndef LV_SVG_H
7 #define LV_SVG_H
8 
9 /*********************
10  *      INCLUDES
11  *********************/
12 #include "../../lv_conf_internal.h"
13 #if LV_USE_SVG
14 
15 #include "../../misc/lv_array.h"
16 #include "../../misc/lv_tree.h"
17 /*********************
18  *      DEFINES
19  *********************/
20 
21 /**********************
22  *      TYPEDEFS
23  **********************/
24 enum {
25     LV_SVG_TAG_INVALID = -1,
26     LV_SVG_TAG_CONTENT,
27     LV_SVG_TAG_SVG,
28     LV_SVG_TAG_USE,
29     LV_SVG_TAG_G,
30     LV_SVG_TAG_PATH,
31     LV_SVG_TAG_RECT,
32     LV_SVG_TAG_CIRCLE,
33     LV_SVG_TAG_ELLIPSE,
34     LV_SVG_TAG_LINE,
35     LV_SVG_TAG_POLYLINE,
36     LV_SVG_TAG_POLYGON,
37     LV_SVG_TAG_SOLID_COLOR,
38     LV_SVG_TAG_LINEAR_GRADIENT,
39     LV_SVG_TAG_RADIAL_GRADIENT,
40     LV_SVG_TAG_STOP,
41     LV_SVG_TAG_DEFS,
42     LV_SVG_TAG_IMAGE,
43 #if LV_USE_SVG_ANIMATION
44     LV_SVG_TAG_MPATH,
45     LV_SVG_TAG_SET,
46     LV_SVG_TAG_ANIMATE,
47     LV_SVG_TAG_ANIMATE_COLOR,
48     LV_SVG_TAG_ANIMATE_TRANSFORM,
49     LV_SVG_TAG_ANIMATE_MOTION,
50 #endif
51     LV_SVG_TAG_TEXT,
52     LV_SVG_TAG_TSPAN,
53     LV_SVG_TAG_TEXT_AREA,
54 };
55 typedef int8_t lv_svg_tag_t;
56 
57 enum {
58     LV_SVG_ATTR_INVALID = 0,
59     LV_SVG_ATTR_ID,
60     LV_SVG_ATTR_XML_ID,
61     LV_SVG_ATTR_VERSION,
62     LV_SVG_ATTR_BASE_PROFILE,
63     LV_SVG_ATTR_VIEWBOX,
64     LV_SVG_ATTR_PRESERVE_ASPECT_RATIO,
65     LV_SVG_ATTR_VIEWPORT_FILL,
66     LV_SVG_ATTR_VIEWPORT_FILL_OPACITY,
67     LV_SVG_ATTR_DISPLAY,
68     LV_SVG_ATTR_VISIBILITY,
69     LV_SVG_ATTR_X,
70     LV_SVG_ATTR_Y,
71     LV_SVG_ATTR_WIDTH,
72     LV_SVG_ATTR_HEIGHT,
73     LV_SVG_ATTR_RX,
74     LV_SVG_ATTR_RY,
75     LV_SVG_ATTR_CX,
76     LV_SVG_ATTR_CY,
77     LV_SVG_ATTR_R,
78     LV_SVG_ATTR_X1,
79     LV_SVG_ATTR_Y1,
80     LV_SVG_ATTR_X2,
81     LV_SVG_ATTR_Y2,
82     LV_SVG_ATTR_POINTS,
83     LV_SVG_ATTR_D,
84     LV_SVG_ATTR_PATH_LENGTH,
85     LV_SVG_ATTR_XLINK_HREF,
86     LV_SVG_ATTR_FILL,
87     LV_SVG_ATTR_FILL_RULE,
88     LV_SVG_ATTR_FILL_OPACITY,
89     LV_SVG_ATTR_STROKE,
90     LV_SVG_ATTR_STROKE_WIDTH,
91     LV_SVG_ATTR_STROKE_LINECAP,
92     LV_SVG_ATTR_STROKE_LINEJOIN,
93     LV_SVG_ATTR_STROKE_MITER_LIMIT,
94     LV_SVG_ATTR_STROKE_DASH_ARRAY,
95     LV_SVG_ATTR_STROKE_DASH_OFFSET,
96     LV_SVG_ATTR_STROKE_OPACITY,
97     LV_SVG_ATTR_OPACITY,
98     LV_SVG_ATTR_SOLID_COLOR,
99     LV_SVG_ATTR_SOLID_OPACITY,
100     LV_SVG_ATTR_GRADIENT_UNITS,
101     LV_SVG_ATTR_GRADIENT_STOP_OFFSET,
102     LV_SVG_ATTR_GRADIENT_STOP_COLOR,
103     LV_SVG_ATTR_GRADIENT_STOP_OPACITY,
104     LV_SVG_ATTR_FONT_FAMILY,
105     LV_SVG_ATTR_FONT_STYLE,
106     LV_SVG_ATTR_FONT_VARIANT,
107     LV_SVG_ATTR_FONT_WEIGHT,
108     LV_SVG_ATTR_FONT_SIZE,
109     LV_SVG_ATTR_TRANSFORM,
110     LV_SVG_ATTR_TEXT_ANCHOR,
111 #if LV_USE_SVG_ANIMATION
112     LV_SVG_ATTR_ATTRIBUTE_NAME,
113     LV_SVG_ATTR_ATTRIBUTE_TYPE,
114     LV_SVG_ATTR_BEGIN,
115     LV_SVG_ATTR_END,
116     LV_SVG_ATTR_DUR,
117     LV_SVG_ATTR_MIN,
118     LV_SVG_ATTR_MAX,
119     LV_SVG_ATTR_RESTART,
120     LV_SVG_ATTR_REPEAT_COUNT,
121     LV_SVG_ATTR_REPEAT_DUR,
122     LV_SVG_ATTR_CALC_MODE,
123     LV_SVG_ATTR_VALUES,
124     LV_SVG_ATTR_KEY_TIMES,
125     LV_SVG_ATTR_KEY_SPLINES,
126     LV_SVG_ATTR_KEY_POINTS,
127     LV_SVG_ATTR_FROM,
128     LV_SVG_ATTR_TO,
129     LV_SVG_ATTR_BY,
130     LV_SVG_ATTR_ADDITIVE,
131     LV_SVG_ATTR_ACCUMULATE,
132     LV_SVG_ATTR_PATH,
133     LV_SVG_ATTR_ROTATE,
134     LV_SVG_ATTR_TRANSFORM_TYPE,
135 #endif
136 };
137 typedef uint8_t lv_svg_attr_type_t;
138 
139 enum {
140     LV_SVG_TRANSFORM_TYPE_MATRIX = 1,
141     LV_SVG_TRANSFORM_TYPE_TRANSLATE,
142     LV_SVG_TRANSFORM_TYPE_ROTATE,
143     LV_SVG_TRANSFORM_TYPE_SCALE,
144     LV_SVG_TRANSFORM_TYPE_SKEW_X,
145     LV_SVG_TRANSFORM_TYPE_SKEW_Y,
146 };
147 typedef uint8_t lv_svg_transform_type_t;
148 
149 #if LV_USE_SVG_ANIMATION
150 enum {
151     LV_SVG_ANIM_REMOVE = 0,
152     LV_SVG_ANIM_FREEZE,
153 };
154 
155 enum {
156     LV_SVG_ANIM_RESTART_ALWAYS = 0,
157     LV_SVG_ANIM_RESTART_WHEN_NOT_ACTIVE,
158     LV_SVG_ANIM_RESTART_NEVER,
159 };
160 
161 enum {
162     LV_SVG_ANIM_CALC_MODE_LINEAR = 0,
163     LV_SVG_ANIM_CALC_MODE_PACED,
164     LV_SVG_ANIM_CALC_MODE_SPLINE,
165     LV_SVG_ANIM_CALC_MODE_DISCRETE,
166 };
167 
168 enum {
169     LV_SVG_ANIM_ADDITIVE_REPLACE = 0,
170     LV_SVG_ANIM_ADDITIVE_SUM,
171 };
172 
173 enum {
174     LV_SVG_ANIM_ACCUMULATE_NONE = 0,
175     LV_SVG_ANIM_ACCUMULATE_SUM,
176 };
177 #endif
178 
179 enum {
180     LV_SVG_ASPECT_RATIO_NONE = 0,
181     LV_SVG_ASPECT_RATIO_XMIN_YMIN = (1 << 1),
182     LV_SVG_ASPECT_RATIO_XMID_YMIN = (2 << 1),
183     LV_SVG_ASPECT_RATIO_XMAX_YMIN = (3 << 1),
184     LV_SVG_ASPECT_RATIO_XMIN_YMID = (4 << 1),
185     LV_SVG_ASPECT_RATIO_XMID_YMID = (5 << 1),
186     LV_SVG_ASPECT_RATIO_XMAX_YMID = (6 << 1),
187     LV_SVG_ASPECT_RATIO_XMIN_YMAX = (7 << 1),
188     LV_SVG_ASPECT_RATIO_XMID_YMAX = (8 << 1),
189     LV_SVG_ASPECT_RATIO_XMAX_YMAX = (9 << 1),
190 };
191 
192 enum {
193     LV_SVG_ASPECT_RATIO_OPT_MEET = 0,
194     LV_SVG_ASPECT_RATIO_OPT_SLICE,
195 };
196 typedef uint32_t lv_svg_aspect_ratio_t;
197 
198 typedef struct {
199     float x;
200     float y;
201 } lv_svg_point_t;
202 
203 typedef struct {
204     float m[3][3];
205 } lv_svg_matrix_t;
206 
207 typedef uint32_t lv_svg_color_t;
208 
209 enum {
210     LV_SVG_FILL_NONZERO = 0,
211     LV_SVG_FILL_EVENODD,
212 };
213 typedef uint8_t lv_svg_fill_rule_t;
214 
215 enum {
216     LV_SVG_LINE_CAP_BUTT = 0,
217     LV_SVG_LINE_CAP_SQUARE,
218     LV_SVG_LINE_CAP_ROUND,
219 };
220 typedef uint8_t lv_svg_line_cap_t;
221 
222 enum {
223     LV_SVG_LINE_JOIN_MITER = 0,
224     LV_SVG_LINE_JOIN_BEVEL,
225     LV_SVG_LINE_JOIN_ROUND,
226 };
227 typedef uint8_t lv_svg_line_join_t;
228 
229 enum {
230     LV_SVG_GRADIENT_UNITS_OBJECT = 0,
231     LV_SVG_GRADIENT_UNITS_USER_SPACE,
232 };
233 typedef uint8_t lv_svg_gradient_units_t;
234 
235 typedef union {
236     int32_t ival;
237     uint32_t uval;
238     float fval;
239     char * sval;
240     void * val;
241 } lv_svg_attr_value_t;
242 
243 /*
244  * to simplify list buffer management, allocate enough memory for all data and length.
245  * | size | data[0] | data[1] | data[2] | ... |
246  */
247 typedef struct {
248     uint32_t length;
249     uint8_t data[1];
250 } lv_svg_attr_values_list_t;
251 
252 /* https://www.w3.org/TR/SVGTiny12/svgudomidl.html */
253 enum {
254     LV_SVG_PATH_CMD_MOVE_TO = 77,
255     LV_SVG_PATH_CMD_LINE_TO = 76,
256     LV_SVG_PATH_CMD_CURVE_TO = 67,
257     LV_SVG_PATH_CMD_QUAD_TO = 81,
258     LV_SVG_PATH_CMD_CLOSE = 90,
259 };
260 
261 /*
262  * to simplify list buffer management, allocate enough memory for all path data and cmd.
263  * | cmd | data[0] | data[1] | data[2] | ... |
264  */
265 typedef struct {
266     uint32_t cmd;
267     uint8_t data[1];
268 } lv_svg_attr_path_value_t;
269 
270 enum {
271     LV_SVG_ATTR_VALUE_DATA = 0,
272     LV_SVG_ATTR_VALUE_PTR,
273 };
274 typedef uint8_t lv_svg_attr_value_type_t;
275 
276 enum {
277     LV_SVG_ATTR_VALUE_NONE = 0,
278     LV_SVG_ATTR_VALUE_INITIAL,
279     LV_SVG_ATTR_VALUE_INHERIT,
280 };
281 typedef uint8_t lv_svg_attr_value_class_t;
282 
283 typedef struct {
284     lv_svg_attr_type_t id;
285     lv_svg_attr_value_type_t val_type;
286     lv_svg_attr_value_class_t class_type;
287     lv_svg_attr_value_t value;
288 } lv_svg_attr_t;
289 
290 struct _lv_svg_render_obj;
291 
292 typedef struct {
293     lv_tree_node_t base;
294     char * xml_id; /* xml_id or content */
295     lv_svg_tag_t type;
296     lv_array_t attrs;
297     struct _lv_svg_render_obj * render_obj;
298 } lv_svg_node_t;
299 
300 /**********************
301  * GLOBAL PROTOTYPES
302  **********************/
303 
304 /**
305  * @brief Loading SVG data and creating the DOM tree
306  * @param svg_data pointer to the SVG data
307  * @param data_len the SVG data length
308  */
309 lv_svg_node_t * lv_svg_load_data(const char * svg_data, uint32_t data_len);
310 
311 /**
312  * @brief Create an SVG DOM node
313  * @param parent pointer to the parent node
314  * @return true: an new SVG DOM node, false: NULL
315  */
316 lv_svg_node_t * lv_svg_node_create(lv_svg_node_t * parent);
317 
318 /**
319  * @brief Delete an SVG DOM subtree
320  * @param node pointer to an SVG DOM subtree
321  */
322 void lv_svg_node_delete(lv_svg_node_t * node);
323 
324 /**********************
325  *      MACROS
326  **********************/
327 #define LV_SVG_NODE_CHILD(n, i) \
328     ((lv_svg_node_t *)(LV_TREE_NODE((n))->children[i]))
329 
330 #define LV_SVG_NODE(n) ((lv_svg_node_t*)(n))
331 
332 #endif /*LV_USE_SVG*/
333 
334 #endif /*LV_SVG_H*/
335