summaryrefslogtreecommitdiffstats
path: root/src/extension/internal/svg.cpp
diff options
context:
space:
mode:
authorMartin Owens <doctormo@gmail.com>2014-04-04 04:39:23 +0000
committerMartin Owens <doctormo@gmail.com>2014-04-04 04:39:23 +0000
commit3ae99b454b4561440a18f54729826ecd429b6cfe (patch)
tree485e73476abc4cedee9abee231ee3c61026e6945 /src/extension/internal/svg.cpp
parentextensions. Measure Path. add center point, modify path id (Bug 171331) (diff)
downloadinkscape-3ae99b454b4561440a18f54729826ecd429b6cfe.tar.gz
inkscape-3ae99b454b4561440a18f54729826ecd429b6cfe.zip
Cleanup namespace removal so that it doesn't require bugs in updateRepr to work. Move to using a duplicate node-tree. Fixes bug #419266
Fixed bugs: - https://launchpad.net/bugs/419266 (bzr r13260)
Diffstat (limited to 'src/extension/internal/svg.cpp')
-rw-r--r--src/extension/internal/svg.cpp55
1 files changed, 38 insertions, 17 deletions
diff --git a/src/extension/internal/svg.cpp b/src/extension/internal/svg.cpp
index 8b272af60..a94bc2141 100644
--- a/src/extension/internal/svg.cpp
+++ b/src/extension/internal/svg.cpp
@@ -24,6 +24,7 @@
#include "extension/output.h"
#include <vector>
#include "xml/attribute-record.h"
+#include "xml/simple-document.h"
#include "sp-root.h"
#include "document.h"
@@ -42,27 +43,37 @@ using Inkscape::Util::List;
using Inkscape::XML::AttributeRecord;
using Inkscape::XML::Node;
-
-
-static void pruneExtendedAttributes( Inkscape::XML::Node *repr )
+/*
+ * Removes all sodipodi and inkscape elements and attributes from an xml tree.
+ * used to make plain svg output.
+ */
+static void pruneExtendedNamespaces( Inkscape::XML::Node *repr )
{
if (repr) {
if ( repr->type() == Inkscape::XML::ELEMENT_NODE ) {
- std::vector<gchar const*> toBeRemoved;
+ std::vector<gchar const*> attrsRemoved;
for ( List<AttributeRecord const> it = repr->attributeList(); it; ++it ) {
const gchar* attrName = g_quark_to_string(it->key);
if ((strncmp("inkscape:", attrName, 9) == 0) || (strncmp("sodipodi:", attrName, 9) == 0)) {
- toBeRemoved.push_back(attrName);
+ attrsRemoved.push_back(attrName);
}
}
// Can't change the set we're interating over while we are iterating.
- for ( std::vector<gchar const*>::iterator it = toBeRemoved.begin(); it != toBeRemoved.end(); ++it ) {
+ for ( std::vector<gchar const*>::iterator it = attrsRemoved.begin(); it != attrsRemoved.end(); ++it ) {
repr->setAttribute(*it, 0);
}
}
+ std::vector<Inkscape::XML::Node *> nodesRemoved;
for ( Node *child = repr->firstChild(); child; child = child->next() ) {
- pruneExtendedAttributes(child);
+ if((strncmp("inkscape:", child->name(), 9) == 0) || strncmp("sodipodi:", child->name(), 9) == 0) {
+ nodesRemoved.push_back(child);
+ } else {
+ pruneExtendedNamespaces(child);
+ }
+ }
+ for ( std::vector<Inkscape::XML::Node *>::iterator it = nodesRemoved.begin(); it != nodesRemoved.end(); ++it ) {
+ repr->removeChild(*it);
}
}
}
@@ -229,24 +240,34 @@ Svg::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const *filena
{
g_return_if_fail(doc != NULL);
g_return_if_fail(filename != NULL);
+ Inkscape::XML::Document *rdoc = doc->rdoc;
bool const exportExtensions = ( !mod->get_id()
|| !strcmp (mod->get_id(), SP_MODULE_KEY_OUTPUT_SVG_INKSCAPE)
|| !strcmp (mod->get_id(), SP_MODULE_KEY_OUTPUT_SVGZ_INKSCAPE));
- Inkscape::XML::Document *rdoc = NULL;
- Inkscape::XML::Node *repr = NULL;
- if (exportExtensions) {
- repr = doc->getReprRoot();
- } else {
- rdoc = sp_repr_document_new ("svg:svg");
- repr = rdoc->root();
- repr = doc->getRoot()->updateRepr(rdoc, repr, SP_OBJECT_WRITE_BUILD);
+ if (!exportExtensions) {
+ // We make a duplicate document so we don't prune the in-use document
+ // and loose data. Perhaps the user intends to save as inkscape-svg next.
+ Inkscape::XML::Document *new_rdoc = new Inkscape::XML::SimpleDocument();
+
+ // Comments and PI nodes are not included in this duplication
+ // TODO: Move this code into xml/document.h and duplicate rdoc instead of root.
+ new_rdoc->setAttribute("version", "1.0");
+ new_rdoc->setAttribute("standalone", "no");
+
+ // Get a new xml repr for the svg root node
+ Inkscape::XML::Node *root = rdoc->root()->duplicate(new_rdoc);
+
+ // Add the duplicated svg node as the document's rdoc
+ new_rdoc->appendChild(root);
+ Inkscape::GC::release(root);
- pruneExtendedAttributes(repr);
+ pruneExtendedNamespaces(root);
+ rdoc = new_rdoc;
}
- if (!sp_repr_save_rebased_file(repr->document(), filename, SP_SVG_NS_URI,
+ if (!sp_repr_save_rebased_file(rdoc, filename, SP_SVG_NS_URI,
doc->getBase(), filename)) {
throw Inkscape::Extension::Output::save_failed();
}