1 #define __SP_OBJECT_REPR_C__
3 /*
4 * Object type dictionary and build frontend
5 *
6 * Authors:
7 * Lauris Kaplinski <lauris@kaplinski.com>
8 *
9 * Copyright (C) 1999-2003 Lauris Kaplinski
10 *
11 * Released under GNU GPL, read the file 'COPYING' for more information
12 */
14 #include "sp-defs.h"
15 #include "sp-symbol.h"
16 #include "marker.h"
17 #include "sp-use.h"
18 #include "sp-root.h"
19 #include "sp-image.h"
20 #include "sp-linear-gradient-fns.h"
21 #include "sp-path.h"
22 #include "sp-radial-gradient-fns.h"
23 #include "sp-rect.h"
24 #include "box3d.h"
25 #include "box3d-side.h"
26 #include "persp3d.h"
27 #include "sp-ellipse.h"
28 #include "sp-star.h"
29 #include "sp-stop-fns.h"
30 #include "sp-spiral.h"
31 #include "sp-offset.h"
32 #include "sp-line.h"
33 #include "sp-metadata.h"
34 #include "sp-polyline.h"
35 #include "sp-textpath.h"
36 #include "sp-tref.h"
37 #include "sp-tspan.h"
38 #include "sp-pattern.h"
39 #include "sp-clippath.h"
40 #include "sp-mask.h"
41 #include "sp-anchor.h"
42 //#include "sp-animation.h"
43 #include "sp-flowdiv.h"
44 #include "sp-flowregion.h"
45 #include "sp-flowtext.h"
46 #include "sp-font.h"
47 #include "sp-style-elem.h"
48 #include "sp-switch.h"
49 #include "color-profile-fns.h"
50 #include "xml/repr.h"
51 #include "sp-filter.h"
52 #include "sp-gaussian-blur.h"
53 #include "sp-feblend.h"
54 #include "sp-fecolormatrix.h"
55 #include "sp-fecomponenttransfer.h"
56 #include "sp-fecomponenttransfer-funcnode.h"
57 #include "sp-fecomposite.h"
58 #include "sp-feconvolvematrix.h"
59 #include "sp-fediffuselighting.h"
60 #include "sp-fedistantlight.h"
61 #include "sp-fedisplacementmap.h"
62 #include "sp-feflood.h"
63 #include "sp-feimage.h"
64 #include "sp-femerge.h"
65 #include "sp-femorphology.h"
66 #include "sp-feoffset.h"
67 #include "sp-fepointlight.h"
68 #include "sp-fespecularlighting.h"
69 #include "sp-fespotlight.h"
70 #include "sp-fetile.h"
71 #include "sp-feturbulence.h"
72 #include "sp-femergenode.h"
73 #include "live_effects/lpeobject.h"
76 enum NameType { REPR_NAME, SODIPODI_TYPE };
77 static unsigned const N_NAME_TYPES = SODIPODI_TYPE + 1;
79 static GType name_to_gtype(NameType name_type, gchar const *name);
81 /**
82 * Construct an SPRoot and all its descendents from the given repr.
83 */
84 SPObject *
85 sp_object_repr_build_tree(SPDocument *document, Inkscape::XML::Node *repr)
86 {
87 g_assert(document != NULL);
88 g_assert(repr != NULL);
90 gchar const * const name = repr->name();
91 g_assert(name != NULL);
92 GType const type = name_to_gtype(REPR_NAME, name);
93 g_assert(g_type_is_a(type, SP_TYPE_ROOT));
94 gpointer newobj = g_object_new(type, 0);
95 g_assert(newobj != NULL);
96 SPObject *const object = SP_OBJECT(newobj);
97 g_assert(object != NULL);
98 sp_object_invoke_build(object, document, repr, FALSE);
100 return object;
101 }
103 GType
104 sp_repr_type_lookup(Inkscape::XML::Node *repr)
105 {
106 if ( repr->type() == Inkscape::XML::TEXT_NODE ) {
107 return SP_TYPE_STRING;
108 } else if ( repr->type() == Inkscape::XML::ELEMENT_NODE ) {
109 gchar const * const type_name = repr->attribute("sodipodi:type");
110 return ( type_name
111 ? name_to_gtype(SODIPODI_TYPE, type_name)
112 : name_to_gtype(REPR_NAME, repr->name()) );
113 } else {
114 return 0;
115 }
116 }
118 static GHashTable *t2dtable[N_NAME_TYPES] = {NULL};
120 static void
121 populate_dtables()
122 {
123 struct NameTypeEntry { char const *const name; GType const type_id; };
124 NameTypeEntry const repr_name_entries[] = {
125 { "svg:a", SP_TYPE_ANCHOR },
126 //{ "svg:animate", SP_TYPE_ANIMATE },
127 { "svg:circle", SP_TYPE_CIRCLE },
128 { "svg:color-profile", COLORPROFILE_TYPE },
129 { "svg:clipPath", SP_TYPE_CLIPPATH },
130 { "svg:defs", SP_TYPE_DEFS },
131 { "svg:ellipse", SP_TYPE_ELLIPSE },
132 { "svg:filter", SP_TYPE_FILTER },
133 /* Note: flow* elements are proposed additions for SVG 1.2, they aren't in
134 SVG 1.1. */
135 { "svg:flowDiv", SP_TYPE_FLOWDIV },
136 { "svg:flowLine", SP_TYPE_FLOWLINE },
137 { "svg:flowPara", SP_TYPE_FLOWPARA },
138 { "svg:flowRegion", SP_TYPE_FLOWREGION },
139 { "svg:flowRegionBreak", SP_TYPE_FLOWREGIONBREAK },
140 { "svg:flowRegionExclude", SP_TYPE_FLOWREGIONEXCLUDE },
141 { "svg:flowRoot", SP_TYPE_FLOWTEXT },
142 { "svg:flowSpan", SP_TYPE_FLOWTSPAN },
143 { "svg:font", SP_TYPE_FONT },
144 { "svg:g", SP_TYPE_GROUP },
145 { "svg:feBlend", SP_TYPE_FEBLEND },
146 { "svg:feColorMatrix", SP_TYPE_FECOLORMATRIX },
147 { "svg:feComponentTransfer", SP_TYPE_FECOMPONENTTRANSFER },
148 { "svg:feComposite", SP_TYPE_FECOMPOSITE },
149 { "svg:feConvolveMatrix", SP_TYPE_FECONVOLVEMATRIX },
150 { "svg:feDiffuseLighting", SP_TYPE_FEDIFFUSELIGHTING },
151 { "svg:feDistantLight", SP_TYPE_FEDISTANTLIGHT },
152 { "svg:feDisplacementMap", SP_TYPE_FEDISPLACEMENTMAP },
153 { "svg:feFlood", SP_TYPE_FEFLOOD },
154 { "svg:feFuncR", SP_TYPE_FEFUNCR },
155 { "svg:feFuncG", SP_TYPE_FEFUNCG },
156 { "svg:feFuncB", SP_TYPE_FEFUNCB },
157 { "svg:feFuncA", SP_TYPE_FEFUNCA },
158 { "svg:feGaussianBlur", SP_TYPE_GAUSSIANBLUR },
159 { "svg:feImage", SP_TYPE_FEIMAGE },
160 { "svg:feMerge", SP_TYPE_FEMERGE },
161 { "svg:feMorphology", SP_TYPE_FEMORPHOLOGY },
162 { "svg:feOffset", SP_TYPE_FEOFFSET },
163 { "svg:fePointLight", SP_TYPE_FEPOINTLIGHT },
164 { "svg:feSpecularLighting", SP_TYPE_FESPECULARLIGHTING },
165 { "svg:feSpotLight", SP_TYPE_FESPOTLIGHT },
166 { "svg:feTile", SP_TYPE_FETILE },
167 { "svg:feTurbulence", SP_TYPE_FETURBULENCE },
168 { "svg:feMergeNode", SP_TYPE_FEMERGENODE },
169 { "svg:image", SP_TYPE_IMAGE },
170 { "svg:line", SP_TYPE_LINE },
171 { "svg:linearGradient", SP_TYPE_LINEARGRADIENT },
172 { "svg:marker", SP_TYPE_MARKER },
173 { "svg:mask", SP_TYPE_MASK },
174 { "svg:metadata", SP_TYPE_METADATA },
175 { "svg:path", SP_TYPE_PATH },
176 { "svg:pattern", SP_TYPE_PATTERN },
177 { "svg:polygon", SP_TYPE_POLYGON },
178 { "svg:polyline", SP_TYPE_POLYLINE },
179 { "svg:radialGradient", SP_TYPE_RADIALGRADIENT },
180 { "svg:rect", SP_TYPE_RECT },
181 { "svg:stop", SP_TYPE_STOP },
182 { "svg:svg", SP_TYPE_ROOT },
183 { "svg:style", SP_TYPE_STYLE_ELEM },
184 { "svg:switch", SP_TYPE_SWITCH },
185 { "svg:symbol", SP_TYPE_SYMBOL },
186 { "svg:text", SP_TYPE_TEXT },
187 { "svg:textPath", SP_TYPE_TEXTPATH },
188 { "svg:tref", SP_TYPE_TREF },
189 { "svg:tspan", SP_TYPE_TSPAN },
190 { "svg:use", SP_TYPE_USE },
191 { "inkscape:path-effect", TYPE_LIVEPATHEFFECT }
192 };
193 NameTypeEntry const sodipodi_name_entries[] = {
194 { "arc", SP_TYPE_ARC },
195 { "inkscape:offset", SP_TYPE_OFFSET },
196 { "spiral", SP_TYPE_SPIRAL },
197 { "star", SP_TYPE_STAR },
198 { "inkscape:box3d", SP_TYPE_BOX3D },
199 { "inkscape:box3dside", SP_TYPE_BOX3D_SIDE },
200 { "inkscape:persp3d", SP_TYPE_PERSP3D }
201 };
203 NameTypeEntry const *const t2entries[] = {
204 repr_name_entries,
205 sodipodi_name_entries
206 };
207 unsigned const t2n_entries[] = {
208 G_N_ELEMENTS(repr_name_entries),
209 G_N_ELEMENTS(sodipodi_name_entries)
210 };
212 for (unsigned nt = 0; nt < N_NAME_TYPES; ++nt) {
213 NameTypeEntry const *const entries = t2entries[nt];
214 unsigned const n_entries = t2n_entries[nt];
215 GHashTable *&dtable = t2dtable[nt];
217 dtable = g_hash_table_new(g_str_hash, g_str_equal);
218 for (unsigned i = 0; i < n_entries; ++i) {
219 g_hash_table_insert(dtable,
220 (void *)entries[i].name,
221 (gpointer) entries[i].type_id);
222 }
223 }
224 }
226 static inline void
227 ensure_dtables_populated()
228 {
229 if (!*t2dtable) {
230 populate_dtables();
231 }
232 }
234 static GType
235 name_to_gtype(NameType const name_type, gchar const *name)
236 {
237 ensure_dtables_populated();
239 gpointer const data = g_hash_table_lookup(t2dtable[name_type], name);
240 return ( ( data == NULL )
241 ? SP_TYPE_OBJECT
242 : (GType) data );
243 }
245 void
246 sp_object_type_register(gchar const *name, GType const gtype)
247 {
248 GType const current = name_to_gtype(REPR_NAME, name);
249 if (current == SP_TYPE_OBJECT) {
250 g_hash_table_insert(t2dtable[REPR_NAME],
251 const_cast<gchar *>(name),
252 (gpointer) gtype);
253 } else {
254 /* Already registered. */
255 if (current != gtype) {
256 g_warning("repr type `%s' already registered as type #%lu, ignoring attempt to re-register as #%lu.",
257 name, current, gtype);
258 }
259 }
260 }
262 /*
263 Local Variables:
264 mode:c++
265 c-file-style:"stroustrup"
266 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
267 indent-tabs-mode:nil
268 fill-column:99
269 End:
270 */
271 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :