summaryrefslogtreecommitdiffstats
path: root/src/manipulation
diff options
context:
space:
mode:
Diffstat (limited to 'src/manipulation')
-rw-r--r--src/manipulation/README16
-rw-r--r--src/manipulation/copy-resource.cpp72
-rw-r--r--src/manipulation/copy-resource.h22
3 files changed, 110 insertions, 0 deletions
diff --git a/src/manipulation/README b/src/manipulation/README
new file mode 100644
index 0000000..461fc45
--- /dev/null
+++ b/src/manipulation/README
@@ -0,0 +1,16 @@
+
+This directory contains code that allows manipulation of the SVG
+tree. The manipulations can be to:
+
+* Elements: creating, deleting, reordering, selection.
+* Attributes: adding, removing, changing the value.
+* Properties: adding, removing, changing the value.
+
+This code in this directory should be kept GUI independent.
+
+To do:
+
+* Move relevant code here.
+* Remove GUI dependency if necessary.
+
+
diff --git a/src/manipulation/copy-resource.cpp b/src/manipulation/copy-resource.cpp
new file mode 100644
index 0000000..f30045c
--- /dev/null
+++ b/src/manipulation/copy-resource.cpp
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "copy-resource.h"
+#include "document.h"
+#include "object/sp-defs.h"
+#include "object/sp-object.h"
+#include "extract-uri.h"
+#include "style.h"
+#include "xml/repr.h"
+
+// Make a copy of referenced: fill and stroke styles, clip paths
+void copy_style_links(const SPObject* source, SPDocument* src_document, SPDocument* dest_document) {
+
+ SPCSSAttr* css = sp_css_attr_from_object(const_cast<SPObject*>(source), SP_STYLE_FLAG_ALWAYS);
+
+ const char* fill = sp_repr_css_property(css, "fill", "none");
+ if (auto link = try_extract_uri(fill)) {
+ sp_copy_resource(src_document->getObjectByHref(*link), dest_document);
+ }
+
+ const char* stroke = sp_repr_css_property(css, "stroke", "none");
+ if (auto link = try_extract_uri(stroke)) {
+ sp_copy_resource(src_document->getObjectByHref(*link), dest_document);
+ }
+
+ sp_repr_css_attr_unref(css);
+
+ if (auto clip = source->getAttribute("clip-path")) {
+ if (auto clip_path = try_extract_uri(clip)) {
+ sp_copy_resource(src_document->getObjectByHref(*clip_path), dest_document);
+ }
+ }
+
+ for (auto& child : source->children) {
+ copy_style_links(&child, src_document, dest_document);
+ }
+}
+
+
+SPObject* sp_copy_resource(const SPObject* source, SPDocument* dest_document) {
+ if (!source || !source->document || !dest_document) {
+ return nullptr;
+ }
+
+ // make a copy of the 'source' object
+ auto src_doc = source->document;
+ auto dest_defs = dest_document->getDefs();
+ Inkscape::XML::Document* xml_doc = dest_document->getReprDoc();
+ Inkscape::XML::Node* repr = source->getRepr()->duplicate(xml_doc);
+ dest_defs->getRepr()->addChild(repr, nullptr);
+ auto object = dest_document->getObjectByRepr(repr);
+ g_assert(object != nullptr);
+ Inkscape::GC::release(repr);
+
+ // if 'source' references another object, copy it too
+ auto xhref = object->getAttribute("xlink:href");
+ auto href = object->getAttribute("href");
+
+ if (href || xhref) {
+ if (!href) {
+ href = xhref;
+ }
+ if (!dest_document->getObjectByHref(href)) {
+ sp_copy_resource(src_doc->getObjectByHref(href), dest_document);
+ }
+ }
+
+ // check fill and stroke for references to other objects, like gradients, and copy them too
+ copy_style_links(object, src_doc, dest_document);
+
+ return object;
+}
diff --git a/src/manipulation/copy-resource.h b/src/manipulation/copy-resource.h
new file mode 100644
index 0000000..08348be
--- /dev/null
+++ b/src/manipulation/copy-resource.h
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#ifndef _SEEN_COPY_RESOURCE_H_
+#define _SEEN_COPY_RESOURCE_H_
+
+class SPDocument;
+class SPObject;
+
+/**
+ * @brief
+ * Copy source resource form one document into another destination document.
+ * Resources are elements inside "def" element (gradients, markers, etc).
+ * Also copy any href-ed objects or styles referencing other objects (like gradients).
+ * In this sense it is a deep copy.
+ *
+ * @param source
+ * @param dest_document
+ * @return SPObject*
+ */
+SPObject* sp_copy_resource(const SPObject* source, SPDocument* dest_document);
+
+#endif // _SEEN_COPY_RESOURCE_H_ \ No newline at end of file