1 #if LV_BUILD_TEST
2 #include "../lvgl.h"
3 #include "lv_test_helpers.h"
4 #include <string.h>
5 
6 #include "unity/unity.h"
7 
8 static lv_layer_t layer;
9 static lv_obj_t * canvas;
10 static lv_draw_buf_t * canvas_buf;
11 
setUp(void)12 void setUp(void)
13 {
14     canvas = lv_canvas_create(lv_scr_act());
15     canvas_buf = lv_draw_buf_create(480, 480, LV_COLOR_FORMAT_ARGB8888, 0);
16     TEST_ASSERT_NOT_NULL(canvas_buf);
17     lv_canvas_set_draw_buf(canvas, canvas_buf);
18     lv_canvas_fill_bg(canvas, lv_color_make(0xff, 0xff, 0xff), 255);
19     lv_canvas_init_layer(canvas, &layer);
20 }
21 
tearDown(void)22 void tearDown(void)
23 {
24     lv_image_cache_drop(canvas_buf);
25     lv_draw_buf_destroy(canvas_buf);
26     lv_obj_del(canvas);
27 }
28 
29 #if LV_USE_VECTOR_GRAPHIC && LV_USE_SVG
30 
31 #define SNAPSHOT_NAME(n) (#n)
32 
draw_snapshot(const char * name)33 static void draw_snapshot(const char * name)
34 {
35     LV_UNUSED(name);
36 #ifndef NON_AMD64_BUILD
37     char fn_buf[64];
38     lv_snprintf(fn_buf, sizeof(fn_buf), "draw/svg_draw_%s.lp64.png", name);
39     TEST_ASSERT_EQUAL_SCREENSHOT(fn_buf);
40 #else
41     char fn_buf[64];
42     lv_snprintf(fn_buf, sizeof(fn_buf), "draw/svg_draw_%s.lp32.png", name);
43     TEST_ASSERT_EQUAL_SCREENSHOT(fn_buf);
44 #endif
45 }
46 
draw_svg(lv_svg_node_t * svg)47 static void draw_svg(lv_svg_node_t * svg)
48 {
49     lv_image_cache_drop(canvas_buf);
50     lv_canvas_set_draw_buf(canvas, canvas_buf);
51     lv_canvas_fill_bg(canvas, lv_color_make(0xff, 0xff, 0xff), 255);
52     lv_draw_svg(&layer, svg);
53     lv_canvas_finish_layer(canvas, &layer);
54 }
55 
test_draw_group(void)56 void test_draw_group(void)
57 {
58     const char * svg_group_1 = \
59                                "<svg><g fill=\"#FF0000\">"
60                                "<rect x=\"0\" y=\"0\" width=\"100\" height=\"100\"/>"
61                                "<circle cx=\"100\" cy=\"100\" r=\"50\"/>"
62                                "<ellipse fill=\"#00F\" cx=\"200\" cy=\"200\" rx=\"100\" ry=50/>"
63                                "</g></svg>";
64 
65     lv_svg_node_t * svg = lv_svg_load_data(svg_group_1, lv_strlen(svg_group_1));
66     TEST_ASSERT_NOT_EQUAL(NULL, svg);
67     draw_svg(svg);
68     draw_snapshot(SNAPSHOT_NAME(svg_group_1));
69     lv_svg_node_delete(svg);
70 
71     const char * svg_group_2 = \
72                                "<svg><g fill=\"blue\"><g>"
73                                "<rect width=\"100\" height=\"100\" fill=\"inherit\"/>"
74                                "<circle cx=\"200\" cy=\"200\" r=\"50\" fill=\"green\"/>"
75                                "</g></g></svg>";
76 
77     svg = lv_svg_load_data(svg_group_2, lv_strlen(svg_group_2));
78     TEST_ASSERT_NOT_EQUAL(NULL, svg);
79     draw_svg(svg);
80     draw_snapshot(SNAPSHOT_NAME(svg_group_2));
81     lv_svg_node_delete(svg);
82 
83     const char * svg_group_3 = \
84                                "<svg><use xlink:href=\"#g1\" x=50 y=50/>"
85                                "<g fill=\"blue\" xml:id=\"g1\">"
86                                "<rect width=20 height=20/>"
87                                "<rect x=30 width=20 height=20 fill=green/>"
88                                "</g></svg>";
89 
90     svg = lv_svg_load_data(svg_group_3, lv_strlen(svg_group_3));
91     TEST_ASSERT_NOT_EQUAL(NULL, svg);
92     draw_svg(svg);
93     draw_snapshot(SNAPSHOT_NAME(svg_group_3));
94     lv_svg_node_delete(svg);
95 
96     const char * svg_group_4 = \
97                                "<svg><defs><linearGradient id=\"s1\">"
98                                "<stop offset=\"0.1\" stop-color=\"red\"/>"
99                                "<stop offset=\"0.8\" stop-color=\"green\"/>"
100                                "</linearGradient></defs>"
101                                "<g fill=\"url(#s1)\" id=\"g1\">"
102                                "<rect width=20 height=20/><g>"
103                                "<rect x=30 width=20 height=20 fill=blue/>"
104                                "<rect x=30 x=80 y= 30 width=20 height =20 fill=red/></g></g>"
105                                "<use xlink:href=\"#g1\" x=150 y=100/>"
106                                "<use xlink:href=\"#g1\" x=250 y=100/></svg>";
107 
108     svg = lv_svg_load_data(svg_group_4, lv_strlen(svg_group_4));
109     TEST_ASSERT_NOT_EQUAL(NULL, svg);
110     draw_svg(svg);
111     draw_snapshot(SNAPSHOT_NAME(svg_group_4));
112     lv_svg_node_delete(svg);
113 
114 }
115 
load_image(const char * image_url,lv_draw_image_dsc_t * img_dsc)116 static void load_image(const char * image_url, lv_draw_image_dsc_t * img_dsc)
117 {
118     if(strcmp(image_url, "cogwheel.bin") == 0) {
119         LV_IMAGE_DECLARE(test_image_cogwheel_argb8888);
120         img_dsc->header = test_image_cogwheel_argb8888.header;
121         img_dsc->src = &test_image_cogwheel_argb8888;
122     }
123 }
124 
get_font_path(const char * font_family)125 static const char * get_font_path(const char * font_family)
126 {
127     LV_UNUSED(font_family);
128 #ifndef TEST_FONT_PATH
129     return "./src/test_files/fonts/noto/NotoSansSC-Regular.ttf";
130 #else
131     return TEST_FONT_PATH;
132 #endif
133 }
134 
135 const lv_svg_render_hal_t hal = {
136     .load_image = load_image,
137     .get_font_path = get_font_path,
138 };
139 
test_draw_shapes(void)140 void test_draw_shapes(void)
141 {
142     lv_svg_render_init(&hal);
143     const char * svg_shapes_1 = \
144                                 "<svg><rect fill=\"red\" x=\"0\" y=\"0\" width=\"100\" height=\"100\"/>"
145                                 "<circle fill=\"red\" cx=\"100\" cy=\"100\" r=\"50\"/>"
146                                 "<ellipse stroke=\"red\" fill=\"none\" cx=\"200\" cy=\"200\" rx=\"100\" ry=50/>"
147                                 "</svg>";
148 
149     lv_svg_node_t * svg = lv_svg_load_data(svg_shapes_1, lv_strlen(svg_shapes_1));
150     TEST_ASSERT_NOT_EQUAL(NULL, svg);
151     draw_svg(svg);
152     draw_snapshot(SNAPSHOT_NAME(svg_shapes_1));
153     lv_svg_node_delete(svg);
154 
155     const char * svg_shapes_2 = \
156                                 "<svg>"
157                                 "<rect fill=\"rgb(0, 0, 200)\" x=\"0\" y=\"0\" width=\"100\" height=\"100\""
158                                 " transform=\"translate(50, 50) rotate(45) translate(-50, -50)\"/>"
159                                 "</svg>";
160 
161     svg = lv_svg_load_data(svg_shapes_2, lv_strlen(svg_shapes_2));
162     TEST_ASSERT_NOT_EQUAL(NULL, svg);
163     draw_svg(svg);
164     draw_snapshot(SNAPSHOT_NAME(svg_shapes_2));
165     lv_svg_node_delete(svg);
166 
167     const char * svg_shapes_3 = \
168                                 "<svg width=\"4cm\" height=\"2cm\" viewBox=\"0 0 400 200\">"
169                                 "<defs><linearGradient xml:id=\"MyGradient\">"
170                                 "<stop offset=\"0.05\" stop-color=\"#F60\"/>"
171                                 "<stop offset=\"0.95\" stop-color=\"#FF6\"/>"
172                                 "</linearGradient></defs>"
173                                 "<rect fill=\"url(#MyGradient)\" stroke=\"black\" stroke-width=\"5\""
174                                 " x=\"100\" y=\"100\" width=\"600\" height=\"200\"/>"
175                                 "</svg>";
176 
177     svg = lv_svg_load_data(svg_shapes_3, lv_strlen(svg_shapes_3));
178     TEST_ASSERT_NOT_EQUAL(NULL, svg);
179     draw_svg(svg);
180     draw_snapshot(SNAPSHOT_NAME(svg_shapes_3));
181     lv_svg_node_delete(svg);
182 
183     const char * svg_shapes_4 = \
184                                 "<svg width=\"480\" height=\"360\" viewBox=\"0 0 480 360\">"
185                                 "<defs><solidColor xml:id=\"solidMaroon\" solid-color=\"maroon\" solid-opacity=\"0.7\"/>"
186                                 "</defs><g>"
187                                 "<circle transform=\"translate(100, 150)\" fill=\"url(#solidMaroon)\" r=\"30\"/>"
188                                 "<rect fill=\"url(#solidMaroon)\" transform=\"translate(190, 150)\" x=\"-30\" y=\"-30\" width=\"60\" height=\"60\"/>"
189                                 "<path fill=\"url(#solidMaroon)\" transform=\"translate(270, 150)\"  d=\"M 0 -30 L 30 30 L -30 30 Z\" />"
190                                 "<text fill=\"url(#solidMaroon)\" transform=\"translate(340, 150)\" "
191                                 "y=\"21\" font-weight=\"bold\" font-size=\"60\">A</text>"
192                                 "</g></svg>";
193 
194     svg = lv_svg_load_data(svg_shapes_4, lv_strlen(svg_shapes_4));
195     TEST_ASSERT_NOT_EQUAL(NULL, svg);
196     draw_svg(svg);
197     draw_snapshot(SNAPSHOT_NAME(svg_shapes_4));
198     lv_svg_node_delete(svg);
199 
200     const char * svg_shapes_5 = \
201                                 "<svg width=\"8cm\" height=\"4cm\" viewBox=\"0 0 800 400\">"
202                                 "<defs><radialGradient id=\"MyGradient\" gradientUnits=\"userSpaceOnUse\""
203                                 "  cx=\"400\" cy=\"200\" r=\"300\">"
204                                 "<stop offset=\"0.2\" stop-color=\"black\"/>"
205                                 "<stop offset=\"0.75\" stop-color=\"white\"/>"
206                                 "</radialGradient></defs>"
207                                 "<rect fill=\"url(#MyGradient)\" stroke=\"black\" stroke-width=\"5\""
208                                 " x=\"100\" y=\"100\" width=\"600\" height=\"200\"/></svg>";
209 
210     svg = lv_svg_load_data(svg_shapes_5, lv_strlen(svg_shapes_5));
211     TEST_ASSERT_NOT_EQUAL(NULL, svg);
212     draw_svg(svg);
213     draw_snapshot(SNAPSHOT_NAME(svg_shapes_5));
214     lv_svg_node_delete(svg);
215 
216     const char * svg_shapes_6 = \
217                                 "<svg width=\"8cm\" height=\"4cm\" viewBox=\"0 0 800 400\">"
218                                 "<defs><radialGradient id=\"MyGradient\">"
219                                 "<stop offset=\"0.2\" stop-color=\"white\"/>"
220                                 "<stop offset=\"0.75\" stop-color=\"black\"/>"
221                                 "</radialGradient></defs>"
222                                 "<rect fill=\"url(#MyGradient)\" stroke=\"black\" stroke-width=\"5\""
223                                 "x=\"100\" y=\"100\" width=\"300\" height=\"300\"/></svg>";
224 
225     svg = lv_svg_load_data(svg_shapes_6, lv_strlen(svg_shapes_6));
226     TEST_ASSERT_NOT_EQUAL(NULL, svg);
227     draw_svg(svg);
228     draw_snapshot(SNAPSHOT_NAME(svg_shapes_6));
229     lv_svg_node_delete(svg);
230 
231     const char * svg_shapes_7 = \
232                                 "<svg width=\"8cm\" height=\"4cm\" viewBox=\"0 0 800 400\">"
233                                 "<defs><linearGradient xml:id=\"MyGradient\" x1=0 y1=0 x2=500 y2=350 gradientUnits=\"userSpaceOnUse\">"
234                                 "<stop offset=\"0.05\" stop-color=\"#F60\"/>"
235                                 "<stop offset=\"0.95\" stop-color=\"#FF6\"/>"
236                                 "</linearGradient></defs>"
237                                 "<rect fill=\"url(#MyGradient)\" stroke=\"black\" stroke-width=\"5\""
238                                 " x=\"100\" y=\"100\" width=\"600\" height=\"200\"/></svg>";
239 
240     svg = lv_svg_load_data(svg_shapes_7, lv_strlen(svg_shapes_7));
241     TEST_ASSERT_NOT_EQUAL(NULL, svg);
242     draw_svg(svg);
243     draw_snapshot(SNAPSHOT_NAME(svg_shapes_7));
244     lv_svg_node_delete(svg);
245 
246     const char * svg_shapes_8 = \
247                                 "<svg width=\"7cm\" height=\"2cm\" viewBox=\"0 0 700 200\">"
248                                 "<g><defs><linearGradient id=\"MyGradient\" gradientUnits=\"objectBoundingBox\">"
249                                 "<stop offset=\"0\" stop-color=\"#F60\"/>"
250                                 "<stop offset=\"1\" stop-color=\"#FF6\"/>"
251                                 "</linearGradient></defs>"
252                                 "<rect x=\"1\" y=\"1\" width=\"698\" height=\"198\" fill=\"none\" stroke=\"blue\" stroke-width=\"2\"/>"
253                                 "<g fill=\"url(#MyGradient)\">"
254                                 "<rect x=\"100\" y=\"50\" width=\"200\" height=\"100\"/>"
255                                 "<rect x=\"400\" y=\"50\" width=\"200\" height=\"100\"/>"
256                                 "</g></g></svg>";
257 
258     svg = lv_svg_load_data(svg_shapes_8, lv_strlen(svg_shapes_8));
259     TEST_ASSERT_NOT_EQUAL(NULL, svg);
260     draw_svg(svg);
261     draw_snapshot(SNAPSHOT_NAME(svg_shapes_8));
262     lv_svg_node_delete(svg);
263 
264     const char * svg_shapes_9 = \
265                                 "<svg width=\"8cm\" height=\"4cm\" viewBox=\"0 0 800 400\">"
266                                 "<g><defs><linearGradient id=\"MyGradient\" gradientUnits=\"userSpaceOnUse\""
267                                 " x1=0 y1=0 x2=350 y2=350>"
268                                 "<stop offset=\"0\" stop-color=\"red\"/>"
269                                 "<stop offset=\"0.5\" stop-color=\"blue\"/>"
270                                 "</linearGradient></defs>"
271                                 "<rect fill=\"url(#MyGradient)\" stroke=\"black\" stroke-width=\"5\""
272                                 " x=\"0\" y=\"0\" width=\"200\" height=\"600\"/></g></svg>";
273 
274     svg = lv_svg_load_data(svg_shapes_9, lv_strlen(svg_shapes_9));
275     TEST_ASSERT_NOT_EQUAL(NULL, svg);
276     draw_svg(svg);
277     draw_snapshot(SNAPSHOT_NAME(svg_shapes_9));
278     lv_svg_node_delete(svg);
279 
280     const char * svg_shapes_10 = \
281                                  "<svg width='144' height='144' viewBox='0 0 144 144'><g>"
282                                  "<rect x='4' y='4' width='136' height='136' fill='url(#paint2_linear_13691_50994)' fill-opacity='1.0'/>"
283                                  "</g><defs><linearGradient id='paint2_linear_13691_50994' x1='4' y1='4' x2='280' y2='280'"
284                                  " gradientUnits='userSpaceOnUse'>"
285                                  "<stop stop-color='white'/><stop offset='1' stop-color='#000000'/></linearGradient>"
286                                  "</defs></svg>";
287 
288     svg = lv_svg_load_data(svg_shapes_10, lv_strlen(svg_shapes_10));
289     TEST_ASSERT_NOT_EQUAL(NULL, svg);
290     draw_svg(svg);
291     draw_snapshot(SNAPSHOT_NAME(svg_shapes_10));
292     lv_svg_node_delete(svg);
293 
294     const char * svg_shapes_11 = \
295                                  "<svg width=\'800\' height=\'800\' viewBox=\'0 0 800 800\' fill=\'none\' xmlns=\'http://www.w3.org/2000/svg\'>"
296                                  "<rect x=\'10\' y=\'10\' width=\'200\' height=\'200\' fill=\'url(#paint0_linear_13691_50971)\'/>"
297                                  "<rect x=\'212\' y=\'10\' width=\'200\' height=\'200\' fill=\'url(#paint0_linear_13691_50971)\'/>"
298                                  "<rect x=\'10\' y=\'212\' width=\'200\' height=\'200\' fill=\'url(#paint0_linear_13691_50971)\'/>"
299                                  "<rect x=\'212\' y=\'212\' width=\'200\' height=\'200\' fill=\'url(#paint0_linear_13691_50971)\'/>"
300                                  "<defs><linearGradient id=\'paint0_linear_13691_50971\' x1=\'10\' y1=\'10\' "
301                                  "x2=\'400\' y2=\'400\' gradientUnits=\'userSpaceOnUse\' >"
302                                  "<stop offset=\'0\' stop-color=\'red\' stop-opacity=\'1\'/>"
303                                  "<stop offset=\'1\' stop-color=\'green\' stop-opacity=\'1\'/>"
304                                  "</linearGradient></defs></svg>";
305 
306     svg = lv_svg_load_data(svg_shapes_11, lv_strlen(svg_shapes_11));
307     TEST_ASSERT_NOT_EQUAL(NULL, svg);
308     draw_svg(svg);
309     draw_snapshot(SNAPSHOT_NAME(svg_shapes_11));
310     lv_svg_node_delete(svg);
311 }
312 
test_draw_image(void)313 void test_draw_image(void)
314 {
315     lv_svg_render_init(&hal);
316 
317     const char * svg_image_0 = \
318                                "<svg width=\"400\" height=\"400\">"
319                                "<image x=\"0\" y=\"0\" width=\"360\" height=\"240\" preserveAspectRatio=\"none\""
320                                "xlink:href=\"cogwheel.bin\" />"
321                                "<rect x=\"0\" y=\"0\" width=\"360\" height=\"240\" fill=\"none\" stroke=\"blue\"/></svg>";
322 
323     lv_svg_node_t * svg = lv_svg_load_data(svg_image_0, lv_strlen(svg_image_0));
324     TEST_ASSERT_NOT_EQUAL(NULL, svg);
325     draw_svg(svg);
326     draw_snapshot(SNAPSHOT_NAME(svg_image_0));
327     lv_svg_node_delete(svg);
328 
329     const char * svg_image_1 = \
330                                "<svg width=\"400\" height=\"400\">"
331                                "<image x=\"0\" y=\"0\" width=\"360\" height=\"240\""
332                                "xlink:href=\"cogwheel.bin\" />"
333                                "<rect x=\"0\" y=\"0\" width=\"360\" height=\"240\" fill=\"none\" stroke=\"blue\"/></svg>";
334 
335     svg = lv_svg_load_data(svg_image_1, lv_strlen(svg_image_1));
336     TEST_ASSERT_NOT_EQUAL(NULL, svg);
337     draw_svg(svg);
338     draw_snapshot(SNAPSHOT_NAME(svg_image_1));
339     lv_svg_node_delete(svg);
340 
341     const char * svg_image_2 = \
342                                "<svg width=\"400\" height=\"400\">"
343                                "<image x=\"0\" y=\"0\" width=\"360\" height=\"540\" preserveAspectRatio=\"xMinYMin\" "
344                                "xlink:href=\"cogwheel.bin\" />"
345                                "<rect x=\"0\" y=\"0\" width=\"360\" height=\"540\" fill=\"none\" stroke=\"blue\"/></svg>";
346 
347     svg = lv_svg_load_data(svg_image_2, lv_strlen(svg_image_2));
348     TEST_ASSERT_NOT_EQUAL(NULL, svg);
349     draw_svg(svg);
350     draw_snapshot(SNAPSHOT_NAME(svg_image_2));
351     lv_svg_node_delete(svg);
352 
353     const char * svg_image_3 = \
354                                "<svg width=\"400\" height=\"400\">"
355                                "<image x=\"0\" y=\"0\" width=\"360\" height=\"540\" preserveAspectRatio=\" xMinYMid\" "
356                                "xlink:href=\"cogwheel.bin\" />"
357                                "<rect x=\"0\" y=\"0\" width=\"360\" height=\"540\" fill=\"none\" stroke=\"blue\"/></svg>";
358 
359     svg = lv_svg_load_data(svg_image_3, lv_strlen(svg_image_3));
360     TEST_ASSERT_NOT_EQUAL(NULL, svg);
361     draw_svg(svg);
362     draw_snapshot(SNAPSHOT_NAME(svg_image_3));
363     lv_svg_node_delete(svg);
364 
365     const char * svg_image_4 = \
366                                "<svg width=\"400\" height=\"400\">"
367                                "<image x=\"0\" y=\"0\" width=\"360\" height=\"540\" opacity=\"0.5\" preserveAspectRatio=\" xMinYMax\" "
368                                "xlink:href=\"cogwheel.bin\" />"
369                                "<rect x=\"0\" y=\"0\" width=\"360\" height=\"540\" fill=\"none\" stroke=\"blue\"/></svg>";
370 
371     svg = lv_svg_load_data(svg_image_4, lv_strlen(svg_image_4));
372     TEST_ASSERT_NOT_EQUAL(NULL, svg);
373     draw_svg(svg);
374     draw_snapshot(SNAPSHOT_NAME(svg_image_4));
375     lv_svg_node_delete(svg);
376 
377     const char * svg_image_5 = \
378                                "<svg width=\"400\" height=\"400\">"
379                                "<image x=\"0\" y=\"0\" width=\"360\" height=\"240\" preserveAspectRatio=\"xMidYMin\" "
380                                "xlink:href=\"cogwheel.bin\" />"
381                                "<rect x=\"0\" y=\"0\" width=\"360\" height=\"240\" fill=\"none\" stroke=\"blue\"/></svg>";
382 
383     svg = lv_svg_load_data(svg_image_5, lv_strlen(svg_image_5));
384     TEST_ASSERT_NOT_EQUAL(NULL, svg);
385     draw_svg(svg);
386     draw_snapshot(SNAPSHOT_NAME(svg_image_5));
387     lv_svg_node_delete(svg);
388 
389     const char * svg_image_6 = \
390                                "<svg width=\"400\" height=\"400\">"
391                                "<image x=\"0\" y=\"0\" width=\"360\" height=\"240\" preserveAspectRatio=\"xMidYMax\" "
392                                "xlink:href=\"cogwheel.bin\" />"
393                                "<rect x=\"0\" y=\"0\" width=\"360\" height=\"240\" fill=\"none\" stroke=\"blue\"/></svg>";
394 
395     svg = lv_svg_load_data(svg_image_6, lv_strlen(svg_image_6));
396     TEST_ASSERT_NOT_EQUAL(NULL, svg);
397     draw_svg(svg);
398     draw_snapshot(SNAPSHOT_NAME(svg_image_6));
399     lv_svg_node_delete(svg);
400 
401     const char * svg_image_7 = \
402                                "<svg width=\"400\" height=\"400\">"
403                                "<image x=\"0\" y=\"0\" width=\"360\" height=\"240\" preserveAspectRatio=\"xMaxYMin\" "
404                                "xlink:href=\"cogwheel.bin\" />"
405                                "<rect x=\"0\" y=\"0\" width=\"360\" height=\"240\" fill=\"none\" stroke=\"blue\"/></svg>";
406 
407     svg = lv_svg_load_data(svg_image_7, lv_strlen(svg_image_7));
408     TEST_ASSERT_NOT_EQUAL(NULL, svg);
409     draw_svg(svg);
410     draw_snapshot(SNAPSHOT_NAME(svg_image_7));
411     lv_svg_node_delete(svg);
412 
413     const char * svg_image_8 = \
414                                "<svg width=\"400\" height=\"400\">"
415                                "<image x=\"0\" y=\"0\" width=\"360\" height=\"240\" preserveAspectRatio=\"xMaxYMid\" "
416                                "xlink:href=\"cogwheel.bin\" />"
417                                "<rect x=\"0\" y=\"0\" width=\"360\" height=\"240\" fill=\"none\" stroke=\"blue\"/></svg>";
418 
419     svg = lv_svg_load_data(svg_image_8, lv_strlen(svg_image_8));
420     TEST_ASSERT_NOT_EQUAL(NULL, svg);
421     draw_svg(svg);
422     draw_snapshot(SNAPSHOT_NAME(svg_image_8));
423     lv_svg_node_delete(svg);
424 
425     const char * svg_image_9 = \
426                                "<svg width=\"400\" height=\"400\">"
427                                "<image x=\"0\" y=\"0\" width=\"360\" height=\"240\" preserveAspectRatio=\"xMaxYMax\" "
428                                "xlink:href=\"cogwheel.bin\" />"
429                                "<rect x=\"0\" y=\"0\" width=\"360\" height=\"240\" fill=\"none\" stroke=\"blue\"/></svg>";
430 
431     svg = lv_svg_load_data(svg_image_9, lv_strlen(svg_image_9));
432     TEST_ASSERT_NOT_EQUAL(NULL, svg);
433     draw_svg(svg);
434     draw_snapshot(SNAPSHOT_NAME(svg_image_9));
435     lv_svg_node_delete(svg);
436 
437     const char * svg_image_10 = \
438                                 "<svg width=\"400\" height=\"400\">"
439                                 "<image x=\"0\" y=\"0\" width=\"50\" height=\"30\" preserveAspectRatio=\"meet\""
440                                 "xlink:href=\"cogwheel.bin\" />"
441                                 "<rect x=\"0\" y=\"0\" width=\"50\" height=\"30\" fill=\"none\" stroke=\"blue\"/></svg>";
442 
443     svg = lv_svg_load_data(svg_image_10, lv_strlen(svg_image_10));
444     TEST_ASSERT_NOT_EQUAL(NULL, svg);
445     draw_svg(svg);
446     draw_snapshot(SNAPSHOT_NAME(svg_image_10));
447     lv_svg_node_delete(svg);
448 
449     const char * svg_image_11 = \
450                                 "<svg width=\"400\" height=\"400\">"
451                                 "<image x=\"0\" y=\"0\" width=\"50\" height=\"30\" preserveAspectRatio=\"xMidYMid slice\""
452                                 "xlink:href=\"cogwheel.bin\" />"
453                                 "<rect x=\"0\" y=\"0\" width=\"50\" height=\"30\" fill=\"none\" stroke=\"blue\"/></svg>";
454 
455     svg = lv_svg_load_data(svg_image_11, lv_strlen(svg_image_11));
456     TEST_ASSERT_NOT_EQUAL(NULL, svg);
457     draw_svg(svg);
458     draw_snapshot(SNAPSHOT_NAME(svg_image_11));
459     lv_svg_node_delete(svg);
460 
461     const char * svg_image_12 = \
462                                 "<svg width=\"200\" height=\"200\">"
463                                 "<image x=\"90\" y=\"-65\" width=\"80\" height=\"90\" transform=\"rotate(45)\""
464                                 " xlink:href=\"cogwheel.bin\"/>"
465                                 "</svg>";
466 
467     svg = lv_svg_load_data(svg_image_12, lv_strlen(svg_image_12));
468     TEST_ASSERT_NOT_EQUAL(NULL, svg);
469     draw_svg(svg);
470     draw_snapshot(SNAPSHOT_NAME(svg_image_12));
471     lv_svg_node_delete(svg);
472 }
473 
test_draw_text(void)474 void test_draw_text(void)
475 {
476     lv_svg_render_init(&hal);
477 
478     const char * svg_text_1 = \
479                               "<svg><text x=20 y=60 font-family=\"sans-serif\" font-size=\"24\">"
480                               "hello <tspan fill=\"red\" font-size=\"36\">all</tspan> world"
481                               "</text></svg>";
482 
483     lv_svg_node_t * svg = lv_svg_load_data(svg_text_1, lv_strlen(svg_text_1));
484     TEST_ASSERT_NOT_EQUAL(NULL, svg);
485     draw_svg(svg);
486     draw_snapshot(SNAPSHOT_NAME(svg_text_1));
487     lv_svg_node_delete(svg);
488 
489     const char * svg_text_2 = \
490                               "<svg><defs><linearGradient id=\"g1\">"
491                               "<stop offset=\"0.1\" stop-color=\"blue\"/>"
492                               "<stop offset =\"0.8\" stop-color=\"red\"/>"
493                               "</linearGradient></defs>"
494                               "<text fill=\"url(#g1)\" x=20 y=60 font-family=\"sans-serif\" font-size=\"48px\" font-weight=\"bold\">"
495                               "hello <tspan fill=\"green\" font-size=\"24px\">all</tspan> world"
496                               "</text></svg>";
497 
498     svg = lv_svg_load_data(svg_text_2, lv_strlen(svg_text_2));
499     TEST_ASSERT_NOT_EQUAL(NULL, svg);
500     draw_svg(svg);
501     draw_snapshot(SNAPSHOT_NAME(svg_text_2));
502     lv_svg_node_delete(svg);
503 }
504 
test_draw_complex(void)505 void test_draw_complex(void)
506 {
507     lv_svg_render_init(&hal);
508 
509     const char * svg_com_1 = \
510                              "<?xml version=\"1.0\"?><svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\""
511                              "version=\"1.2\" baseProfile=\"tiny\" width=\"10cm\" height=\"3cm\" viewBox=\"0 0 100 30\">"
512                              "<desc>'use' with a 'transform' attribute</desc>"
513                              "<defs><rect xml:id=\"MyRect\" x=\"0\" y=\"0\" width=\"60\" height=\"10\"/></defs>"
514                              "<rect x=\".1\" y=\".1\" width=\"99.8\" height=\"29.8\" fill=\"none\" stroke=\"blue\" stroke-width=\".2\"/>"
515                              "<use xlink:href=\"#MyRect\" fill=\"red\" transform=\"translate(20,2.5) rotate(10)\"/>"
516                              "<use xlink:href=\"#MyRect\" fill=\"green\" transform=\"translate(20,2.5) rotate(-10)\"/>"
517                              "</svg>";
518 
519     lv_svg_node_t * svg = lv_svg_load_data(svg_com_1, lv_strlen(svg_com_1));
520     TEST_ASSERT_NOT_EQUAL(NULL, svg);
521     draw_svg(svg);
522     draw_snapshot(SNAPSHOT_NAME(svg_com_1));
523     lv_svg_node_delete(svg);
524 
525     const char * svg_com_2 = \
526                              "<svg width=\"10cm\" height=\"3cm\" viewBox=\"0 0 100 30\">"
527                              "<g id=g1><rect id=\"MyRect1\" x=\"0\" y=\"0\" width=\"60\" height=\"10\"/>"
528                              "<rect id=\"MyRect2\" x=\"0\" y=\"12\" width=\"60\" height=\"10\"/>"
529                              "</g><rect x=\".1\" y=\".1\" width=\"99.8\" height=\"29.8\""
530                              " fill=\"none\" stroke=\"blue\" stroke-width=\".2\"/>"
531                              "<use xlink:href=\"#g1\" fill=\"green\" transform=\"translate(20,2.5) rotate(-10)\"/>"
532                              "<use xlink:href=\"#MyRect1\" fill=\"red\" transform=\"translate(20,2.5) rotate(10)\"/>"
533                              "</svg>";
534 
535     svg = lv_svg_load_data(svg_com_2, lv_strlen(svg_com_2));
536     TEST_ASSERT_NOT_EQUAL(NULL, svg);
537     draw_svg(svg);
538     draw_snapshot(SNAPSHOT_NAME(svg_com_2));
539     lv_svg_node_delete(svg);
540 
541     const char * svg_com_3 = \
542                              "<svg width=5cm height=4cm viewBox=\"0 0 500 400\">"
543                              "<rect fill=none stroke=blue stroke-width=1 x=1 y=1 width=498 height=398 />"
544                              "<polyline fill=none stroke=#888888 stroke-width=1 points=\"100,200 100,100\" />"
545                              "<polyline fill=none stroke=#888888 stroke-width=1 points=\"250,100 250,200\" />"
546                              "<polyline fill=none stroke=#888888 stroke-width=1 points=\"250,200 250,300\" />"
547                              "<polyline fill=none stroke=#888888 stroke-width=1 points=\"400,300 400,200\" />"
548                              "<path fill=none stroke=red stroke-width=5 d=\"M100,200 C100,100 250,100 250,200"
549                              "                                       S400,300 400,200\" />"
550                              "<circle fill=#888888 stroke=none stroke-width=2 cx=100 cy=200 r=10 />"
551                              "<circle fill=#888888 stroke=none stroke-width=2 cx=250 cy=200 r=10 />"
552                              "<circle fill=#888888 stroke=none stroke-width=2 cx=400 cy=200 r=10 />"
553                              "<circle fill=#888888 stroke=none cx=100 cy=100 r=10 />"
554                              "<circle fill=#888888 stroke=none cx=250 cy=100 r=10 />"
555                              "<circle fill=#888888 stroke=none cx=400 cy=300 r=10 />"
556                              "<circle fill=none stroke=blue stroke-width=4 cx=250 cy=300 r=9 />"
557                              "<text font-size=22 font-family=\"Verdana\" x=25 y=70>M100,200 C100,100 250,100 250,200</text>"
558                              "<text font-size=22 font-family=\"Verdana\" x=325 y=350>S400,300 400,200</text>"
559                              "</svg>";
560 
561     svg = lv_svg_load_data(svg_com_3, lv_strlen(svg_com_3));
562     TEST_ASSERT_NOT_EQUAL(NULL, svg);
563     draw_svg(svg);
564     draw_snapshot(SNAPSHOT_NAME(svg_com_3));
565     lv_svg_node_delete(svg);
566 
567     const char * svg_com_4 = \
568                              "<?xml version='1.0'?>"
569                              "<svg width='12cm' height='4cm' viewBox='0 0 1200 400' "
570                              "xmlns='http://www.w3.org/2000/svg' version='1.2' baseProfile='tiny'>"
571                              "<desc>Example rect02 - rounded rectangles</desc>"
572                              "<!-- Show outline of canvas using 'rect' element -->"
573                              "<rect x='1' y='1' width='1198' height='398'"
574                              " fill='none' stroke='blue' stroke-width='2'/>"
575                              "<rect x='100' y='100' width='400' height='200' rx='50'"
576                              " fill='green' />"
577                              "<g transform='translate(700 210) rotate(-30)'>"
578                              "<rect x='0' y='0' width='400' height='200' rx='50'"
579                              " fill='none' stroke='purple' stroke-width='30' />"
580                              "</g></svg>";
581 
582     svg = lv_svg_load_data(svg_com_4, lv_strlen(svg_com_4));
583     TEST_ASSERT_NOT_EQUAL(NULL, svg);
584     draw_svg(svg);
585     draw_snapshot(SNAPSHOT_NAME(svg_com_4));
586     lv_svg_node_delete(svg);
587 
588     const char * svg_com_5 = \
589                              "<svg width='12cm' height='4cm' viewBox='0 0 1200 400'>"
590                              "<rect x='1' y='1' width='1198' height='398' "
591                              " fill='none' stroke='blue' stroke-width='2' />"
592                              "<g transform='translate(300 200)'>"
593                              "<ellipse rx='250' ry='100' "
594                              "fill='red'  /></g>"
595                              "<ellipse transform='translate(900 200) rotate(-30)' "
596                              "rx='250' ry='100' fill='none' stroke='blue' stroke-width='20'  />"
597                              "</svg>";
598 
599     svg = lv_svg_load_data(svg_com_5, lv_strlen(svg_com_5));
600     TEST_ASSERT_NOT_EQUAL(NULL, svg);
601     draw_svg(svg);
602     draw_snapshot(SNAPSHOT_NAME(svg_com_5));
603     lv_svg_node_delete(svg);
604 
605     const char * svg_com_6 = \
606                              "<svg width='12cm' height='4cm' viewBox='0 0 1200 400'>"
607                              "<rect x='1' y='1' width='1198' height='398'"
608                              " fill='none' stroke='blue' stroke-width='2' />"
609                              "<g stroke='green' >"
610                              "<line x1='100' y1='300' x2='300' y2='100'"
611                              " stroke-width='5'  />"
612                              "<line x1='300' y1='300' x2='500' y2='100'"
613                              "     stroke-width='10'  />"
614                              "<line x1='500' y1='300' x2='700' y2='100'"
615                              "    stroke-width='15'  />"
616                              "<line x1='700' y1='300' x2='900' y2='100'"
617                              "      stroke-width='20'  />"
618                              "<line x1='900' y1='300' x2='1100' y2='100'"
619                              "     stroke-width='25'  />"
620                              "</g></svg>";
621 
622     svg = lv_svg_load_data(svg_com_6, lv_strlen(svg_com_6));
623     TEST_ASSERT_NOT_EQUAL(NULL, svg);
624     draw_svg(svg);
625     draw_snapshot(SNAPSHOT_NAME(svg_com_6));
626     lv_svg_node_delete(svg);
627 
628     const char * svg_com_7 = \
629                              "<svg width='12cm' height='4cm' viewBox='0 0 1200 400'>"
630                              "<rect x='1' y='1' width='1198' height='398'"
631                              " fill='none' stroke='blue' stroke-width='2' />"
632                              "<polyline fill='none' stroke='blue' stroke-width='10' "
633                              " points='50,375"
634                              "    150,375 150,325 250,325 250,375"
635                              "    350,375 350,250 450,250 450,375"
636                              "    550,375 550,175 650,175 650,375"
637                              "    750,375 750,100 850,100 850,375"
638                              "    950,375 950,25 1050,25 1050,375"
639                              "    1150,375' />"
640                              "</svg>";
641 
642     svg = lv_svg_load_data(svg_com_7, lv_strlen(svg_com_7));
643     TEST_ASSERT_NOT_EQUAL(NULL, svg);
644     draw_svg(svg);
645     draw_snapshot(SNAPSHOT_NAME(svg_com_7));
646     lv_svg_node_delete(svg);
647 
648     const char * svg_com_8 = \
649                              "<svg xmlns='http://www.w3.org/2000/svg' "
650                              "width='100%' height='100%' viewBox='0 0 400 400' "
651                              "direction='rtl' xml:lang='fa'>"
652                              "<text x='200' y='200' font-size='20'>داستان SVG Tiny 1.2 طولا ني است.</text>"
653                              "</svg>";
654 
655     svg = lv_svg_load_data(svg_com_8, lv_strlen(svg_com_8));
656     TEST_ASSERT_NOT_EQUAL(NULL, svg);
657     draw_svg(svg);
658     draw_snapshot(SNAPSHOT_NAME(svg_com_8));
659     lv_svg_node_delete(svg);
660 
661 }
662 
test_draw_svg(void)663 void test_draw_svg(void)
664 {
665     const char * svg_viewport_1 = \
666                                   "<svg width=\"300px\" height=\"300px\" viewport-fill-opacity=\"0.5\" viewport-fill=\"blue\"></svg>";
667 
668     lv_svg_node_t * svg = lv_svg_load_data(svg_viewport_1, lv_strlen(svg_viewport_1));
669     TEST_ASSERT_NOT_EQUAL(NULL, svg);
670     draw_svg(svg);
671     draw_snapshot(SNAPSHOT_NAME(svg_viewport_1));
672     lv_svg_node_delete(svg);
673 
674     const char * svg_viewport_2 = \
675                                   "<svg width=\"100px\" height=\"100px\" viewport-fill=\"green\"></svg>";
676 
677     svg = lv_svg_load_data(svg_viewport_2, lv_strlen(svg_viewport_2));
678     TEST_ASSERT_NOT_EQUAL(NULL, svg);
679     draw_svg(svg);
680     draw_snapshot(SNAPSHOT_NAME(svg_viewport_2));
681     lv_svg_node_delete(svg);
682 
683     const char * svg_viewport_3 = \
684                                   "<svg width=\"300\" height=\"200\" viewBox=\"100 0 1500 1000\""
685                                   "preserveAspectRatio=\"none\">"
686                                   "<rect x=\"0\" y=\"0\" width=\"1500\" height=\"1000\""
687                                   "fill=\"yellow\" stroke=\"blue\" stroke-width=\"12\"/>"
688                                   "<path fill=\"red\"  d=\"M 750,100 L 250,900 L 1250,900 z\"/>"
689                                   "<text x=\"100\" y=\"600\" font-size=\"200\" font-family=\"Verdana\">"
690                                   "Stretch to fit</text>"
691                                   "</svg>";
692 
693     svg = lv_svg_load_data(svg_viewport_3, lv_strlen(svg_viewport_3));
694     TEST_ASSERT_NOT_EQUAL(NULL, svg);
695     draw_svg(svg);
696     draw_snapshot(SNAPSHOT_NAME(svg_viewport_3));
697     lv_svg_node_delete(svg);
698 }
699 #else
700 
test_draw_svg(void)701 void test_draw_svg(void)
702 {
703     ;
704 }
705 #endif
706 #endif
707