summaryrefslogtreecommitdiffstats
path: root/src/sp-object-repr.cpp
diff options
context:
space:
mode:
authorMenTaLguY <mental@rydia.net>2006-01-16 02:36:01 +0000
committermental <mental@users.sourceforge.net>2006-01-16 02:36:01 +0000
commit179fa413b047bede6e32109e2ce82437c5fb8d34 (patch)
treea5a6ac2c1708bd02288fbd8edb2ff500ff2e0916 /src/sp-object-repr.cpp
downloadinkscape-179fa413b047bede6e32109e2ce82437c5fb8d34.tar.gz
inkscape-179fa413b047bede6e32109e2ce82437c5fb8d34.zip
moving trunk for module inkscape
(bzr r1)
Diffstat (limited to 'src/sp-object-repr.cpp')
-rw-r--r--src/sp-object-repr.cpp208
1 files changed, 208 insertions, 0 deletions
diff --git a/src/sp-object-repr.cpp b/src/sp-object-repr.cpp
new file mode 100644
index 000000000..4b631f3d5
--- /dev/null
+++ b/src/sp-object-repr.cpp
@@ -0,0 +1,208 @@
+#define __SP_OBJECT_REPR_C__
+
+/*
+ * Object type dictionary and build frontend
+ *
+ * Authors:
+ * Lauris Kaplinski <lauris@kaplinski.com>
+ *
+ * Copyright (C) 1999-2003 Lauris Kaplinski
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "sp-defs.h"
+#include "sp-symbol.h"
+#include "sp-marker.h"
+#include "sp-use.h"
+#include "sp-root.h"
+#include "sp-image.h"
+#include "sp-linear-gradient-fns.h"
+#include "sp-path.h"
+#include "sp-radial-gradient-fns.h"
+#include "sp-rect.h"
+#include "sp-ellipse.h"
+#include "sp-star.h"
+#include "sp-stop-fns.h"
+#include "sp-spiral.h"
+#include "sp-offset.h"
+#include "sp-line.h"
+#include "sp-metadata.h"
+#include "sp-polyline.h"
+#include "sp-textpath.h"
+#include "sp-tspan.h"
+#include "sp-pattern.h"
+#include "sp-clippath.h"
+#include "sp-mask.h"
+#include "sp-anchor.h"
+//#include "sp-animation.h"
+#include "sp-flowdiv.h"
+#include "sp-flowregion.h"
+#include "sp-flowtext.h"
+#include "sp-style-elem.h"
+#include "xml/repr.h"
+
+enum NameType { REPR_NAME, SODIPODI_TYPE };
+static unsigned const N_NAME_TYPES = SODIPODI_TYPE + 1;
+
+static GType name_to_gtype(NameType name_type, gchar const *name);
+
+/**
+ * Construct an SPRoot and all its descendents from the given repr.
+ */
+SPObject *
+sp_object_repr_build_tree(SPDocument *document, Inkscape::XML::Node *repr)
+{
+ g_assert(document != NULL);
+ g_assert(repr != NULL);
+
+ gchar const * const name = repr->name();
+ g_assert(name != NULL);
+ GType const type = name_to_gtype(REPR_NAME, name);
+ g_assert(g_type_is_a(type, SP_TYPE_ROOT));
+ gpointer newobj = g_object_new(type, 0);
+ g_assert(newobj != NULL);
+ SPObject *const object = SP_OBJECT(newobj);
+ g_assert(object != NULL);
+ sp_object_invoke_build(object, document, repr, FALSE);
+
+ return object;
+}
+
+GType
+sp_repr_type_lookup(Inkscape::XML::Node *repr)
+{
+ if ( repr->type() == Inkscape::XML::TEXT_NODE ) {
+ return SP_TYPE_STRING;
+ } else if ( repr->type() == Inkscape::XML::ELEMENT_NODE ) {
+ gchar const * const type_name = repr->attribute("sodipodi:type");
+ return ( type_name
+ ? name_to_gtype(SODIPODI_TYPE, type_name)
+ : name_to_gtype(REPR_NAME, repr->name()) );
+ } else {
+ return 0;
+ }
+}
+
+static GHashTable *t2dtable[N_NAME_TYPES] = {NULL};
+
+static void
+populate_dtables()
+{
+ struct NameTypeEntry { char const *const name; GType const type_id; };
+ NameTypeEntry const repr_name_entries[] = {
+ { "svg:a", SP_TYPE_ANCHOR },
+ //{ "svg:animate", SP_TYPE_ANIMATE },
+ { "svg:circle", SP_TYPE_CIRCLE },
+ { "svg:clipPath", SP_TYPE_CLIPPATH },
+ { "svg:defs", SP_TYPE_DEFS },
+ { "svg:ellipse", SP_TYPE_ELLIPSE },
+ /* Note: flow* elements are proposed additions for SVG 1.2, they aren't in
+ SVG 1.1. */
+ { "svg:flowDiv", SP_TYPE_FLOWDIV },
+ { "svg:flowLine", SP_TYPE_FLOWLINE },
+ { "svg:flowPara", SP_TYPE_FLOWPARA },
+ { "svg:flowRegion", SP_TYPE_FLOWREGION },
+ { "svg:flowRegionBreak", SP_TYPE_FLOWREGIONBREAK },
+ { "svg:flowRegionExclude", SP_TYPE_FLOWREGIONEXCLUDE },
+ { "svg:flowRoot", SP_TYPE_FLOWTEXT },
+ { "svg:flowSpan", SP_TYPE_FLOWTSPAN },
+ { "svg:g", SP_TYPE_GROUP },
+ { "svg:image", SP_TYPE_IMAGE },
+ { "svg:line", SP_TYPE_LINE },
+ { "svg:linearGradient", SP_TYPE_LINEARGRADIENT },
+ { "svg:marker", SP_TYPE_MARKER },
+ { "svg:mask", SP_TYPE_MASK },
+ { "svg:metadata", SP_TYPE_METADATA },
+ { "svg:path", SP_TYPE_PATH },
+ { "svg:pattern", SP_TYPE_PATTERN },
+ { "svg:polygon", SP_TYPE_POLYGON },
+ { "svg:polyline", SP_TYPE_POLYLINE },
+ { "svg:radialGradient", SP_TYPE_RADIALGRADIENT },
+ { "svg:rect", SP_TYPE_RECT },
+ { "svg:stop", SP_TYPE_STOP },
+ { "svg:svg", SP_TYPE_ROOT },
+ { "svg:style", SP_TYPE_STYLE_ELEM },
+ { "svg:switch", SP_TYPE_GROUP },
+ { "svg:symbol", SP_TYPE_SYMBOL },
+ { "svg:text", SP_TYPE_TEXT },
+ { "svg:textPath", SP_TYPE_TEXTPATH },
+ { "svg:tspan", SP_TYPE_TSPAN },
+ { "svg:use", SP_TYPE_USE }
+ };
+ NameTypeEntry const sodipodi_name_entries[] = {
+ { "arc", SP_TYPE_ARC },
+ { "inkscape:offset", SP_TYPE_OFFSET },
+ { "spiral", SP_TYPE_SPIRAL },
+ { "star", SP_TYPE_STAR }
+ };
+
+ NameTypeEntry const *const t2entries[] = {
+ repr_name_entries,
+ sodipodi_name_entries
+ };
+ unsigned const t2n_entries[] = {
+ G_N_ELEMENTS(repr_name_entries),
+ G_N_ELEMENTS(sodipodi_name_entries)
+ };
+
+ for (unsigned nt = 0; nt < N_NAME_TYPES; ++nt) {
+ NameTypeEntry const *const entries = t2entries[nt];
+ unsigned const n_entries = t2n_entries[nt];
+ GHashTable *&dtable = t2dtable[nt];
+
+ dtable = g_hash_table_new(g_str_hash, g_str_equal);
+ for (unsigned i = 0; i < n_entries; ++i) {
+ g_hash_table_insert(dtable,
+ (void *)entries[i].name,
+ (gpointer) entries[i].type_id);
+ }
+ }
+}
+
+static inline void
+ensure_dtables_populated()
+{
+ if (!*t2dtable) {
+ populate_dtables();
+ }
+}
+
+static GType
+name_to_gtype(NameType const name_type, gchar const *name)
+{
+ ensure_dtables_populated();
+
+ gpointer const data = g_hash_table_lookup(t2dtable[name_type], name);
+ return ( ( data == NULL )
+ ? SP_TYPE_OBJECT
+ : (GType) data );
+}
+
+void
+sp_object_type_register(gchar const *name, GType const gtype)
+{
+ GType const current = name_to_gtype(REPR_NAME, name);
+ if (current == SP_TYPE_OBJECT) {
+ g_hash_table_insert(t2dtable[REPR_NAME],
+ const_cast<gchar *>(name),
+ (gpointer) gtype);
+ } else {
+ /* Already registered. */
+ if (current != gtype) {
+ g_warning("repr type `%s' already registered as type #%lu, ignoring attempt to re-register as #%lu.",
+ name, current, gtype);
+ }
+ }
+}
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :