1 /*
2 * GPAC - Multimedia Framework C SDK
3 *
4 * Authors: Cyril Concolato
5 * Copyright (c) Telecom ParisTech 2004-2012
6 * All rights reserved
7 *
8 * This file is part of GPAC / SVG Scene Graph Generator sub-project
9 *
10 * GPAC is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2, or (at your option)
13 * any later version.
14 *
15 * GPAC is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; see the file COPYING. If not, write to
22 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 */
25
26 #include "svggen.h"
27
28
buildGlobalAttributeList(GF_List * svg_elements,GF_List * all_atts)29 void buildGlobalAttributeList(GF_List *svg_elements, GF_List *all_atts)
30 {
31 u32 i, j, k;
32 Bool added = 0;
33
34 for (i=0; i<gf_list_count(svg_elements); i++) {
35 SVGGenElement *elt = (SVGGenElement *)gf_list_get(svg_elements, i);
36 for (j = 0; j < gf_list_count(elt->generic_attributes); j++) {
37 SVGGenAttribute *att = gf_list_get(elt->generic_attributes, j);
38 added = 0;
39 if (!strcmp(att->impl_type, "SMIL_Fill")) {
40 strcpy(att->implementation_name, "smil_fill");
41 } else if (!strcmp(att->impl_type, "SVG_TransformType")) {
42 strcpy(att->implementation_name, "transform_type");
43 }
44 for (k = 0; k < gf_list_count(all_atts); k++) {
45 SVGGenAttribute *a = gf_list_get(all_atts, k);
46 if (!strcmp(a->implementation_name, att->implementation_name)
47 && !strcmp(a->impl_type, att->impl_type)) {
48 added = 1;
49 break;
50 }
51 }
52 if (!added) {
53 gf_list_add(all_atts, att);
54 }
55 }
56 for (j = 0; j < gf_list_count(elt->attributes); j++) {
57 SVGGenAttribute *att = gf_list_get(elt->attributes, j);
58 added = 0;
59 if (!strcmp(elt->svg_name, "text")) {
60 if (!strcmp(att->implementation_name, "x")) {
61 strcpy(att->implementation_name, "text_x");
62 } else if (!strcmp(att->implementation_name, "y")) {
63 strcpy(att->implementation_name, "text_y");
64 } else if (!strcmp(att->implementation_name, "rotate")) {
65 strcpy(att->implementation_name, "text_rotate");
66 }
67 } else if (!strcmp(elt->svg_name, "listener") && !strcmp(att->implementation_name, "target")) {
68 strcpy(att->implementation_name, "listener_target");
69 } else if (!strcmp(elt->svg_name, "a") && !strcmp(att->implementation_name, "target")) {
70 strcpy(att->impl_type, "SVG_String");
71 } else if (!strcmp(elt->svg_name, "cursorManager")) {
72 if (!strcmp(att->implementation_name, "x")) {
73 strcpy(att->implementation_name, "cursorManager_x");
74 } else if (!strcmp(att->implementation_name, "y")) {
75 strcpy(att->implementation_name, "cursorManager_y");
76 }
77 }
78 for (k = 0; k < gf_list_count(all_atts); k++) {
79 SVGGenAttribute *a = gf_list_get(all_atts, k);
80 if (!strcmp(a->implementation_name, att->implementation_name)
81 && !strcmp(a->impl_type, att->impl_type)) {
82 added = 1;
83 break;
84 }
85 }
86 if (!added) {
87 gf_list_add(all_atts, att);
88 }
89 }
90 }
91 /*motionTransform is not parsed in rng*/
92 {
93 SVGGenAttribute *att = NewSVGGenAttribute();
94 strcpy(att->implementation_name, "motionTransform");
95 strcpy(att->impl_type, "SVG_Motion");
96 att->svg_name = "motionTransform";
97 att->svg_type = "SVG_Motion";
98 gf_list_add(all_atts, att);
99 }
100 }
101
generateSVGCode_V3(GF_List * svg_elements)102 void generateSVGCode_V3(GF_List *svg_elements)
103 {
104 FILE *output;
105 u32 i;
106 GF_List *all_atts = gf_list_new();
107
108 buildGlobalAttributeList(svg_elements, all_atts);
109
110 /***************************************************/
111 /***************************************************/
112 /*************** Creating .h file ******************/
113 /***************************************************/
114 /***************************************************/
115 output = BeginFile(0);
116 fprintf(output, "#include <gpac/scenegraph_svg.h>\n\n\n");
117
118 /* Generation of ELEMENT tags */
119 fprintf(output, "/* Definition of SVG 3 Alternate element internal tags */\n");
120 fprintf(output, "/* TAG names are made of \"TAG_SVG\" + SVG element name (with - replaced by _) */\n");
121 fprintf(output, "enum {\n");
122 for (i=0; i<gf_list_count(svg_elements); i++) {
123 SVGGenElement *elt = (SVGGenElement *)gf_list_get(svg_elements, i);
124 if (i == 0) {
125 fprintf(output, "\tTAG_SVG_%s = GF_NODE_RANGE_FIRST_SVG", elt->implementation_name);
126 } else {
127 fprintf(output, ",\n\tTAG_SVG_%s", elt->implementation_name);
128 }
129 }
130 fprintf(output, ",\n\t/*undefined elements (when parsing) use this tag*/\n\tTAG_SVG_UndefinedElement\n};\n\n");
131
132 /* Generation of ATTRIBUTE tags */
133 fprintf(output, "/* Definition of SVG 3 attribute internal tags - %d defined */\n", gf_list_count(all_atts));
134 fprintf(output, "/* TAG names are made of \"TAG_SVG_ATT_\" + SVG attribute name (with - replaced by _) */\n");
135 fprintf(output, "enum {\n");
136
137 for (i=0; i<gf_list_count(all_atts); i++) {
138 SVGGenAttribute *att = (SVGGenAttribute *)gf_list_get(all_atts, i);
139 if (i) fprintf(output, "\tTAG_SVG_ATT_%s,\n", att->implementation_name);
140 else fprintf(output, "\tTAG_SVG_ATT_%s = TAG_SVG_ATT_RANGE_FIRST,\n", att->implementation_name);
141 }
142 fprintf(output, "\t/*undefined attributes (when parsing) use this tag*/\n\tTAG_SVG_ATT_Unknown\n};\n\n");
143
144 /* Generation of the flatten structure pointing to all possible attributes in SVG */
145 fprintf(output, "struct _all_atts {\n");
146 for (i=0; i<gf_list_count(all_atts); i++) {
147 SVGGenAttribute *att = (SVGGenAttribute *)gf_list_get(all_atts, i);
148 fprintf(output, "\t%s *%s;\n", att->impl_type, att->implementation_name);
149 }
150 fprintf(output, "};\n");
151
152 EndFile(output, 0);
153
154 /***************************************************/
155 /***************************************************/
156 /*************** Creating .c file ******************/
157 /***************************************************/
158 /***************************************************/
159 output = BeginFile(1);
160 fprintf(output, "#ifndef GPAC_DISABLE_SVG\n\n");
161 fprintf(output, "#include <gpac/internal/scenegraph_dev.h>\n\n");
162 fprintf(output, "#include <gpac/nodes_svg_da.h>\n\n");
163
164
165 /****************************************************************/
166 /* u32 gf_svg_get_attribute_tag(u32 element_tag, const char *attribute_name) */
167 /****************************************************************/
168 fprintf(output, "u32 gf_svg_get_attribute_tag(u32 element_tag, const char *attribute_name)\n{\n\tif (!attribute_name) return TAG_SVG_ATT_Unknown;\n");
169 for (i=0; i<gf_list_count(all_atts); i++) {
170 SVGGenAttribute *att = (SVGGenAttribute *)gf_list_get(all_atts, i);
171
172 /* get rid of duplicates */
173 if (!strcmp(att->impl_type, "SMIL_Fill")) continue;
174 if (!strcmp(att->impl_type, "SVG_ContentType")) continue;
175 if (!strcmp(att->implementation_name, "text_x")) continue;
176 if (!strcmp(att->implementation_name, "text_y")) continue;
177 if (!strcmp(att->implementation_name, "text_rotate")) continue;
178 if (!strcmp(att->implementation_name, "cursorManager_x")) continue;
179 if (!strcmp(att->implementation_name, "cursorManager_y")) continue;
180
181 if (!strcmp(att->svg_name, "x") || !strcmp(att->svg_name, "y")) {
182 fprintf(output, "\tif (!stricmp(attribute_name, \"%s\")) {\n", att->svg_name);
183 fprintf(output, "\t\tif (element_tag == TAG_SVG_text) return TAG_SVG_ATT_text_%s;\n", att->implementation_name);
184 fprintf(output, "\t\telse if (element_tag == TAG_SVG_cursorManager) return TAG_SVG_ATT_cursorManager_%s;\n", att->implementation_name);
185 fprintf(output, "\t\telse return TAG_SVG_ATT_%s;\n", att->implementation_name);
186 fprintf(output, "\t}\n");
187 } else if (!strcmp(att->svg_name, "rotate")) {
188 fprintf(output, "\tif (!stricmp(attribute_name, \"%s\")) {\n", att->svg_name);
189 fprintf(output, "\t\tif (element_tag == TAG_SVG_text) return TAG_SVG_ATT_text_%s;\n", att->implementation_name);
190 fprintf(output, "\t\telse return TAG_SVG_ATT_%s;\n", att->implementation_name);
191 fprintf(output, "\t}\n");
192 } else if (!strcmp(att->svg_name, "type")) {
193 fprintf(output, "\tif (!stricmp(attribute_name, \"%s\")) {\n", att->svg_name);
194 fprintf(output, "\t\tif (element_tag == TAG_SVG_animateTransform) return TAG_SVG_ATT_transform_type;\n");
195 fprintf(output, "\t\telse return TAG_SVG_ATT_%s;\n", att->implementation_name);
196 fprintf(output, "\t}\n");
197 } else if (!strcmp(att->svg_name, "fill")) {
198 fprintf(output, "\tif (!stricmp(attribute_name, \"%s\")) {\n", att->svg_name);
199 fprintf(output, "\t\tif (element_tag == TAG_SVG_animate || element_tag == TAG_SVG_animateColor || element_tag == TAG_SVG_animateMotion || element_tag == TAG_SVG_animateTransform || element_tag == TAG_SVG_animation || element_tag == TAG_SVG_audio || element_tag == TAG_SVG_video || element_tag == TAG_SVG_set) return TAG_SVG_ATT_smil_fill;\n");
200 fprintf(output, "\t\telse return TAG_SVG_ATT_%s;\n", att->implementation_name);
201 fprintf(output, "\t}\n");
202 } else {
203 fprintf(output, "\tif (!stricmp(attribute_name, \"%s\")) return TAG_SVG_ATT_%s;\n", att->svg_name, att->implementation_name);
204 }
205 }
206 fprintf(output, "\treturn TAG_SVG_ATT_Unknown;\n}\n\n");
207
208 /****************************************************************/
209 /* u32 gf_svg_get_attribute_type(u32 tag) */
210 /****************************************************************/
211 fprintf(output, "u32 gf_svg_get_attribute_type(u32 tag)\n{\n");
212 fprintf(output, "\tswitch(tag) {\n");
213 for (i=0; i<gf_list_count(all_atts); i++) {
214 SVGGenAttribute *att = (SVGGenAttribute *)gf_list_get(all_atts, i);
215 fprintf(output, "\t\tcase TAG_SVG_ATT_%s: return %s_datatype;\n", att->implementation_name, att->impl_type);
216 }
217 fprintf(output, "\t\tdefault: return SVG_Unknown_datatype;\n");
218 fprintf(output, "\t}\n");
219 fprintf(output, "\treturn TAG_SVG_ATT_Unknown;\n}\n\n");
220
221 /****************************************************************/
222 /* const char* gf_svg_get_attribute_name(u32 tag) */
223 /****************************************************************/
224 fprintf(output, "const char*gf_svg_get_attribute_name(u32 tag)\n{\n");
225 fprintf(output, "\tswitch(tag) {\n");
226 for (i=0; i<gf_list_count(all_atts); i++) {
227 SVGGenAttribute *att = (SVGGenAttribute *)gf_list_get(all_atts, i);
228 fprintf(output, "\t\tcase TAG_SVG_ATT_%s: return \"%s\";\n", att->implementation_name, att->svg_name);
229 }
230 fprintf(output, "\t\tdefault: return \"unknown\";\n");
231 fprintf(output, "\t}\n");
232 fprintf(output, "}\n\n");
233
234 /***************************************************/
235 /* SVGAttribute *gf_svg_create_attribute(GF_Node *node, u32 tag) */
236 /***************************************************/
237 fprintf(output, "SVGAttribute *gf_svg_create_attribute(GF_Node *node, u32 tag)\n{\n\tswitch(tag) {\n");
238 for (i=0; i<gf_list_count(all_atts); i++) {
239 SVGGenAttribute *att = (SVGGenAttribute *)gf_list_get(all_atts, i);
240 fprintf(output, "\tcase TAG_SVG_ATT_%s: return gf_svg_create_attribute_from_datatype(%s_datatype, tag);\n", att->implementation_name, att->impl_type);
241 }
242 fprintf(output, "\tdefault: return NULL;\n\t}\n}\n\n");
243
244 /****************************************************************/
245 /* void gf_svg_flatten_attributes(SVG_Element *e, SVGAllAttributes *all_atts) */
246 /****************************************************************/
247 fprintf(output, "void gf_svg_flatten_attributes(SVG_Element *e, SVGAllAttributes *all_atts)\n");
248
249 fprintf(output, "{\n");
250 fprintf(output, "\tSVGAttribute *att;\n");
251 fprintf(output, "\tmemset(all_atts, 0, sizeof(SVGAllAttributes));\n");
252 fprintf(output, "\tif (e->sgprivate->tag <= GF_NODE_FIRST_DOM_NODE_TAG) return;\n");
253 fprintf(output, "\tatt = e->attributes;\n");
254 fprintf(output, "\twhile (att) {\n");
255 fprintf(output, "\t\tswitch(att->tag) {\n");
256 for (i=0; i<gf_list_count(all_atts); i++) {
257 SVGGenAttribute *att = (SVGGenAttribute *)gf_list_get(all_atts, i);
258 fprintf(output, "\t\tcase TAG_SVG_ATT_%s: all_atts->%s = (%s *)att->data; break;\n", att->implementation_name, att->implementation_name, att->impl_type);
259 }
260 fprintf(output, "\t\t}\n");
261 fprintf(output, "\tatt = att->next;\n");
262 fprintf(output, "\t}\n");
263 fprintf(output, "}\n");
264 fprintf(output, "\n");
265
266 /****************************************************************/
267 /* u32 gf_svg_get_element_tag(const char *element_name) */
268 /****************************************************************/
269 fprintf(output, "u32 gf_svg_get_element_tag(const char *element_name)\n{\n\tif (!element_name) return TAG_UndefinedNode;\n");
270 for (i=0; i<gf_list_count(svg_elements); i++) {
271 SVGGenElement *elt = (SVGGenElement *)gf_list_get(svg_elements, i);
272 fprintf(output, "\tif (!stricmp(element_name, \"%s\")) return TAG_SVG_%s;\n", elt->svg_name, elt->implementation_name);
273 }
274 fprintf(output, "\treturn TAG_UndefinedNode;\n}\n\n");
275
276 /***************************************************/
277 /* const char *gf_svg_get_element_name(u32 tag) */
278 /***************************************************/
279 fprintf(output, "const char *gf_svg_get_element_name(u32 tag)\n{\n\tswitch(tag) {\n");
280 for (i=0; i<gf_list_count(svg_elements); i++) {
281 SVGGenElement *elt = (SVGGenElement *)gf_list_get(svg_elements, i);
282 fprintf(output, "\tcase TAG_SVG_%s: return \"%s\";\n", elt->implementation_name, elt->svg_name);
283 }
284 fprintf(output, "\tdefault: return \"TAG_SVG_UndefinedNode\";\n\t}\n}\n\n");
285
286 fprintf(output, "#endif /*GPAC_DISABLE_SVG*/\n\n");
287 EndFile(output, 1);
288
289
290 generate_laser_tables_da(all_atts);
291
292 gf_list_del(all_atts);
293
294 }
295
296