summaryrefslogtreecommitdiffstats
path: root/src/extension/internal/filter/filter-file.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/extension/internal/filter/filter-file.cpp')
-rw-r--r--src/extension/internal/filter/filter-file.cpp139
1 files changed, 139 insertions, 0 deletions
diff --git a/src/extension/internal/filter/filter-file.cpp b/src/extension/internal/filter/filter-file.cpp
new file mode 100644
index 0000000..0776350
--- /dev/null
+++ b/src/extension/internal/filter/filter-file.cpp
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2008 Authors:
+ * Ted Gould <ted@gould.cx>
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+
+#include "filter.h"
+
+#include "io/sys.h"
+#include "io/resource.h"
+#include "io/stream/inkscapestream.h"
+
+/* Directory includes */
+#include "path-prefix.h"
+#include "inkscape.h"
+
+/* Extension */
+#include "extension/extension.h"
+#include "extension/system.h"
+
+/* System includes */
+#include <glibmm/i18n.h>
+#include <glibmm/fileutils.h>
+
+using namespace Inkscape::IO::Resource;
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+namespace Filter {
+
+void
+filters_load_file (Glib::ustring filename, gchar * menuname)
+{
+ Inkscape::XML::Document *doc = sp_repr_read_file(filename.c_str(), INKSCAPE_EXTENSION_URI);
+ if (doc == nullptr) {
+ g_warning("File (%s) is not parseable as XML. Ignored.", filename.c_str());
+ return;
+ }
+
+ Inkscape::XML::Node * root = doc->root();
+ if (strcmp(root->name(), "svg:svg")) {
+ Inkscape::GC::release(doc);
+ g_warning("File (%s) is not SVG. Ignored.", filename.c_str());
+ return;
+ }
+
+ for (Inkscape::XML::Node * child = root->firstChild();
+ child != nullptr; child = child->next()) {
+ if (!strcmp(child->name(), "svg:defs")) {
+ for (Inkscape::XML::Node * defs = child->firstChild();
+ defs != nullptr; defs = defs->next()) {
+ if (!strcmp(defs->name(), "svg:filter")) {
+ Filter::filters_load_node(defs, menuname);
+ } // oh! a filter
+ } //defs
+ } // is defs
+ } // children of root
+
+ Inkscape::GC::release(doc);
+ return;
+}
+
+void Filter::filters_all_files()
+{
+ for(auto &filename: get_filenames(USER, FILTERS, {".svg"})) {
+ filters_load_file(filename, _("Personal"));
+ }
+ for(auto &filename: get_filenames(SYSTEM, FILTERS, {".svg"})) {
+ filters_load_file(filename, _("Bundled"));
+ }
+}
+
+
+#include "extension/internal/clear-n_.h"
+
+class mywriter : public Inkscape::IO::BasicWriter {
+ Glib::ustring _str;
+public:
+ void close() override;
+ void flush() override;
+ void put (char ch) override;
+ gchar const * c_str () { return _str.c_str(); }
+};
+
+void mywriter::close () { return; }
+void mywriter::flush () { return; }
+void mywriter::put (char ch) { _str += ch; }
+
+
+void
+Filter::filters_load_node (Inkscape::XML::Node *node, gchar * menuname)
+{
+ gchar const * label = node->attribute("inkscape:label");
+ gchar const * menu = node->attribute("inkscape:menu");
+ gchar const * menu_tooltip = node->attribute("inkscape:menu-tooltip");
+ gchar const * id = node->attribute("id");
+
+ if (label == nullptr) {
+ label = id;
+ }
+
+ // clang-format off
+ gchar * xml_str = g_strdup_printf(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>%s</name>\n"
+ "<id>org.inkscape.effect.filter.%s</id>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"%s\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>%s</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", label, id, menu? menu : menuname, menu_tooltip? menu_tooltip : label);
+ // clang-format on
+
+ // FIXME: Bad hack: since we pull out a single filter node out of SVG file and
+ // serialize it, it loses the namespace declarations from the root, so we must provide
+ // one right here for our inkscape attributes
+ node->setAttribute("xmlns:inkscape", SP_INKSCAPE_NS_URI);
+
+ mywriter writer;
+ sp_repr_write_stream(node, writer, 0, FALSE, g_quark_from_static_string("svg"), 0, 0);
+
+ Inkscape::Extension::build_from_mem(xml_str, new Filter(g_strdup(writer.c_str())));
+ g_free(xml_str);
+ return;
+}
+
+}; /* namespace Filter */
+}; /* namespace Internal */
+}; /* namespace Extension */
+}; /* namespace Inkscape */
+