diff options
Diffstat (limited to 'src/manipulation')
-rw-r--r-- | src/manipulation/README | 16 | ||||
-rw-r--r-- | src/manipulation/copy-resource.cpp | 72 | ||||
-rw-r--r-- | src/manipulation/copy-resource.h | 22 |
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 |