summaryrefslogtreecommitdiffstats
path: root/src/extension/internal/filter
diff options
context:
space:
mode:
Diffstat (limited to 'src/extension/internal/filter')
-rw-r--r--src/extension/internal/filter/BUILD_YOUR_OWN2
-rw-r--r--src/extension/internal/filter/bevels.h283
-rw-r--r--src/extension/internal/filter/blurs.h420
-rw-r--r--src/extension/internal/filter/bumps.h486
-rw-r--r--src/extension/internal/filter/color.h1886
-rw-r--r--src/extension/internal/filter/distort.h250
-rw-r--r--src/extension/internal/filter/filter-all.cpp128
-rw-r--r--src/extension/internal/filter/filter-file.cpp137
-rw-r--r--src/extension/internal/filter/filter.cpp235
-rw-r--r--src/extension/internal/filter/filter.h62
-rw-r--r--src/extension/internal/filter/image.h114
-rw-r--r--src/extension/internal/filter/morphology.h326
-rw-r--r--src/extension/internal/filter/overlays.h148
-rw-r--r--src/extension/internal/filter/paint.h1029
-rw-r--r--src/extension/internal/filter/protrusions.h100
-rw-r--r--src/extension/internal/filter/shadows.h190
-rw-r--r--src/extension/internal/filter/textures.h159
-rw-r--r--src/extension/internal/filter/transparency.h400
18 files changed, 6355 insertions, 0 deletions
diff --git a/src/extension/internal/filter/BUILD_YOUR_OWN b/src/extension/internal/filter/BUILD_YOUR_OWN
new file mode 100644
index 0000000..ba6ca5a
--- /dev/null
+++ b/src/extension/internal/filter/BUILD_YOUR_OWN
@@ -0,0 +1,2 @@
+This directory contains filter effects. They're designed to be simle.
+Very, very simple. Here is how to build your own.
diff --git a/src/extension/internal/filter/bevels.h b/src/extension/internal/filter/bevels.h
new file mode 100644
index 0000000..2fce96c
--- /dev/null
+++ b/src/extension/internal/filter/bevels.h
@@ -0,0 +1,283 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#ifndef SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_BEVELS_H__
+#define SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_BEVELS_H__
+/* Change the 'BEVELS' above to be your file name */
+
+/*
+ * Copyright (C) 2011 Authors:
+ * Ivan Louette (filters)
+ * Nicolas Dufour (UI) <nicoduf@yahoo.fr>
+ *
+ * Bevel filters
+ * Diffuse light
+ * Matte jelly
+ * Specular light
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+/* ^^^ Change the copyright to be you and your e-mail address ^^^ */
+
+#include "filter.h"
+
+#include "extension/internal/clear-n_.h"
+#include "extension/system.h"
+#include "extension/extension.h"
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+namespace Filter {
+
+/**
+ \brief Custom predefined Diffuse light filter.
+
+ Basic diffuse bevel to use for building textures
+
+ Filter's parameters:
+ * Smoothness (0.->10., default 6.) -> blur (stdDeviation)
+ * Elevation (0->360, default 25) -> feDistantLight (elevation)
+ * Azimuth (0->360, default 235) -> feDistantLight (azimuth)
+ * Lighting color (guint, default -1 [white]) -> diffuse (lighting-color)
+*/
+
+class DiffuseLight : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ DiffuseLight ( ) : Filter() { };
+ ~DiffuseLight ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Diffuse Light") "</name>\n"
+ "<id>org.inkscape.effect.filter.DiffuseLight</id>\n"
+ "<param name=\"smooth\" gui-text=\"" N_("Smoothness") "\" type=\"float\" appearance=\"full\" min=\"0.0\" max=\"10\">6</param>\n"
+ "<param name=\"elevation\" gui-text=\"" N_("Elevation (°)") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">25</param>\n"
+ "<param name=\"azimuth\" gui-text=\"" N_("Azimuth (°)") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">235</param>\n"
+ "<param name=\"color\" gui-text=\"" N_("Lighting color") "\" type=\"color\">-1</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Bevels") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Basic diffuse bevel to use for building textures") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new DiffuseLight());
+ };
+
+};
+
+gchar const *
+DiffuseLight::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream smooth;
+ std::ostringstream elevation;
+ std::ostringstream azimuth;
+ std::ostringstream r;
+ std::ostringstream g;
+ std::ostringstream b;
+ std::ostringstream a;
+
+ smooth << ext->get_param_float("smooth");
+ elevation << ext->get_param_int("elevation");
+ azimuth << ext->get_param_int("azimuth");
+ guint32 color = ext->get_param_color("color");
+
+ r << ((color >> 24) & 0xff);
+ g << ((color >> 16) & 0xff);
+ b << ((color >> 8) & 0xff);
+ a << (color & 0xff) / 255.0F;
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Diffuse Light\">\n"
+ "<feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"%s\" result=\"blur\" />\n"
+ "<feDiffuseLighting diffuseConstant=\"1\" surfaceScale=\"10\" lighting-color=\"rgb(%s,%s,%s)\" result=\"diffuse\">\n"
+ "<feDistantLight elevation=\"%s\" azimuth=\"%s\" />\n"
+ "</feDiffuseLighting>\n"
+ "<feComposite in=\"diffuse\" in2=\"diffuse\" operator=\"arithmetic\" k1=\"1\" result=\"composite1\" />\n"
+ "<feComposite in=\"composite1\" in2=\"SourceGraphic\" k1=\"%s\" operator=\"arithmetic\" k3=\"1\" result=\"composite2\" />\n"
+ "</filter>\n", smooth.str().c_str(), r.str().c_str(), g.str().c_str(), b.str().c_str(), elevation.str().c_str(), azimuth.str().c_str(), a.str().c_str());
+
+ return _filter;
+}; /* DiffuseLight filter */
+
+/**
+ \brief Custom predefined Matte jelly filter.
+
+ Bulging, matte jelly covering
+
+ Filter's parameters:
+ * Smoothness (0.0->10., default 7.) -> blur (stdDeviation)
+ * Brightness (0.0->5., default .9) -> specular (specularConstant)
+ * Elevation (0->360, default 60) -> feDistantLight (elevation)
+ * Azimuth (0->360, default 225) -> feDistantLight (azimuth)
+ * Lighting color (guint, default -1 [white]) -> specular (lighting-color)
+*/
+
+class MatteJelly : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ MatteJelly ( ) : Filter() { };
+ ~MatteJelly ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Matte Jelly") "</name>\n"
+ "<id>org.inkscape.effect.filter.MatteJelly</id>\n"
+ "<param name=\"smooth\" gui-text=\"" N_("Smoothness") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.00\" max=\"10.00\">7</param>\n"
+ "<param name=\"bright\" gui-text=\"" N_("Brightness") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.00\" max=\"5.00\">0.9</param>\n"
+ "<param name=\"elevation\" gui-text=\"" N_("Elevation (°)") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">60</param>\n"
+ "<param name=\"azimuth\" gui-text=\"" N_("Azimuth (°)") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">225</param>\n"
+ "<param name=\"color\" gui-text=\"" N_("Lighting color") "\" type=\"color\">-1</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Bevels") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Bulging, matte jelly covering") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new MatteJelly());
+ };
+
+};
+
+gchar const *
+MatteJelly::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream smooth;
+ std::ostringstream bright;
+ std::ostringstream elevation;
+ std::ostringstream azimuth;
+ std::ostringstream r;
+ std::ostringstream g;
+ std::ostringstream b;
+ std::ostringstream a;
+
+ smooth << ext->get_param_float("smooth");
+ bright << ext->get_param_float("bright");
+ elevation << ext->get_param_int("elevation");
+ azimuth << ext->get_param_int("azimuth");
+ guint32 color = ext->get_param_color("color");
+
+ r << ((color >> 24) & 0xff);
+ g << ((color >> 16) & 0xff);
+ b << ((color >> 8) & 0xff);
+ a << (color & 0xff) / 255.0F;
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Matte Jelly\">\n"
+ "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0.85 0\" result=\"color\" in=\"SourceGraphic\" />\n"
+ "<feGaussianBlur in=\"SourceAlpha\" stdDeviation=\"%s\" result=\"blur\" />\n"
+ "<feSpecularLighting in=\"blur\" specularExponent=\"25\" specularConstant=\"%s\" surfaceScale=\"5\" lighting-color=\"rgb(%s,%s,%s)\" result=\"specular\">\n"
+ "<feDistantLight elevation=\"%s\" azimuth=\"%s\" />\n"
+ "</feSpecularLighting>\n"
+ "<feComposite in=\"specular\" in2=\"SourceGraphic\" k3=\"1\" k2=\"%s\" operator=\"arithmetic\" result=\"composite1\" />\n"
+ "<feComposite in=\"composite1\" in2=\"color\" operator=\"atop\" result=\"composite2\" />\n"
+ "</filter>\n", smooth.str().c_str(), bright.str().c_str(), r.str().c_str(), g.str().c_str(), b.str().c_str(), elevation.str().c_str(), azimuth.str().c_str(), a.str().c_str());
+
+ return _filter;
+}; /* MatteJelly filter */
+
+/**
+ \brief Custom predefined Specular light filter.
+
+ Basic specular bevel to use for building textures
+
+ Filter's parameters:
+ * Smoothness (0.0->10., default 6.) -> blur (stdDeviation)
+ * Brightness (0.0->5., default 1.) -> specular (specularConstant)
+ * Elevation (0->360, default 45) -> feDistantLight (elevation)
+ * Azimuth (0->360, default 235) -> feDistantLight (azimuth)
+ * Lighting color (guint, default -1 [white]) -> specular (lighting-color)
+*/
+
+class SpecularLight : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ SpecularLight ( ) : Filter() { };
+ ~SpecularLight ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Specular Light") "</name>\n"
+ "<id>org.inkscape.effect.filter.SpecularLight</id>\n"
+ "<param name=\"smooth\" gui-text=\"" N_("Smoothness") "\" type=\"float\" appearance=\"full\" min=\"0.0\" max=\"10\">6</param>\n"
+ "<param name=\"bright\" gui-text=\"" N_("Brightness") "\" type=\"float\" appearance=\"full\" min=\"0.0\" max=\"5\">1</param>\n"
+ "<param name=\"elevation\" gui-text=\"" N_("Elevation (°)") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">45</param>\n"
+ "<param name=\"azimuth\" gui-text=\"" N_("Azimuth (°)") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">235</param>\n"
+ "<param name=\"color\" gui-text=\"" N_("Lighting color") "\" type=\"color\">-1</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Bevels") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Basic specular bevel to use for building textures") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new SpecularLight());
+ };
+
+};
+
+gchar const *
+SpecularLight::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream smooth;
+ std::ostringstream bright;
+ std::ostringstream elevation;
+ std::ostringstream azimuth;
+ std::ostringstream r;
+ std::ostringstream g;
+ std::ostringstream b;
+ std::ostringstream a;
+
+ smooth << ext->get_param_float("smooth");
+ bright << ext->get_param_float("bright");
+ elevation << ext->get_param_int("elevation");
+ azimuth << ext->get_param_int("azimuth");
+ guint32 color = ext->get_param_color("color");
+
+ r << ((color >> 24) & 0xff);
+ g << ((color >> 16) & 0xff);
+ b << ((color >> 8) & 0xff);
+ a << (color & 0xff) / 255.0F;
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Specular Light\">\n"
+ "<feGaussianBlur in=\"SourceAlpha\" stdDeviation=\"%s\" result=\"blur\" />\n"
+ "<feSpecularLighting in=\"blur\" specularExponent=\"25\" specularConstant=\"%s\" surfaceScale=\"10\" lighting-color=\"rgb(%s,%s,%s)\" result=\"specular\">\n"
+ "<feDistantLight elevation=\"%s\" azimuth=\"%s\" />\n"
+ "</feSpecularLighting>\n"
+ "<feComposite in=\"specular\" in2=\"SourceGraphic\" k3=\"1\" k2=\"%s\" operator=\"arithmetic\" result=\"composite1\" />\n"
+ "<feComposite in=\"composite1\" in2=\"SourceAlpha\" operator=\"in\" result=\"composite2\" />\n"
+ "</filter>\n", smooth.str().c_str(), bright.str().c_str(), r.str().c_str(), g.str().c_str(), b.str().c_str(), elevation.str().c_str(), azimuth.str().c_str(), a.str().c_str());
+
+ return _filter;
+}; /* SpecularLight filter */
+
+}; /* namespace Filter */
+}; /* namespace Internal */
+}; /* namespace Extension */
+}; /* namespace Inkscape */
+
+/* Change the 'BEVELS' below to be your file name */
+#endif /* SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_BEVELS_H__ */
diff --git a/src/extension/internal/filter/blurs.h b/src/extension/internal/filter/blurs.h
new file mode 100644
index 0000000..15b9c49
--- /dev/null
+++ b/src/extension/internal/filter/blurs.h
@@ -0,0 +1,420 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#ifndef SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_BLURS_H__
+#define SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_BLURS_H__
+/* Change the 'BLURS' above to be your file name */
+
+/*
+ * Copyright (C) 2011 Authors:
+ * Ivan Louette (filters)
+ * Nicolas Dufour (UI) <nicoduf@yahoo.fr>
+ *
+ * Blur filters
+ * Blur
+ * Clean edges
+ * Cross blur
+ * Feather
+ * Out of focus
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+/* ^^^ Change the copyright to be you and your e-mail address ^^^ */
+
+#include "filter.h"
+
+#include "extension/internal/clear-n_.h"
+#include "extension/system.h"
+#include "extension/extension.h"
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+namespace Filter {
+
+/**
+ \brief Custom predefined Blur filter.
+
+ Simple horizontal and vertical blur
+
+ Filter's parameters:
+ * Horizontal blur (0.01->100., default 2) -> blur (stdDeviation)
+ * Vertical blur (0.01->100., default 2) -> blur (stdDeviation)
+ * Blur content only (boolean, default false) ->
+*/
+
+class Blur : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ Blur ( ) : Filter() { };
+ ~Blur ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Blur") "</name>\n"
+ "<id>org.inkscape.effect.filter.Blur</id>\n"
+ "<param name=\"hblur\" gui-text=\"" N_("Horizontal blur") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"100.00\">2</param>\n"
+ "<param name=\"vblur\" gui-text=\"" N_("Vertical blur") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"100.00\">2</param>\n"
+ "<param name=\"content\" gui-text=\"" N_("Blur content only") "\" type=\"bool\">false</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Blurs") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Simple vertical and horizontal blur effect") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new Blur());
+ };
+
+};
+
+gchar const *
+Blur::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream bbox;
+ std::ostringstream hblur;
+ std::ostringstream vblur;
+ std::ostringstream content;
+
+ hblur << ext->get_param_float("hblur");
+ vblur << ext->get_param_float("vblur");
+
+ if (ext->get_param_bool("content")) {
+ bbox << "height=\"1\" width=\"1\" y=\"0\" x=\"0\"";
+ content << "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 50 0 \" result=\"colormatrix\" />\n"
+ << "<feComposite in=\"colormatrix\" in2=\"SourceGraphic\" operator=\"in\" />\n";
+ } else {
+ bbox << "" ;
+ content << "" ;
+ }
+
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" %s style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Blur\">\n"
+ "<feGaussianBlur stdDeviation=\"%s %s\" result=\"blur\" />\n"
+ "%s"
+ "</filter>\n", bbox.str().c_str(), hblur.str().c_str(), vblur.str().c_str(), content.str().c_str() );
+
+ return _filter;
+}; /* Blur filter */
+
+/**
+ \brief Custom predefined Clean edges filter.
+
+ Removes or decreases glows and jaggeries around objects edges after applying some filters
+
+ Filter's parameters:
+ * Strength (0.01->2., default 0.4) -> blur (stdDeviation)
+*/
+
+class CleanEdges : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ CleanEdges ( ) : Filter() { };
+ ~CleanEdges ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Clean Edges") "</name>\n"
+ "<id>org.inkscape.effect.filter.CleanEdges</id>\n"
+ "<param name=\"blur\" gui-text=\"" N_("Strength") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"2.00\">0.4</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Blurs") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Removes or decreases glows and jaggeries around objects edges after applying some filters") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new CleanEdges());
+ };
+
+};
+
+gchar const *
+CleanEdges::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream blur;
+
+ blur << ext->get_param_float("blur");
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Clean Edges\">\n"
+ "<feGaussianBlur stdDeviation=\"%s\" result=\"blur\" />\n"
+ "<feComposite in=\"SourceGraphic\" in2=\"blur\" operator=\"in\" result=\"composite1\" />\n"
+ "<feComposite in=\"composite1\" in2=\"composite1\" k2=\"1\" operator=\"in\" result=\"composite2\" />\n"
+ "</filter>\n", blur.str().c_str());
+
+ return _filter;
+}; /* CleanEdges filter */
+
+/**
+ \brief Custom predefined Cross blur filter.
+
+ Combine vertical and horizontal blur
+
+ Filter's parameters:
+ * Brightness (0.->10., default 0) -> composite (k3)
+ * Fading (0.->1., default 0) -> composite (k4)
+ * Horizontal blur (0.01->20., default 5) -> blur (stdDeviation)
+ * Vertical blur (0.01->20., default 5) -> blur (stdDeviation)
+ * Blend mode (enum, default Darken) -> blend (mode)
+*/
+
+class CrossBlur : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ CrossBlur ( ) : Filter() { };
+ ~CrossBlur ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Cross Blur") "</name>\n"
+ "<id>org.inkscape.effect.filter.CrossBlur</id>\n"
+ "<param name=\"bright\" gui-text=\"" N_("Brightness") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.\" max=\"10.00\">0</param>\n"
+ "<param name=\"fade\" gui-text=\"" N_("Fading") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.\" max=\"1.00\">0</param>\n"
+ "<param name=\"hblur\" gui-text=\"" N_("Horizontal blur") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"20.00\">5</param>\n"
+ "<param name=\"vblur\" gui-text=\"" N_("Vertical blur") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"20.00\">5</param>\n"
+ "<param name=\"blend\" gui-text=\"" N_("Blend:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"darken\">" N_("Darken") "</option>\n"
+ "<option value=\"screen\">" N_("Screen") "</option>\n"
+ "<option value=\"multiply\">" N_("Multiply") "</option>\n"
+ "<option value=\"lighten\">" N_("Lighten") "</option>\n"
+ "</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Blurs") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Combine vertical and horizontal blur") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new CrossBlur());
+ };
+
+};
+
+gchar const *
+CrossBlur::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream bright;
+ std::ostringstream fade;
+ std::ostringstream hblur;
+ std::ostringstream vblur;
+ std::ostringstream blend;
+
+ bright << ext->get_param_float("bright");
+ fade << ext->get_param_float("fade");
+ hblur << ext->get_param_float("hblur");
+ vblur << ext->get_param_float("vblur");
+ blend << ext->get_param_optiongroup("blend");
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Cross Blur\">\n"
+ "<feColorMatrix in=\"SourceGraphic\" values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -0.2125 -0.7154 -0.0721 1 0 \" result=\"colormatrix\" />\n"
+ "<feComposite in=\"SourceGraphic\" in2=\"colormatrix\" operator=\"arithmetic\" k2=\"1\" k3=\"%s\" k4=\"%s\" result=\"composite\" />\n"
+ "<feGaussianBlur stdDeviation=\"%s 0.01\" result=\"blur1\" />\n"
+ "<feGaussianBlur in=\"composite\" stdDeviation=\"0.01 %s\" result=\"blur2\" />\n"
+ "<feBlend in=\"blur2\" in2=\"blur1\" mode=\"%s\" result=\"blend\" />\n"
+ "</filter>\n", bright.str().c_str(), fade.str().c_str(), hblur.str().c_str(), vblur.str().c_str(), blend.str().c_str());
+
+ return _filter;
+}; /* Cross blur filter */
+
+/**
+ \brief Custom predefined Feather filter.
+
+ Blurred mask on the edge without altering the contents
+
+ Filter's parameters:
+ * Strength (0.01->100., default 5) -> blur (stdDeviation)
+*/
+
+class Feather : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ Feather ( ) : Filter() { };
+ ~Feather ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Feather") "</name>\n"
+ "<id>org.inkscape.effect.filter.Feather</id>\n"
+ "<param name=\"blur\" gui-text=\"" N_("Strength") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"100.00\">5</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Blurs") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Blurred mask on the edge without altering the contents") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new Feather());
+ };
+
+};
+
+gchar const *
+Feather::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream blur;
+
+ blur << ext->get_param_float("blur");
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Feather\">\n"
+ "<feGaussianBlur stdDeviation=\"%s\" result=\"blur\" />\n"
+ "<feComposite in=\"SourceGraphic\" in2=\"blur\" operator=\"atop\" result=\"composite1\" />\n"
+ "<feComposite in2=\"composite1\" operator=\"in\" result=\"composite2\" />\n"
+ "<feComposite in2=\"composite2\" operator=\"in\" result=\"composite3\" />\n"
+ "</filter>\n", blur.str().c_str());
+
+ return _filter;
+}; /* Feather filter */
+
+/**
+ \brief Custom predefined Out of Focus filter.
+
+ Blur eroded by white or transparency
+
+ Filter's parameters:
+ * Horizontal blur (0.01->10., default 3) -> blur (stdDeviation)
+ * Vertical blur (0.01->10., default 3) -> blur (stdDeviation)
+ * Dilatation (n-1th value, 0.->100., default 6) -> colormatrix2 (matrix)
+ * Erosion (nth value, 0.->100., default 2) -> colormatrix2 (matrix)
+ * Opacity (0.->1., default 1.) -> composite1 (k2)
+ * Background color (guint, default -1) -> flood (flood-opacity, flood-color)
+ * Blend type (enum, default normal) -> blend (mode)
+ * Blend to background (boolean, default false) -> blend (false: in2="flood", true: in2="BackgroundImage")
+
+*/
+
+class ImageBlur : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ ImageBlur ( ) : Filter() { };
+ ~ImageBlur ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Out of Focus") "</name>\n"
+ "<id>org.inkscape.effect.filter.ImageBlur</id>\n"
+ "<param name=\"tab\" type=\"notebook\">\n"
+ "<page name=\"optionstab\" gui-text=\"Options\">\n"
+ "<param name=\"hblur\" gui-text=\"" N_("Horizontal blur") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"50.00\">3</param>\n"
+ "<param name=\"vblur\" gui-text=\"" N_("Vertical blur") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"50.00\">3</param>\n"
+ "<param name=\"dilat\" gui-text=\"" N_("Dilatation") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"100\">6</param>\n"
+ "<param name=\"erosion\" gui-text=\"" N_("Erosion") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"100\">2</param>\n"
+ "<param name=\"opacity\" gui-text=\"" N_("Opacity") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"1\">1</param>\n"
+ "</page>\n"
+ "<page name=\"backgroundtab\" gui-text=\"Background\">\n"
+ "<param name=\"color\" gui-text=\"" N_("Background color") "\" type=\"color\">-1</param>\n"
+ "<param name=\"blend\" gui-text=\"" N_("Blend type:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"normal\">" N_("Normal") "</option>\n"
+ "<option value=\"darken\">" N_("Darken") "</option>\n"
+ "<option value=\"screen\">" N_("Screen") "</option>\n"
+ "<option value=\"multiply\">" N_("Multiply") "</option>\n"
+ "<option value=\"lighten\">" N_("Lighten") "</option>\n"
+ "</param>\n"
+ "<param name=\"background\" gui-text=\"" N_("Blend to background") "\" type=\"bool\" >false</param>\n"
+ "</page>\n"
+ "</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Blurs") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Blur eroded by white or transparency") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new ImageBlur());
+ };
+
+};
+
+gchar const *
+ImageBlur::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream hblur;
+ std::ostringstream vblur;
+ std::ostringstream dilat;
+ std::ostringstream erosion;
+ std::ostringstream opacity;
+ std::ostringstream r;
+ std::ostringstream g;
+ std::ostringstream b;
+ std::ostringstream a;
+ std::ostringstream blend;
+ std::ostringstream background;
+
+ hblur << ext->get_param_float("hblur");
+ vblur << ext->get_param_float("vblur");
+ dilat << ext->get_param_float("dilat");
+ erosion << -ext->get_param_float("erosion");
+ opacity << ext->get_param_float("opacity");
+
+ guint32 color = ext->get_param_color("color");
+ r << ((color >> 24) & 0xff);
+ g << ((color >> 16) & 0xff);
+ b << ((color >> 8) & 0xff);
+ a << (color & 0xff) / 255.0F;
+ blend << ext->get_param_optiongroup("blend");
+
+ if (ext->get_param_bool("background")) {
+ background << "BackgroundImage" ;
+ } else {
+ background << "flood" ;
+ }
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Out of Focus\">\n"
+ "<feFlood flood-opacity=\"%s\" flood-color=\"rgb(%s,%s,%s)\" result=\"flood\" />\n"
+ "<feColorMatrix in=\"SourceGraphic\" values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -0.2125 -0.7154 -0.0721 1 0 \" result=\"colormatrix1\" />\n"
+ "<feGaussianBlur in=\"colormatrix1\" stdDeviation=\"%s %s\" result=\"blur\" />\n"
+ "<feColorMatrix in=\"blur\" values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 %s %s \" result=\"colormatrix2\" />\n"
+ "<feBlend in=\"colormatrix2\" in2=\"%s\" mode=\"%s\" result=\"blend\" />\n"
+ "<feComposite in=\"blend\" in2=\"blend\" operator=\"arithmetic\" k2=\"%s\" result=\"composite1\" />\n"
+ "<feComposite in2=\"SourceGraphic\" operator=\"in\" />\n"
+ "</filter>\n", a.str().c_str(), r.str().c_str(), g.str().c_str(), b.str().c_str(),
+ hblur.str().c_str(), vblur.str().c_str(), dilat.str().c_str(), erosion.str().c_str(),
+ background.str().c_str(), blend.str().c_str(), opacity.str().c_str());
+
+ return _filter;
+}; /* Out of Focus filter */
+
+}; /* namespace Filter */
+}; /* namespace Internal */
+}; /* namespace Extension */
+}; /* namespace Inkscape */
+
+/* Change the 'BLURS' below to be your file name */
+#endif /* SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_BLURS_H__ */
diff --git a/src/extension/internal/filter/bumps.h b/src/extension/internal/filter/bumps.h
new file mode 100644
index 0000000..21328f4
--- /dev/null
+++ b/src/extension/internal/filter/bumps.h
@@ -0,0 +1,486 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#ifndef SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_BUMPS_H__
+#define SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_BUMPS_H__
+/* Change the 'BUMPS' above to be your file name */
+
+/*
+ * Copyright (C) 2011 Authors:
+ * Ivan Louette (filters)
+ * Nicolas Dufour (UI) <nicoduf@yahoo.fr>
+ *
+ * Bump filters
+ * Bump
+ * Wax bump
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+/* ^^^ Change the copyright to be you and your e-mail address ^^^ */
+
+#include "filter.h"
+
+#include "extension/internal/clear-n_.h"
+#include "extension/system.h"
+#include "extension/extension.h"
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+namespace Filter {
+
+/**
+ \brief Custom predefined Bump filter.
+
+ All purpose bump filter
+
+ Filter's parameters:
+ Options
+ * Image simplification (0.01->10., default 0.01) -> blur1 (stdDeviation)
+ * Bump simplification (0.01->10., default 0.01) -> blur2 (stdDeviation)
+ * Crop (-50.->50., default 0.) -> composite1 (k3)
+ * Red (-50.->50., default 0.) -> colormatrix1 (values)
+ * Green (-50.->50., default 0.) -> colormatrix1 (values)
+ * Blue (-50.->50., default 0.) -> colormatrix1 (values)
+ * Bump from background (boolean, default false) -> colormatrix1 (false: in="SourceGraphic", true: in="BackgroundImage")
+ Lighting
+ * Lighting type (enum, default specular) -> lighting block
+ * Height (0.->50., default 5.) -> lighting (surfaceScale)
+ * Lightness (0.->5., default 1.) -> lighting [diffuselighting (diffuseConstant)|specularlighting (specularConstant)]
+ * Precision (1->128, default 15) -> lighting (specularExponent)
+ * Color (guint, default -1 (RGB:255,255,255))-> lighting (lighting-color)
+ Light source
+ * Azimuth (0->360, default 225) -> lightsOptions (distantAzimuth)
+ * Elevation (0->180, default 45) -> lightsOptions (distantElevation)
+ * X location [point] (-5000->5000, default 526) -> lightsOptions (x)
+ * Y location [point] (-5000->5000, default 372) -> lightsOptions (y)
+ * Z location [point] (0->5000, default 150) -> lightsOptions (z)
+ * X location [spot] (-5000->5000, default 526) -> lightsOptions (x)
+ * Y location [spot] (-5000->5000, default 372) -> lightsOptions (y)
+ * Z location [spot] (-5000->5000, default 150) -> lightsOptions (z)
+ * X target (-5000->5000, default 0) -> lightsOptions (pointsAtX)
+ * Y target (-5000->5000, default 0) -> lightsOptions (pointsAtX)
+ * Z target (-5000->0, default -1000) -> lightsOptions (pointsAtX)
+ * Specular exponent (1->100, default 1) -> lightsOptions (specularExponent)
+ * Cone angle (0->100, default 50) -> lightsOptions (limitingConeAngle)
+ Color bump
+ * Blend type (enum, default normal) -> blend (mode)
+ * Image color (guint, default -987158017 (RGB:197,41,41)) -> flood (flood-color)
+ * Color bump (boolean, default false) -> composite2 (false: in="diffuselighting", true in="flood")
+*/
+
+class Bump : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ Bump ( ) : Filter() { };
+ ~Bump ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Bump") "</name>\n"
+ "<id>org.inkscape.effect.filter.Bump</id>\n"
+ "<param name=\"tab\" type=\"notebook\">\n"
+ "<page name=\"optionstab\" gui-text=\"Options\">\n"
+ "<param name=\"simplifyImage\" gui-text=\"" N_("Image simplification") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"10.00\">0.01</param>\n"
+ "<param name=\"simplifyBump\" gui-text=\"" N_("Bump simplification") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"10.00\">0.01</param>\n"
+ "<param name=\"crop\" gui-text=\"" N_("Crop") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-50.\" max=\"50.\">0</param>\n"
+ "<label appearance=\"header\">" N_("Bump source") "</label>\n"
+ "<param name=\"red\" gui-text=\"" N_("Red") "\" type=\"float\" indent=\"1\" appearance=\"full\" precision=\"2\" min=\"-50.\" max=\"50.\">0</param>\n"
+ "<param name=\"green\" gui-text=\"" N_("Green") "\" type=\"float\" indent=\"1\" appearance=\"full\" precision=\"2\" min=\"-50.\" max=\"50.\">0</param>\n"
+ "<param name=\"blue\" gui-text=\"" N_("Blue") "\" type=\"float\" indent=\"1\" appearance=\"full\" precision=\"2\" min=\"-50.\" max=\"50.\">0</param>\n"
+ "<param name=\"background\" gui-text=\"" N_("Bump from background") "\" indent=\"1\" type=\"bool\">false</param>\n"
+ "</page>\n"
+ "<page name=\"lightingtab\" gui-text=\"Lighting\">\n"
+ "<param name=\"lightType\" gui-text=\"" N_("Lighting type:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"specular\">" N_("Specular") "</option>\n"
+ "<option value=\"diffuse\">" N_("Diffuse") "</option>\n"
+ "</param>\n"
+ "<param name=\"height\" gui-text=\"" N_("Height") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"50.\">5</param>\n"
+ "<param name=\"lightness\" gui-text=\"" N_("Lightness") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"5.\">1</param>\n"
+ "<param name=\"precision\" gui-text=\"" N_("Precision") "\" type=\"int\" appearance=\"full\" min=\"1\" max=\"128\">15</param>\n"
+ "<param name=\"lightingColor\" gui-text=\"" N_("Color") "\" type=\"color\">-1</param>\n"
+ "</page>\n"
+ "<page name=\"lightsourcetab\" gui-text=\"" N_("Light source") "\">\n"
+ "<param name=\"lightSource\" gui-text=\"" N_("Light source:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"distant\">" N_("Distant") "</option>\n"
+ "<option value=\"point\">" N_("Point") "</option>\n"
+ "<option value=\"spot\">" N_("Spot") "</option>\n"
+ "</param>\n"
+ "<label appearance=\"header\">" N_("Distant light options") "</label>\n"
+ "<param name=\"distantAzimuth\" gui-text=\"" N_("Azimuth") "\" type=\"int\" indent=\"1\" appearance=\"full\" min=\"0\" max=\"360\">225</param>\n"
+ "<param name=\"distantElevation\" gui-text=\"" N_("Elevation") "\" type=\"int\" indent=\"1\" appearance=\"full\" min=\"0\" max=\"180\">45</param>\n"
+ "<label appearance=\"header\">" N_("Point light options") "</label>\n"
+ "<param name=\"pointX\" gui-text=\"" N_("X location") "\" type=\"int\" indent=\"1\" appearance=\"full\" min=\"-5000\" max=\"5000\">526</param>\n"
+ "<param name=\"pointY\" gui-text=\"" N_("Y location") "\" type=\"int\" indent=\"1\" appearance=\"full\" min=\"-5000\" max=\"5000\">372</param>\n"
+ "<param name=\"pointZ\" gui-text=\"" N_("Z location") "\" type=\"int\" indent=\"1\" appearance=\"full\" min=\"0\" max=\"5000\">150</param>\n"
+ "<label appearance=\"header\">" N_("Spot light options") "</label>\n"
+ "<param name=\"spotX\" gui-text=\"" N_("X location") "\" type=\"int\" indent=\"1\" appearance=\"full\" min=\"-5000\" max=\"5000\">526</param>\n"
+ "<param name=\"spotY\" gui-text=\"" N_("Y location") "\" type=\"int\" indent=\"1\" appearance=\"full\" min=\"-5000\" max=\"5000\">372</param>\n"
+ "<param name=\"spotZ\" gui-text=\"" N_("Z location") "\" type=\"int\" indent=\"1\" appearance=\"full\" min=\"-5000\" max=\"5000\">150</param>\n"
+ "<param name=\"spotAtX\" gui-text=\"" N_("X target") "\" type=\"int\" indent=\"1\" appearance=\"full\" min=\"-5000\" max=\"5000\">0</param>\n"
+ "<param name=\"spotAtY\" gui-text=\"" N_("Y target") "\" type=\"int\" indent=\"1\" appearance=\"full\" min=\"-5000\" max=\"5000\">0</param>\n"
+ "<param name=\"spotAtZ\" gui-text=\"" N_("Z target") "\" type=\"int\" indent=\"1\" appearance=\"full\" min=\"-5000\" max=\"0\">-1000</param>\n"
+ "<param name=\"spotExponent\" gui-text=\"" N_("Specular exponent") "\" type=\"int\" indent=\"1\" appearance=\"full\" min=\"1\" max=\"100\">1</param>\n"
+ "<param name=\"spotConeAngle\" gui-text=\"" N_("Cone angle") "\" type=\"int\" indent=\"1\" appearance=\"full\" min=\"0\" max=\"100\">50</param>\n"
+ "</page>\n"
+ "<page name=\"colortab\" gui-text=\"Color bump\">\n"
+ "<param name=\"imageColor\" gui-text=\"" N_("Image color") "\" type=\"color\">-987158017</param>\n"
+ "<param name=\"colorize\" gui-text=\"" N_("Color bump") "\" type=\"bool\" >false</param>\n"
+ "<param name=\"blend\" gui-text=\"" N_("Blend type:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"normal\">" N_("Normal") "</option>\n"
+ "<option value=\"darken\">" N_("Darken") "</option>\n"
+ "<option value=\"screen\">" N_("Screen") "</option>\n"
+ "<option value=\"multiply\">" N_("Multiply") "</option>\n"
+ "<option value=\"lighten\">" N_("Lighten") "</option>\n"
+ "</param>\n"
+ "</page>\n"
+ "</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Bumps") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("All purposes bump filter") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new Bump());
+ };
+
+};
+
+gchar const *
+Bump::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream simplifyImage;
+ std::ostringstream simplifyBump;
+ std::ostringstream red;
+ std::ostringstream green;
+ std::ostringstream blue;
+ std::ostringstream crop;
+ std::ostringstream bumpSource;
+ std::ostringstream blend;
+
+ std::ostringstream lightStart;
+ std::ostringstream lightOptions;
+ std::ostringstream lightEnd;
+
+ std::ostringstream floodRed;
+ std::ostringstream floodGreen;
+ std::ostringstream floodBlue;
+ std::ostringstream floodAlpha;
+ std::ostringstream colorize;
+
+
+ simplifyImage << ext->get_param_float("simplifyImage");
+ simplifyBump << ext->get_param_float("simplifyBump");
+ red << ext->get_param_float("red");
+ green << ext->get_param_float("green");
+ blue << ext->get_param_float("blue");
+ crop << ext->get_param_float("crop");
+ blend << ext->get_param_optiongroup("blend");
+
+ guint32 lightingColor = ext->get_param_color("lightingColor");
+ guint32 imageColor = ext->get_param_color("imageColor");
+
+ if (ext->get_param_bool("background")) {
+ bumpSource << "BackgroundImage" ;
+ } else {
+ bumpSource << "blur1" ;
+ }
+
+ const gchar *lightType = ext->get_param_optiongroup("lightType");
+ if ((g_ascii_strcasecmp("specular", lightType) == 0)) {
+ // Specular
+ lightStart << "<feSpecularLighting lighting-color=\"rgb(" << ((lightingColor >> 24) & 0xff) << ","
+ << ((lightingColor >> 16) & 0xff) << "," << ((lightingColor >> 8) & 0xff) << ")\" surfaceScale=\""
+ << ext->get_param_float("height") << "\" specularConstant=\"" << ext->get_param_float("lightness")
+ << "\" specularExponent=\"" << ext->get_param_int("precision") << "\" result=\"lighting\">";
+ lightEnd << "</feSpecularLighting>";
+ } else {
+ // Diffuse
+ lightStart << "<feDiffuseLighting lighting-color=\"rgb(" << ((lightingColor >> 24) & 0xff) << ","
+ << ((lightingColor >> 16) & 0xff) << "," << ((lightingColor >> 8) & 0xff) << ")\" surfaceScale=\""
+ << ext->get_param_float("height") << "\" diffuseConstant=\"" << ext->get_param_float("lightness")
+ << "\" result=\"lighting\">";
+ lightEnd << "</feDiffuseLighting>";
+ }
+
+ const gchar *lightSource = ext->get_param_optiongroup("lightSource");
+ if ((g_ascii_strcasecmp("distant", lightSource) == 0)) {
+ // Distant
+ lightOptions << "<feDistantLight azimuth=\"" << ext->get_param_int("distantAzimuth") << "\" elevation=\""
+ << ext->get_param_int("distantElevation") << "\" />";
+ } else if ((g_ascii_strcasecmp("point", lightSource) == 0)) {
+ // Point
+ lightOptions << "<fePointLight z=\"" << ext->get_param_int("pointX") << "\" y=\"" << ext->get_param_int("pointY")
+ << "\" x=\"" << ext->get_param_int("pointZ") << "\" />";
+ } else {
+ // Spot
+ lightOptions << "<feSpotLight x=\"" << ext->get_param_int("pointX") << "\" y=\"" << ext->get_param_int("pointY")
+ << "\" z=\"" << ext->get_param_int("pointZ") << "\" pointsAtX=\"" << ext->get_param_int("spotAtX")
+ << "\" pointsAtY=\"" << ext->get_param_int("spotAtY") << "\" pointsAtZ=\"" << ext->get_param_int("spotAtZ")
+ << "\" specularExponent=\"" << ext->get_param_int("spotExponent")
+ << "\" limitingConeAngle=\"" << ext->get_param_int("spotConeAngle")
+ << "\" />";
+ }
+
+ floodRed << ((imageColor >> 24) & 0xff);
+ floodGreen << ((imageColor >> 16) & 0xff);
+ floodBlue << ((imageColor >> 8) & 0xff);
+ floodAlpha << (imageColor & 0xff) / 255.0F;
+
+ if (ext->get_param_bool("colorize")) {
+ colorize << "flood" ;
+ } else {
+ colorize << "blur1" ;
+ }
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Bump\">\n"
+ "<feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"%s\" result=\"blur1\" />\n"
+ "<feColorMatrix in=\"%s\" values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 %s %s %s 1 0 \" result=\"colormatrix1\" />\n"
+ "<feColorMatrix in=\"colormatrix1\" type=\"luminanceToAlpha\" result=\"colormatrix2\" />\n"
+ "<feComposite in2=\"blur1\" operator=\"arithmetic\" k2=\"1\" k3=\"%s\" result=\"composite1\" />\n"
+ "<feGaussianBlur in=\"composite1\" stdDeviation=\"%s\" result=\"blur2\" />\n"
+ "%s\n"
+ "%s\n"
+ "%s\n"
+ "<feFlood flood-color=\"rgb(%s,%s,%s)\" flood-opacity=\"%s\" result=\"flood\" />\n"
+ "<feComposite in=\"lighting\" in2=\"%s\" operator=\"arithmetic\" k3=\"1\" k2=\"1\" result=\"composite2\" />\n"
+ "<feBlend in2=\"SourceGraphic\" mode=\"%s\" result=\"blend\" />\n"
+ "<feComposite in=\"blend\" in2=\"SourceGraphic\" operator=\"in\" k2=\"1\" result=\"composite3\" />\n"
+ "</filter>\n", simplifyImage.str().c_str(), bumpSource.str().c_str(), red.str().c_str(), green.str().c_str(), blue.str().c_str(),
+ crop.str().c_str(), simplifyBump.str().c_str(),
+ lightStart.str().c_str(), lightOptions.str().c_str(), lightEnd.str().c_str(),
+ floodRed.str().c_str(), floodGreen.str().c_str(), floodBlue.str().c_str(), floodAlpha.str().c_str(),
+ colorize.str().c_str(), blend.str().c_str());
+
+ return _filter;
+
+}; /* Bump filter */
+
+/**
+ \brief Custom predefined Wax Bump filter.
+
+ Turns an image to jelly
+
+ Filter's parameters:
+ Options
+ * Image simplification (0.01->10., default 1.5) -> blur1 (stdDeviation)
+ * Bump simplification (0.01->10., default 1) -> blur2 (stdDeviation)
+ * Crop (-10.->10., default 1.) -> colormatrix2 (4th value of the last line)
+ * Red (-10.->10., default 0.) -> colormatrix2 (values, substract 0.21)
+ * Green (-10.->10., default 0.) -> colormatrix2 (values, substract 0.72)
+ * Blue (-10.->10., default 0.) -> colormatrix2 (values, substract 0.07)
+ * Background (enum, default color) ->
+ * color: colormatrix1 (in="flood1")
+ * image: colormatrix1 (in="SourceGraphic")
+ * blurred image: colormatrix1 (in="blur1")
+ * Background opacity (0.->1., default 0) -> colormatrix1 (last value)
+ Lighting (specular, distant light)
+ * Color (guint, default -1 (RGB:255,255,255))-> lighting (lighting-color)
+ * Height (-50.->50., default 5.) -> lighting (surfaceScale)
+ * Lightness (0.->10., default 1.4) -> lighting [diffuselighting (diffuseConstant)|specularlighting (specularConstant)]
+ * Precision (0->50, default 35) -> lighting (specularExponent)
+ * Azimuth (0->360, default 225) -> lightsOptions (distantAzimuth)
+ * Elevation (0->180, default 60) -> lightsOptions (distantElevation)
+ * Lighting blend (enum, default screen) -> blend1 (mode)
+ * Highlight blend (enum, default screen) -> blend2 (mode)
+ Bump
+ * Trasparency type (enum [in,atop], default atop) -> composite2 (operator)
+ * Color (guint, default -520083713 (RGB:225,0,38)) -> flood2 (flood-color)
+ * Revert bump (boolean, default false) -> composite1 (false: operator="out", true operator="in")
+*/
+
+class WaxBump : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ WaxBump ( ) : Filter() { };
+ ~WaxBump ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Wax Bump") "</name>\n"
+ "<id>org.inkscape.effect.filter.WaxBump</id>\n"
+ "<param name=\"tab\" type=\"notebook\">\n"
+ "<page name=\"optionstab\" gui-text=\"Options\">\n"
+ "<param name=\"simplifyImage\" gui-text=\"" N_("Image simplification") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"10.00\">1.5</param>\n"
+ "<param name=\"simplifyBump\" gui-text=\"" N_("Bump simplification") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"10.00\">1</param>\n"
+ "<param name=\"crop\" gui-text=\"" N_("Crop") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-10.\" max=\"10.\">1</param>\n"
+ "<label appearance=\"header\">" N_("Bump source") "</label>\n"
+ "<param name=\"red\" gui-text=\"" N_("Red") "\" type=\"float\" indent=\"1\" appearance=\"full\" precision=\"2\" min=\"-10.\" max=\"10.\">0</param>\n"
+ "<param name=\"green\" gui-text=\"" N_("Green") "\" type=\"float\" indent=\"1\" appearance=\"full\" precision=\"2\" min=\"-10.\" max=\"10.\">0</param>\n"
+ "<param name=\"blue\" gui-text=\"" N_("Blue") "\" type=\"float\" indent=\"1\" appearance=\"full\" precision=\"2\" min=\"-10.\" max=\"10.\">0</param>\n"
+ "<param name=\"background\" gui-text=\"" N_("Background:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"flood1\">" N_("Color") "</option>\n"
+ "<option value=\"SourceGraphic\">" N_("Image") "</option>\n"
+ "<option value=\"blur1\">" N_("Blurred image") "</option>\n"
+ "</param>\n"
+ "<param name=\"bgopacity\" gui-text=\"" N_("Background opacity") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.\" max=\"1.\">0</param>\n"
+ "</page>\n"
+ "<page name=\"lightingtab\" gui-text=\"" N_("Lighting") "\">\n"
+ "<param name=\"lightingColor\" gui-text=\"" N_("Color") "\" type=\"color\">-1</param>\n"
+ "<param name=\"height\" gui-text=\"" N_("Height") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-50.\" max=\"50.\">5</param>\n"
+ "<param name=\"lightness\" gui-text=\"" N_("Lightness") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"10.\">1.4</param>\n"
+ "<param name=\"precision\" gui-text=\"" N_("Precision") "\" type=\"int\" appearance=\"full\" min=\"1\" max=\"50\">35</param>\n"
+ "<param name=\"distantAzimuth\" gui-text=\"" N_("Azimuth") "\" type=\"int\" indent=\"1\" appearance=\"full\" min=\"0\" max=\"360\">225</param>\n"
+ "<param name=\"distantElevation\" gui-text=\"" N_("Elevation") "\" type=\"int\" indent=\"1\" appearance=\"full\" min=\"0\" max=\"180\">60</param>\n"
+ "<param name=\"lightingblend\" gui-text=\"" N_("Lighting blend:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"screen\">" N_("Screen") "</option>\n"
+ "<option value=\"normal\">" N_("Normal") "</option>\n"
+ "<option value=\"darken\">" N_("Darken") "</option>\n"
+ "<option value=\"multiply\">" N_("Multiply") "</option>\n"
+ "<option value=\"lighten\">" N_("Lighten") "</option>\n"
+ "</param>\n"
+ "<param name=\"highlightblend\" gui-text=\"" N_("Highlight blend:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"screen\">" N_("Screen") "</option>\n"
+ "<option value=\"normal\">" N_("Normal") "</option>\n"
+ "<option value=\"darken\">" N_("Darken") "</option>\n"
+ "<option value=\"multiply\">" N_("Multiply") "</option>\n"
+ "<option value=\"lighten\">" N_("Lighten") "</option>\n"
+ "</param>\n"
+ "</page>\n"
+ "<page name=\"colortab\" gui-text=\"Bump\">\n"
+ "<param name=\"imageColor\" gui-text=\"" N_("Bump color") "\" type=\"color\">-520083713</param>\n"
+ "<param name=\"revert\" gui-text=\"" N_("Revert bump") "\" type=\"bool\" >false</param>\n"
+ "<param name=\"transparency\" gui-text=\"" N_("Transparency type:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"atop\">" N_("Atop") "</option>\n"
+ "<option value=\"in\">" N_("In") "</option>\n"
+ "</param>\n"
+ "</page>\n"
+ "</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Bumps") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Turns an image to jelly") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new WaxBump());
+ };
+
+};
+
+gchar const *
+WaxBump::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream simplifyImage;
+ std::ostringstream simplifyBump;
+ std::ostringstream crop;
+
+ std::ostringstream red;
+ std::ostringstream green;
+ std::ostringstream blue;
+
+ std::ostringstream background;
+ std::ostringstream bgopacity;
+
+ std::ostringstream height;
+ std::ostringstream lightness;
+ std::ostringstream precision;
+ std::ostringstream distantAzimuth;
+ std::ostringstream distantElevation;
+
+ std::ostringstream lightRed;
+ std::ostringstream lightGreen;
+ std::ostringstream lightBlue;
+
+ std::ostringstream floodRed;
+ std::ostringstream floodGreen;
+ std::ostringstream floodBlue;
+ std::ostringstream floodAlpha;
+
+ std::ostringstream revert;
+ std::ostringstream lightingblend;
+ std::ostringstream highlightblend;
+ std::ostringstream transparency;
+
+ simplifyImage << ext->get_param_float("simplifyImage");
+ simplifyBump << ext->get_param_float("simplifyBump");
+ crop << ext->get_param_float("crop");
+
+ red << ext->get_param_float("red") - 0.21;
+ green << ext->get_param_float("green") - 0.72;
+ blue << ext->get_param_float("blue") - 0.07;
+
+ background << ext->get_param_optiongroup("background");
+ bgopacity << ext->get_param_float("bgopacity");
+
+ height << ext->get_param_float("height");
+ lightness << ext->get_param_float("lightness");
+ precision << ext->get_param_int("precision");
+ distantAzimuth << ext->get_param_int("distantAzimuth");
+ distantElevation << ext->get_param_int("distantElevation");
+
+ guint32 lightingColor = ext->get_param_color("lightingColor");
+ lightRed << ((lightingColor >> 24) & 0xff);
+ lightGreen << ((lightingColor >> 16) & 0xff);
+ lightBlue << ((lightingColor >> 8) & 0xff);
+
+ guint32 imageColor = ext->get_param_color("imageColor");
+ floodRed << ((imageColor >> 24) & 0xff);
+ floodGreen << ((imageColor >> 16) & 0xff);
+ floodBlue << ((imageColor >> 8) & 0xff);
+ floodAlpha << (imageColor & 0xff) / 255.0F;
+
+ if (ext->get_param_bool("revert")) {
+ revert << "in" ;
+ } else {
+ revert << "out" ;
+ }
+
+ lightingblend << ext->get_param_optiongroup("lightingblend");
+ highlightblend << ext->get_param_optiongroup("highlightblend");
+ transparency << ext->get_param_optiongroup("transparency");
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Wax Bump\">\n"
+ "<feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"%s\" result=\"blur1\" />\n"
+ "<feFlood flood-opacity=\"1\" flood-color=\"rgb(255,255,255)\" result=\"flood1\" />\n"
+ "<feColorMatrix in=\"%s\" values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 %s \" result=\"colormatrix1\" />\n"
+ "<feColorMatrix in=\"blur1\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 %s %s %s %s 0 \" result=\"colormatrix2\" />\n"
+ "<feFlood flood-color=\"rgb(%s,%s,%s)\" flood-opacity=\"%s\" result=\"flood2\" />\n"
+ "<feComposite in=\"flood2\" in2=\"colormatrix2\" operator=\"%s\" result=\"composite1\" />\n"
+ "<feGaussianBlur in=\"composite1\" stdDeviation=\"%s\" result=\"blur2\" />\n"
+ "<feSpecularLighting in=\"blur2\" lighting-color=\"rgb(%s,%s,%s)\" specularConstant=\"%s\" surfaceScale=\"%s\" specularExponent=\"%s\" result=\"specular\">\n"
+ "<feDistantLight elevation=\"%s\" azimuth=\"%s\" />\n"
+ "</feSpecularLighting>\n"
+ "<feBlend in=\"specular\" in2=\"blur2\" specularConstant=\"1\" mode=\"%s\" result=\"blend1\" />\n"
+ "<feComposite in=\"blend1\" in2=\"blur2\" k2=\"0\" operator=\"%s\" k1=\"0.5\" k3=\"0.5\" k4=\"0\" result=\"composite2\" />\n"
+ "<feMerge result=\"merge\">\n"
+ "<feMergeNode in=\"colormatrix1\" />\n"
+ "<feMergeNode in=\"composite2\" />\n"
+ "</feMerge>\n"
+ "<feBlend in2=\"composite2\" mode=\"%s\" result=\"blend2\" />\n"
+ "<feComposite in=\"blend2\" in2=\"SourceGraphic\" operator=\"in\" result=\"composite3\" />\n"
+ "</filter>\n", simplifyImage.str().c_str(), background.str().c_str(), bgopacity.str().c_str(),
+ red.str().c_str(), green.str().c_str(), blue.str().c_str(), crop.str().c_str(),
+ floodRed.str().c_str(), floodGreen.str().c_str(), floodBlue.str().c_str(), floodAlpha.str().c_str(),
+ revert.str().c_str(), simplifyBump.str().c_str(),
+ lightRed.str().c_str(), lightGreen.str().c_str(), lightBlue.str().c_str(),
+ lightness.str().c_str(), height.str().c_str(), precision.str().c_str(),
+ distantElevation.str().c_str(), distantAzimuth.str().c_str(),
+ lightingblend.str().c_str(), transparency.str().c_str(), highlightblend.str().c_str() );
+
+ return _filter;
+
+}; /* Wax bump filter */
+
+}; /* namespace Filter */
+}; /* namespace Internal */
+}; /* namespace Extension */
+}; /* namespace Inkscape */
+
+/* Change the 'BUMPS' below to be your file name */
+#endif /* SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_BUMPS_H__ */
diff --git a/src/extension/internal/filter/color.h b/src/extension/internal/filter/color.h
new file mode 100644
index 0000000..1b0b9e2
--- /dev/null
+++ b/src/extension/internal/filter/color.h
@@ -0,0 +1,1886 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#ifndef SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_COLOR_H__
+#define SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_COLOR_H__
+/* Change the 'COLOR' above to be your file name */
+
+/*
+ * Copyright (C) 2013-2015 Authors:
+ * Ivan Louette (filters)
+ * Nicolas Dufour (UI) <nicoduf@yahoo.fr>
+ *
+ * Color filters
+ * Brilliance
+ * Channel painting
+ * Color blindness
+ * Color shift
+ * Colorize
+ * Component transfer
+ * Duochrome
+ * Extract channel
+ * Fade to black or white
+ * Greyscale
+ * Invert
+ * Lighting
+ * Lightness-contrast
+ * Nudge RGB
+ * Nudge CMY
+ * Quadritone
+ * Simple blend
+ * Solarize
+ * Tritone
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+/* ^^^ Change the copyright to be you and your e-mail address ^^^ */
+
+#include "filter.h"
+
+#include "extension/internal/clear-n_.h"
+#include "extension/system.h"
+#include "extension/extension.h"
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+namespace Filter {
+
+/**
+ \brief Custom predefined Brilliance filter.
+
+ Brilliance filter.
+
+ Filter's parameters:
+ * Brilliance (1.->10., default 2.) -> colorMatrix (RVB entries)
+ * Over-saturation (0.->10., default 0.5) -> colorMatrix (6 other entries)
+ * Lightness (-10.->10., default 0.) -> colorMatrix (last column)
+ * Inverted (boolean, default false) -> colorMatrix
+
+ Matrix:
+ St Vi Vi 0 Li
+ Vi St Vi 0 Li
+ Vi Vi St 0 Li
+ 0 0 0 1 0
+*/
+class Brilliance : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ Brilliance ( ) : Filter() { };
+ ~Brilliance ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Brilliance") "</name>\n"
+ "<id>org.inkscape.effect.filter.Brilliance</id>\n"
+ "<param name=\"brightness\" gui-text=\"" N_("Brightness") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"1\" max=\"10.00\">2</param>\n"
+ "<param name=\"sat\" gui-text=\"" N_("Over-saturation") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.0\" max=\"10.00\">0.5</param>\n"
+ "<param name=\"lightness\" gui-text=\"" N_("Lightness") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-10.00\" max=\"10.00\">0</param>\n"
+ "<param name=\"invert\" gui-text=\"" N_("Inverted") "\" type=\"bool\">false</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Color") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Brightness filter") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new Brilliance());
+ };
+};
+
+gchar const *
+Brilliance::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream brightness;
+ std::ostringstream sat;
+ std::ostringstream lightness;
+
+ if (ext->get_param_bool("invert")) {
+ brightness << -ext->get_param_float("brightness");
+ sat << 1 + ext->get_param_float("sat");
+ lightness << -ext->get_param_float("lightness");
+ } else {
+ brightness << ext->get_param_float("brightness");
+ sat << -ext->get_param_float("sat");
+ lightness << ext->get_param_float("lightness");
+ }
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Brilliance\">\n"
+ "<feColorMatrix values=\"%s %s %s 0 %s %s %s %s 0 %s %s %s %s 0 %s 0 0 0 1 0 \" />\n"
+ "</filter>\n", brightness.str().c_str(), sat.str().c_str(), sat.str().c_str(),
+ lightness.str().c_str(), sat.str().c_str(), brightness.str().c_str(),
+ sat.str().c_str(), lightness.str().c_str(), sat.str().c_str(),
+ sat.str().c_str(), brightness.str().c_str(), lightness.str().c_str() );
+
+ return _filter;
+}; /* Brilliance filter */
+
+/**
+ \brief Custom predefined Channel Painting filter.
+
+ Channel Painting filter.
+
+ Filter's parameters:
+ * Saturation (0.->1., default 1.) -> colormatrix1 (values)
+ * Red (-10.->10., default -1.) -> colormatrix2 (values)
+ * Green (-10.->10., default 0.5) -> colormatrix2 (values)
+ * Blue (-10.->10., default 0.5) -> colormatrix2 (values)
+ * Alpha (-10.->10., default 1.) -> colormatrix2 (values)
+ * Flood colors (guint, default 16777215) -> flood (flood-opacity, flood-color)
+ * Inverted (boolean, default false) -> composite1 (operator, true='in', false='out')
+
+ Matrix:
+ 1 0 0 0 0
+ 0 1 0 0 0
+ 0 0 1 0 0
+ R G B A 0
+*/
+class ChannelPaint : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ ChannelPaint ( ) : Filter() { };
+ ~ChannelPaint ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Channel Painting") "</name>\n"
+ "<id>org.inkscape.effect.filter.ChannelPaint</id>\n"
+ "<param name=\"tab\" type=\"notebook\">\n"
+ "<page name=\"optionstab\" gui-text=\"Options\">\n"
+ "<param name=\"saturation\" gui-text=\"" N_("Saturation") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.\" max=\"1.\">1</param>\n"
+ "<param name=\"red\" gui-text=\"" N_("Red") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-10.\" max=\"10.\">-1</param>\n"
+ "<param name=\"green\" gui-text=\"" N_("Green") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-10.\" max=\"10.\">0.5</param>\n"
+ "<param name=\"blue\" gui-text=\"" N_("Blue") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-10.\" max=\"10.\">0.5</param>\n"
+ "<param name=\"alpha\" gui-text=\"" N_("Alpha") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-10.\" max=\"10.\">1</param>\n"
+ "<param name=\"invert\" gui-text=\"" N_("Inverted") "\" type=\"bool\">false</param>\n"
+ "</page>\n"
+ "<page name=\"colortab\" gui-text=\"Color\">\n"
+ "<param name=\"color\" gui-text=\"" N_("Color") "\" type=\"color\">16777215</param>\n"
+ "</page>\n"
+ "</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Color") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Replace RGB by any color") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new ChannelPaint());
+ };
+};
+
+gchar const *
+ChannelPaint::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream saturation;
+ std::ostringstream red;
+ std::ostringstream green;
+ std::ostringstream blue;
+ std::ostringstream alpha;
+ std::ostringstream invert;
+ std::ostringstream floodRed;
+ std::ostringstream floodGreen;
+ std::ostringstream floodBlue;
+ std::ostringstream floodAlpha;
+
+ saturation << ext->get_param_float("saturation");
+ red << ext->get_param_float("red");
+ green << ext->get_param_float("green");
+ blue << ext->get_param_float("blue");
+ alpha << ext->get_param_float("alpha");
+
+ guint32 color = ext->get_param_color("color");
+ floodRed << ((color >> 24) & 0xff);
+ floodGreen << ((color >> 16) & 0xff);
+ floodBlue << ((color >> 8) & 0xff);
+ floodAlpha << (color & 0xff) / 255.0F;
+
+ if (ext->get_param_bool("invert")) {
+ invert << "in";
+ } else {
+ invert << "out";
+ }
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Channel Painting\">\n"
+ "<feColorMatrix values=\"%s\" type=\"saturate\" result=\"colormatrix1\" />\n"
+ "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 %s %s %s %s 0 \" in=\"SourceGraphic\" result=\"colormatrix2\" />\n"
+ "<feFlood flood-color=\"rgb(%s,%s,%s)\" flood-opacity=\"%s\" result=\"flood\" />\n"
+ "<feComposite in2=\"colormatrix2\" operator=\"%s\" result=\"composite1\" />\n"
+ "<feMerge result=\"merge\">\n"
+ "<feMergeNode in=\"colormatrix1\" />\n"
+ "<feMergeNode in=\"composite1\" />\n"
+ "</feMerge>\n"
+ "<feComposite in=\"merge\" in2=\"SourceGraphic\" operator=\"in\" result=\"composite2\" />\n"
+ "</filter>\n", saturation.str().c_str(), red.str().c_str(), green.str().c_str(),
+ blue.str().c_str(), alpha.str().c_str(), floodRed.str().c_str(),
+ floodGreen.str().c_str(), floodBlue.str().c_str(), floodAlpha.str().c_str(),
+ invert.str().c_str() );
+
+ return _filter;
+}; /* Channel Painting filter */
+
+/**
+ \brief Custom predefined Color Blindness filter.
+
+ Color Blindness filter.
+ Based on https://openclipart.org/detail/22299/Color%20Blindness%20filters
+
+ Filter's parameters:
+ * Blindness type (enum, default Achromatomaly) -> colormatrix
+*/
+class ColorBlindness : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ ColorBlindness ( ) : Filter() { };
+ ~ColorBlindness ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Color Blindness") "</name>\n"
+ "<id>org.inkscape.effect.filter.ColorBlindness</id>\n"
+ "<param name=\"tab\" type=\"notebook\">\n"
+ "<page name=\"optionstab\" gui-text=\"Options\">\n"
+ "<param name=\"type\" gui-text=\"" N_("Blindness type:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"0.618 0.32 0.062 0 0 0.163 0.775 0.062 0 0 0.163 0.32 0.516 0 0 0 0 0 1 0 \">" N_("Rod monochromacy (atypical achromatopsia)") "</option>\n"
+ "<option value=\"0.299 0.587 0.114 0 0 0.299 0.587 0.114 0 0 0.299 0.587 0.114 0 0 0 0 0 1 0 \">" N_("Cone monochromacy (typical achromatopsia)") "</option>\n"
+ "<option value=\"0.8 0.2 0 0 0 0.2583 0.74167 0 0 0 0 0.14167 0.85833 0 0 0 0 0 1 0 \">" N_("Green weak (deuteranomaly)") "</option>\n"
+ "<option value=\"0.625 0.375 0 0 0 0.7 0.3 0 0 0 0 0.3 0.7 0 0 0 0 0 1 0 \">" N_("Green blind (deuteranopia)") "</option>\n"
+ "<option value=\"0.8166 0.1833 0 0 0 0.333 0.666 0 0 0 0 0.125 0.875 0 0 0 0 0 1 0 \">" N_("Red weak (protanomaly)") "</option>\n"
+ "<option value=\"0.566 0.43333 0 0 0 0.55833 0.4416 0 0 0 0 0.24167 0.75833 0 0 0 0 0 1 0 \">" N_("Red blind (protanopia)") "</option>\n"
+ "<option value=\"0.966 0.033 0 0 0 0 0.733 0.266 0 0 0 0.1833 0.816 0 0 0 0 0 1 0 \">" N_("Blue weak (tritanomaly)") "</option>\n"
+ "<option value=\"0.95 0.05 0 0 0 0.2583 0.4333 0.5667 0 0 0 0.475 0.525 0 0 0 0 0 1 0 \">" N_("Blue blind (tritanopia)") "</option>\n"
+ "</param>\n"
+ "</page>\n"
+ "<page name=\"helptab\" gui-text=\"Help\">\n"
+ "<label xml:space=\"preserve\">\n"
+"Filters based on https://openclipart.org/detail/22299/Color%20Blindness%20filters\n"
+"\n"
+"These filters don't correctly reflect actual color blindness for two main reasons:\n"
+" * Everyone is different, and is not affected exactly the same way.\n"
+" * The filters are in the RGB color space, and ignore confusion lines.\n"
+ "</label>\n"
+ "</page>\n"
+ "</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Color") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Simulate color blindness") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new ColorBlindness());
+ };
+};
+
+gchar const *
+ColorBlindness::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream type;
+ type << ext->get_param_optiongroup("type");
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" height=\"1\" width=\"1\" y=\"0\" x=\"0\" inkscape:label=\"Color Blindness\">\n"
+ "<feColorMatrix values=\"%s\" type=\"matrix\" result=\"colormatrix1\" />\n"
+ "</filter>\n", type.str().c_str());
+
+ return _filter;
+}; /* Color Blindness filter */
+
+/**
+ \brief Custom predefined Color shift filter.
+
+ Rotate and desaturate hue
+
+ Filter's parameters:
+ * Shift (0->360, default 330) -> color1 (values)
+ * Saturation (0.->1., default 0.6) -> color2 (values)
+*/
+
+class ColorShift : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ ColorShift ( ) : Filter() { };
+ ~ColorShift ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Color Shift") "</name>\n"
+ "<id>org.inkscape.effect.filter.ColorShift</id>\n"
+ "<param name=\"shift\" gui-text=\"" N_("Shift (°)") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">330</param>\n"
+ "<param name=\"sat\" gui-text=\"" N_("Saturation") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.\" max=\"1\">0.6</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Color") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Rotate and desaturate hue") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new ColorShift());
+ };
+
+};
+
+gchar const *
+ColorShift::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream shift;
+ std::ostringstream sat;
+
+ shift << ext->get_param_int("shift");
+ sat << ext->get_param_float("sat");
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Color Shift\">\n"
+ "<feColorMatrix type=\"hueRotate\" values=\"%s\" result=\"color1\" />\n"
+ "<feColorMatrix type=\"saturate\" values=\"%s\" result=\"color2\" />\n"
+ "</filter>\n", shift.str().c_str(), sat.str().c_str() );
+
+ return _filter;
+}; /* ColorShift filter */
+
+/**
+ \brief Custom predefined Colorize filter.
+
+ Blend image or object with a flood color.
+
+ Filter's parameters:
+ * Harsh light (0.->10., default 0) -> composite1 (k1)
+ * Normal light (0.->10., default 1) -> composite2 (k2)
+ * Duotone (boolean, default false) -> colormatrix1 (values="0")
+ * Filtered greys (boolean, default false) -> colormatrix2 (values="0")
+ * Blend mode 1 (enum, default Multiply) -> blend1 (mode)
+ * Blend mode 2 (enum, default Screen) -> blend2 (mode)
+*/
+
+class Colorize : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ Colorize ( ) : Filter() { };
+ ~Colorize ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Colorize") "</name>\n"
+ "<id>org.inkscape.effect.filter.Colorize</id>\n"
+ "<param name=\"tab\" type=\"notebook\">\n"
+ "<page name=\"optionstab\" gui-text=\"Options\">\n"
+ "<param name=\"hlight\" gui-text=\"" N_("Harsh light") "\" type=\"float\" appearance=\"full\" min=\"0\" max=\"10\">0</param>\n"
+ "<param name=\"nlight\" gui-text=\"" N_("Normal light") "\" type=\"float\" appearance=\"full\" min=\"0\" max=\"10\">1</param>\n"
+ "<param name=\"duotone\" gui-text=\"" N_("Duotone") "\" type=\"bool\" >false</param>\n"
+ "<param name=\"blend1\" gui-text=\"" N_("Blend 1:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"multiply\">" N_("Multiply") "</option>\n"
+ "<option value=\"normal\">" N_("Normal") "</option>\n"
+ "<option value=\"screen\">" N_("Screen") "</option>\n"
+ "<option value=\"lighten\">" N_("Lighten") "</option>\n"
+ "<option value=\"darken\">" N_("Darken") "</option>\n"
+ "</param>\n"
+ "<param name=\"blend2\" gui-text=\"" N_("Blend 2:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"screen\">" N_("Screen") "</option>\n"
+ "<option value=\"multiply\">" N_("Multiply") "</option>\n"
+ "<option value=\"normal\">" N_("Normal") "</option>\n"
+ "<option value=\"lighten\">" N_("Lighten") "</option>\n"
+ "<option value=\"darken\">" N_("Darken") "</option>\n"
+ "</param>\n"
+ "</page>\n"
+ "<page name=\"colortab\" gui-text=\"Color\">\n"
+ "<param name=\"color\" gui-text=\"" N_("Color") "\" type=\"color\">-1639776001</param>\n"
+ "</page>\n"
+ "</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Color") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Blend image or object with a flood color") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new Colorize());
+ };
+
+};
+
+gchar const *
+Colorize::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream a;
+ std::ostringstream r;
+ std::ostringstream g;
+ std::ostringstream b;
+ std::ostringstream hlight;
+ std::ostringstream nlight;
+ std::ostringstream duotone;
+ std::ostringstream blend1;
+ std::ostringstream blend2;
+
+ guint32 color = ext->get_param_color("color");
+ r << ((color >> 24) & 0xff);
+ g << ((color >> 16) & 0xff);
+ b << ((color >> 8) & 0xff);
+ a << (color & 0xff) / 255.0F;
+
+ hlight << ext->get_param_float("hlight");
+ nlight << ext->get_param_float("nlight");
+ blend1 << ext->get_param_optiongroup("blend1");
+ blend2 << ext->get_param_optiongroup("blend2");
+ if (ext->get_param_bool("duotone")) {
+ duotone << "0";
+ } else {
+ duotone << "1";
+ }
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Colorize\">\n"
+ "<feComposite in2=\"SourceGraphic\" operator=\"arithmetic\" k1=\"%s\" k2=\"%s\" result=\"composite1\" />\n"
+ "<feColorMatrix in=\"composite1\" values=\"%s\" type=\"saturate\" result=\"colormatrix1\" />\n"
+ "<feFlood flood-opacity=\"%s\" flood-color=\"rgb(%s,%s,%s)\" result=\"flood1\" />\n"
+ "<feBlend in=\"flood1\" in2=\"colormatrix1\" mode=\"%s\" result=\"blend1\" />\n"
+ "<feBlend in2=\"blend1\" mode=\"%s\" result=\"blend2\" />\n"
+ "<feColorMatrix in=\"blend2\" values=\"1\" type=\"saturate\" result=\"colormatrix2\" />\n"
+ "<feComposite in=\"colormatrix2\" in2=\"SourceGraphic\" operator=\"in\" k2=\"1\" result=\"composite2\" />\n"
+ "</filter>\n", hlight.str().c_str(), nlight.str().c_str(), duotone.str().c_str(),
+ a.str().c_str(), r.str().c_str(), g.str().c_str(), b.str().c_str(),
+ blend1.str().c_str(), blend2.str().c_str() );
+
+ return _filter;
+}; /* Colorize filter */
+
+/**
+ \brief Custom predefined ComponentTransfer filter.
+
+ Basic component transfer structure.
+
+ Filter's parameters:
+ * Type (enum, default identity) -> component function
+
+*/
+class ComponentTransfer : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ ComponentTransfer ( ) : Filter() { };
+ ~ComponentTransfer ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Component Transfer") "</name>\n"
+ "<id>org.inkscape.effect.filter.ComponentTransfer</id>\n"
+ "<param name=\"type\" gui-text=\"" N_("Type:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"identity\">" N_("Identity") "</option>\n"
+ "<option value=\"table\">" N_("Table") "</option>\n"
+ "<option value=\"discrete\">" N_("Discrete") "</option>\n"
+ "<option value=\"linear\">" N_("Linear") "</option>\n"
+ "<option value=\"gamma\">" N_("Gamma") "</option>\n"
+ "</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Color") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Basic component transfer structure") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new ComponentTransfer());
+ };
+};
+
+gchar const *
+ComponentTransfer::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream CTfunction;
+ const gchar *type = ext->get_param_optiongroup("type");
+
+ if ((g_ascii_strcasecmp("identity", type) == 0)) {
+ CTfunction << "<feFuncR type=\"identity\" tableValues=\"1 0\" />\n"
+ << "<feFuncG type=\"identity\" tableValues=\"1 0\" />\n"
+ << "<feFuncB type=\"identity\" tableValues=\"1 0\" />\n"
+ << "<feFuncA type=\"identity\" tableValues=\"0 1\" />\n";
+ } else if ((g_ascii_strcasecmp("table", type) == 0)) {
+ CTfunction << "<feFuncR type=\"table\" tableValues=\"0 1 0\" />\n"
+ << "<feFuncG type=\"table\" tableValues=\"0 1 0\" />\n"
+ << "<feFuncB type=\"table\" tableValues=\"0 1 0\" />\n";
+ } else if ((g_ascii_strcasecmp("discrete", type) == 0)) {
+ CTfunction << "<feFuncR tableValues=\"0 0.2 0.4 0.6 0.8 1 1\" type=\"discrete\" />\n"
+ << "<feFuncG tableValues=\"0 0.2 0.4 0.6 0.8 1 1\" type=\"discrete\" />\n"
+ << "<feFuncB tableValues=\"0 0.2 0.4 0.6 0.8 1 1\" type=\"discrete\" />\n";
+ } else if ((g_ascii_strcasecmp("linear", type) == 0)) {
+ CTfunction << "<feFuncR type=\"linear\" slope=\".5\" intercept=\".10\" />\n"
+ << "<feFuncG type=\"linear\" slope=\".5\" intercept=\".10\" />\n"
+ << "<feFuncB type=\"linear\" slope=\".5\" intercept=\".10\" />\n";
+ } else { //Gamma
+ CTfunction << "<feFuncR type=\"gamma\" amplitude=\"3\" exponent=\"3\" offset=\"0.1\" />\n"
+ << "<feFuncG type=\"gamma\" amplitude=\"3\" exponent=\"3\" offset=\"0.1\" />\n"
+ << "<feFuncB type=\"gamma\" amplitude=\"3\" exponent=\"3\" offset=\"0.1\" />\n";
+ }
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Component Transfer\">\n"
+ "<feComponentTransfer>\n"
+ "%s\n"
+ "</feComponentTransfer>\n"
+ "</filter>\n", CTfunction.str().c_str());
+
+ return _filter;
+}; /* ComponentTransfer filter */
+
+/**
+ \brief Custom predefined Duochrome filter.
+
+ Convert luminance values to a duochrome palette.
+
+ Filter's parameters:
+ * Fluorescence level (0.->2., default 0) -> composite4 (k2)
+ * Swap (enum, default "No swap") -> composite1, composite2 (operator)
+ * Color 1 (guint, default 1364325887) -> flood1 (flood-opacity, flood-color)
+ * Color 2 (guint, default -65281) -> flood2 (flood-opacity, flood-color)
+*/
+
+class Duochrome : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ Duochrome ( ) : Filter() { };
+ ~Duochrome ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Duochrome") "</name>\n"
+ "<id>org.inkscape.effect.filter.Duochrome</id>\n"
+ "<param name=\"tab\" type=\"notebook\">\n"
+ "<page name=\"optionstab\" gui-text=\"Options\">\n"
+ "<param name=\"fluo\" gui-text=\"" N_("Fluorescence level") "\" type=\"float\" appearance=\"full\" min=\"0\" max=\"2\">0</param>\n"
+ "<param name=\"swap\" gui-text=\"" N_("Swap:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"none\">" N_("No swap") "</option>\n"
+ "<option value=\"full\">" N_("Color and alpha") "</option>\n"
+ "<option value=\"color\">" N_("Color only") "</option>\n"
+ "<option value=\"alpha\">" N_("Alpha only") "</option>\n"
+ "</param>\n"
+ "</page>\n"
+ "<page name=\"co11tab\" gui-text=\"Color 1\">\n"
+ "<param name=\"color1\" gui-text=\"" N_("Color 1") "\" type=\"color\">1364325887</param>\n"
+ "</page>\n"
+ "<page name=\"co12tab\" gui-text=\"Color 2\">\n"
+ "<param name=\"color2\" gui-text=\"" N_("Color 2") "\" type=\"color\">-65281</param>\n"
+ "</page>\n"
+ "</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Color") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Convert luminance values to a duochrome palette") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new Duochrome());
+ };
+
+};
+
+gchar const *
+Duochrome::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream a1;
+ std::ostringstream r1;
+ std::ostringstream g1;
+ std::ostringstream b1;
+ std::ostringstream a2;
+ std::ostringstream r2;
+ std::ostringstream g2;
+ std::ostringstream b2;
+ std::ostringstream fluo;
+ std::ostringstream swap1;
+ std::ostringstream swap2;
+ guint32 color1 = ext->get_param_color("color1");
+ guint32 color2 = ext->get_param_color("color2");
+ float fluorescence = ext->get_param_float("fluo");
+ const gchar *swaptype = ext->get_param_optiongroup("swap");
+
+ r1 << ((color1 >> 24) & 0xff);
+ g1 << ((color1 >> 16) & 0xff);
+ b1 << ((color1 >> 8) & 0xff);
+ r2 << ((color2 >> 24) & 0xff);
+ g2 << ((color2 >> 16) & 0xff);
+ b2 << ((color2 >> 8) & 0xff);
+ fluo << fluorescence;
+
+ if ((g_ascii_strcasecmp("full", swaptype) == 0)) {
+ swap1 << "in";
+ swap2 << "out";
+ a1 << (color1 & 0xff) / 255.0F;
+ a2 << (color2 & 0xff) / 255.0F;
+ } else if ((g_ascii_strcasecmp("color", swaptype) == 0)) {
+ swap1 << "in";
+ swap2 << "out";
+ a1 << (color2 & 0xff) / 255.0F;
+ a2 << (color1 & 0xff) / 255.0F;
+ } else if ((g_ascii_strcasecmp("alpha", swaptype) == 0)) {
+ swap1 << "out";
+ swap2 << "in";
+ a1 << (color2 & 0xff) / 255.0F;
+ a2 << (color1 & 0xff) / 255.0F;
+ } else {
+ swap1 << "out";
+ swap2 << "in";
+ a1 << (color1 & 0xff) / 255.0F;
+ a2 << (color2 & 0xff) / 255.0F;
+ }
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Duochrome\">\n"
+ "<feColorMatrix type=\"luminanceToAlpha\" result=\"colormatrix1\" />\n"
+ "<feFlood flood-opacity=\"%s\" flood-color=\"rgb(%s,%s,%s)\" result=\"flood1\" />\n"
+ "<feComposite in2=\"colormatrix1\" operator=\"%s\" result=\"composite1\" />\n"
+ "<feFlood flood-opacity=\"%s\" flood-color=\"rgb(%s,%s,%s)\" result=\"flood2\" />\n"
+ "<feComposite in2=\"colormatrix1\" result=\"composite2\" operator=\"%s\" />\n"
+ "<feComposite in=\"composite2\" in2=\"composite1\" k2=\"1\" k3=\"1\" operator=\"arithmetic\" result=\"composite3\" />\n"
+ "<feColorMatrix in=\"composite3\" type=\"matrix\" values=\"2 -1 0 0 0 0 2 -1 0 0 -1 0 2 0 0 0 0 0 1 0 \" result=\"colormatrix2\" />\n"
+ "<feComposite in=\"colormatrix2\" in2=\"composite3\" operator=\"arithmetic\" k2=\"%s\" result=\"composite4\" />\n"
+ "<feBlend in=\"composite4\" in2=\"composite3\" mode=\"normal\" result=\"blend\" />\n"
+ "<feComposite in2=\"SourceGraphic\" operator=\"in\" />\n"
+ "</filter>\n", a1.str().c_str(), r1.str().c_str(), g1.str().c_str(), b1.str().c_str(), swap1.str().c_str(),
+ a2.str().c_str(), r2.str().c_str(), g2.str().c_str(), b2.str().c_str(), swap2.str().c_str(),
+ fluo.str().c_str() );
+
+ return _filter;
+}; /* Duochrome filter */
+
+/**
+ \brief Custom predefined Extract Channel filter.
+
+ Extract color channel as a transparent image.
+
+ Filter's parameters:
+ * Channel (enum, all colors, default Red) -> colormatrix (values)
+ * Background blend (enum, Normal, Multiply, Screen, default Normal) -> blend (mode)
+ * Channel to alpha (boolean, default false) -> colormatrix (values)
+
+*/
+class ExtractChannel : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ ExtractChannel ( ) : Filter() { };
+ ~ExtractChannel ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Extract Channel") "</name>\n"
+ "<id>org.inkscape.effect.filter.ExtractChannel</id>\n"
+ "<param name=\"source\" gui-text=\"" N_("Channel:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"r\">" N_("Red") "</option>\n"
+ "<option value=\"g\">" N_("Green") "</option>\n"
+ "<option value=\"b\">" N_("Blue") "</option>\n"
+ "<option value=\"c\">" N_("Cyan") "</option>\n"
+ "<option value=\"m\">" N_("Magenta") "</option>\n"
+ "<option value=\"y\">" N_("Yellow") "</option>\n"
+ "</param>\n"
+ "<param name=\"blend\" gui-text=\"" N_("Background blend mode:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"multiply\">" N_("Multiply") "</option>\n"
+ "<option value=\"normal\">" N_("Normal") "</option>\n"
+ "<option value=\"screen\">" N_("Screen") "</option>\n"
+ "</param>\n"
+ "<param name=\"alpha\" gui-text=\"" N_("Channel to alpha") "\" type=\"bool\">false</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Color") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Extract color channel as a transparent image") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new ExtractChannel());
+ };
+};
+
+gchar const *
+ExtractChannel::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream blend;
+ std::ostringstream colors;
+
+ blend << ext->get_param_optiongroup("blend");
+
+ const gchar *channel = ext->get_param_optiongroup("source");
+ if (ext->get_param_bool("alpha")) {
+ if ((g_ascii_strcasecmp("r", channel) == 0)) {
+ colors << "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0";
+ } else if ((g_ascii_strcasecmp("g", channel) == 0)) {
+ colors << "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0";
+ } else if ((g_ascii_strcasecmp("b", channel) == 0)) {
+ colors << "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0";
+ } else if ((g_ascii_strcasecmp("c", channel) == 0)) {
+ colors << "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 0 0 1 0";
+ } else if ((g_ascii_strcasecmp("m", channel) == 0)) {
+ colors << "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 0 1 0";
+ } else {
+ colors << "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 0";
+ }
+ } else {
+ if ((g_ascii_strcasecmp("r", channel) == 0)) {
+ colors << "0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0";
+ } else if ((g_ascii_strcasecmp("g", channel) == 0)) {
+ colors << "0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0";
+ } else if ((g_ascii_strcasecmp("b", channel) == 0)) {
+ colors << "0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0";
+ } else if ((g_ascii_strcasecmp("c", channel) == 0)) {
+ colors << "0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 -1 0 0 1 0";
+ } else if ((g_ascii_strcasecmp("m", channel) == 0)) {
+ colors << "0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 -1 0 1 0";
+ } else {
+ colors << "0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 -1 1 0";
+ }
+ }
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Extract Channel\">\n"
+ "<feColorMatrix in=\"SourceGraphic\" values=\"%s 0 \" result=\"colormatrix\" />\n"
+ "<feBlend in2=\"BackgroundImage\" mode=\"%s\" result=\"blend\" />\n"
+ "</filter>\n", colors.str().c_str(), blend.str().c_str() );
+
+ return _filter;
+}; /* ExtractChannel filter */
+
+/**
+ \brief Custom predefined Fade to Black or White filter.
+
+ Fade to black or white.
+
+ Filter's parameters:
+ * Level (0.->1., default 1.) -> colorMatrix (RVB entries)
+ * Fade to (enum [black|white], default black) -> colorMatrix (RVB entries)
+
+ Matrix
+ black white
+ Lv 0 0 0 0 Lv 0 0 1-lv 0
+ 0 Lv 0 0 0 0 Lv 0 1-lv 0
+ 0 0 Lv 0 0 0 0 Lv 1-lv 0
+ 0 0 0 1 0 0 0 0 1 0
+*/
+class FadeToBW : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ FadeToBW ( ) : Filter() { };
+ ~FadeToBW ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Fade to Black or White") "</name>\n"
+ "<id>org.inkscape.effect.filter.FadeToBW</id>\n"
+ "<param name=\"level\" gui-text=\"" N_("Level") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"1\">1</param>\n"
+ "<param name=\"fadeto\" gui-text=\"" N_("Fade to:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"black\">" N_("Black") "</option>\n"
+ "<option value=\"white\">" N_("White") "</option>\n"
+ "</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Color") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Fade to black or white") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new FadeToBW());
+ };
+};
+
+gchar const *
+FadeToBW::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream level;
+ std::ostringstream wlevel;
+
+ level << ext->get_param_float("level");
+
+ const gchar *fadeto = ext->get_param_optiongroup("fadeto");
+ if ((g_ascii_strcasecmp("white", fadeto) == 0)) {
+ // White
+ wlevel << (1 - ext->get_param_float("level"));
+ } else {
+ // Black
+ wlevel << "0";
+ }
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Fade to Black or White\">\n"
+ "<feColorMatrix values=\"%s 0 0 0 %s 0 %s 0 0 %s 0 0 %s 0 %s 0 0 0 1 0\" />\n"
+ "</filter>\n", level.str().c_str(), wlevel.str().c_str(),
+ level.str().c_str(), wlevel.str().c_str(),
+ level.str().c_str(), wlevel.str().c_str() );
+
+ return _filter;
+}; /* Fade to black or white filter */
+
+/**
+ \brief Custom predefined Greyscale filter.
+
+ Customize greyscale components.
+
+ Filter's parameters:
+ * Red (-10.->10., default .21) -> colorMatrix (values)
+ * Green (-10.->10., default .72) -> colorMatrix (values)
+ * Blue (-10.->10., default .072) -> colorMatrix (values)
+ * Lightness (-10.->10., default 0.) -> colorMatrix (values)
+ * Transparent (boolean, default false) -> matrix structure
+
+ Matrix:
+ normal transparency
+ R G B St 0 0 0 0 0 0
+ R G B St 0 0 0 0 0 0
+ R G B St 0 0 0 0 0 0
+ 0 0 0 1 0 R G B 1-St 0
+*/
+class Greyscale : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ Greyscale ( ) : Filter() { };
+ ~Greyscale ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Greyscale") "</name>\n"
+ "<id>org.inkscape.effect.filter.Greyscale</id>\n"
+ "<param name=\"red\" gui-text=\"" N_("Red") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-10.00\" max=\"10.00\">0.21</param>\n"
+ "<param name=\"green\" gui-text=\"" N_("Green") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-10.00\" max=\"10.00\">0.72</param>\n"
+ "<param name=\"blue\" gui-text=\"" N_("Blue") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-10.00\" max=\"10.00\">0.072</param>\n"
+ "<param name=\"strength\" gui-text=\"" N_("Lightness") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-10.00\" max=\"10.00\">0</param>\n"
+ "<param name=\"transparent\" gui-text=\"" N_("Transparent") "\" type=\"bool\" >false</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Color") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Customize greyscale components") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new Greyscale());
+ };
+};
+
+gchar const *
+Greyscale::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream red;
+ std::ostringstream green;
+ std::ostringstream blue;
+ std::ostringstream strength;
+ std::ostringstream redt;
+ std::ostringstream greent;
+ std::ostringstream bluet;
+ std::ostringstream strengtht;
+ std::ostringstream transparency;
+ std::ostringstream line;
+
+ red << ext->get_param_float("red");
+ green << ext->get_param_float("green");
+ blue << ext->get_param_float("blue");
+ strength << ext->get_param_float("strength");
+
+ redt << - ext->get_param_float("red");
+ greent << - ext->get_param_float("green");
+ bluet << - ext->get_param_float("blue");
+ strengtht << 1 - ext->get_param_float("strength");
+
+ if (ext->get_param_bool("transparent")) {
+ line << "0 0 0 0";
+ transparency << redt.str().c_str() << " " << greent.str().c_str() << " " << bluet.str().c_str() << " " << strengtht.str().c_str();
+ } else {
+ line << red.str().c_str() << " " << green.str().c_str() << " " << blue.str().c_str() << " " << strength.str().c_str();
+ transparency << "0 0 0 1";
+ }
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Greyscale\">\n"
+ "<feColorMatrix values=\"%s 0 %s 0 %s 0 %s 0 \" />\n"
+ "</filter>\n", line.str().c_str(), line.str().c_str(), line.str().c_str(), transparency.str().c_str() );
+ return _filter;
+}; /* Greyscale filter */
+
+/**
+ \brief Custom predefined Invert filter.
+
+ Manage hue, lightness and transparency inversions
+
+ Filter's parameters:
+ * Invert hue (boolean, default false) -> color1 (values, true: 180, false: 0)
+ * Invert lightness (boolean, default false) -> color1 (values, true: 180, false: 0; XOR with Invert hue),
+ color2 (values: from a00 to a22, if 1, set -1 and set 1 in ax4, if -1, set 1 and set 0 in ax4)
+ * Invert transparency (boolean, default false) -> color2 (values: negate a30, a31 and a32, substract 1 from a33)
+ * Invert channels (enum, default Red and blue) -> color2 (values -for R&B: swap ax0 and ax2 in the first 3 lines)
+ * Light transparency (0.->1., default 0.) -> color2 (values: a33=a33-x)
+*/
+
+class Invert : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ Invert ( ) : Filter() { };
+ ~Invert ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Invert") "</name>\n"
+ "<id>org.inkscape.effect.filter.Invert</id>\n"
+ "<param name=\"channels\" gui-text=\"" N_("Invert channels:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"0\">" N_("No inversion") "</option>\n"
+ "<option value=\"1\">" N_("Red and blue") "</option>\n"
+ "<option value=\"2\">" N_("Red and green") "</option>\n"
+ "<option value=\"3\">" N_("Green and blue") "</option>\n"
+ "</param>\n"
+ "<param name=\"opacify\" gui-text=\"" N_("Light transparency") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.\" max=\"1\">0</param>\n"
+ "<param name=\"hue\" gui-text=\"" N_("Invert hue") "\" type=\"bool\" >false</param>\n"
+ "<param name=\"lightness\" gui-text=\"" N_("Invert lightness") "\" type=\"bool\" >false</param>\n"
+ "<param name=\"transparency\" gui-text=\"" N_("Invert transparency") "\" type=\"bool\" >false</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Color") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Manage hue, lightness and transparency inversions") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new Invert());
+ };
+
+};
+
+gchar const *
+Invert::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream line1;
+ std::ostringstream line2;
+ std::ostringstream line3;
+
+ std::ostringstream col5;
+ std::ostringstream transparency;
+ std::ostringstream hue;
+
+ if (ext->get_param_bool("hue") ^ ext->get_param_bool("lightness")) {
+ hue << "<feColorMatrix type=\"hueRotate\" values=\"180\" result=\"color1\" />\n";
+ } else {
+ hue << "";
+ }
+
+ if (ext->get_param_bool("transparency")) {
+ transparency << "0.21 0.72 0.07 " << 1 - ext->get_param_float("opacify");
+ } else {
+ transparency << "-0.21 -0.72 -0.07 " << 2 - ext->get_param_float("opacify");
+ }
+
+ if (ext->get_param_bool("lightness")) {
+ switch (atoi(ext->get_param_optiongroup("channels"))) {
+ case 1:
+ line1 << "0 0 -1";
+ line2 << "0 -1 0";
+ line3 << "-1 0 0";
+ break;
+ case 2:
+ line1 << "0 -1 0";
+ line2 << "-1 0 0";
+ line3 << "0 0 -1";
+ break;
+ case 3:
+ line1 << "-1 0 0";
+ line2 << "0 0 -1";
+ line3 << "0 -1 0";
+ break;
+ default:
+ line1 << "-1 0 0";
+ line2 << "0 -1 0";
+ line3 << "0 0 -1";
+ break;
+ }
+ col5 << "1";
+ } else {
+ switch (atoi(ext->get_param_optiongroup("channels"))) {
+ case 1:
+ line1 << "0 0 1";
+ line2 << "0 1 0";
+ line3 << "1 0 0";
+ break;
+ case 2:
+ line1 << "0 1 0";
+ line2 << "1 0 0";
+ line3 << "0 0 1";
+ break;
+ case 3:
+ line1 << "1 0 0";
+ line2 << "0 0 1";
+ line3 << "0 1 0";
+ break;
+ default:
+ line1 << "1 0 0";
+ line2 << "0 1 0";
+ line3 << "0 0 1";
+ break;
+ }
+ col5 << "0";
+ }
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Invert\">\n"
+ "%s"
+ "<feColorMatrix values=\"%s 0 %s %s 0 %s %s 0 %s %s 0 \" result=\"color2\" />\n"
+ "</filter>\n", hue.str().c_str(),
+ line1.str().c_str(), col5.str().c_str(),
+ line2.str().c_str(), col5.str().c_str(),
+ line3.str().c_str(), col5.str().c_str(),
+ transparency.str().c_str() );
+
+ return _filter;
+}; /* Invert filter */
+
+/**
+ \brief Custom predefined Lighting filter.
+
+ Modify lights and shadows separately.
+
+ Filter's parameters:
+ * Lightness (0.->20., default 1.) -> component (amplitude)
+ * Shadow (0.->20., default 1.) -> component (exponent)
+ * Offset (-1.->1., default 0.) -> component (offset)
+*/
+class Lighting : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ Lighting ( ) : Filter() { };
+ ~Lighting ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Lighting") "</name>\n"
+ "<id>org.inkscape.effect.filter.Lighting</id>\n"
+ "<param name=\"amplitude\" gui-text=\"" N_("Lights") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.00\" max=\"20.00\">1</param>\n"
+ "<param name=\"exponent\" gui-text=\"" N_("Shadows") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.00\" max=\"20.00\">1</param>\n"
+ "<param name=\"offset\" gui-text=\"" N_("Offset") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-1.00\" max=\"1.00\">0</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Color") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Modify lights and shadows separately") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new Lighting());
+ };
+};
+
+gchar const *
+Lighting::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream amplitude;
+ std::ostringstream exponent;
+ std::ostringstream offset;
+
+ amplitude << ext->get_param_float("amplitude");
+ exponent << ext->get_param_float("exponent");
+ offset << ext->get_param_float("offset");
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Lighting\">\n"
+ "<feComponentTransfer in=\"blur\" result=\"component\" >\n"
+ "<feFuncR type=\"gamma\" amplitude=\"%s\" exponent=\"%s\" offset=\"%s\" />\n"
+ "<feFuncG type=\"gamma\" amplitude=\"%s\" exponent=\"%s\" offset=\"%s\" />\n"
+ "<feFuncB type=\"gamma\" amplitude=\"%s\" exponent=\"%s\" offset=\"%s\" />\n"
+ "</feComponentTransfer>\n"
+ "</filter>\n", amplitude.str().c_str(), exponent.str().c_str(), offset.str().c_str(),
+ amplitude.str().c_str(), exponent.str().c_str(), offset.str().c_str(),
+ amplitude.str().c_str(), exponent.str().c_str(), offset.str().c_str() );
+
+ return _filter;
+}; /* Lighting filter */
+
+/**
+ \brief Custom predefined Lightness-Contrast filter.
+
+ Modify lightness and contrast separately.
+
+ Filter's parameters:
+ * Lightness (0.->100., default 0.) -> colorMatrix
+ * Contrast (0.->100., default 0.) -> colorMatrix
+
+ Matrix:
+ Co/10 0 0 1+(Co-1)*Li/2000 -(Co-1)/20
+ 0 Co/10 0 1+(Co-1)*Li/2000 -(Co-1)/20
+ 0 0 Co/10 1+(Co-1)*Li/2000 -(Co-1)/20
+ 0 0 0 1 0
+*/
+class LightnessContrast : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ LightnessContrast ( ) : Filter() { };
+ ~LightnessContrast ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Lightness-Contrast") "</name>\n"
+ "<id>org.inkscape.effect.filter.LightnessContrast</id>\n"
+ "<param name=\"lightness\" gui-text=\"" N_("Lightness") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-100\" max=\"100\">0</param>\n"
+ "<param name=\"contrast\" gui-text=\"" N_("Contrast") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-100\" max=\"100\">0</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Color") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Modify lightness and contrast separately") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new LightnessContrast());
+ };
+};
+
+gchar const *
+LightnessContrast::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream lightness;
+ std::ostringstream contrast;
+ std::ostringstream contrast5;
+
+ gfloat c5;
+ if (ext->get_param_float("contrast") > 0) {
+ contrast << (1 + ext->get_param_float("contrast") / 10);
+ c5 = (- ext->get_param_float("contrast") / 20);
+ } else {
+ contrast << (1 + ext->get_param_float("contrast") / 100);
+ c5 =(- ext->get_param_float("contrast") / 200);
+ }
+
+ contrast5 << c5;
+ lightness << ((1 - c5) * ext->get_param_float("lightness") / 100);
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Lightness-Contrast\">\n"
+ "<feColorMatrix values=\"%s 0 0 %s %s 0 %s 0 %s %s 0 0 %s %s %s 0 0 0 1 0\" />\n"
+ "</filter>\n", contrast.str().c_str(), lightness.str().c_str(), contrast5.str().c_str(),
+ contrast.str().c_str(), lightness.str().c_str(), contrast5.str().c_str(),
+ contrast.str().c_str(), lightness.str().c_str(), contrast5.str().c_str() );
+
+ return _filter;
+}; /* Lightness-Contrast filter */
+
+/**
+ \brief Custom predefined Nudge RGB filter.
+
+ Nudge RGB channels separately and blend them to different types of backgrounds
+
+ Filter's parameters:
+ Offsets
+ * Red
+ * x (-100.->100., default -6) -> offset1 (dx)
+ * y (-100.->100., default -6) -> offset1 (dy)
+ * Green
+ * x (-100.->100., default 6) -> offset2 (dx)
+ * y (-100.->100., default 7) -> offset2 (dy)
+ * Blue
+ * x (-100.->100., default 1) -> offset3 (dx)
+ * y (-100.->100., default -16) -> offset3 (dy)
+ Color
+ * Background color (guint, default 255)-> flood (flood-color, flood-opacity)
+
+*/
+class NudgeRGB : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ NudgeRGB ( ) : Filter() { };
+ ~NudgeRGB ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Nudge RGB") "</name>\n"
+ "<id>org.inkscape.effect.filter.NudgeRGB</id>\n"
+ "<param name=\"tab\" type=\"notebook\">\n"
+ "<page name=\"offsettab\" gui-text=\"Offset\">\n"
+ "<label appearance=\"header\">" N_("Red offset") "</label>\n"
+ "<param name=\"rx\" gui-text=\"" N_("X") "\" type=\"float\" indent=\"1\" appearance=\"full\" precision=\"2\" min=\"-100.\" max=\"100.\">-6</param>\n"
+ "<param name=\"ry\" gui-text=\"" N_("Y") "\" type=\"float\" indent=\"1\" appearance=\"full\" precision=\"2\" min=\"-100.\" max=\"100.\">-6</param>\n"
+ "<label appearance=\"header\">" N_("Green offset") "</label>\n"
+ "<param name=\"gx\" gui-text=\"" N_("X") "\" type=\"float\" indent=\"1\" appearance=\"full\" precision=\"2\" min=\"-100.\" max=\"100.\">6</param>\n"
+ "<param name=\"gy\" gui-text=\"" N_("Y") "\" type=\"float\" indent=\"1\" appearance=\"full\" precision=\"2\" min=\"-100.\" max=\"100.\">7</param>\n"
+ "<label appearance=\"header\">" N_("Blue offset") "</label>\n"
+ "<param name=\"bx\" gui-text=\"" N_("X") "\" type=\"float\" indent=\"1\" appearance=\"full\" precision=\"2\" min=\"-100.\" max=\"100.\">1</param>\n"
+ "<param name=\"by\" gui-text=\"" N_("Y") "\" type=\"float\" indent=\"1\" appearance=\"full\" precision=\"2\" min=\"-100.\" max=\"100.\">-16</param>\n"
+ "</page>\n"
+ "<page name=\"coltab\" gui-text=\"Color\">\n"
+ "<param name=\"color\" gui-text=\"" N_("Background color") "\" type=\"color\">255</param>\n"
+ "</page>\n"
+ "</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Color") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Nudge RGB channels separately and blend them to different types of backgrounds") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new NudgeRGB());
+ };
+};
+
+gchar const *
+NudgeRGB::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream rx;
+ std::ostringstream ry;
+ std::ostringstream gx;
+ std::ostringstream gy;
+ std::ostringstream bx;
+ std::ostringstream by;
+
+ std::ostringstream a;
+ std::ostringstream r;
+ std::ostringstream g;
+ std::ostringstream b;
+
+ rx << ext->get_param_float("rx");
+ ry << ext->get_param_float("ry");
+ gx << ext->get_param_float("gx");
+ gy << ext->get_param_float("gy");
+ bx << ext->get_param_float("bx");
+ by << ext->get_param_float("by");
+
+ guint32 color = ext->get_param_color("color");
+ r << ((color >> 24) & 0xff);
+ g << ((color >> 16) & 0xff);
+ b << ((color >> 8) & 0xff);
+ a << (color & 0xff) / 255.0F;
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Nudge RGB\">\n"
+ "<feFlood flood-opacity=\"%s\" flood-color=\"rgb(%s,%s,%s)\" result=\"flood\" />\n"
+ "<feColorMatrix in=\"SourceGraphic\" values=\"0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 \" result=\"colormatrix1\" />\n"
+ "<feOffset dy=\"%s\" dx=\"%s\" result=\"offset1\" />\n"
+ "<feBlend in2=\"flood\" mode=\"screen\" result=\"blend1\" />\n"
+ "<feColorMatrix in=\"SourceGraphic\" values=\"0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 \" result=\"colormatrix2\" />\n"
+ "<feOffset dy=\"%s\" dx=\"%s\" result=\"offset2\" />\n"
+ "<feBlend in2=\"blend1\" mode=\"screen\" result=\"blend2\" />\n"
+ "<feOffset dy=\"%s\" dx=\"%s\" result=\"offset3\" />\n"
+ "<feColorMatrix in=\"SourceGraphic\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 \" result=\"colormatrix3\" />\n"
+ "<feBlend in2=\"offset3\" mode=\"screen\" result=\"blend3\" />\n"
+ "</filter>\n", a.str().c_str(), r.str().c_str(), g.str().c_str(), b.str().c_str(),
+ rx.str().c_str(), ry.str().c_str(),
+ gx.str().c_str(), gy.str().c_str(),
+ bx.str().c_str(), by.str().c_str() );
+
+ return _filter;
+
+}; /* Nudge RGB filter */
+
+/**
+ \brief Custom predefined Nudge CMY filter.
+
+ Nudge CMY channels separately and blend them to different types of backgrounds
+
+ Filter's parameters:
+ Offsets
+ * Cyan
+ * x (-100.->100., default -6) -> offset1 (dx)
+ * y (-100.->100., default -6) -> offset1 (dy)
+ * Magenta
+ * x (-100.->100., default 6) -> offset2 (dx)
+ * y (-100.->100., default 7) -> offset2 (dy)
+ * Yellow
+ * x (-100.->100., default 1) -> offset3 (dx)
+ * y (-100.->100., default -16) -> offset3 (dy)
+ Color
+ * Background color (guint, default -1)-> flood (flood-color, flood-opacity)
+*/
+class NudgeCMY : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ NudgeCMY ( ) : Filter() { };
+ ~NudgeCMY ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Nudge CMY") "</name>\n"
+ "<id>org.inkscape.effect.filter.NudgeCMY</id>\n"
+ "<param name=\"tab\" type=\"notebook\">\n"
+ "<page name=\"offsettab\" gui-text=\"Offset\">\n"
+ "<label appearance=\"header\">" N_("Cyan offset") "</label>\n"
+ "<param name=\"cx\" gui-text=\"" N_("X") "\" type=\"float\" indent=\"1\" appearance=\"full\" precision=\"2\" min=\"-100.\" max=\"100.\">-6</param>\n"
+ "<param name=\"cy\" gui-text=\"" N_("Y") "\" type=\"float\" indent=\"1\" appearance=\"full\" precision=\"2\" min=\"-100.\" max=\"100.\">-6</param>\n"
+ "<label appearance=\"header\">" N_("Magenta offset") "</label>\n"
+ "<param name=\"mx\" gui-text=\"" N_("X") "\" type=\"float\" indent=\"1\" appearance=\"full\" precision=\"2\" min=\"-100.\" max=\"100.\">6</param>\n"
+ "<param name=\"my\" gui-text=\"" N_("Y") "\" type=\"float\" indent=\"1\" appearance=\"full\" precision=\"2\" min=\"-100.\" max=\"100.\">7</param>\n"
+ "<label appearance=\"header\">" N_("Yellow offset") "</label>\n"
+ "<param name=\"yx\" gui-text=\"" N_("X") "\" type=\"float\" indent=\"1\" appearance=\"full\" precision=\"2\" min=\"-100.\" max=\"100.\">1</param>\n"
+ "<param name=\"yy\" gui-text=\"" N_("Y") "\" type=\"float\" indent=\"1\" appearance=\"full\" precision=\"2\" min=\"-100.\" max=\"100.\">-16</param>\n"
+ "</page>\n"
+ "<page name=\"coltab\" gui-text=\"Color\">\n"
+ "<param name=\"color\" gui-text=\"" N_("Background color") "\" type=\"color\">-1</param>\n"
+ "</page>\n"
+ "</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Color") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Nudge CMY channels separately and blend them to different types of backgrounds") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new NudgeCMY());
+ };
+};
+
+gchar const *
+NudgeCMY::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream cx;
+ std::ostringstream cy;
+ std::ostringstream mx;
+ std::ostringstream my;
+ std::ostringstream yx;
+ std::ostringstream yy;
+
+ std::ostringstream a;
+ std::ostringstream r;
+ std::ostringstream g;
+ std::ostringstream b;
+
+ cx << ext->get_param_float("cx");
+ cy << ext->get_param_float("cy");
+ mx << ext->get_param_float("mx");
+ my << ext->get_param_float("my");
+ yx << ext->get_param_float("yx");
+ yy << ext->get_param_float("yy");
+
+ guint32 color = ext->get_param_color("color");
+ r << ((color >> 24) & 0xff);
+ g << ((color >> 16) & 0xff);
+ b << ((color >> 8) & 0xff);
+ a << (color & 0xff) / 255.0F;
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Nudge CMY\">\n"
+ "<feFlood flood-opacity=\"%s\" flood-color=\"rgb(%s,%s,%s)\" result=\"flood\" />\n"
+ "<feColorMatrix in=\"SourceGraphic\" values=\"0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 -1 0 0 1 0 \" result=\"colormatrix1\" />\n"
+ "<feOffset dy=\"%s\" dx=\"%s\" result=\"offset1\" />\n"
+ "<feBlend in2=\"flood\" mode=\"multiply\" result=\"blend1\" />\n"
+ "<feColorMatrix in=\"SourceGraphic\" values=\"0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 -1 0 1 0 \" result=\"colormatrix2\" />\n"
+ "<feOffset dy=\"%s\" dx=\"%s\" result=\"offset2\" />\n"
+ "<feBlend in2=\"blend1\" mode=\"multiply\" result=\"blend2\" />\n"
+ "<feOffset dy=\"%s\" dx=\"%s\" result=\"offset3\" />\n"
+ "<feColorMatrix in=\"SourceGraphic\" values=\"0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 -1 1 0 \" result=\"colormatrix3\" />\n"
+ "<feBlend in2=\"offset3\" mode=\"multiply\" result=\"blend3\" />\n"
+ "</filter>\n", a.str().c_str(), r.str().c_str(), g.str().c_str(), b.str().c_str(),
+ cx.str().c_str(), cy.str().c_str(),
+ mx.str().c_str(), my.str().c_str(),
+ yx.str().c_str(), yy.str().c_str() );
+
+ return _filter;
+
+}; /* Nudge CMY filter */
+
+/**
+ \brief Custom predefined Quadritone filter.
+
+ Replace hue by two colors.
+
+ Filter's parameters:
+ * Hue distribution (0->360, default 280) -> colormatrix1 (values)
+ * Colors (0->360, default 100) -> colormatrix3 (values)
+ * Blend mode 1 (enum, default Normal) -> blend1 (mode)
+ * Over-saturation (0.->1., default 0) -> composite1 (k2)
+ * Blend mode 2 (enum, default Normal) -> blend2 (mode)
+*/
+
+class Quadritone : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ Quadritone ( ) : Filter() { };
+ ~Quadritone ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Quadritone Fantasy") "</name>\n"
+ "<id>org.inkscape.effect.filter.Quadritone</id>\n"
+ "<param name=\"dist\" gui-text=\"" N_("Hue distribution (°)") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">280</param>\n"
+ "<param name=\"colors\" gui-text=\"" N_("Colors") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">100</param>\n"
+ "<param name=\"blend1\" gui-text=\"" N_("Blend 1:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"normal\">" N_("Normal") "</option>\n"
+ "<option value=\"multiply\">" N_("Multiply") "</option>\n"
+ "<option value=\"screen\">" N_("Screen") "</option>\n"
+ "</param>\n"
+ "<param name=\"sat\" gui-text=\"" N_("Over-saturation") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.00\" max=\"1.00\">0</param>\n"
+ "<param name=\"blend2\" gui-text=\"" N_("Blend 2:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"normal\">" N_("Normal") "</option>\n"
+ "<option value=\"screen\">" N_("Screen") "</option>\n"
+ "<option value=\"multiply\">" N_("Multiply") "</option>\n"
+ "<option value=\"lighten\">" N_("Lighten") "</option>\n"
+ "<option value=\"darken\">" N_("Darken") "</option>\n"
+ "</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Color") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Replace hue by two colors") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new Quadritone());
+ };
+
+};
+
+gchar const *
+Quadritone::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream dist;
+ std::ostringstream colors;
+ std::ostringstream blend1;
+ std::ostringstream sat;
+ std::ostringstream blend2;
+
+ dist << ext->get_param_int("dist");
+ colors << ext->get_param_int("colors");
+ blend1 << ext->get_param_optiongroup("blend1");
+ sat << ext->get_param_float("sat");
+ blend2 << ext->get_param_optiongroup("blend2");
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Quadritone fantasy\">\n"
+ "<feColorMatrix in=\"SourceGraphic\" type=\"hueRotate\" values=\"%s\" result=\"colormatrix1\" />\n"
+ "<feColorMatrix type=\"matrix\" values=\"0.5 0 0.5 0 0 0 1 0 0 0 0.5 0 0.5 0 0 0 0 0 1 0 \" result=\"colormatrix2\" />\n"
+ "<feColorMatrix type=\"hueRotate\" values=\"%s\" result=\"colormatrix3\" />\n"
+ "<feBlend in2=\"colormatrix3\" mode=\"%s\" result=\"blend1\" />\n"
+ "<feColorMatrix type=\"matrix\" values=\"2.5 -0.75 -0.75 0 0 -0.75 2.5 -0.75 0 0 -0.75 -0.75 2.5 0 0 0 0 0 1 0 \" result=\"colormatrix4\" />\n"
+ "<feComposite in=\"colormatrix4\" in2=\"blend1\" operator=\"arithmetic\" k2=\"%s\" result=\"composite1\" />\n"
+ "<feBlend in2=\"blend1\" mode=\"%s\" result=\"blend2\" />\n"
+ "</filter>\n", dist.str().c_str(), colors.str().c_str(), blend1.str().c_str(), sat.str().c_str(), blend2.str().c_str() );
+
+ return _filter;
+}; /* Quadritone filter */
+
+
+/**
+ \brief Custom predefined Simple blend filter.
+
+ Simple blend filter.
+
+ Filter's parameters:
+ * Color (guint, default 16777215) -> flood1 (flood-opacity, flood-color)
+ * Blend mode (enum, default Hue) -> blend1 (mode)
+*/
+class SimpleBlend : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ SimpleBlend ( ) : Filter() { };
+ ~SimpleBlend ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Simple blend") "</name>\n"
+ "<id>org.inkscape.effect.filter.SimpleBlend</id>\n"
+ "<param name=\"color\" gui-text=\"" N_("Color") "\" type=\"color\">16777215</param>\n"
+ "<param name=\"blendmode\" gui-text=\"" N_("Blend mode:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"normal\">" N_("Normal") "</option>\n"
+ "<option value=\"multiply\">" N_("Multiply") "</option>\n"
+ "<option value=\"screen\">" N_("Screen") "</option>\n"
+ "<option value=\"saturation\">" N_("Saturation") "</option>\n"
+ "<option value=\"darken\">" N_("Darken") "</option>\n"
+ "<option value=\"difference\">" N_("Difference") "</option>\n"
+ "<option value=\"lighten\">" N_("Lighten") "</option>\n"
+ "<option value=\"luminosity\">" N_("Luminosity") "</option>\n"
+ "<option value=\"overlay\">" N_("Overlay") "</option>\n"
+ "<option value=\"color-dodge\">" N_("Color Dodge") "</option>\n"
+ "<option value=\"color-burn\">" N_("Color Burn") "</option>\n"
+ "<option value=\"color\">" N_("Color") "</option>\n"
+ "<option value=\"hard-light\">" N_("Hard Light") "</option>\n"
+ "<option value=\"hue\">" N_("Hue") "</option>\n"
+ "<option value=\"exclusion\">" N_("Exclusion") "</option>\n"
+ "</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Color") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Simple blend filter") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new SimpleBlend());
+ };
+};
+
+gchar const *
+SimpleBlend::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream a;
+ std::ostringstream r;
+ std::ostringstream g;
+ std::ostringstream b;
+ std::ostringstream blend;
+
+ guint32 color = ext->get_param_color("color");
+ r << ((color >> 24) & 0xff);
+ g << ((color >> 16) & 0xff);
+ b << ((color >> 8) & 0xff);
+ a << (color & 0xff) / 255.0F;
+ blend << ext->get_param_optiongroup("blendmode");
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Simple blend\">\n"
+ "<feFlood result=\"flood1\" flood-color=\"rgb(%s,%s,%s)\" flood-opacity=\"%s\" />\n"
+ "<feBlend result=\"blend1\" in=\"flood1\" in2=\"SourceGraphic\" mode=\"%s\" />\n"
+ "<feComposite operator=\"in\" in=\"blend1\" in2=\"SourceGraphic\" />\n"
+ "</filter>\n", r.str().c_str(), g.str().c_str(), b.str().c_str(),
+ a.str().c_str(), blend.str().c_str());
+
+ return _filter;
+}; /* SimpleBlend filter */
+
+/**
+ \brief Custom predefined Solarize filter.
+
+ Classic photographic solarization effect.
+
+ Filter's parameters:
+ * Type (enum, default "Solarize") ->
+ Solarize = blend1 (mode="darken"), blend2 (mode="screen")
+ Moonarize = blend1 (mode="lighten"), blend2 (mode="multiply") [No other access to the blend modes]
+ * Hue rotation (0->360, default 0) -> colormatrix1 (values)
+*/
+
+
+class Solarize : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ Solarize ( ) : Filter() { };
+ ~Solarize ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Solarize") "</name>\n"
+ "<id>org.inkscape.effect.filter.Solarize</id>\n"
+ "<param name=\"rotate\" gui-text=\"" N_("Hue rotation (°)") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">0</param>\n"
+ "<param name=\"type\" gui-text=\"" N_("Type:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"solarize\">" N_("Solarize") "</option>\n"
+ "<option value=\"moonarize\">" N_("Moonarize") "</option>\n"
+ "</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Color") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Classic photographic solarization effect") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new Solarize());
+ };
+
+};
+
+gchar const *
+Solarize::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream rotate;
+ std::ostringstream blend1;
+ std::ostringstream blend2;
+
+ rotate << ext->get_param_int("rotate");
+ const gchar *type = ext->get_param_optiongroup("type");
+ if ((g_ascii_strcasecmp("solarize", type) == 0)) {
+ // Solarize
+ blend1 << "darken";
+ blend2 << "screen";
+ } else {
+ // Moonarize
+ blend1 << "lighten";
+ blend2 << "multiply";
+ }
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Solarize\">\n"
+ "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 1 \" />\n"
+ "<feColorMatrix type=\"hueRotate\" values=\"%s\" result=\"colormatrix2\" />\n"
+ "<feColorMatrix in=\"colormatrix2\" values=\"-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 \" result=\"colormatrix3\" />\n"
+ "<feBlend in=\"colormatrix3\" in2=\"colormatrix2\" mode=\"%s\" result=\"blend1\" />\n"
+ "<feBlend in2=\"blend1\" mode=\"%s\" result=\"blend2\" />\n"
+ "<feComposite in2=\"SourceGraphic\" operator=\"in\" />\n"
+ "</filter>\n", rotate.str().c_str(), blend1.str().c_str(), blend2.str().c_str() );
+
+ return _filter;
+}; /* Solarize filter */
+
+/**
+ \brief Custom predefined Tritone filter.
+
+ Create a custom tritone palette with additional glow, blend modes and hue moving.
+
+ Filter's parameters:
+ * Option (enum, default Normal) ->
+ Normal = composite1 (in2="flood"), composite2 (in="p", in2="blend6"), blend6 (in2="composite1")
+ Enhance hue = Normal + composite2 (in="SourceGraphic")
+ Phosphorescence = Normal + blend6 (in2="SourceGraphic") composite2 (in="blend6", in2="composite1")
+ PhosphorescenceB = Normal + blend6 (in2="flood") composite1 (in2="SourceGraphic")
+ Hue to background = Normal + composite1 (in2="BackgroundImage") [a template with an activated background is needed, or colors become black]
+ * Hue distribution (0->360, default 0) -> colormatrix1 (values)
+ * Colors (guint, default -73203457) -> flood (flood-opacity, flood-color)
+ * Global blend (enum, default Lighten) -> blend5 (mode) [Multiply, Screen, Darken, Lighten only!]
+ * Glow (0.01->10., default 0.01) -> blur (stdDeviation)
+ * Glow & blend (enum, default Normal) -> blend6 (mode) [Normal, Multiply and Darken only!]
+ * Local light (0.->10., default 0) -> composite2 (k1)
+ * Global light (0.->10., default 1) -> composite2 (k3) [k2 must be fixed to 1].
+*/
+
+class Tritone : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ Tritone ( ) : Filter() { };
+ ~Tritone ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Tritone") "</name>\n"
+ "<id>org.inkscape.effect.filter.Tritone</id>\n"
+ "<param name=\"tab\" type=\"notebook\">\n"
+ "<page name=\"optionstab\" gui-text=\"Options\">\n"
+ "<param name=\"type\" gui-text=\"" N_("Type:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"normal\">" N_("Normal") "</option>\n"
+ "<option value=\"enhue\">" N_("Enhance hue") "</option>\n"
+ "<option value=\"phospho\">" N_("Phosphorescence") "</option>\n"
+ "<option value=\"phosphoB\">" N_("Colored nights") "</option>\n"
+ "<option value=\"htb\">" N_("Hue to background") "</option>\n"
+ "</param>\n"
+ "<param name=\"globalblend\" gui-text=\"" N_("Global blend:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"lighten\">" N_("Lighten") "</option>\n"
+ "<option value=\"screen\">" N_("Screen") "</option>\n"
+ "<option value=\"multiply\">" N_("Multiply") "</option>\n"
+ "<option value=\"darken\">" N_("Darken") "</option>\n"
+ "</param>\n"
+ "<param name=\"glow\" gui-text=\"" N_("Glow") "\" type=\"float\" appearance=\"full\" min=\"0.01\" max=\"10\">0.01</param>\n"
+ "<param name=\"glowblend\" gui-text=\"" N_("Glow blend:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"normal\">" N_("Normal") "</option>\n"
+ "<option value=\"multiply\">" N_("Multiply") "</option>\n"
+ "<option value=\"darken\">" N_("Darken") "</option>\n"
+ "</param>\n"
+ "<param name=\"llight\" gui-text=\"" N_("Local light") "\" type=\"float\" appearance=\"full\" min=\"0\" max=\"10\">0</param>\n"
+ "<param name=\"glight\" gui-text=\"" N_("Global light") "\" type=\"float\" appearance=\"full\" min=\"0\" max=\"10\">1</param>\n"
+ "</page>\n"
+ "<page name=\"co1tab\" gui-text=\"Color\">\n"
+ "<param name=\"dist\" gui-text=\"" N_("Hue distribution (°):") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">0</param>\n"
+ "<param name=\"color\" gui-text=\"" N_("Color") "\" type=\"color\">-73203457</param>\n"
+ "</page>\n"
+ "</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Color") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Create a custom tritone palette with additional glow, blend modes and hue moving") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new Tritone());
+ };
+
+};
+
+gchar const *
+Tritone::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream dist;
+ std::ostringstream a;
+ std::ostringstream r;
+ std::ostringstream g;
+ std::ostringstream b;
+ std::ostringstream globalblend;
+ std::ostringstream glow;
+ std::ostringstream glowblend;
+ std::ostringstream llight;
+ std::ostringstream glight;
+ std::ostringstream c1in2;
+ std::ostringstream c2in;
+ std::ostringstream c2in2;
+ std::ostringstream b6in2;
+
+ guint32 color = ext->get_param_color("color");
+ r << ((color >> 24) & 0xff);
+ g << ((color >> 16) & 0xff);
+ b << ((color >> 8) & 0xff);
+ a << (color & 0xff) / 255.0F;
+ globalblend << ext->get_param_optiongroup("globalblend");
+ dist << ext->get_param_int("dist");
+ glow << ext->get_param_float("glow");
+ glowblend << ext->get_param_optiongroup("glowblend");
+ llight << ext->get_param_float("llight");
+ glight << ext->get_param_float("glight");
+
+ const gchar *type = ext->get_param_optiongroup("type");
+ if ((g_ascii_strcasecmp("enhue", type) == 0)) {
+ // Enhance hue
+ c1in2 << "flood";
+ c2in << "SourceGraphic";
+ c2in2 << "blend6";
+ b6in2 << "composite1";
+ } else if ((g_ascii_strcasecmp("phospho", type) == 0)) {
+ // Phosphorescence
+ c1in2 << "flood";
+ c2in << "blend6";
+ c2in2 << "composite1";
+ b6in2 << "SourceGraphic";
+ } else if ((g_ascii_strcasecmp("phosphoB", type) == 0)) {
+ // Phosphorescence B
+ c1in2 << "SourceGraphic";
+ c2in << "blend6";
+ c2in2 << "composite1";
+ b6in2 << "flood";
+ } else if ((g_ascii_strcasecmp("htb", type) == 0)) {
+ // Hue to background
+ c1in2 << "BackgroundImage";
+ c2in << "blend2";
+ c2in2 << "blend6";
+ b6in2 << "composite1";
+ } else {
+ // Normal
+ c1in2 << "flood";
+ c2in << "blend2";
+ c2in2 << "blend6";
+ b6in2 << "composite";
+ }
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Tritone\">\n"
+ "<feColorMatrix type=\"hueRotate\" values=\"%s\" result=\"colormatrix1\" />\n"
+ "<feColorMatrix in=\"colormatrix1\" type=\"matrix\" values=\"1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 \" result=\"colormatrix2\" />\n"
+ "<feColorMatrix in=\"colormatrix1\" type=\"matrix\" values=\"0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1 \" result=\"colormatrix3\" />\n"
+ "<feColorMatrix in=\"colormatrix1\" type=\"matrix\" values=\"0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 \" result=\"colormatrix4\" />\n"
+ "<feBlend in=\"colormatrix2\" in2=\"colormatrix3\" mode=\"darken\" result=\"blend1\" />\n"
+ "<feBlend in=\"blend1\" in2=\"colormatrix4\" mode=\"darken\" result=\"blend2\" />\n"
+ "<feBlend in=\"colormatrix2\" in2=\"colormatrix3\" mode=\"lighten\" result=\"blend3\" />\n"
+ "<feBlend in=\"blend3\" in2=\"colormatrix4\" mode=\"lighten\" result=\"blend4\" />\n"
+ "<feComponentTransfer in=\"blend4\" result=\"componentTransfer\">\n"
+ "<feFuncR type=\"linear\" slope=\"0\" />\n"
+ "</feComponentTransfer>\n"
+ "<feBlend in=\"blend2\" in2=\"componentTransfer\" mode=\"%s\" result=\"blend5\" />\n"
+ "<feColorMatrix in=\"blend5\" type=\"matrix\" values=\"-1 1 0 0 0 -1 1 0 0 0 -1 1 0 0 0 0 0 0 0 1 \" result=\"colormatrix5\" />\n"
+ "<feFlood flood-opacity=\"%s\" flood-color=\"rgb(%s,%s,%s)\" result=\"flood\" />\n"
+ "<feComposite in=\"colormatrix5\" in2=\"%s\" operator=\"arithmetic\" k1=\"1\" result=\"composite1\" />\n"
+ "<feGaussianBlur stdDeviation=\"%s\" result=\"blur\" />\n"
+ "<feBlend in2=\"%s\" mode=\"%s\" result=\"blend6\" />\n"
+ "<feComposite in=\"%s\" in2=\"%s\" operator=\"arithmetic\" k1=\"%s\" k2=\"1\" k3=\"%s\" k4=\"0\" result=\"composite2\" />\n"
+ "<feComposite in2=\"SourceGraphic\" operator=\"in\" result=\"composite3\" />\n"
+ "</filter>\n", dist.str().c_str(), globalblend.str().c_str(),
+ a.str().c_str(), r.str().c_str(), g.str().c_str(), b.str().c_str(),
+ c1in2.str().c_str(), glow.str().c_str(), b6in2.str().c_str(), glowblend.str().c_str(),
+ c2in.str().c_str(), c2in2.str().c_str(), llight.str().c_str(), glight.str().c_str() );
+
+ return _filter;
+}; /* Tritone filter */
+
+}; /* namespace Filter */
+}; /* namespace Internal */
+}; /* namespace Extension */
+}; /* namespace Inkscape */
+
+/* Change the 'COLOR' below to be your file name */
+#endif /* SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_COLOR_H__ */
diff --git a/src/extension/internal/filter/distort.h b/src/extension/internal/filter/distort.h
new file mode 100644
index 0000000..b8f66b6
--- /dev/null
+++ b/src/extension/internal/filter/distort.h
@@ -0,0 +1,250 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#ifndef SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_DISTORT_H__
+#define SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_DISTORT_H__
+/* Change the 'DISTORT' above to be your file name */
+
+/*
+ * Copyright (C) 2011 Authors:
+ * Ivan Louette (filters)
+ * Nicolas Dufour (UI) <nicoduf@yahoo.fr>
+ *
+ * Distort filters
+ * Felt Feather
+ * Roughen
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+/* ^^^ Change the copyright to be you and your e-mail address ^^^ */
+
+#include "filter.h"
+
+#include "extension/internal/clear-n_.h"
+#include "extension/system.h"
+#include "extension/extension.h"
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+namespace Filter {
+
+/**
+ \brief Custom predefined FeltFeather filter.
+
+ Blur and displace edges of shapes and pictures
+
+ Filter's parameters:
+ * Type (enum, default "In") ->
+ in = map (in="composite3")
+ out = map (in="blur")
+ * Horizontal blur (0.01->30., default 15) -> blur (stdDeviation)
+ * Vertical blur (0.01->30., default 15) -> blur (stdDeviation)
+ * Dilatation (n-1th value, 0.->100., default 1) -> colormatrix (matrix)
+ * Erosion (nth value, 0.->100., default 0) -> colormatrix (matrix)
+ * Stroke (enum, default "Normal") ->
+ Normal = composite4 (operator="atop")
+ Wide = composite4 (operator="over")
+ Narrow = composite4 (operator="in")
+ No fill = composite4 (operator="xor")
+ * Roughness (group)
+ * Turbulence type (enum, default fractalNoise else turbulence) -> turbulence (type)
+ * Horizontal frequency (0.001->1., default 0.05) -> turbulence (baseFrequency [/100])
+ * Vertical frequency (0.001->1., default 0.05) -> turbulence (baseFrequency [/100])
+ * Complexity (1->5, default 3) -> turbulence (numOctaves)
+ * Variation (0->100, default 0) -> turbulence (seed)
+ * Intensity (0.0->100., default 30) -> displacement (scale)
+*/
+
+class FeltFeather : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ FeltFeather ( ) : Filter() { };
+ ~FeltFeather ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Felt Feather") "</name>\n"
+ "<id>org.inkscape.effect.filter.FeltFeather</id>\n"
+ "<param name=\"type\" gui-text=\"" N_("Type:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"in\">" N_("In") "</option>\n"
+ "<option value=\"out\">" N_("Out") "</option>\n"
+ "</param>\n"
+ "<param name=\"hblur\" gui-text=\"" N_("Horizontal blur") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"30.00\">15</param>\n"
+ "<param name=\"vblur\" gui-text=\"" N_("Vertical blur") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"30.00\">15</param>\n"
+ "<param name=\"dilat\" gui-text=\"" N_("Dilatation") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"100\">1</param>\n"
+ "<param name=\"erosion\" gui-text=\"" N_("Erosion") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"100\">0</param>\n"
+ "<param name=\"stroke\" gui-text=\"" N_("Stroke:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"atop\">" N_("Normal") "</option>\n"
+ "<option value=\"over\">" N_("Wide") "</option>\n"
+ "<option value=\"in\">" N_("Narrow") "</option>\n"
+ "<option value=\"xor\">" N_("No fill") "</option>\n"
+ "</param>\n"
+ "<param name=\"turbulence\" indent=\"1\" gui-text=\"" N_("Turbulence:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"fractalNoise\">" N_("Fractal noise") "</option>\n"
+ "<option value=\"turbulence\">" N_("Turbulence") "</option>\n"
+ "</param>\n"
+ "<param name=\"hfreq\" gui-text=\"" N_("Horizontal frequency") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"100.\">5</param>\n"
+ "<param name=\"vfreq\" gui-text=\"" N_("Vertical frequency") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"100.\">5</param>\n"
+ "<param name=\"complexity\" gui-text=\"" N_("Complexity") "\" type=\"int\" appearance=\"full\" min=\"1\" max=\"5\">3</param>\n"
+ "<param name=\"variation\" gui-text=\"" N_("Variation") "\" type=\"int\" appearance=\"full\" min=\"1\" max=\"100\">0</param>\n"
+ "<param name=\"intensity\" gui-text=\"" N_("Intensity") "\" type=\"float\" appearance=\"full\" min=\"0.0\" max=\"100\">30</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Distort") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Blur and displace edges of shapes and pictures") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new FeltFeather());
+ };
+
+};
+
+gchar const *
+FeltFeather::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+
+ std::ostringstream hblur;
+ std::ostringstream vblur;
+ std::ostringstream dilat;
+ std::ostringstream erosion;
+
+ std::ostringstream turbulence;
+ std::ostringstream hfreq;
+ std::ostringstream vfreq;
+ std::ostringstream complexity;
+ std::ostringstream variation;
+ std::ostringstream intensity;
+
+ std::ostringstream map;
+ std::ostringstream stroke;
+
+ hblur << ext->get_param_float("hblur");
+ vblur << ext->get_param_float("vblur");
+ dilat << ext->get_param_float("dilat");
+ erosion << -ext->get_param_float("erosion");
+
+ turbulence << ext->get_param_optiongroup("turbulence");
+ hfreq << ext->get_param_float("hfreq") / 100;
+ vfreq << ext->get_param_float("vfreq") / 100;
+ complexity << ext->get_param_int("complexity");
+ variation << ext->get_param_int("variation");
+ intensity << ext->get_param_float("intensity");
+
+ stroke << ext->get_param_optiongroup("stroke");
+
+ const gchar *maptype = ext->get_param_optiongroup("type");
+ if (g_ascii_strcasecmp("in", maptype) == 0) {
+ map << "composite3";
+ } else {
+ map << "blur";
+ }
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" x=\"-0.3\" width=\"1.6\" y=\"-0.3\" height=\"1.6\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Felt Feather\">\n"
+ "<feGaussianBlur stdDeviation=\"%s %s\" result=\"blur\" />\n"
+ "<feComposite in=\"SourceGraphic\" in2=\"blur\" operator=\"atop\" result=\"composite1\" />\n"
+ "<feComposite in2=\"composite1\" operator=\"in\" result=\"composite2\" />\n"
+ "<feComposite in2=\"composite2\" operator=\"in\" result=\"composite3\" />\n"
+ "<feTurbulence type=\"%s\" numOctaves=\"%s\" seed=\"%s\" baseFrequency=\"%s %s\" result=\"turbulence\" />\n"
+ "<feDisplacementMap in=\"%s\" in2=\"turbulence\" xChannelSelector=\"R\" scale=\"%s\" yChannelSelector=\"G\" result=\"map\" />\n"
+ "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 %s %s \" result=\"colormatrix\" />\n"
+ "<feComposite in=\"composite3\" in2=\"colormatrix\" operator=\"%s\" result=\"composite4\" />\n"
+ "</filter>\n", hblur.str().c_str(), vblur.str().c_str(),
+ turbulence.str().c_str(), complexity.str().c_str(), variation.str().c_str(), hfreq.str().c_str(), vfreq.str().c_str(),
+ map.str().c_str(), intensity.str().c_str(), dilat.str().c_str(), erosion.str().c_str(), stroke.str().c_str() );
+
+ return _filter;
+}; /* Felt feather filter */
+
+/**
+ \brief Custom predefined Roughen filter.
+
+ Small-scale roughening to edges and content
+
+ Filter's parameters:
+ * Turbulence type (enum, default fractalNoise else turbulence) -> turbulence (type)
+ * Horizontal frequency (0.001->10., default 0.013) -> turbulence (baseFrequency [/100])
+ * Vertical frequency (0.001->10., default 0.013) -> turbulence (baseFrequency [/100])
+ * Complexity (1->5, default 5) -> turbulence (numOctaves)
+ * Variation (1->360, default 1) -> turbulence (seed)
+ * Intensity (0.0->50., default 6.6) -> displacement (scale)
+*/
+
+class Roughen : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ Roughen ( ) : Filter() { };
+ ~Roughen ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Roughen") "</name>\n"
+ "<id>org.inkscape.effect.filter.Roughen</id>\n"
+ "<param name=\"type\" gui-text=\"" N_("Turbulence type:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"fractalNoise\">" N_("Fractal noise") "</option>\n"
+ "<option value=\"turbulence\">" N_("Turbulence") "</option>\n"
+ "</param>\n"
+ "<param name=\"hfreq\" gui-text=\"" N_("Horizontal frequency") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.1\" max=\"1000.00\">1.3</param>\n"
+ "<param name=\"vfreq\" gui-text=\"" N_("Vertical frequency") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.1\" max=\"1000.00\">1.3</param>\n"
+ "<param name=\"complexity\" gui-text=\"" N_("Complexity") "\" type=\"int\" appearance=\"full\" min=\"1\" max=\"5\">5</param>\n"
+ "<param name=\"variation\" gui-text=\"" N_("Variation") "\" type=\"int\" appearance=\"full\" min=\"1\" max=\"360\">0</param>\n"
+ "<param name=\"intensity\" gui-text=\"" N_("Intensity") "\" type=\"float\" appearance=\"full\" min=\"0.0\" max=\"50\">6.6</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Distort") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Small-scale roughening to edges and content") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new Roughen());
+ };
+
+};
+
+gchar const *
+Roughen::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream type;
+ std::ostringstream hfreq;
+ std::ostringstream vfreq;
+ std::ostringstream complexity;
+ std::ostringstream variation;
+ std::ostringstream intensity;
+
+ type << ext->get_param_optiongroup("type");
+ hfreq << ext->get_param_float("hfreq") / 100;
+ vfreq << ext->get_param_float("vfreq") / 100;
+ complexity << ext->get_param_int("complexity");
+ variation << ext->get_param_int("variation");
+ intensity << ext->get_param_float("intensity");
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Roughen\">\n"
+ "<feTurbulence type=\"%s\" numOctaves=\"%s\" seed=\"%s\" baseFrequency=\"%s %s\" result=\"turbulence\" />\n"
+ "<feDisplacementMap in=\"SourceGraphic\" in2=\"turbulence\" scale=\"%s\" yChannelSelector=\"G\" xChannelSelector=\"R\" />\n"
+ "</filter>\n", type.str().c_str(), complexity.str().c_str(), variation.str().c_str(), hfreq.str().c_str(), vfreq.str().c_str(), intensity.str().c_str());
+
+ return _filter;
+}; /* Roughen filter */
+
+}; /* namespace Filter */
+}; /* namespace Internal */
+}; /* namespace Extension */
+}; /* namespace Inkscape */
+
+/* Change the 'DISTORT' below to be your file name */
+#endif /* SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_DISTORT_H__ */
diff --git a/src/extension/internal/filter/filter-all.cpp b/src/extension/internal/filter/filter-all.cpp
new file mode 100644
index 0000000..5aa3900
--- /dev/null
+++ b/src/extension/internal/filter/filter-all.cpp
@@ -0,0 +1,128 @@
+// 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"
+
+/* Put your filter here */
+#include "bevels.h"
+#include "blurs.h"
+#include "bumps.h"
+#include "color.h"
+#include "distort.h"
+#include "image.h"
+#include "morphology.h"
+#include "overlays.h"
+#include "paint.h"
+#include "protrusions.h"
+#include "shadows.h"
+#include "textures.h"
+#include "transparency.h"
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+namespace Filter {
+
+
+void
+Filter::filters_all ( )
+{
+ // Here come the filters which are coded in C++ in order to present a parameters dialog
+
+ /* Experimental custom predefined filters */
+
+ // Bevels
+ DiffuseLight::init();
+ MatteJelly::init();
+ SpecularLight::init();
+
+ // Blurs
+ Blur::init();
+ CleanEdges::init();
+ CrossBlur::init();
+ Feather::init();
+ ImageBlur::init();
+
+ // Bumps
+ Bump::init();
+ WaxBump::init();
+
+ // Color
+ Brilliance::init();
+ ChannelPaint::init();
+ ColorBlindness::init();
+ ColorShift::init();
+ Colorize::init();
+ ComponentTransfer::init();
+ Duochrome::init();
+ ExtractChannel::init();
+ FadeToBW::init();
+ Greyscale::init();
+ Invert::init();
+ Lighting::init();
+ LightnessContrast::init();
+ NudgeRGB::init();
+ NudgeCMY::init();
+ Quadritone::init();
+ SimpleBlend::init();
+ Solarize::init();
+ Tritone::init();
+
+ // Distort
+ FeltFeather::init();
+ Roughen::init();
+
+ // Image effect
+ EdgeDetect::init();
+
+ // Image paint and draw
+ Chromolitho::init();
+ CrossEngraving::init();
+ Drawing::init();
+ Electrize::init();
+ NeonDraw::init();
+ PointEngraving::init();
+ Posterize::init();
+ PosterizeBasic::init();
+
+ // Morphology
+ Crosssmooth::init();
+ Outline::init();
+
+ // Overlays
+ NoiseFill::init();
+
+ // Protrusions
+ Snow::init();
+
+ // Shadows and glows
+ ColorizableDropShadow::init();
+
+ // Textures
+ InkBlot::init();
+
+ // Fill and transparency
+ Blend::init();
+ ChannelTransparency::init();
+ LightEraser::init();
+ Opacity::init();
+ Silhouette::init();
+
+ // Here come the rest of the filters that are read from SVG files in share/filters and
+ // .config/Inkscape/filters
+ /* This should always be last, don't put stuff below this
+ * line. */
+ Filter::filters_all_files();
+
+ return;
+}
+
+}; /* namespace Filter */
+}; /* namespace Internal */
+}; /* namespace Extension */
+}; /* namespace Inkscape */
diff --git a/src/extension/internal/filter/filter-file.cpp b/src/extension/internal/filter/filter-file.cpp
new file mode 100644
index 0000000..afa979f
--- /dev/null
+++ b/src/extension/internal/filter/filter-file.cpp
@@ -0,0 +1,137 @@
+// 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;
+ }
+
+ 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);
+
+ // 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 */
+
diff --git a/src/extension/internal/filter/filter.cpp b/src/extension/internal/filter/filter.cpp
new file mode 100644
index 0000000..45f2d0a
--- /dev/null
+++ b/src/extension/internal/filter/filter.cpp
@@ -0,0 +1,235 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Authors:
+ * Ted Gould <ted@gould.cx>
+ *
+ * Copyright (C) 2008 Authors
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+
+#include "desktop.h"
+#include "selection.h"
+#include "extension/extension.h"
+#include "extension/effect.h"
+#include "extension/system.h"
+#include "xml/repr.h"
+#include "xml/simple-node.h"
+#include "xml/attribute-record.h"
+#include "object/sp-defs.h"
+
+#include "filter.h"
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+namespace Filter {
+
+Filter::Filter() :
+ Inkscape::Extension::Implementation::Implementation(),
+ _filter(nullptr) {
+ return;
+}
+
+Filter::Filter(gchar const * filter) :
+ Inkscape::Extension::Implementation::Implementation(),
+ _filter(filter) {
+ return;
+}
+
+Filter::~Filter () {
+ if (_filter != nullptr) {
+ _filter = nullptr;
+ }
+
+ return;
+}
+
+bool Filter::load(Inkscape::Extension::Extension * /*module*/)
+{
+ return true;
+}
+
+Inkscape::Extension::Implementation::ImplementationDocumentCache *Filter::newDocCache(Inkscape::Extension::Extension * /*ext*/,
+ Inkscape::UI::View::View * /*doc*/)
+{
+ return nullptr;
+}
+
+gchar const *Filter::get_filter_text(Inkscape::Extension::Extension * /*ext*/)
+{
+ return _filter;
+}
+
+Inkscape::XML::Document *
+Filter::get_filter (Inkscape::Extension::Extension * ext) {
+ gchar const * filter = get_filter_text(ext);
+ return sp_repr_read_mem(filter, strlen(filter), nullptr);
+}
+
+void
+Filter::merge_filters( Inkscape::XML::Node * to, Inkscape::XML::Node * from,
+ Inkscape::XML::Document * doc,
+ gchar const * srcGraphic, gchar const * srcGraphicAlpha)
+{
+ if (from == nullptr) return;
+
+ // copy attributes
+ for ( Inkscape::Util::List<Inkscape::XML::AttributeRecord const> iter = from->attributeList() ;
+ iter ; ++iter ) {
+ gchar const * attr = g_quark_to_string(iter->key);
+ //printf("Attribute List: %s\n", attr);
+ if (!strcmp(attr, "id")) continue; // nope, don't copy that one!
+ to->setAttribute(attr, from->attribute(attr));
+
+ if (!strcmp(attr, "in") || !strcmp(attr, "in2") || !strcmp(attr, "in3")) {
+ if (srcGraphic != nullptr && !strcmp(from->attribute(attr), "SourceGraphic")) {
+ to->setAttribute(attr, srcGraphic);
+ }
+
+ if (srcGraphicAlpha != nullptr && !strcmp(from->attribute(attr), "SourceAlpha")) {
+ to->setAttribute(attr, srcGraphicAlpha);
+ }
+ }
+ }
+
+ // for each child call recursively
+ for (Inkscape::XML::Node * from_child = from->firstChild();
+ from_child != nullptr ; from_child = from_child->next()) {
+ Glib::ustring name = "svg:";
+ name += from_child->name();
+
+ Inkscape::XML::Node * to_child = doc->createElement(name.c_str());
+ to->appendChild(to_child);
+ merge_filters(to_child, from_child, doc, srcGraphic, srcGraphicAlpha);
+
+ if (from_child == from->firstChild() && !strcmp("filter", from->name()) && srcGraphic != nullptr && to_child->attribute("in") == nullptr) {
+ to_child->setAttribute("in", srcGraphic);
+ }
+ Inkscape::GC::release(to_child);
+ }
+}
+
+#define FILTER_SRC_GRAPHIC "fbSourceGraphic"
+#define FILTER_SRC_GRAPHIC_ALPHA "fbSourceGraphicAlpha"
+
+void Filter::effect(Inkscape::Extension::Effect *module, Inkscape::UI::View::View *document,
+ Inkscape::Extension::Implementation::ImplementationDocumentCache * /*docCache*/)
+{
+ Inkscape::XML::Document *filterdoc = get_filter(module);
+ if (filterdoc == nullptr) {
+ return; // could not parse the XML source of the filter; typically parser will stderr a warning
+ }
+
+ //printf("Calling filter effect\n");
+ Inkscape::Selection * selection = ((SPDesktop *)document)->selection;
+
+ // TODO need to properly refcount the items, at least
+ std::vector<SPItem*> items(selection->items().begin(), selection->items().end());
+
+ Inkscape::XML::Document * xmldoc = document->doc()->getReprDoc();
+ Inkscape::XML::Node * defsrepr = document->doc()->getDefs()->getRepr();
+
+ for(auto spitem : items) {
+ Inkscape::XML::Node *node = spitem->getRepr();
+
+ SPCSSAttr * css = sp_repr_css_attr(node, "style");
+ gchar const * filter = sp_repr_css_property(css, "filter", nullptr);
+
+ if (filter == nullptr) {
+
+ Inkscape::XML::Node * newfilterroot = xmldoc->createElement("svg:filter");
+ merge_filters(newfilterroot, filterdoc->root(), xmldoc);
+ defsrepr->appendChild(newfilterroot);
+ document->doc()->resources_changed_signals[g_quark_from_string("filter")].emit();
+
+ Glib::ustring url = "url(#"; url += newfilterroot->attribute("id"); url += ")";
+
+
+ Inkscape::GC::release(newfilterroot);
+
+ sp_repr_css_set_property(css, "filter", url.c_str());
+ sp_repr_css_set(node, css, "style");
+ } else {
+ if (strncmp(filter, "url(#", strlen("url(#")) || filter[strlen(filter) - 1] != ')') {
+ // This is not url(#id) -- we can't handle it
+ continue;
+ }
+
+ gchar * lfilter = g_strndup(filter + 5, strlen(filter) - 6);
+ Inkscape::XML::Node * filternode = nullptr;
+ for (Inkscape::XML::Node * child = defsrepr->firstChild(); child != nullptr; child = child->next()) {
+ if (!strcmp(lfilter, child->attribute("id"))) {
+ filternode = child;
+ break;
+ }
+ }
+ g_free(lfilter);
+
+ // no filter
+ if (filternode == nullptr) {
+ g_warning("no assigned filter found!");
+ continue;
+ }
+
+ if (filternode->lastChild() == nullptr) {
+ // empty filter, we insert
+ merge_filters(filternode, filterdoc->root(), xmldoc);
+ } else {
+ // existing filter, we merge
+ filternode->lastChild()->setAttribute("result", FILTER_SRC_GRAPHIC);
+ Inkscape::XML::Node * alpha = xmldoc->createElement("svg:feColorMatrix");
+ alpha->setAttribute("result", FILTER_SRC_GRAPHIC_ALPHA);
+ alpha->setAttribute("in", FILTER_SRC_GRAPHIC); // not required, but we're being explicit
+ alpha->setAttribute("values", "0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0");
+
+ filternode->appendChild(alpha);
+
+ merge_filters(filternode, filterdoc->root(), xmldoc, FILTER_SRC_GRAPHIC, FILTER_SRC_GRAPHIC_ALPHA);
+
+ Inkscape::GC::release(alpha);
+ }
+ }
+ }
+
+ return;
+}
+
+#include "extension/internal/clear-n_.h"
+
+void
+Filter::filter_init (gchar const * id, gchar const * name, gchar const * submenu, gchar const * tip, gchar const * filter)
+{
+ 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"
+ "</effects-menu>\n"
+ "<menu-tip>%s</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", name, id, submenu, tip);
+ Inkscape::Extension::build_from_mem(xml_str, new Filter(filter));
+ g_free(xml_str);
+ return;
+}
+
+}; /* namespace Filter */
+}; /* namespace Internal */
+}; /* namespace Extension */
+}; /* namespace Inkscape */
+
+/*
+ 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:fileencoding=utf-8:textwidth=99 :
diff --git a/src/extension/internal/filter/filter.h b/src/extension/internal/filter/filter.h
new file mode 100644
index 0000000..cb3ed36
--- /dev/null
+++ b/src/extension/internal/filter/filter.h
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#ifndef INKSCAPE_EXTENSION_INTERNAL_FILTER_FILTER_H
+#define INKSCAPE_EXTENSION_INTERNAL_FILTER_FILTER_H
+
+/*
+ * Copyright (C) 2008 Authors:
+ * Ted Gould <ted@gould.cx>
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+
+#include <glibmm/i18n.h>
+
+#include "extension/implementation/implementation.h"
+
+namespace Inkscape {
+
+namespace XML {
+ struct Document;
+}
+
+namespace Extension {
+
+class Effect;
+class Extension;
+
+namespace Internal {
+namespace Filter {
+
+class Filter : public Inkscape::Extension::Implementation::Implementation {
+protected:
+ gchar const * _filter;
+ virtual gchar const * get_filter_text (Inkscape::Extension::Extension * ext);
+
+private:
+ Inkscape::XML::Document * get_filter (Inkscape::Extension::Extension * ext);
+ void merge_filters (Inkscape::XML::Node * to, Inkscape::XML::Node * from, Inkscape::XML::Document * doc, gchar const * srcGraphic = nullptr, gchar const * srcGraphicAlpha = nullptr);
+
+public:
+ Filter();
+ Filter(gchar const * filter);
+ ~Filter() override;
+
+ bool load(Inkscape::Extension::Extension *module) override;
+ Inkscape::Extension::Implementation::ImplementationDocumentCache * newDocCache (Inkscape::Extension::Extension * ext, Inkscape::UI::View::View * doc) override;
+ void effect(Inkscape::Extension::Effect *module, Inkscape::UI::View::View *document, Inkscape::Extension::Implementation::ImplementationDocumentCache * docCache) override;
+
+ static void filter_init(gchar const * id, gchar const * name, gchar const * submenu, gchar const * tip, gchar const * filter);
+ static void filters_all();
+
+ /* File loader related */
+ static void filters_all_files();
+ static void filters_load_node(Inkscape::XML::Node *node, gchar * menuname);
+
+};
+
+}; /* namespace Filter */
+}; /* namespace Internal */
+}; /* namespace Extension */
+}; /* namespace Inkscape */
+
+#endif // INKSCAPE_EXTENSION_INTERNAL_FILTER_FILTER_H
diff --git a/src/extension/internal/filter/image.h b/src/extension/internal/filter/image.h
new file mode 100644
index 0000000..2a0e334
--- /dev/null
+++ b/src/extension/internal/filter/image.h
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#ifndef SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_IMAGE_H__
+#define SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_IMAGE_H__
+/* Change the 'IMAGE' above to be your file name */
+
+/*
+ * Copyright (C) 2011 Authors:
+ * Ivan Louette (filters)
+ * Nicolas Dufour (UI) <nicoduf@yahoo.fr>
+ *
+ * Image filters
+ * Edge detect
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+/* ^^^ Change the copyright to be you and your e-mail address ^^^ */
+
+#include "filter.h"
+
+#include "extension/internal/clear-n_.h"
+#include "extension/system.h"
+#include "extension/extension.h"
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+namespace Filter {
+
+/**
+ \brief Custom predefined Edge detect filter.
+
+ Detect color edges in object.
+
+ Filter's parameters:
+ * Detection type (enum, default Full) -> convolve (kernelMatrix)
+ * Level (0.01->10., default 1.) -> convolve (divisor)
+ * Inverted (boolean, default false) -> convolve (bias)
+*/
+class EdgeDetect : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ EdgeDetect ( ) : Filter() { };
+ ~EdgeDetect ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Edge Detect") "</name>\n"
+ "<id>org.inkscape.effect.filter.EdgeDetect</id>\n"
+ "<param name=\"type\" gui-text=\"" N_("Detect:") "\" type=\"optiongroup\" appearance=\"combo\" >\n"
+ "<option value=\"all\">" N_("All") "</option>\n"
+ "<option value=\"vertical\">" N_("Vertical lines") "</option>\n"
+ "<option value=\"horizontal\">" N_("Horizontal lines") "</option>\n"
+ "</param>\n"
+ "<param name=\"level\" gui-text=\"" N_("Level") "\" type=\"float\" appearance=\"full\" min=\"0.1\" max=\"100.0\">1.0</param>\n"
+ "<param name=\"inverted\" gui-text=\"" N_("Invert colors") "\" type=\"bool\" >false</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Image Effects") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Detect color edges in object") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new EdgeDetect());
+ };
+
+};
+
+gchar const *
+EdgeDetect::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream matrix;
+ std::ostringstream inverted;
+ std::ostringstream level;
+
+ const gchar *type = ext->get_param_optiongroup("type");
+
+ level << 1 / ext->get_param_float("level");
+
+ if ((g_ascii_strcasecmp("vertical", type) == 0)) {
+ matrix << "0 0 0 1 -2 1 0 0 0";
+ } else if ((g_ascii_strcasecmp("horizontal", type) == 0)) {
+ matrix << "0 1 0 0 -2 0 0 1 0";
+ } else {
+ matrix << "0 1 0 1 -4 1 0 1 0";
+ }
+
+ if (ext->get_param_bool("inverted")) {
+ inverted << "1";
+ } else {
+ inverted << "0";
+ }
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Edge Detect\">\n"
+ "<feConvolveMatrix in=\"SourceGraphic\" kernelMatrix=\"%s\" order=\"3 3\" bias=\"%s\" divisor=\"%s\" targetX=\"1\" targetY=\"1\" preserveAlpha=\"true\" result=\"convolve\" />\n"
+ "</filter>\n", matrix.str().c_str(), inverted.str().c_str(), level.str().c_str());
+
+ return _filter;
+};
+
+}; /* namespace Filter */
+}; /* namespace Internal */
+}; /* namespace Extension */
+}; /* namespace Inkscape */
+
+/* Change the 'IMAGE' below to be your file name */
+#endif /* SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_IMAGE_H__ */
diff --git a/src/extension/internal/filter/morphology.h b/src/extension/internal/filter/morphology.h
new file mode 100644
index 0000000..9c29153
--- /dev/null
+++ b/src/extension/internal/filter/morphology.h
@@ -0,0 +1,326 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#ifndef SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_MORPHOLOGY_H__
+#define SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_MORPHOLOGY_H__
+/* Change the 'MORPHOLOGY' above to be your file name */
+
+/*
+ * Copyright (C) 2011 Authors:
+ * Ivan Louette (filters)
+ * Nicolas Dufour (UI) <nicoduf@yahoo.fr>
+ *
+ * Morphology filters
+ * Cross-smooth
+ * Outline
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+/* ^^^ Change the copyright to be you and your e-mail address ^^^ */
+
+#include "filter.h"
+
+#include "extension/internal/clear-n_.h"
+#include "extension/system.h"
+#include "extension/extension.h"
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+namespace Filter {
+
+/**
+ \brief Custom predefined Cross-smooth filter.
+
+ Smooth the outside of shapes and pictures.
+
+ Filter's parameters:
+ * Type (enum, default "Smooth edges") ->
+ Inner = composite1 (operator="in")
+ Outer = composite1 (operator="over")
+ Open = composite1 (operator="XOR")
+ * Width (0.01->30., default 10.) -> blur (stdDeviation)
+ * Level (0.2->2., default 1.) -> composite2 (k2)
+ * Dilatation (1.->100., default 10.) -> colormatrix1 (last-1 value)
+ * Erosion (1.->100., default 1.) -> colormatrix1 (last value)
+ * Antialiasing (0.01->1., default 1) -> blur2 (stdDeviation)
+ * Blur content (boolean, default false) -> blend (true: in="colormatrix2", false: in="SourceGraphic")
+*/
+
+class Crosssmooth : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ Crosssmooth ( ) : Filter() { };
+ ~Crosssmooth ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Cross-smooth") "</name>\n"
+ "<id>org.inkscape.effect.filter.crosssmooth</id>\n"
+ "<param name=\"type\" gui-text=\"" N_("Type:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"in\">" N_("Inner") "</option>\n"
+ "<option value=\"over\">" N_("Outer") "</option>\n"
+ "<option value=\"xor\">" N_("Open") "</option>\n"
+ "</param>\n"
+ "<param name=\"width\" gui-text=\"" N_("Width") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"30.\">10</param>\n"
+ "<param name=\"level\" gui-text=\"" N_("Level") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.2\" max=\"2\">1</param>\n"
+ "<param name=\"dilat\" gui-text=\"" N_("Dilatation") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"1\" max=\"100\">10</param>\n"
+ "<param name=\"erosion\" gui-text=\"" N_("Erosion") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"1\" max=\"100\">1</param>\n"
+ "<param name=\"antialias\" gui-text=\"" N_("Antialiasing") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"1\">1</param>\n"
+ "<param name=\"content\" gui-text=\"" N_("Blur content") "\" type=\"bool\" >false</param>\n"
+
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Morphology") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Smooth edges and angles of shapes") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new Crosssmooth());
+ };
+
+};
+
+gchar const *
+Crosssmooth::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream type;
+ std::ostringstream width;
+ std::ostringstream level;
+ std::ostringstream dilat;
+ std::ostringstream erosion;
+ std::ostringstream antialias;
+ std::ostringstream content;
+
+ type << ext->get_param_optiongroup("type");
+ width << ext->get_param_float("width");
+ level << ext->get_param_float("level");
+ dilat << ext->get_param_float("dilat");
+ erosion << (1 - ext->get_param_float("erosion"));
+ antialias << ext->get_param_float("antialias");
+
+ if (ext->get_param_bool("content")) {
+ content << "colormatrix2";
+ } else {
+ content << "SourceGraphic";
+ }
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Cross-smooth\">\n"
+ "<feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"%s\" result=\"blur1\" />\n"
+ "<feComposite in=\"blur1\" in2=\"blur1\" operator=\"%s\" result=\"composite1\" />\n"
+ "<feComposite in=\"composite1\" in2=\"composite1\" k2=\"%s\" operator=\"arithmetic\" result=\"composite2\" />\n"
+ "<feColorMatrix in=\"composite2\" values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 %s %s \" result=\"colormatrix1\" />\n"
+ "<feGaussianBlur stdDeviation=\"%s\" result=\"blur2\" />\n"
+ "<feColorMatrix in=\"blur2\" values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 5 -1 \" result=\"colormatrix2\" />\n"
+ "<feBlend in=\"%s\" in2=\"colormatrix2\" stdDeviation=\"17\" mode=\"normal\" result=\"blend\" />\n"
+ "<feComposite in=\"blend\" in2=\"colormatrix2\" operator=\"in\" result=\"composite3\" />\n"
+ "</filter>\n", width.str().c_str(), type.str().c_str(), level.str().c_str(),
+ dilat.str().c_str(), erosion.str().c_str(), antialias.str().c_str(),
+ content.str().c_str());
+
+ return _filter;
+}; /* Cross-smooth filter */
+
+/**
+ \brief Custom predefined Outline filter.
+
+ Adds a colorizable outline
+
+ Filter's parameters:
+ * Fill image (boolean, default false) -> true: composite2 (in="SourceGraphic"), false: composite2 (in="blur2")
+ * Hide image (boolean, default false) -> true: composite4 (in="composite3"), false: composite4 (in="SourceGraphic")
+ * Stroke type (enum, default over) -> composite2 (operator)
+ * Stroke position (enum, default inside)
+ * inside -> composite1 (operator="out", in="SourceGraphic", in2="blur1")
+ * outside -> composite1 (operator="out", in="blur1", in2="SourceGraphic")
+ * overlayed -> composite1 (operator="xor", in="blur1", in2="SourceGraphic")
+ * Width 1 (0.01->20., default 4) -> blur1 (stdDeviation)
+ * Dilatation 1 (1.->100., default 100) -> colormatrix1 (n-1th value)
+ * Erosion 1 (0.->100., default 1) -> colormatrix1 (nth value 0->-100)
+ * Width 2 (0.01->20., default 0.5) -> blur2 (stdDeviation)
+ * Dilatation 2 (1.->100., default 50) -> colormatrix2 (n-1th value)
+ * Erosion 2 (0.->100., default 5) -> colormatrix2 (nth value 0->-100)
+ * Antialiasing (0.01->1., default 1) -> blur3 (stdDeviation)
+ * Color (guint, default 0,0,0,255) -> flood (flood-color, flood-opacity)
+ * Fill opacity (0.->1., default 1) -> composite5 (k2)
+ * Stroke opacity (0.->1., default 1) -> composite5 (k3)
+
+*/
+
+class Outline : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ Outline ( ) : Filter() { };
+ ~Outline ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Outline") "</name>\n"
+ "<id>org.inkscape.effect.filter.Outline</id>\n"
+ "<param name=\"tab\" type=\"notebook\">\n"
+ "<page name=\"optionstab\" gui-text=\"Options\">\n"
+ "<param name=\"fill\" gui-text=\"" N_("Fill image") "\" type=\"bool\" >false</param>\n"
+ "<param name=\"outline\" gui-text=\"" N_("Hide image") "\" type=\"bool\" >false</param>\n"
+ "<param name=\"type\" gui-text=\"" N_("Composite type:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"over\">" N_("Over") "</option>\n"
+ "<option value=\"in\">" N_("In") "</option>\n"
+ "<option value=\"out\">" N_("Out") "</option>\n"
+ "<option value=\"atop\">" N_("Atop") "</option>\n"
+ "<option value=\"xor\">" N_("XOR") "</option>\n"
+ "</param>\n"
+ "<param name=\"position\" gui-text=\"" N_("Position:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"inside\">" N_("Inside") "</option>\n"
+ "<option value=\"outside\">" N_("Outside") "</option>\n"
+ "<option value=\"overlayed\">" N_("Overlayed") "</option>\n"
+ "</param>\n"
+ "<param name=\"width1\" gui-text=\"" N_("Width 1") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"20.00\">4</param>\n"
+ "<param name=\"dilat1\" gui-text=\"" N_("Dilatation 1") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"1\" max=\"100\">100</param>\n"
+ "<param name=\"erosion1\" gui-text=\"" N_("Erosion 1") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"100\">1</param>\n"
+ "<param name=\"width2\" gui-text=\"" N_("Width 2") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"20.00\">0.5</param>\n"
+ "<param name=\"dilat2\" gui-text=\"" N_("Dilatation 2") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"1\" max=\"100\">50</param>\n"
+ "<param name=\"erosion2\" gui-text=\"" N_("Erosion 2") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"100\">5</param>\n"
+ "<param name=\"antialias\" gui-text=\"" N_("Antialiasing") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"1\">1</param>\n"
+ "<param name=\"smooth\" gui-text=\"" N_("Smooth") "\" type=\"bool\" >false</param>\n"
+ "</page>\n"
+ "<page name=\"co11tab\" gui-text=\"Color\">\n"
+ "<param name=\"color\" gui-text=\"" N_("Color") "\" type=\"color\">255</param>\n"
+ "<param name=\"fopacity\" gui-text=\"" N_("Fill opacity:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"1\">1</param>\n"
+ "<param name=\"sopacity\" gui-text=\"" N_("Stroke opacity:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"1\">1</param>\n"
+ "</page>\n"
+ "</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Morphology") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Adds a colorizable outline") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new Outline());
+ };
+
+};
+
+gchar const *
+Outline::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream width1;
+ std::ostringstream dilat1;
+ std::ostringstream erosion1;
+ std::ostringstream width2;
+ std::ostringstream dilat2;
+ std::ostringstream erosion2;
+ std::ostringstream antialias;
+ std::ostringstream r;
+ std::ostringstream g;
+ std::ostringstream b;
+ std::ostringstream a;
+ std::ostringstream fopacity;
+ std::ostringstream sopacity;
+ std::ostringstream smooth;
+
+ std::ostringstream c1in;
+ std::ostringstream c1in2;
+ std::ostringstream c1op;
+ std::ostringstream c2in;
+ std::ostringstream c2op;
+ std::ostringstream c4in;
+
+
+ width1 << ext->get_param_float("width1");
+ dilat1 << ext->get_param_float("dilat1");
+ erosion1 << (- ext->get_param_float("erosion1"));
+ width2 << ext->get_param_float("width2");
+ dilat2 << ext->get_param_float("dilat2");
+ erosion2 << (- ext->get_param_float("erosion2"));
+ antialias << ext->get_param_float("antialias");
+ guint32 color = ext->get_param_color("color");
+ r << ((color >> 24) & 0xff);
+ g << ((color >> 16) & 0xff);
+ b << ((color >> 8) & 0xff);
+ a << (color & 0xff) / 255.0F;
+
+ fopacity << ext->get_param_float("fopacity");
+ sopacity << ext->get_param_float("sopacity");
+
+ const gchar *position = ext->get_param_optiongroup("position");
+ if((g_ascii_strcasecmp("inside", position) == 0)) {
+ // Indide
+ c1in << "SourceGraphic";
+ c1in2 << "blur1";
+ c1op << "out";
+ } else if((g_ascii_strcasecmp("outside", position) == 0)) {
+ // Outside
+ c1in << "blur1";
+ c1in2 << "SourceGraphic";
+ c1op << "out";
+ } else {
+ // Overlayed
+ c1in << "blur1";
+ c1in2 << "SourceGraphic";
+ c1op << "xor";
+ }
+
+ if (ext->get_param_bool("fill")) {
+ c2in << "SourceGraphic";
+ } else {
+ c2in << "blur2";
+ }
+
+ c2op << ext->get_param_optiongroup("type");
+
+ if (ext->get_param_bool("outline")) {
+ c4in << "composite3";
+ } else {
+ c4in << "SourceGraphic";
+ }
+
+ if (ext->get_param_bool("smooth")) {
+ smooth << "1 0";
+ } else {
+ smooth << "5 -1";
+ }
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" height=\"1.4\" width=\"1.4\" y=\"-0.2\" x=\"-0.2\" inkscape:label=\"Outline\">\n"
+ "<feGaussianBlur in=\"SourceAlpha\" stdDeviation=\"%s\" result=\"blur1\" />\n"
+ "<feComposite in=\"%s\" in2=\"%s\" operator=\"%s\" result=\"composite1\" />\n"
+ "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 %s %s \" result=\"colormatrix1\" />\n"
+ "<feGaussianBlur stdDeviation=\"%s\" result=\"blur2\" />\n"
+ "<feComposite in=\"%s\" in2=\"blur2\" operator=\"%s\" result=\"composite2\" />\n"
+ "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 %s %s \" result=\"colormatrix2\" />\n"
+ "<feGaussianBlur stdDeviation=\"%s\" result=\"blur3\" />\n"
+ "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 %s \" result=\"colormatrix3\" />\n"
+ "<feFlood flood-opacity=\"%s\" flood-color=\"rgb(%s,%s,%s)\" result=\"flood\" />\n"
+ "<feComposite in=\"flood\" in2=\"colormatrix3\" k2=\"1\" operator=\"in\" result=\"composite3\" />\n"
+ "<feComposite in=\"%s\" in2=\"colormatrix3\" operator=\"out\" result=\"composite4\" />\n"
+ "<feComposite in=\"composite4\" in2=\"composite3\" k2=\"%s\" k3=\"%s\" operator=\"arithmetic\" result=\"composite5\" />\n"
+ "</filter>\n", width1.str().c_str(), c1in.str().c_str(), c1in2.str().c_str(), c1op.str().c_str(),
+ dilat1.str().c_str(), erosion1.str().c_str(),
+ width2.str().c_str(), c2in.str().c_str(), c2op.str().c_str(),
+ dilat2.str().c_str(), erosion2.str().c_str(), antialias.str().c_str(), smooth.str().c_str(),
+ a.str().c_str(), r.str().c_str(), g.str().c_str(), b.str().c_str(),
+ c4in.str().c_str(), fopacity.str().c_str(), sopacity.str().c_str() );
+
+ return _filter;
+}; /* Outline filter */
+
+}; /* namespace Filter */
+}; /* namespace Internal */
+}; /* namespace Extension */
+}; /* namespace Inkscape */
+
+/* Change the 'MORPHOLOGY' below to be your file name */
+#endif /* SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_MORPHOLOGY_H__ */
diff --git a/src/extension/internal/filter/overlays.h b/src/extension/internal/filter/overlays.h
new file mode 100644
index 0000000..fd88460
--- /dev/null
+++ b/src/extension/internal/filter/overlays.h
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#ifndef SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_OVERLAYS_H__
+#define SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_OVERLAYS_H__
+/* Change the 'OVERLAYS' above to be your file name */
+
+/*
+ * Copyright (C) 2011 Authors:
+ * Ivan Louette (filters)
+ * Nicolas Dufour (UI) <nicoduf@yahoo.fr>
+ *
+ * Overlays filters
+ * Noise fill
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+/* ^^^ Change the copyright to be you and your e-mail address ^^^ */
+
+#include "filter.h"
+
+#include "extension/internal/clear-n_.h"
+#include "extension/system.h"
+#include "extension/extension.h"
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+namespace Filter {
+
+/**
+ \brief Custom predefined Noise fill filter.
+
+ Basic noise fill and transparency texture
+
+ Filter's parameters:
+ * Turbulence type (enum, default fractalNoise else turbulence) -> turbulence (type)
+ * Horizontal frequency (*1000) (0.01->10000., default 20) -> turbulence (baseFrequency [/1000])
+ * Vertical frequency (*1000) (0.01->10000., default 40) -> turbulence (baseFrequency [/1000])
+ * Complexity (1->5, default 5) -> turbulence (numOctaves)
+ * Variation (1->360, default 1) -> turbulence (seed)
+ * Dilatation (1.->50., default 3) -> color (n-1th value)
+ * Erosion (0.->50., default 1) -> color (nth value 0->-50)
+ * Color (guint, default 148,115,39,255) -> flood (flood-color, flood-opacity)
+ * Inverted (boolean, default false) -> composite1 (operator, true="in", false="out")
+*/
+
+class NoiseFill : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ NoiseFill ( ) : Filter() { };
+ ~NoiseFill ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Noise Fill") "</name>\n"
+ "<id>org.inkscape.effect.filter.NoiseFill</id>\n"
+ "<param name=\"tab\" type=\"notebook\">\n"
+ "<page name=\"optionstab\" gui-text=\"" N_("Options") "\">\n"
+ "<param name=\"type\" gui-text=\"" N_("Turbulence type:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"fractalNoise\">" N_("Fractal noise") "</option>\n"
+ "<option value=\"turbulence\">" N_("Turbulence") "</option>\n"
+ "</param>\n"
+ "<param name=\"hfreq\" gui-text=\"" N_("Horizontal frequency:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"10000.00\">20</param>\n"
+ "<param name=\"vfreq\" gui-text=\"" N_("Vertical frequency:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"10000.00\">40</param>\n"
+ "<param name=\"complexity\" gui-text=\"" N_("Complexity:") "\" type=\"int\" appearance=\"full\" min=\"1\" max=\"5\">5</param>\n"
+ "<param name=\"variation\" gui-text=\"" N_("Variation:") "\" type=\"int\" appearance=\"full\" min=\"1\" max=\"360\">0</param>\n"
+ "<param name=\"dilat\" gui-text=\"" N_("Dilatation:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"1\" max=\"50\">3</param>\n"
+ "<param name=\"erosion\" gui-text=\"" N_("Erosion:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"50\">1</param>\n"
+ "<param name=\"inverted\" gui-text=\"" N_("Inverted") "\" type=\"bool\" >false</param>\n"
+ "</page>\n"
+ "<page name=\"co11tab\" gui-text=\"" N_("Noise color") "\">\n"
+ "<param name=\"color\" gui-text=\"" N_("Color") "\" type=\"color\">354957823</param>\n"
+ "</page>\n"
+ "</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Overlays") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Basic noise fill and transparency texture") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new NoiseFill());
+ };
+
+};
+
+gchar const *
+NoiseFill::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream type;
+ std::ostringstream hfreq;
+ std::ostringstream vfreq;
+ std::ostringstream complexity;
+ std::ostringstream variation;
+ std::ostringstream dilat;
+ std::ostringstream erosion;
+ std::ostringstream r;
+ std::ostringstream g;
+ std::ostringstream b;
+ std::ostringstream a;
+ std::ostringstream inverted;
+
+ type << ext->get_param_optiongroup("type");
+ hfreq << (ext->get_param_float("hfreq") / 1000);
+ vfreq << (ext->get_param_float("vfreq") / 1000);
+ complexity << ext->get_param_int("complexity");
+ variation << ext->get_param_int("variation");
+ dilat << ext->get_param_float("dilat");
+ erosion << (- ext->get_param_float("erosion"));
+ guint32 color = ext->get_param_color("color");
+ r << ((color >> 24) & 0xff);
+ g << ((color >> 16) & 0xff);
+ b << ((color >> 8) & 0xff);
+ a << (color & 0xff) / 255.0F;
+ if (ext->get_param_bool("inverted"))
+ inverted << "out";
+ else
+ inverted << "in";
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Noise Fill\">\n"
+ "<feTurbulence type=\"%s\" baseFrequency=\"%s %s\" numOctaves=\"%s\" seed=\"%s\" result=\"turbulence\"/>\n"
+ "<feComposite in=\"SourceGraphic\" in2=\"turbulence\" operator=\"%s\" result=\"composite1\" />\n"
+ "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 %s %s \" result=\"color\" />\n"
+ "<feFlood flood-opacity=\"%s\" flood-color=\"rgb(%s,%s,%s)\" result=\"flood\" />\n"
+ "<feMerge result=\"merge\">\n"
+ "<feMergeNode in=\"flood\" />\n"
+ "<feMergeNode in=\"color\" />\n"
+ "</feMerge>\n"
+ "<feComposite in2=\"SourceGraphic\" operator=\"in\" result=\"composite2\" />\n"
+ "</filter>\n", type.str().c_str(), hfreq.str().c_str(), vfreq.str().c_str(), complexity.str().c_str(), variation.str().c_str(), inverted.str().c_str(), dilat.str().c_str(), erosion.str().c_str(), a.str().c_str(), r.str().c_str(), g.str().c_str(), b.str().c_str());
+
+ return _filter;
+}; /* NoiseFill filter */
+
+}; /* namespace Filter */
+}; /* namespace Internal */
+}; /* namespace Extension */
+}; /* namespace Inkscape */
+
+/* Change the 'OVERLAYS' below to be your file name */
+#endif /* SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_OVERLAYS_H__ */
diff --git a/src/extension/internal/filter/paint.h b/src/extension/internal/filter/paint.h
new file mode 100644
index 0000000..162d150
--- /dev/null
+++ b/src/extension/internal/filter/paint.h
@@ -0,0 +1,1029 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#ifndef SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_PAINT_H__
+#define SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_PAINT_H__
+/* Change the 'PAINT' above to be your file name */
+
+/*
+ * Copyright (C) 2012 Authors:
+ * Ivan Louette (filters)
+ * Nicolas Dufour (UI) <nicoduf@yahoo.fr>
+ *
+ * Image paint and draw filters
+ * Chromolitho
+ * Cross engraving
+ * Drawing
+ * Electrize
+ * Neon draw
+ * Point engraving
+ * Posterize
+ * Posterize basic
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+/* ^^^ Change the copyright to be you and your e-mail address ^^^ */
+
+#include "filter.h"
+
+#include "extension/internal/clear-n_.h"
+#include "extension/system.h"
+#include "extension/extension.h"
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+namespace Filter {
+
+/**
+ \brief Custom predefined Chromolitho filter.
+
+ Chromo effect with customizable edge drawing and graininess
+
+ Filter's parameters:
+ * Drawing (boolean, default checked) -> Checked = blend1 (in="convolve1"), unchecked = blend1 (in="composite1")
+ * Transparent (boolean, default unchecked) -> Checked = colormatrix5 (in="colormatrix4"), Unchecked = colormatrix5 (in="component1")
+ * Invert (boolean, default false) -> component1 (tableValues) [adds a trailing 0]
+ * Dented (boolean, default false) -> component1 (tableValues) [adds intermediate 0s]
+ * Lightness (0.->10., default 0.) -> composite1 (k1)
+ * Saturation (0.->1., default 1.) -> colormatrix3 (values)
+ * Noise reduction (1->1000, default 20) -> convolve (kernelMatrix, central value -1001->-2000, default -1020)
+ * Drawing blend (enum, default Normal) -> blend1 (mode)
+ * Smoothness (0.01->10, default 1) -> blur1 (stdDeviation)
+ * Grain (boolean, default unchecked) -> Checked = blend2 (in="colormatrix2"), Unchecked = blend2 (in="blur1")
+ * Grain x frequency (0.->1000, default 1000) -> turbulence1 (baseFrequency, first value)
+ * Grain y frequency (0.->1000, default 1000) -> turbulence1 (baseFrequency, second value)
+ * Grain complexity (1->5, default 1) -> turbulence1 (numOctaves)
+ * Grain variation (0->1000, default 0) -> turbulence1 (seed)
+ * Grain expansion (1.->50., default 1.) -> colormatrix1 (n-1 value)
+ * Grain erosion (0.->40., default 0.) -> colormatrix1 (nth value) [inverted]
+ * Grain color (boolean, default true) -> colormatrix2 (values)
+ * Grain blend (enum, default Normal) -> blend2 (mode)
+*/
+class Chromolitho : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ Chromolitho ( ) : Filter() { };
+ ~Chromolitho ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Chromolitho") "</name>\n"
+ "<id>org.inkscape.effect.filter.Chromolitho</id>\n"
+ "<param name=\"tab\" type=\"notebook\">\n"
+ "<page name=\"optionstab\" gui-text=\"Options\">\n"
+ "<param name=\"drawing\" gui-text=\"" N_("Drawing mode") "\" type=\"bool\" >true</param>\n"
+ "<param name=\"dblend\" gui-text=\"" N_("Drawing blend:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"darken\">Darken</option>\n"
+ "<option value=\"normal\">Normal</option>\n"
+ "<option value=\"multiply\">Multiply</option>\n"
+ "<option value=\"screen\">Screen</option>\n"
+ "<option value=\"lighten\">Lighten</option>\n"
+ "</param>\n"
+ "<param name=\"transparent\" gui-text=\"" N_("Transparent") "\" type=\"bool\" >false</param>\n"
+ "<param name=\"dented\" gui-text=\"" N_("Dented") "\" type=\"bool\" >false</param>\n"
+ "<param name=\"inverted\" gui-text=\"" N_("Inverted") "\" type=\"bool\" >false</param>\n"
+ "<param name=\"light\" gui-text=\"" N_("Lightness") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"10\">0</param>\n"
+ "<param name=\"saturation\" gui-text=\"" N_("Saturation") "\" type=\"float\" precision=\"2\" appearance=\"full\" min=\"0\" max=\"1\">1</param>\n"
+ "<param name=\"noise\" gui-text=\"" N_("Noise reduction") "\" type=\"int\" appearance=\"full\" min=\"1\" max=\"1000\">10</param>\n"
+ "<param name=\"smooth\" gui-text=\"" N_("Smoothness") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"10.00\">1</param>\n"
+ "</page>\n"
+ "<page name=\"graintab\" gui-text=\"" N_("Grain") "\">\n"
+ "<param name=\"grain\" gui-text=\"" N_("Grain mode") "\" type=\"bool\" >true</param>\n"
+ "<param name=\"grainxf\" gui-text=\"" N_("Horizontal frequency") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"1000\">1000</param>\n"
+ "<param name=\"grainyf\" gui-text=\"" N_("Vertical frequency") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"1000\">1000</param>\n"
+ "<param name=\"grainc\" gui-text=\"" N_("Complexity") "\" type=\"int\" appearance=\"full\" min=\"1\" max=\"5\">1</param>\n"
+ "<param name=\"grainv\" gui-text=\"" N_("Variation") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"1000\">0</param>\n"
+ "<param name=\"grainexp\" gui-text=\"" N_("Expansion") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"1\" max=\"50\">1</param>\n"
+ "<param name=\"grainero\" gui-text=\"" N_("Erosion") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"40\">0</param>\n"
+ "<param name=\"graincol\" gui-text=\"" N_("Color") "\" type=\"bool\" >true</param>\n"
+ "<param name=\"gblend\" gui-text=\"" N_("Grain blend:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"normal\">Normal</option>\n"
+ "<option value=\"multiply\">Multiply</option>\n"
+ "<option value=\"screen\">Screen</option>\n"
+ "<option value=\"lighten\">Lighten</option>\n"
+ "<option value=\"darken\">Darken</option>\n"
+ "</param>\n"
+ "</page>\n"
+ "</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Image Paint and Draw") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Chromo effect with customizable edge drawing and graininess") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new Chromolitho());
+ };
+};
+
+gchar const *
+Chromolitho::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream b1in;
+ std::ostringstream b2in;
+ std::ostringstream col3in;
+ std::ostringstream transf;
+ std::ostringstream light;
+ std::ostringstream saturation;
+ std::ostringstream noise;
+ std::ostringstream dblend;
+ std::ostringstream smooth;
+ std::ostringstream grainxf;
+ std::ostringstream grainyf;
+ std::ostringstream grainc;
+ std::ostringstream grainv;
+ std::ostringstream gblend;
+ std::ostringstream grainexp;
+ std::ostringstream grainero;
+ std::ostringstream graincol;
+
+ if (ext->get_param_bool("drawing"))
+ b1in << "convolve1";
+ else
+ b1in << "composite1";
+
+ if (ext->get_param_bool("transparent"))
+ col3in << "colormatrix4";
+ else
+ col3in << "component1";
+ light << ext->get_param_float("light");
+ saturation << ext->get_param_float("saturation");
+ noise << (-1000 - ext->get_param_int("noise"));
+ dblend << ext->get_param_optiongroup("dblend");
+ smooth << ext->get_param_float("smooth");
+
+ if (ext->get_param_bool("dented")) {
+ transf << "0 1 0 1";
+ } else {
+ transf << "0 1 1";
+ }
+ if (ext->get_param_bool("inverted"))
+ transf << " 0";
+
+ if (ext->get_param_bool("grain"))
+ b2in << "colormatrix2";
+ else
+ b2in << "blur1";
+ grainxf << (ext->get_param_float("grainxf") / 1000);
+ grainyf << (ext->get_param_float("grainyf") / 1000);
+ grainc << ext->get_param_int("grainc");
+ grainv << ext->get_param_int("grainv");
+ gblend << ext->get_param_optiongroup("gblend");
+ grainexp << ext->get_param_float("grainexp");
+ grainero << (-ext->get_param_float("grainero"));
+ if (ext->get_param_bool("graincol"))
+ graincol << "1";
+ else
+ graincol << "0";
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Chromolitho\">\n"
+ "<feComposite in=\"SourceGraphic\" in2=\"SourceGraphic\" operator=\"arithmetic\" k1=\"%s\" k2=\"1\" result=\"composite1\" />\n"
+ "<feConvolveMatrix in=\"composite1\" kernelMatrix=\"0 250 0 250 %s 250 0 250 0 \" order=\"3 3\" result=\"convolve1\" />\n"
+ "<feBlend in=\"%s\" in2=\"composite1\" mode=\"%s\" result=\"blend1\" />\n"
+ "<feGaussianBlur in=\"blend1\" stdDeviation=\"%s\" result=\"blur1\" />\n"
+ "<feTurbulence baseFrequency=\"%s %s\" numOctaves=\"%s\" seed=\"%s\" type=\"fractalNoise\" result=\"turbulence1\" />\n"
+ "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 %s %s \" result=\"colormatrix1\" />\n"
+ "<feColorMatrix type=\"saturate\" values=\"%s\" result=\"colormatrix2\" />\n"
+ "<feBlend in=\"%s\" in2=\"blur1\" mode=\"%s\" result=\"blend2\" />\n"
+ "<feColorMatrix in=\"blend2\" type=\"saturate\" values=\"%s\" result=\"colormatrix3\" />\n"
+ "<feComponentTransfer in=\"colormatrix3\" result=\"component1\">\n"
+ "<feFuncR type=\"discrete\" tableValues=\"%s\" />\n"
+ "<feFuncG type=\"discrete\" tableValues=\"%s\" />\n"
+ "<feFuncB type=\"discrete\" tableValues=\"%s\" />\n"
+ "</feComponentTransfer>\n"
+ "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -0.2125 -0.7154 -0.0721 1 0 \" result=\"colormatrix4\" />\n"
+ "<feColorMatrix in=\"%s\" values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 15 0 \" result=\"colormatrix5\" />\n"
+ "<feComposite in2=\"SourceGraphic\" operator=\"in\" result=\"composite2\" />\n"
+ "</filter>\n", light.str().c_str(), noise.str().c_str(), b1in.str().c_str(), dblend.str().c_str(), smooth.str().c_str(), grainxf.str().c_str(), grainyf.str().c_str(), grainc.str().c_str(), grainv.str().c_str(), grainexp.str().c_str(), grainero.str().c_str(), graincol.str().c_str(), b2in.str().c_str(), gblend.str().c_str(), saturation.str().c_str(), transf.str().c_str(), transf.str().c_str(), transf.str().c_str(), col3in.str().c_str());
+
+ return _filter;
+}; /* Chromolitho filter */
+
+/**
+ \brief Custom predefined Cross engraving filter.
+
+ Convert image to an engraving made of vertical and horizontal lines
+
+ Filter's parameters:
+ * Clean-up (1->500, default 30) -> convolve1 (kernelMatrix, central value -1001->-1500, default -1030)
+ * Dilatation (1.->50., default 1) -> color2 (n-1th value)
+ * Erosion (0.->50., default 0) -> color2 (nth value 0->-50)
+ * Strength (0.->10., default 0.5) -> composite2 (k2)
+ * Length (0.5->20, default 4) -> blur1 (stdDeviation x), blur2 (stdDeviation y)
+ * Transparent (boolean, default false) -> composite 4 (in, true->composite3, false->blend)
+*/
+class CrossEngraving : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ CrossEngraving ( ) : Filter() { };
+ ~CrossEngraving ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Cross Engraving") "</name>\n"
+ "<id>org.inkscape.effect.filter.CrossEngraving</id>\n"
+ "<param name=\"clean\" gui-text=\"" N_("Clean-up") "\" type=\"int\" appearance=\"full\" min=\"1\" max=\"500\">30</param>\n"
+ "<param name=\"dilat\" gui-text=\"" N_("Dilatation") "\" type=\"float\" appearance=\"full\" min=\"1\" max=\"50\">1</param>\n"
+ "<param name=\"erosion\" gui-text=\"" N_("Erosion") "\" type=\"float\" appearance=\"full\" min=\"0\" max=\"50\">0</param>\n"
+ "<param name=\"strength\" gui-text=\"" N_("Strength") "\" type=\"float\" appearance=\"full\" min=\"0.1\" max=\"10\">0.5</param>\n"
+ "<param name=\"length\" gui-text=\"" N_("Length") "\" type=\"float\" appearance=\"full\" min=\"0.5\" max=\"20\">4</param>\n"
+ "<param name=\"trans\" gui-text=\"" N_("Transparent") "\" type=\"bool\" >false</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Image Paint and Draw") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Convert image to an engraving made of vertical and horizontal lines") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new CrossEngraving());
+ };
+};
+
+gchar const *
+CrossEngraving::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream clean;
+ std::ostringstream dilat;
+ std::ostringstream erosion;
+ std::ostringstream strength;
+ std::ostringstream length;
+ std::ostringstream trans;
+
+ clean << (-1000 - ext->get_param_int("clean"));
+ dilat << ext->get_param_float("dilat");
+ erosion << (- ext->get_param_float("erosion"));
+ strength << ext->get_param_float("strength");
+ length << ext->get_param_float("length");
+ if (ext->get_param_bool("trans"))
+ trans << "composite3";
+ else
+ trans << "blend";
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Cross Engraving\">\n"
+ "<feConvolveMatrix in=\"SourceGraphic\" targetY=\"1\" targetX=\"1\" kernelMatrix=\"0 250 0 250 %s 250 0 250 0 \" order=\"3 3\" result=\"convolve\" />\n"
+ "<feComposite in=\"convolve\" in2=\"convolve\" k1=\"1\" k2=\"1\" operator=\"arithmetic\" result=\"composite1\" />\n"
+ "<feColorMatrix in=\"composite1\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.2125 -0.7154 -0.0721 1 0 \" result=\"color1\" />\n"
+ "<feColorMatrix in=\"color1\" values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 %s %s \" result=\"color2\" />\n"
+ "<feComposite in=\"color2\" in2=\"color2\" operator=\"arithmetic\" k2=\"%s\" result=\"composite2\" />\n"
+ "<feGaussianBlur in=\"composite2\" stdDeviation=\"%s 0.01\" result=\"blur1\" />\n"
+ "<feGaussianBlur in=\"composite2\" stdDeviation=\"0.01 %s\" result=\"blur2\" />\n"
+ "<feComposite in=\"blur2\" in2=\"blur1\" k3=\"1\" k2=\"1\" operator=\"arithmetic\" result=\"composite3\" />\n"
+ "<feFlood flood-color=\"rgb(255,255,255)\" flood-opacity=\"1\" result=\"flood\" />\n"
+ "<feBlend in=\"flood\" in2=\"composite3\" mode=\"multiply\" result=\"blend\" />\n"
+ "<feComposite in=\"%s\" in2=\"SourceGraphic\" operator=\"in\" result=\"composite4\" />\n"
+ "</filter>\n", clean.str().c_str(), dilat.str().c_str(), erosion.str().c_str(), strength.str().c_str(), length.str().c_str(), length.str().c_str(), trans.str().c_str());
+
+ return _filter;
+}; /* CrossEngraving filter */
+
+/**
+ \brief Custom predefined Drawing filter.
+
+ Convert images to duochrome drawings.
+
+ Filter's parameters:
+ * Simplification strength (0.01->20, default 0.6) -> blur1 (stdDeviation)
+ * Clean-up (1->500, default 10) -> convolve1 (kernelMatrix, central value -1001->-1500, default -1010)
+ * Erase (0.->6., default 0) -> composite1 (k4)
+ * Smoothness strength (0.01->20, default 0.6) -> blur2 (stdDeviation)
+ * Dilatation (1.->50., default 6) -> color2 (n-1th value)
+ * Erosion (0.->50., default 2) -> color2 (nth value 0->-50)
+ * translucent (boolean, default false) -> composite 8 (in, true->merge1, false->color5)
+
+ * Blur strength (0.01->20., default 1.) -> blur3 (stdDeviation)
+ * Blur dilatation (1.->50., default 6) -> color4 (n-1th value)
+ * Blur erosion (0.->50., default 2) -> color4 (nth value 0->-50)
+
+ * Stroke color (guint, default 64,64,64,255) -> flood2 (flood-color), composite3 (k2)
+ * Image on stroke (boolean, default false) -> composite2 (in="flood2" true-> in="SourceGraphic")
+ * Offset (-100->100, default 0) -> offset (val)
+
+ * Fill color (guint, default 200,200,200,255) -> flood3 (flood-opacity), composite5 (k2)
+ * Image on fill (boolean, default false) -> composite4 (in="flood3" true-> in="SourceGraphic")
+
+*/
+
+class Drawing : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ Drawing ( ) : Filter() { };
+ ~Drawing ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Drawing") "</name>\n"
+ "<id>org.inkscape.effect.filter.Drawing</id>\n"
+ "<param name=\"tab\" type=\"notebook\">\n"
+ "<page name=\"optionstab\" gui-text=\"Options\">\n"
+ "<label appearance=\"header\">" N_("Simplify") "</label>\n"
+ "<param name=\"simply\" gui-text=\"" N_("Strength") "\" type=\"float\" indent=\"1\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"20.00\">0.6</param>\n"
+ "<param name=\"clean\" gui-text=\"" N_("Clean-up") "\" type=\"int\" indent=\"1\" appearance=\"full\" min=\"1\" max=\"500\">10</param>\n"
+ "<param name=\"erase\" gui-text=\"" N_("Erase") "\" type=\"float\" indent=\"1\" appearance=\"full\" min=\"0\" max=\"60\">0</param>\n"
+ "<param name=\"translucent\" gui-text=\"" N_("Translucent") "\" indent=\"1\" type=\"bool\" >false</param>\n"
+ "<label appearance=\"header\">" N_("Smoothness") "</label>\n"
+ "<param name=\"smooth\" gui-text=\"" N_("Strength") "\" type=\"float\" indent=\"1\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"20.00\">0.6</param>\n"
+ "<param name=\"dilat\" gui-text=\"" N_("Dilatation") "\" type=\"float\" indent=\"1\" appearance=\"full\" min=\"1\" max=\"50\">6</param>\n"
+ "<param name=\"erosion\" gui-text=\"" N_("Erosion") "\" type=\"float\" indent=\"1\" appearance=\"full\" min=\"0\" max=\"50\">2</param>\n"
+ "<label appearance=\"header\">" N_("Melt") "</label>\n"
+ "<param name=\"blur\" gui-text=\"" N_("Level") "\" type=\"float\" indent=\"1\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"20.00\">1</param>\n"
+ "<param name=\"bdilat\" gui-text=\"" N_("Dilatation") "\" type=\"float\" indent=\"1\" appearance=\"full\" min=\"1\" max=\"50\">6</param>\n"
+ "<param name=\"berosion\" gui-text=\"" N_("Erosion") "\" type=\"float\" indent=\"1\" appearance=\"full\" min=\"0\" max=\"50\">2</param>\n"
+ "</page>\n"
+ "<page name=\"co11tab\" gui-text=\"Fill color\">\n"
+ "<param name=\"fcolor\" gui-text=\"" N_("Fill color") "\" type=\"color\">-1515870721</param>\n"
+ "<param name=\"iof\" gui-text=\"" N_("Image on fill") "\" type=\"bool\" >false</param>\n"
+ "</page>\n"
+ "<page name=\"co12tab\" gui-text=\"Stroke color\">\n"
+ "<param name=\"scolor\" gui-text=\"" N_("Stroke color") "\" type=\"color\">589505535</param>\n"
+ "<param name=\"ios\" gui-text=\"" N_("Image on stroke") "\" type=\"bool\" >false</param>\n"
+ "<param name=\"offset\" gui-text=\"" N_("Offset") "\" type=\"int\" appearance=\"full\" min=\"-100\" max=\"100\">0</param>\n"
+ "</page>\n"
+ "</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Image Paint and Draw") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Convert images to duochrome drawings") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new Drawing());
+ };
+};
+
+gchar const *
+Drawing::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream simply;
+ std::ostringstream clean;
+ std::ostringstream erase;
+ std::ostringstream smooth;
+ std::ostringstream dilat;
+ std::ostringstream erosion;
+ std::ostringstream translucent;
+ std::ostringstream offset;
+ std::ostringstream blur;
+ std::ostringstream bdilat;
+ std::ostringstream berosion;
+ std::ostringstream strokea;
+ std::ostringstream stroker;
+ std::ostringstream strokeg;
+ std::ostringstream strokeb;
+ std::ostringstream ios;
+ std::ostringstream filla;
+ std::ostringstream fillr;
+ std::ostringstream fillg;
+ std::ostringstream fillb;
+ std::ostringstream iof;
+
+ simply << ext->get_param_float("simply");
+ clean << (-1000 - ext->get_param_int("clean"));
+ erase << (ext->get_param_float("erase") / 10);
+ smooth << ext->get_param_float("smooth");
+ dilat << ext->get_param_float("dilat");
+ erosion << (- ext->get_param_float("erosion"));
+ if (ext->get_param_bool("translucent"))
+ translucent << "merge1";
+ else
+ translucent << "color5";
+ offset << ext->get_param_int("offset");
+
+ blur << ext->get_param_float("blur");
+ bdilat << ext->get_param_float("bdilat");
+ berosion << (- ext->get_param_float("berosion"));
+
+ guint32 fcolor = ext->get_param_color("fcolor");
+ fillr << ((fcolor >> 24) & 0xff);
+ fillg << ((fcolor >> 16) & 0xff);
+ fillb << ((fcolor >> 8) & 0xff);
+ filla << (fcolor & 0xff) / 255.0F;
+ if (ext->get_param_bool("iof"))
+ iof << "SourceGraphic";
+ else
+ iof << "flood3";
+
+ guint32 scolor = ext->get_param_color("scolor");
+ stroker << ((scolor >> 24) & 0xff);
+ strokeg << ((scolor >> 16) & 0xff);
+ strokeb << ((scolor >> 8) & 0xff);
+ strokea << (scolor & 0xff) / 255.0F;
+ if (ext->get_param_bool("ios"))
+ ios << "SourceGraphic";
+ else
+ ios << "flood2";
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Drawing\">\n"
+ "<feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"%s\" result=\"blur1\" />\n"
+ "<feConvolveMatrix in=\"blur1\" targetX=\"1\" targetY=\"1\" order=\"3 3\" kernelMatrix=\"0 250 0 250 %s 250 0 250 0 \" result=\"convolve1\" />\n"
+ "<feComposite in=\"convolve1\" in2=\"convolve1\" k1=\"1\" k2=\"1\" k4=\"%s\" operator=\"arithmetic\" result=\"composite1\" />\n"
+ "<feColorMatrix in=\"composite1\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.2125 -0.7154 -0.0721 1 0 \" result=\"color1\" />\n"
+ "<feGaussianBlur stdDeviation=\"%s\" result=\"blur2\" />\n"
+ "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 %s %s \" result=\"color2\" />\n"
+ "<feFlood flood-color=\"rgb(255,255,255)\" result=\"flood1\" />\n"
+ "<feBlend in2=\"color2\" mode=\"multiply\" result=\"blend1\" />\n"
+ "<feComponentTransfer in=\"blend1\" result=\"component1\">\n"
+ "<feFuncR type=\"discrete\" tableValues=\"0 1 1 1\" />\n"
+ "<feFuncG type=\"discrete\" tableValues=\"0 1 1 1\" />\n"
+ "<feFuncB type=\"discrete\" tableValues=\"0 1 1 1\" />\n"
+ "</feComponentTransfer>\n"
+ "<feGaussianBlur stdDeviation=\"%s\" result=\"blur3\" />\n"
+ "<feColorMatrix in=\"blur3\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.2125 -0.7154 -0.0721 1 0 \" result=\"color3\" />\n"
+ "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 %s %s \" result=\"color4\" />\n"
+ "<feFlood flood-color=\"rgb(%s,%s,%s)\" result=\"flood2\" />\n"
+ "<feComposite in=\"%s\" in2=\"color4\" operator=\"in\" result=\"composite2\" />\n"
+ "<feComposite in=\"composite2\" in2=\"composite2\" operator=\"arithmetic\" k2=\"%s\" result=\"composite3\" />\n"
+ "<feOffset dx=\"%s\" dy=\"%s\" result=\"offset1\" />\n"
+ "<feFlood in=\"color4\" flood-color=\"rgb(%s,%s,%s)\" result=\"flood3\" />\n"
+ "<feComposite in=\"%s\" in2=\"color4\" operator=\"out\" result=\"composite4\" />\n"
+ "<feComposite in=\"composite4\" in2=\"composite4\" operator=\"arithmetic\" k2=\"%s\" result=\"composite5\" />\n"
+ "<feMerge result=\"merge1\">\n"
+ "<feMergeNode in=\"composite5\" />\n"
+ "<feMergeNode in=\"offset1\" />\n"
+ "</feMerge>\n"
+ "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1.3 0 \" result=\"color5\" flood-opacity=\"0.56\" />\n"
+ "<feComposite in=\"%s\" in2=\"SourceGraphic\" operator=\"in\" result=\"composite8\" />\n"
+ "</filter>\n", simply.str().c_str(), clean.str().c_str(), erase.str().c_str(), smooth.str().c_str(), dilat.str().c_str(), erosion.str().c_str(), blur.str().c_str(), bdilat.str().c_str(), berosion.str().c_str(), stroker.str().c_str(), strokeg.str().c_str(), strokeb.str().c_str(), ios.str().c_str(), strokea.str().c_str(), offset.str().c_str(), offset.str().c_str(), fillr.str().c_str(), fillg.str().c_str(), fillb.str().c_str(), iof.str().c_str(), filla.str().c_str(), translucent.str().c_str());
+
+ return _filter;
+}; /* Drawing filter */
+
+
+/**
+ \brief Custom predefined Electrize filter.
+
+ Electro solarization effects.
+
+ Filter's parameters:
+ * Simplify (0.01->10., default 2.) -> blur (stdDeviation)
+ * Effect type (enum: table or discrete, default "table") -> component (type)
+ * Level (0->10, default 3) -> component (tableValues)
+ * Inverted (boolean, default false) -> component (tableValues)
+*/
+class Electrize : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ Electrize ( ) : Filter() { };
+ ~Electrize ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Electrize") "</name>\n"
+ "<id>org.inkscape.effect.filter.Electrize</id>\n"
+ "<param name=\"blur\" gui-text=\"" N_("Simplify") "\" type=\"float\" appearance=\"full\" min=\"0.01\" max=\"10.0\">2.0</param>\n"
+ "<param name=\"type\" gui-text=\"" N_("Effect type:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"table\">" N_("Table") "</option>\n"
+ "<option value=\"discrete\">" N_("Discrete") "</option>\n"
+ "</param>\n"
+ "<param name=\"levels\" gui-text=\"" N_("Levels") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"10\">3</param>\n"
+ "<param name=\"invert\" gui-text=\"" N_("Inverted") "\" type=\"bool\">false</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Image Paint and Draw") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Electro solarization effects") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new Electrize());
+ };
+};
+
+gchar const *
+Electrize::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream blur;
+ std::ostringstream type;
+ std::ostringstream values;
+
+ blur << ext->get_param_float("blur");
+ type << ext->get_param_optiongroup("type");
+
+ // TransfertComponent table values are calculated based on the effect level and inverted parameters.
+ int val = 0;
+ int levels = ext->get_param_int("levels") + 1;
+ if (ext->get_param_bool("invert")) {
+ val = 1;
+ }
+ values << val;
+ for ( int step = 1 ; step <= levels ; step++ ) {
+ if (val == 1) {
+ val = 0;
+ }
+ else {
+ val = 1;
+ }
+ values << " " << val;
+ }
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Electrize\">\n"
+ "<feGaussianBlur stdDeviation=\"%s\" result=\"blur\" />\n"
+ "<feComponentTransfer in=\"blur\" result=\"component\" >\n"
+ "<feFuncR type=\"%s\" tableValues=\"%s\" />\n"
+ "<feFuncG type=\"%s\" tableValues=\"%s\" />\n"
+ "<feFuncB type=\"%s\" tableValues=\"%s\" />\n"
+ "</feComponentTransfer>\n"
+ "</filter>\n", blur.str().c_str(), type.str().c_str(), values.str().c_str(), type.str().c_str(), values.str().c_str(), type.str().c_str(), values.str().c_str());
+
+ return _filter;
+}; /* Electrize filter */
+
+/**
+ \brief Custom predefined Neon draw filter.
+
+ Posterize and draw smooth lines around color shapes
+
+ Filter's parameters:
+ * Lines type (enum, default smooth) ->
+ smooth = component2 (type="table"), composite1 (in2="blur2")
+ hard = component2 (type="discrete"), composite1 (in2="component1")
+ * Simplify (0.01->20., default 3) -> blur1 (stdDeviation)
+ * Line width (0.01->20., default 3) -> blur2 (stdDeviation)
+ * Lightness (0.->10., default 1) -> composite1 (k2)
+ * Blend (enum [normal, multiply, screen], default normal) -> blend (mode)
+ * Dark mode (boolean, default false) -> composite2 (true: in2="component2")
+*/
+class NeonDraw : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ NeonDraw ( ) : Filter() { };
+ ~NeonDraw ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Neon Draw") "</name>\n"
+ "<id>org.inkscape.effect.filter.NeonDraw</id>\n"
+ "<param name=\"type\" gui-text=\"" N_("Line type:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"table\">" N_("Smoothed") "</option>\n"
+ "<option value=\"discrete\">" N_("Contrasted") "</option>\n"
+ "</param>\n"
+ "<param name=\"simply\" gui-text=\"" N_("Simplify") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"20.00\">3</param>\n"
+ "<param name=\"width\" gui-text=\"" N_("Line width") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"20.00\">3</param>\n"
+ "<param name=\"lightness\" gui-text=\"" N_("Lightness") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.00\" max=\"10.00\">1</param>\n"
+ "<param name=\"blend\" gui-text=\"" N_("Blend mode:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"normal\">Normal</option>\n"
+ "<option value=\"multiply\">Multiply</option>\n"
+ "<option value=\"screen\">Screen</option>\n"
+ "</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Image Paint and Draw") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Posterize and draw smooth lines around color shapes") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new NeonDraw());
+ };
+};
+
+gchar const *
+NeonDraw::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream blend;
+ std::ostringstream simply;
+ std::ostringstream width;
+ std::ostringstream lightness;
+ std::ostringstream type;
+
+ type << ext->get_param_optiongroup("type");
+ blend << ext->get_param_optiongroup("blend");
+ simply << ext->get_param_float("simply");
+ width << ext->get_param_float("width");
+ lightness << ext->get_param_float("lightness");
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Neon Draw\">\n"
+ "<feBlend mode=\"%s\" result=\"blend\" />\n"
+ "<feGaussianBlur in=\"blend\" stdDeviation=\"%s\" result=\"blur1\" />\n"
+ "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 50 0\" result=\"color1\" />\n"
+ "<feComponentTransfer result=\"component1\">\n"
+ "<feFuncR type=\"discrete\" tableValues=\"0 0.3 0.3 0.3 0.3 0.6 0.6 0.6 0.6 1 1\" />\n"
+ "<feFuncG type=\"discrete\" tableValues=\"0 0.3 0.3 0.3 0.3 0.6 0.6 0.6 0.6 1 1\" />\n"
+ "<feFuncB type=\"discrete\" tableValues=\"0 0.3 0.3 0.3 0.3 0.6 0.6 0.6 0.6 1 1\" />\n"
+ "</feComponentTransfer>\n"
+ "<feGaussianBlur in=\"component1\" stdDeviation=\"%s\" result=\"blur2\" />\n"
+ "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 50 0\" result=\"color2\" />\n"
+ "<feComponentTransfer in=\"color2\" result=\"component2\">\n"
+ "<feFuncR type=\"%s\" tableValues=\"0 1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 1\" />\n"
+ "<feFuncG type=\"%s\" tableValues=\"0 1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 1\" />\n"
+ "<feFuncB type=\"%s\" tableValues=\"0 1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 1\" />\n"
+ "</feComponentTransfer>\n"
+ "<feComposite in=\"component2\" in2=\"blur2\" k3=\"%s\" operator=\"arithmetic\" k2=\"1\" result=\"composite1\" />\n"
+ "<feComposite in=\"composite1\" in2=\"SourceGraphic\" operator=\"in\" result=\"composite2\" />\n"
+ "</filter>\n", blend.str().c_str(), simply.str().c_str(), width.str().c_str(), type.str().c_str(), type.str().c_str(), type.str().c_str(), lightness.str().c_str());
+
+ return _filter;
+}; /* NeonDraw filter */
+
+/**
+ \brief Custom predefined Point engraving filter.
+
+ Convert image to a transparent point engraving
+
+ Filter's parameters:
+
+ * Turbulence type (enum, default fractalNoise else turbulence) -> turbulence (type)
+ * Horizontal frequency (0.001->1., default 1) -> turbulence (baseFrequency [/100])
+ * Vertical frequency (0.001->1., default 1) -> turbulence (baseFrequency [/100])
+ * Complexity (1->5, default 3) -> turbulence (numOctaves)
+ * Variation (0->1000, default 0) -> turbulence (seed)
+ * Noise reduction (-1000->-1500, default -1045) -> convolve (kernelMatrix, central value)
+ * Noise blend (enum, all blend options, default normal) -> blend (mode)
+ * Lightness (0.->10., default 2.5) -> composite1 (k1)
+ * Grain lightness (0.->10., default 1.3) -> composite1 (k2)
+ * Erase (0.00->1., default 0) -> composite1 (k4)
+ * Blur (0.01->2., default 0.5) -> blur (stdDeviation)
+
+ * Drawing color (guint32, default rgb(255,255,255)) -> flood1 (flood-color, flood-opacity)
+
+ * Background color (guint32, default rgb(99,89,46)) -> flood2 (flood-color, flood-opacity)
+*/
+
+class PointEngraving : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ PointEngraving ( ) : Filter() { };
+ ~PointEngraving ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Point Engraving") "</name>\n"
+ "<id>org.inkscape.effect.filter.PointEngraving</id>\n"
+ "<param name=\"tab\" type=\"notebook\">\n"
+ "<page name=\"optionstab\" gui-text=\"" N_("Options") "\">\n"
+ "<param name=\"type\" gui-text=\"" N_("Turbulence type:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"fractalNoise\">" N_("Fractal noise") "</option>\n"
+ "<option value=\"turbulence\">" N_("Turbulence") "</option>\n"
+ "</param>\n"
+ "<param name=\"hfreq\" gui-text=\"" N_("Horizontal frequency") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.1\" max=\"100.00\">100</param>\n"
+ "<param name=\"vfreq\" gui-text=\"" N_("Vertical frequency") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.1\" max=\"100.00\">100</param>\n"
+ "<param name=\"complexity\" gui-text=\"" N_("Complexity") "\" type=\"int\" appearance=\"full\" min=\"1\" max=\"5\">1</param>\n"
+ "<param name=\"variation\" gui-text=\"" N_("Variation") "\" type=\"int\" appearance=\"full\" min=\"1\" max=\"100\">0</param>\n"
+ "<param name=\"reduction\" gui-text=\"" N_("Noise reduction") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"500\">45</param>\n"
+ "<param name=\"blend\" gui-text=\"" N_("Noise blend:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"multiply\">" N_("Multiply") "</option>\n"
+ "<option value=\"normal\">" N_("Normal") "</option>\n"
+ "<option value=\"screen\">" N_("Screen") "</option>\n"
+ "<option value=\"lighten\">" N_("Lighten") "</option>\n"
+ "<option value=\"darken\">" N_("Darken") "</option>\n"
+ "</param>\n"
+ "<param name=\"lightness\" gui-text=\"" N_("Lightness") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"10\">2.5</param>\n"
+ "<param name=\"grain\" gui-text=\"" N_("Grain lightness") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"10\">1.3</param>\n"
+ "<param name=\"erase\" gui-text=\"" N_("Erase") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"1\">0</param>\n"
+ "<param name=\"blur\" gui-text=\"" N_("Blur") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"2\">0.5</param>\n"
+ "</page>\n"
+ "<page name=\"fcolortab\" gui-text=\"" N_("Fill color") "\">\n"
+ "<param name=\"fcolor\" gui-text=\"" N_("Color") "\" type=\"color\">-1</param>\n"
+ "<param name=\"iof\" gui-text=\"" N_("Image on fill") "\" type=\"bool\" >false</param>\n"
+ "</page>\n"
+ "<page name=\"pcolortab\" gui-text=\"" N_("Points color") "\">\n"
+ "<param name=\"pcolor\" gui-text=\"" N_("Color") "\" type=\"color\">1666789119</param>\n"
+ "<param name=\"iop\" gui-text=\"" N_("Image on points") "\" type=\"bool\" >false</param>\n"
+ "</page>\n"
+ "</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Image Paint and Draw") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Convert image to a transparent point engraving") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new PointEngraving());
+ };
+
+};
+
+gchar const *
+PointEngraving::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream type;
+ std::ostringstream hfreq;
+ std::ostringstream vfreq;
+ std::ostringstream complexity;
+ std::ostringstream variation;
+ std::ostringstream reduction;
+ std::ostringstream blend;
+ std::ostringstream lightness;
+ std::ostringstream grain;
+ std::ostringstream erase;
+ std::ostringstream blur;
+ std::ostringstream r;
+ std::ostringstream g;
+ std::ostringstream b;
+ std::ostringstream a;
+ std::ostringstream br;
+ std::ostringstream bg;
+ std::ostringstream bb;
+ std::ostringstream ba;
+ std::ostringstream iof;
+ std::ostringstream iop;
+
+ type << ext->get_param_optiongroup("type");
+ hfreq << ext->get_param_float("hfreq") / 100;
+ vfreq << ext->get_param_float("vfreq") / 100;
+ complexity << ext->get_param_int("complexity");
+ variation << ext->get_param_int("variation");
+ reduction << (-1000 - ext->get_param_int("reduction"));
+ blend << ext->get_param_optiongroup("blend");
+ lightness << ext->get_param_float("lightness");
+ grain << ext->get_param_float("grain");
+ erase << ext->get_param_float("erase");
+ blur << ext->get_param_float("blur");
+
+ guint32 fcolor = ext->get_param_color("fcolor");
+ r << ((fcolor >> 24) & 0xff);
+ g << ((fcolor >> 16) & 0xff);
+ b << ((fcolor >> 8) & 0xff);
+ a << (fcolor & 0xff) / 255.0F;
+
+ guint32 pcolor = ext->get_param_color("pcolor");
+ br << ((pcolor >> 24) & 0xff);
+ bg << ((pcolor >> 16) & 0xff);
+ bb << ((pcolor >> 8) & 0xff);
+ ba << (pcolor & 0xff) / 255.0F;
+
+ if (ext->get_param_bool("iof"))
+ iof << "SourceGraphic";
+ else
+ iof << "flood2";
+
+ if (ext->get_param_bool("iop"))
+ iop << "SourceGraphic";
+ else
+ iop << "flood1";
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" inkscape:label=\"Point Engraving\" style=\"color-interpolation-filters:sRGB;\">\n"
+ "<feConvolveMatrix in=\"SourceGraphic\" kernelMatrix=\"0 250 0 250 %s 250 0 250 0\" order=\"3 3\" result=\"convolve\" />\n"
+ "<feBlend in=\"convolve\" in2=\"SourceGraphic\" mode=\"%s\" result=\"blend\" />\n"
+ "<feTurbulence type=\"%s\" baseFrequency=\"%s %s\" numOctaves=\"%s\" seed=\"%s\" result=\"turbulence\" />\n"
+ "<feColorMatrix in=\"blend\" type=\"luminanceToAlpha\" result=\"colormatrix1\" />\n"
+ "<feComposite in=\"turbulence\" in2=\"colormatrix1\" k1=\"%s\" k2=\"%s\" k4=\"%s\" operator=\"arithmetic\" result=\"composite1\" />\n"
+ "<feColorMatrix in=\"composite1\" values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 10 -9 \" result=\"colormatrix2\" />\n"
+ "<feGaussianBlur stdDeviation=\"%s\" result=\"blur\" />\n"
+ "<feFlood flood-color=\"rgb(%s,%s,%s)\" flood-opacity=\"%s\" result=\"flood1\" />\n"
+ "<feComposite in=\"%s\" in2=\"blur\" operator=\"out\" result=\"composite2\" />\n"
+ "<feFlood flood-color=\"rgb(%s,%s,%s)\" flood-opacity=\"%s\" result=\"flood2\" />\n"
+ "<feComposite in=\"%s\" in2=\"blur\" operator=\"in\" result=\"composite3\" />\n"
+ "<feComposite in=\"composite3\" in2=\"composite2\" k2=\"%s\" k3=\"%s\" operator=\"arithmetic\" result=\"composite4\" />\n"
+ "<feComposite in2=\"SourceGraphic\" operator=\"in\" result=\"composite5\" />\n"
+ "</filter>\n", reduction.str().c_str(), blend.str().c_str(),
+ type.str().c_str(), hfreq.str().c_str(), vfreq.str().c_str(), complexity.str().c_str(), variation.str().c_str(),
+ lightness.str().c_str(), grain.str().c_str(), erase.str().c_str(), blur.str().c_str(),
+ br.str().c_str(), bg.str().c_str(), bb.str().c_str(), ba.str().c_str(), iop.str().c_str(),
+ r.str().c_str(), g.str().c_str(), b.str().c_str(), a.str().c_str(), iof.str().c_str(),
+ a.str().c_str(), ba.str().c_str() );
+
+ return _filter;
+}; /* Point engraving filter */
+
+/**
+ \brief Custom predefined Poster paint filter.
+
+ Poster and painting effects.
+
+ Filter's parameters:
+ * Effect type (enum, default "Normal") ->
+ Normal = feComponentTransfer
+ Dented = Normal + intermediate values
+ * Transfer type (enum, default "discrete") -> component (type)
+ * Levels (0->15, default 5) -> component (tableValues)
+ * Blend mode (enum, default "Lighten") -> blend (mode)
+ * Primary simplify (0.01->100., default 4.) -> blur1 (stdDeviation)
+ * Secondary simplify (0.01->100., default 0.5) -> blur2 (stdDeviation)
+ * Pre-saturation (0.->1., default 1.) -> color1 (values)
+ * Post-saturation (0.->1., default 1.) -> color2 (values)
+ * Simulate antialiasing (boolean, default false) -> blur3 (true->stdDeviation=0.5, false->stdDeviation=0.01)
+*/
+class Posterize : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ Posterize ( ) : Filter() { };
+ ~Posterize ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Poster Paint") "</name>\n"
+ "<id>org.inkscape.effect.filter.Posterize</id>\n"
+ "<param name=\"type\" gui-text=\"" N_("Effect type:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"normal\">Normal</option>\n"
+ "<option value=\"dented\">Dented</option>\n"
+ "</param>\n"
+ "<param name=\"table\" gui-text=\"" N_("Transfer type:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"discrete\">" N_("Poster") "</option>\n"
+ "<option value=\"table\">" N_("Painting") "</option>\n"
+ "</param>\n"
+ "<param name=\"levels\" gui-text=\"" N_("Levels") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"15\">5</param>\n"
+ "<param name=\"blend\" gui-text=\"" N_("Blend mode:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"lighten\">Lighten</option>\n"
+ "<option value=\"normal\">Normal</option>\n"
+ "<option value=\"darken\">Darken</option>\n"
+ "<option value=\"multiply\">Multiply</option>\n"
+ "<option value=\"screen\">Screen</option>\n"
+ "</param>\n"
+ "<param name=\"blur1\" gui-text=\"" N_("Simplify (primary)") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"100.00\">4.0</param>\n"
+ "<param name=\"blur2\" gui-text=\"" N_("Simplify (secondary)") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"100.00\">0.5</param>\n"
+ "<param name=\"presaturation\" gui-text=\"" N_("Pre-saturation") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.00\" max=\"1.00\">1.00</param>\n"
+ "<param name=\"postsaturation\" gui-text=\"" N_("Post-saturation") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.00\" max=\"1.00\">1.00</param>\n"
+ "<param name=\"antialiasing\" gui-text=\"" N_("Simulate antialiasing") "\" type=\"bool\">false</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Image Paint and Draw") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Poster and painting effects") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new Posterize());
+ };
+};
+
+gchar const *
+Posterize::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream table;
+ std::ostringstream blendmode;
+ std::ostringstream blur1;
+ std::ostringstream blur2;
+ std::ostringstream presat;
+ std::ostringstream postsat;
+ std::ostringstream transf;
+ std::ostringstream antialias;
+
+ table << ext->get_param_optiongroup("table");
+ blendmode << ext->get_param_optiongroup("blend");
+ blur1 << ext->get_param_float("blur1");
+ blur2 << ext->get_param_float("blur2");
+ presat << ext->get_param_float("presaturation");
+ postsat << ext->get_param_float("postsaturation");
+
+ // TransfertComponent table values are calculated based on the poster type.
+ transf << "0";
+ int levels = ext->get_param_int("levels") + 1;
+ const gchar *effecttype = ext->get_param_optiongroup("type");
+ if (levels == 1) {
+ if ((g_ascii_strcasecmp("dented", effecttype) == 0)) {
+ transf << " 1 0 1";
+ } else {
+ transf << " 1";
+ }
+ } else {
+ for ( int step = 1 ; step <= levels ; step++ ) {
+ float val = (float) step / levels;
+ transf << " " << val;
+ if ((g_ascii_strcasecmp("dented", effecttype) == 0)) {
+ transf << " " << (val - ((float) 1 / (3 * levels))) << " " << (val + ((float) 1 / (2 * levels)));
+ }
+ }
+ }
+ transf << " 1";
+
+ if (ext->get_param_bool("antialiasing"))
+ antialias << "0.5";
+ else
+ antialias << "0.01";
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Poster Paint\">\n"
+ "<feComposite operator=\"arithmetic\" k2=\"1\" result=\"composite1\" />\n"
+ "<feGaussianBlur stdDeviation=\"%s\" result=\"blur1\" />\n"
+ "<feGaussianBlur in=\"composite1\" stdDeviation=\"%s\" result=\"blur2\" />\n"
+ "<feBlend in2=\"blur1\" mode=\"%s\" result=\"blend\"/>\n"
+ "<feColorMatrix type=\"saturate\" values=\"%s\" result=\"color1\" />\n"
+ "<feComponentTransfer result=\"component\">\n"
+ "<feFuncR type=\"%s\" tableValues=\"%s\" />\n"
+ "<feFuncG type=\"%s\" tableValues=\"%s\" />\n"
+ "<feFuncB type=\"%s\" tableValues=\"%s\" />\n"
+ "</feComponentTransfer>\n"
+ "<feColorMatrix type=\"saturate\" values=\"%s\" result=\"color2\" />\n"
+ "<feGaussianBlur stdDeviation=\"%s\" result=\"blur3\" />\n"
+ "<feComposite in2=\"SourceGraphic\" operator=\"in\" result=\"composite3\" />\n"
+ "</filter>\n", blur1.str().c_str(), blur2.str().c_str(), blendmode.str().c_str(), presat.str().c_str(), table.str().c_str(), transf.str().c_str(), table.str().c_str(), transf.str().c_str(), table.str().c_str(), transf.str().c_str(), postsat.str().c_str(), antialias.str().c_str());
+
+ return _filter;
+}; /* Posterize filter */
+
+/**
+ \brief Custom predefined Posterize basic filter.
+
+ Simple posterizing effect
+
+ Filter's parameters:
+ * Levels (0->20, default 5) -> component1 (tableValues)
+ * Blur (0.01->20., default 4.) -> blur1 (stdDeviation)
+*/
+class PosterizeBasic : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ PosterizeBasic ( ) : Filter() { };
+ ~PosterizeBasic ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Posterize Basic") "</name>\n"
+ "<id>org.inkscape.effect.filter.PosterizeBasic</id>\n"
+ "<param name=\"levels\" gui-text=\"" N_("Levels") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"20\">5</param>\n"
+ "<param name=\"blur\" gui-text=\"" N_("Simplify") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"20.00\">4.0</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Image Paint and Draw") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Simple posterizing effect") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new PosterizeBasic());
+ };
+};
+
+gchar const *
+PosterizeBasic::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream blur;
+ std::ostringstream transf;
+
+ blur << ext->get_param_float("blur");
+
+ transf << "0";
+ int levels = ext->get_param_int("levels") + 1;
+ for ( int step = 1 ; step <= levels ; step++ ) {
+ const float val = (float) step / levels;
+ transf << " " << val;
+ }
+ transf << " 1";
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Posterize Basic\">\n"
+ "<feGaussianBlur stdDeviation=\"%s\" result=\"blur1\" />\n"
+ "<feComponentTransfer in=\"blur1\" result=\"component1\">\n"
+ "<feFuncR type=\"discrete\" tableValues=\"%s\" />\n"
+ "<feFuncG type=\"discrete\" tableValues=\"%s\" />\n"
+ "<feFuncB type=\"discrete\" tableValues=\"%s\" />\n"
+ "</feComponentTransfer>\n"
+ "<feComposite in=\"component1\" in2=\"SourceGraphic\" operator=\"in\" />\n"
+ "</filter>\n", blur.str().c_str(), transf.str().c_str(), transf.str().c_str(), transf.str().c_str());
+
+ return _filter;
+}; /* PosterizeBasic filter */
+
+}; /* namespace Filter */
+}; /* namespace Internal */
+}; /* namespace Extension */
+}; /* namespace Inkscape */
+
+/* Change the 'PAINT' below to be your file name */
+#endif /* SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_PAINT_H__ */
diff --git a/src/extension/internal/filter/protrusions.h b/src/extension/internal/filter/protrusions.h
new file mode 100644
index 0000000..590608d
--- /dev/null
+++ b/src/extension/internal/filter/protrusions.h
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#ifndef SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_PROTRUSIONS_H__
+#define SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_PROTRUSIONS_H__
+/* Change the 'PROTRUSIONS' above to be your file name */
+
+/*
+ * Copyright (C) 2008 Authors:
+ * Ted Gould <ted@gould.cx>
+ * Copyright (C) 2011 Authors:
+ * Ivan Louette (filters)
+ * Nicolas Dufour (UI) <nicoduf@yahoo.fr>
+ *
+ * Protrusion filters
+ * Snow
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+/* ^^^ Change the copyright to be you and your e-mail address ^^^ */
+
+#include "filter.h"
+
+#include "extension/internal/clear-n_.h"
+#include "extension/system.h"
+#include "extension/extension.h"
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+namespace Filter {
+
+
+/**
+ \brief Custom predefined Snow filter.
+
+ Snow has fallen on object.
+*/
+class Snow : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ Snow ( ) : Filter() { };
+ ~Snow ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+public:
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Snow Crest") "</name>\n"
+ "<id>org.inkscape.effect.filter.snow</id>\n"
+ "<param name=\"drift\" gui-text=\"" N_("Drift Size") "\" type=\"float\" appearance=\"full\" min=\"0.0\" max=\"20.0\">3.5</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"Protrusions\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Snow has fallen on object") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new Snow());
+ };
+
+};
+
+gchar const *
+Snow::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream drift;
+ drift << ext->get_param_float("drift");
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Snow\">\n"
+ "<feConvolveMatrix order=\"3 3\" kernelMatrix=\"1 1 1 0 0 0 -1 -1 -1\" preserveAlpha=\"false\" divisor=\"3\"/>\n"
+ "<feMorphology operator=\"dilate\" radius=\"1 %s\"/>\n"
+ "<feGaussianBlur stdDeviation=\"1.6270889487870621\" result=\"result0\"/>\n"
+ "<feColorMatrix values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 0\" result=\"result1\"/>\n"
+ "<feOffset dx=\"0\" dy=\"1\" result=\"result5\"/>\n"
+ "<feDiffuseLighting in=\"result0\" diffuseConstant=\"2.2613065326633168\" surfaceScale=\"1\">\n"
+ "<feDistantLight azimuth=\"225\" elevation=\"32\"/>\n"
+ "</feDiffuseLighting>\n"
+ "<feComposite in2=\"result1\" operator=\"in\" result=\"result2\"/>\n"
+ "<feColorMatrix values=\"0.4 0 0 0 0.6 0 0.4 0 0 0.6 0 0 0 0 1 0 0 0 1 0\" result=\"result4\"/>\n"
+ "<feComposite in2=\"result5\" in=\"result4\"/>\n"
+ "<feComposite in2=\"SourceGraphic\"/>\n"
+ "</filter>\n", drift.str().c_str());
+
+ return _filter;
+}; /* Snow filter */
+
+
+}; /* namespace Filter */
+}; /* namespace Internal */
+}; /* namespace Extension */
+}; /* namespace Inkscape */
+
+/* Change the 'PROTRUSIONS' below to be your file name */
+#endif /* SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_PROTRUSIONS_H__ */
diff --git a/src/extension/internal/filter/shadows.h b/src/extension/internal/filter/shadows.h
new file mode 100644
index 0000000..d8aa69e
--- /dev/null
+++ b/src/extension/internal/filter/shadows.h
@@ -0,0 +1,190 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#ifndef SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_SHADOWS_H__
+#define SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_SHADOWS_H__
+/* Change the 'SHADOWS' above to be your file name */
+
+/*
+ * Copyright (C) 2013 Authors:
+ * Ivan Louette (filters)
+ * Nicolas Dufour (UI) <nicoduf@yahoo.fr>
+ *
+ * Shadow filters
+ * Drop shadow
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+/* ^^^ Change the copyright to be you and your e-mail address ^^^ */
+
+#include "filter.h"
+
+#include "extension/internal/clear-n_.h"
+#include "extension/system.h"
+#include "extension/extension.h"
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+namespace Filter {
+
+/**
+ \brief Custom predefined Drop shadow filter.
+
+ Colorizable Drop shadow.
+
+ Filter's parameters:
+ * Blur radius (0.->200., default 3) -> blur (stdDeviation)
+ * Horizontal offset (-50.->50., default 6.0) -> offset (dx)
+ * Vertical offset (-50.->50., default 6.0) -> offset (dy)
+ * Blur type (enum, default outer) ->
+ outer = composite1 (operator="in"), composite2 (operator="over", in1="SourceGraphic", in2="offset")
+ inner = composite1 (operator="out"), composite2 (operator="atop", in1="offset", in2="SourceGraphic")
+ innercut = composite1 (operator="in"), composite2 (operator="out", in1="offset", in2="SourceGraphic")
+ outercut = composite1 (operator="out"), composite2 (operator="in", in1="SourceGraphic", in2="offset")
+ shadow = composite1 (operator="out"), composite2 (operator="atop", in1="offset", in2="offset")
+ * Color (guint, default 0,0,0,127) -> flood (flood-opacity, flood-color)
+ * Use object's color (boolean, default false) -> composite1 (in1, in2)
+*/
+class ColorizableDropShadow : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ ColorizableDropShadow ( ) : Filter() { };
+ ~ColorizableDropShadow ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Drop Shadow") "</name>\n"
+ "<id>org.inkscape.effect.filter.ColorDropShadow</id>\n"
+ "<param name=\"tab\" type=\"notebook\">\n"
+ "<page name=\"optionstab\" gui-text=\"" N_("Options") "\">\n"
+ "<param name=\"blur\" gui-text=\"" N_("Blur radius (px)") "\" type=\"float\" appearance=\"full\" min=\"0.0\" max=\"200.0\">3.0</param>\n"
+ "<param name=\"xoffset\" gui-text=\"" N_("Horizontal offset (px)") "\" type=\"float\" appearance=\"full\" min=\"-50.0\" max=\"50.0\">6.0</param>\n"
+ "<param name=\"yoffset\" gui-text=\"" N_("Vertical offset (px)") "\" type=\"float\" appearance=\"full\" min=\"-50.0\" max=\"50.0\">6.0</param>\n"
+ "<param name=\"type\" gui-text=\"" N_("Shadow type:") "\" type=\"optiongroup\" appearance=\"combo\" >\n"
+ "<option value=\"outer\">" N_("Outer") "</option>\n"
+ "<option value=\"inner\">" N_("Inner") "</option>\n"
+ "<option value=\"outercut\">" N_("Outer cutout") "</option>\n"
+ "<option value=\"innercut\">" N_("Inner cutout") "</option>\n"
+ "<option value=\"shadow\">" N_("Shadow only") "</option>\n"
+ "</param>\n"
+ "</page>\n"
+ "<page name=\"coltab\" gui-text=\"" N_("Blur color") "\">\n"
+ "<param name=\"color\" gui-text=\"" N_("Color") "\" type=\"color\">127</param>\n"
+ "<param name=\"objcolor\" gui-text=\"" N_("Use object's color") "\" type=\"bool\" >false</param>\n"
+ "</page>\n"
+ "</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Shadows and Glows") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Colorizable Drop shadow") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new ColorizableDropShadow());
+ };
+
+};
+
+gchar const *
+ColorizableDropShadow::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream blur;
+ std::ostringstream a;
+ std::ostringstream r;
+ std::ostringstream g;
+ std::ostringstream b;
+ std::ostringstream x;
+ std::ostringstream y;
+ std::ostringstream comp1in1;
+ std::ostringstream comp1in2;
+ std::ostringstream comp1op;
+ std::ostringstream comp2in1;
+ std::ostringstream comp2in2;
+ std::ostringstream comp2op;
+
+ const gchar *type = ext->get_param_optiongroup("type");
+ guint32 color = ext->get_param_color("color");
+
+ blur << ext->get_param_float("blur");
+ x << ext->get_param_float("xoffset");
+ y << ext->get_param_float("yoffset");
+ a << (color & 0xff) / 255.0F;
+ r << ((color >> 24) & 0xff);
+ g << ((color >> 16) & 0xff);
+ b << ((color >> 8) & 0xff);
+
+ // Select object or user-defined color
+ if ((g_ascii_strcasecmp("innercut", type) == 0)) {
+ if (ext->get_param_bool("objcolor")) {
+ comp2in1 << "SourceGraphic";
+ comp2in2 << "offset";
+ } else {
+ comp2in1 << "offset";
+ comp2in2 << "SourceGraphic";
+ }
+ } else {
+ if (ext->get_param_bool("objcolor")) {
+ comp1in1 << "SourceGraphic";
+ comp1in2 << "flood";
+ } else {
+ comp1in1 << "flood";
+ comp1in2 << "SourceGraphic";
+ }
+ }
+
+ // Shadow mode
+ if ((g_ascii_strcasecmp("outer", type) == 0)) {
+ comp1op << "in";
+ comp2op << "over";
+ comp2in1 << "SourceGraphic";
+ comp2in2 << "offset";
+ } else if ((g_ascii_strcasecmp("inner", type) == 0)) {
+ comp1op << "out";
+ comp2op << "atop";
+ comp2in1 << "offset";
+ comp2in2 << "SourceGraphic";
+ } else if ((g_ascii_strcasecmp("outercut", type) == 0)) {
+ comp1op << "in";
+ comp2op << "out";
+ comp2in1 << "offset";
+ comp2in2 << "SourceGraphic";
+ } else if ((g_ascii_strcasecmp("innercut", type) == 0)){
+ comp1op << "out";
+ comp1in1 << "flood";
+ comp1in2 << "SourceGraphic";
+ comp2op << "in";
+ } else { //shadow
+ comp1op << "in";
+ comp2op << "atop";
+ comp2in1 << "offset";
+ comp2in2 << "offset";
+ }
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Drop Shadow\">\n"
+ "<feFlood flood-opacity=\"%s\" flood-color=\"rgb(%s,%s,%s)\" result=\"flood\" />\n"
+ "<feComposite in=\"%s\" in2=\"%s\" operator=\"%s\" result=\"composite1\" />\n"
+ "<feGaussianBlur in=\"composite1\" stdDeviation=\"%s\" result=\"blur\" />\n"
+ "<feOffset dx=\"%s\" dy=\"%s\" result=\"offset\" />\n"
+ "<feComposite in=\"%s\" in2=\"%s\" operator=\"%s\" result=\"composite2\" />\n"
+ "</filter>\n", a.str().c_str(), r.str().c_str(), g.str().c_str(), b.str().c_str(),
+ comp1in1.str().c_str(), comp1in2.str().c_str(), comp1op.str().c_str(),
+ blur.str().c_str(), x.str().c_str(), y.str().c_str(),
+ comp2in1.str().c_str(), comp2in2.str().c_str(), comp2op.str().c_str());
+
+ return _filter;
+}; /* Drop shadow filter */
+
+}; /* namespace Filter */
+}; /* namespace Internal */
+}; /* namespace Extension */
+}; /* namespace Inkscape */
+
+/* Change the 'SHADOWS' below to be your file name */
+#endif /* SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_SHADOWS_H__ */
diff --git a/src/extension/internal/filter/textures.h b/src/extension/internal/filter/textures.h
new file mode 100644
index 0000000..45a78a3
--- /dev/null
+++ b/src/extension/internal/filter/textures.h
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#ifndef SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_TEXTURES_H__
+#define SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_TEXTURES_H__
+/* Change the 'TEXTURES' above to be your file name */
+
+/*
+ * Copyright (C) 2011 Authors:
+ * Ivan Louette (filters)
+ * Nicolas Dufour (UI) <nicoduf@yahoo.fr>
+ *
+ * Protrusion filters
+ * Ink blot
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+/* ^^^ Change the copyright to be you and your e-mail address ^^^ */
+
+#include "filter.h"
+
+#include "extension/internal/clear-n_.h"
+#include "extension/system.h"
+#include "extension/extension.h"
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+namespace Filter {
+
+
+/**
+ \brief Custom predefined Ink Blot filter.
+
+ Inkblot on tissue or rough paper.
+
+ Filter's parameters:
+
+ * Turbulence type (enum, default fractalNoise else turbulence) -> turbulence (type)
+ * Frequency (0.001->1., default 0.04) -> turbulence (baseFrequency [/100])
+ * Complexity (1->5, default 3) -> turbulence (numOctaves)
+ * Variation (0->100, default 0) -> turbulence (seed)
+ * Horizontal inlay (0.01->30., default 10) -> blur1 (stdDeviation x)
+ * Vertical inlay (0.01->30., default 10) -> blur1 (stdDeviation y)
+ * Displacement (0.->100., default 50) -> map (scale)
+ * Blend (0.01->30., default 5) -> blur2 (stdDeviation)
+ * Stroke (enum, default over) -> composite (operator)
+ * Arithmetic stroke options
+ * k1 (-10.->10., default 1.5)
+ * k2 (-10.->10., default -0.25)
+ * k3 (-10.->10., default 0.5)
+*/
+class InkBlot : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ InkBlot ( ) : Filter() { };
+ ~InkBlot ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+public:
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Ink Blot") "</name>\n"
+ "<id>org.inkscape.effect.filter.InkBlot</id>\n"
+ "<param name=\"type\" gui-text=\"" N_("Turbulence type:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"fractalNoise\">Fractal noise</option>\n"
+ "<option value=\"turbulence\">Turbulence</option>\n"
+ "</param>\n"
+ "<param name=\"freq\" gui-text=\"" N_("Frequency:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"100.00\">4</param>\n"
+ "<param name=\"complexity\" gui-text=\"" N_("Complexity:") "\" type=\"int\" appearance=\"full\" min=\"1\" max=\"5\">3</param>\n"
+ "<param name=\"variation\" gui-text=\"" N_("Variation:") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"100\">0</param>\n"
+ "<param name=\"hblur\" gui-text=\"" N_("Horizontal inlay:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"30.00\">10</param>\n"
+ "<param name=\"vblur\" gui-text=\"" N_("Vertical inlay:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"30.00\">10</param>\n"
+ "<param name=\"displacement\" gui-text=\"" N_("Displacement:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.\" max=\"100.00\">50</param>\n"
+ "<param name=\"blend\" gui-text=\"" N_("Blend:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"30.00\">5</param>\n"
+ "<param name=\"stroke\" gui-text=\"" N_("Stroke:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"over\">" N_("Wide") "</option>\n"
+ "<option value=\"atop\">" N_("Normal") "</option>\n"
+ "<option value=\"in\">" N_("Narrow") "</option>\n"
+ "<option value=\"xor\">" N_("Overlapping") "</option>\n"
+ "<option value=\"out\">" N_("External") "</option>\n"
+ "<option value=\"arithmetic\">" N_("Custom") "</option>\n"
+ "</param>\n"
+ "<label appearance=\"header\">" N_("Custom stroke options") "</label>\n"
+ "<param name=\"k1\" gui-text=\"" N_("k1:") "\" type=\"float\" indent=\"1\" appearance=\"full\" precision=\"2\" min=\"-10.\" max=\"10.\">1.5</param>\n"
+ "<param name=\"k2\" gui-text=\"" N_("k2:") "\" type=\"float\" indent=\"1\" appearance=\"full\" precision=\"2\" min=\"-10.\" max=\"10.\">-0.25</param>\n"
+ "<param name=\"k3\" gui-text=\"" N_("k3:") "\" type=\"float\" indent=\"1\" appearance=\"full\" precision=\"2\" min=\"-10.\" max=\"10.\">0.5</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"Textures\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Inkblot on tissue or rough paper") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new InkBlot());
+ };
+
+};
+
+gchar const *
+InkBlot::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream type;
+ std::ostringstream freq;
+ std::ostringstream complexity;
+ std::ostringstream variation;
+ std::ostringstream hblur;
+ std::ostringstream vblur;
+ std::ostringstream displacement;
+ std::ostringstream blend;
+ std::ostringstream stroke;
+ std::ostringstream custom;
+
+ type << ext->get_param_optiongroup("type");
+ freq << ext->get_param_float("freq") / 100;
+ complexity << ext->get_param_int("complexity");
+ variation << ext->get_param_int("variation");
+ hblur << ext->get_param_float("hblur");
+ vblur << ext->get_param_float("vblur");
+ displacement << ext->get_param_float("displacement");
+ blend << ext->get_param_float("blend");
+
+ const gchar *ope = ext->get_param_optiongroup("stroke");
+ if (g_ascii_strcasecmp("arithmetic", ope) == 0) {
+ custom << "k1=\"" << ext->get_param_float("k1") << "\" k2=\"" << ext->get_param_float("k2") << "\" k3=\"" << ext->get_param_float("k3") << "\"";
+ } else {
+ custom << "";
+ }
+
+ stroke << ext->get_param_optiongroup("stroke");
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" x=\"-0.15\" width=\"1.3\" y=\"-0.15\" height=\"1.3\" inkscape:label=\"Ink Blot\" >\n"
+ "<feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"%s %s\" result=\"blur1\" />\n"
+ "<feTurbulence type=\"%s\" baseFrequency=\"%s\" numOctaves=\"%s\" seed=\"%s\" result=\"turbulence\" />\n"
+ "<feDisplacementMap in=\"blur1\" in2=\"turbulence\" xChannelSelector=\"R\" yChannelSelector=\"G\" scale=\"%s\" result=\"map\" />\n"
+ "<feGaussianBlur in=\"map\" stdDeviation=\"%s\" result=\"blur2\" />\n"
+ "<feComposite in=\"blur2\" in2=\"map\" %s operator=\"%s\" result=\"composite\" />\n"
+ "</filter>\n", hblur.str().c_str(), vblur.str().c_str(), type.str().c_str(),
+ freq.str().c_str(), complexity.str().c_str(), variation.str().c_str(),
+ displacement.str().c_str(), blend.str().c_str(),
+ custom.str().c_str(), stroke.str().c_str() );
+
+ return _filter;
+
+}; /* Ink Blot filter */
+
+
+}; /* namespace Filter */
+}; /* namespace Internal */
+}; /* namespace Extension */
+}; /* namespace Inkscape */
+
+/* Change the 'TEXTURES' below to be your file name */
+#endif /* SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_TEXTURES_H__ */
diff --git a/src/extension/internal/filter/transparency.h b/src/extension/internal/filter/transparency.h
new file mode 100644
index 0000000..87a4c88
--- /dev/null
+++ b/src/extension/internal/filter/transparency.h
@@ -0,0 +1,400 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#ifndef SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_TRANSPARENCY_H__
+#define SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_TRANSPARENCY_H__
+/* Change the 'TRANSPARENCY' above to be your file name */
+
+/*
+ * Copyright (C) 2011 Authors:
+ * Ivan Louette (filters)
+ * Nicolas Dufour (UI) <nicoduf@yahoo.fr>
+ *
+ * Fill and transparency filters
+ * Blend
+ * Channel transparency
+ * Light eraser
+ * Opacity
+ * Silhouette
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+/* ^^^ Change the copyright to be you and your e-mail address ^^^ */
+
+#include "filter.h"
+
+#include "extension/internal/clear-n_.h"
+#include "extension/system.h"
+#include "extension/extension.h"
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+namespace Filter {
+
+/**
+ \brief Custom predefined Blend filter.
+
+ Blend objects with background images or with themselves
+
+ Filter's parameters:
+ * Source (enum [SourceGraphic,BackgroundImage], default BackgroundImage) -> blend (in2)
+ * Mode (enum, all blend modes, default Multiply) -> blend (mode)
+*/
+
+class Blend : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ Blend ( ) : Filter() { };
+ ~Blend ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Blend") "</name>\n"
+ "<id>org.inkscape.effect.filter.Blend</id>\n"
+ "<param name=\"source\" gui-text=\"" N_("Source:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"BackgroundImage\">" N_("Background") "</option>\n"
+ "<option value=\"SourceGraphic\">" N_("Image") "</option>\n"
+ "</param>\n"
+ "<param name=\"mode\" gui-text=\"" N_("Mode:") "\" type=\"optiongroup\" appearance=\"combo\">\n"
+ "<option value=\"multiply\">" N_("Multiply") "</option>\n"
+ "<option value=\"normal\">" N_("Normal") "</option>\n"
+ "<option value=\"screen\">" N_("Screen") "</option>\n"
+ "<option value=\"darken\">" N_("Darken") "</option>\n"
+ "<option value=\"lighten\">" N_("Lighten") "</option>\n"
+ "</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Fill and Transparency") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Blend objects with background images or with themselves") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new Blend());
+ };
+
+};
+
+gchar const *
+Blend::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream source;
+ std::ostringstream mode;
+
+ source << ext->get_param_optiongroup("source");
+ mode << ext->get_param_optiongroup("mode");
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Blend\">\n"
+ "<feBlend in2=\"%s\" mode=\"%s\" result=\"blend\" />\n"
+ "</filter>\n", source.str().c_str(), mode.str().c_str() );
+
+ return _filter;
+}; /* Blend filter */
+
+/**
+ \brief Custom predefined Channel transparency filter.
+
+ Channel transparency filter.
+
+ Filter's parameters:
+ * Saturation (0.->1., default 1.) -> colormatrix1 (values)
+ * Red (-10.->10., default -1.) -> colormatrix2 (values)
+ * Green (-10.->10., default 0.5) -> colormatrix2 (values)
+ * Blue (-10.->10., default 0.5) -> colormatrix2 (values)
+ * Alpha (-10.->10., default 1.) -> colormatrix2 (values)
+ * Flood colors (guint, default 16777215) -> flood (flood-opacity, flood-color)
+ * Inverted (boolean, default false) -> composite1 (operator, true='in', false='out')
+
+ Matrix:
+ 1 0 0 0 0
+ 0 1 0 0 0
+ 0 0 1 0 0
+ R G B A 0
+*/
+class ChannelTransparency : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ ChannelTransparency ( ) : Filter() { };
+ ~ChannelTransparency ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Channel Transparency") "</name>\n"
+ "<id>org.inkscape.effect.filter.ChannelTransparency</id>\n"
+ "<param name=\"red\" gui-text=\"" N_("Red") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-10.\" max=\"10.\">-1</param>\n"
+ "<param name=\"green\" gui-text=\"" N_("Green") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-10.\" max=\"10.\">0.5</param>\n"
+ "<param name=\"blue\" gui-text=\"" N_("Blue") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-10.\" max=\"10.\">0.5</param>\n"
+ "<param name=\"alpha\" gui-text=\"" N_("Alpha") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"-10.\" max=\"10.\">1</param>\n"
+ "<param name=\"invert\" gui-text=\"" N_("Inverted") "\" type=\"bool\">false</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Fill and Transparency") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Replace RGB with transparency") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new ChannelTransparency());
+ };
+};
+
+gchar const *
+ChannelTransparency::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream red;
+ std::ostringstream green;
+ std::ostringstream blue;
+ std::ostringstream alpha;
+ std::ostringstream invert;
+
+ red << ext->get_param_float("red");
+ green << ext->get_param_float("green");
+ blue << ext->get_param_float("blue");
+ alpha << ext->get_param_float("alpha");
+
+ if (!ext->get_param_bool("invert")) {
+ invert << "in";
+ } else {
+ invert << "xor";
+ }
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" inkscape:label=\"Channel Transparency\" style=\"color-interpolation-filters:sRGB;\" >\n"
+ "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 %s %s %s %s 0 \" in=\"SourceGraphic\" result=\"colormatrix\" />\n"
+ "<feComposite in=\"colormatrix\" in2=\"SourceGraphic\" operator=\"%s\" result=\"composite1\" />\n"
+ "</filter>\n", red.str().c_str(), green.str().c_str(), blue.str().c_str(), alpha.str().c_str(),
+ invert.str().c_str());
+
+ return _filter;
+}; /* Channel transparency filter */
+
+/**
+ \brief Custom predefined LightEraser filter.
+
+ Make the lightest parts of the object progressively transparent.
+
+ Filter's parameters:
+ * Expansion (0.->1000., default 50) -> colormatrix (4th value, multiplicator)
+ * Erosion (1.->1000., default 100) -> colormatrix (first 3 values, multiplicator)
+ * Global opacity (0.->1., default 1.) -> composite (k2)
+ * Inverted (boolean, default false) -> colormatrix (values, true: first 3 values positive, 4th negative)
+
+*/
+class LightEraser : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ LightEraser ( ) : Filter() { };
+ ~LightEraser ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Light Eraser") "</name>\n"
+ "<id>org.inkscape.effect.filter.LightEraser</id>\n"
+ "<param name=\"expand\" gui-text=\"" N_("Expansion") "\" type=\"float\" appearance=\"full\" min=\"0\" max=\"1000\">50</param>\n"
+ "<param name=\"erode\" gui-text=\"" N_("Erosion") "\" type=\"float\" appearance=\"full\" min=\"1\" max=\"1000\">100</param>\n"
+ "<param name=\"opacity\" gui-text=\"" N_("Global opacity") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.\" max=\"1.\">1</param>\n"
+ "<param name=\"invert\" gui-text=\"" N_("Inverted") "\" type=\"bool\">false</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Fill and Transparency") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Make the lightest parts of the object progressively transparent") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new LightEraser());
+ };
+};
+
+gchar const *
+LightEraser::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream expand;
+ std::ostringstream erode;
+ std::ostringstream opacity;
+
+ opacity << ext->get_param_float("opacity");
+
+ if (ext->get_param_bool("invert")) {
+ expand << (ext->get_param_float("erode") * 0.2125) << " "
+ << (ext->get_param_float("erode") * 0.7154) << " "
+ << (ext->get_param_float("erode") * 0.0721);
+ erode << (-ext->get_param_float("expand"));
+ } else {
+ expand << (-ext->get_param_float("erode") * 0.2125) << " "
+ << (-ext->get_param_float("erode") * 0.7154) << " "
+ << (-ext->get_param_float("erode") * 0.0721);
+ erode << ext->get_param_float("expand");
+ }
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" inkscape:label=\"Light Eraser\" style=\"color-interpolation-filters:sRGB;\" >\n"
+ "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 %s %s 0 \" result=\"colormatrix\" />\n"
+ "<feComposite in2=\"colormatrix\" operator=\"arithmetic\" k2=\"%s\" result=\"composite\" />\n"
+ "</filter>\n", expand.str().c_str(), erode.str().c_str(), opacity.str().c_str());
+
+ return _filter;
+}; /* Light Eraser filter */
+
+
+/**
+ \brief Custom predefined Opacity filter.
+
+ Set opacity and strength of opacity boundaries.
+
+ Filter's parameters:
+ * Expansion (0.->1000., default 5) -> colormatrix (last-1th value)
+ * Erosion (0.->1000., default 1) -> colormatrix (last value)
+ * Global opacity (0.->1., default 1.) -> composite (k2)
+
+*/
+class Opacity : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ Opacity ( ) : Filter() { };
+ ~Opacity ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Opacity") "</name>\n"
+ "<id>org.inkscape.effect.filter.Opacity</id>\n"
+ "<param name=\"expand\" gui-text=\"" N_("Expansion") "\" type=\"float\" appearance=\"full\" min=\"1\" max=\"1000\">5</param>\n"
+ "<param name=\"erode\" gui-text=\"" N_("Erosion") "\" type=\"float\" appearance=\"full\" min=\"0\" max=\"1000\">1</param>\n"
+ "<param name=\"opacity\" gui-text=\"" N_("Global opacity") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.\" max=\"1.\">1</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Fill and Transparency") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Set opacity and strength of opacity boundaries") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new Opacity());
+ };
+};
+
+gchar const *
+Opacity::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream matrix;
+ std::ostringstream opacity;
+
+ opacity << ext->get_param_float("opacity");
+
+ matrix << (ext->get_param_float("expand")) << " "
+ << (-ext->get_param_float("erode"));
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" inkscape:label=\"Opacity\" style=\"color-interpolation-filters:sRGB;\" >\n"
+ "<feColorMatrix values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 %s \" result=\"colormatrix\" />\n"
+ "<feComposite in2=\"colormatrix\" operator=\"arithmetic\" k2=\"%s\" result=\"composite\" />\n"
+ "</filter>\n", matrix.str().c_str(), opacity.str().c_str());
+
+ return _filter;
+}; /* Opacity filter */
+
+/**
+ \brief Custom predefined Silhouette filter.
+
+ Repaint anything visible monochrome
+
+ Filter's parameters:
+ * Blur (0.01->50., default 0.01) -> blur (stdDeviation)
+ * Cutout (boolean, default False) -> composite (false=in, true=out)
+ * Color (guint, default 0,0,0,255) -> flood (flood-color, flood-opacity)
+*/
+
+class Silhouette : public Inkscape::Extension::Internal::Filter::Filter {
+protected:
+ gchar const * get_filter_text (Inkscape::Extension::Extension * ext) override;
+
+public:
+ Silhouette ( ) : Filter() { };
+ ~Silhouette ( ) override { if (_filter != nullptr) g_free((void *)_filter); return; }
+
+ static void init () {
+ Inkscape::Extension::build_from_mem(
+ "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n"
+ "<name>" N_("Silhouette") "</name>\n"
+ "<id>org.inkscape.effect.filter.Silhouette</id>\n"
+ "<param name=\"blur\" gui-text=\"" N_("Blur") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"50.00\">0.01</param>\n"
+ "<param name=\"cutout\" gui-text=\"" N_("Cutout") "\" type=\"bool\">false</param>\n"
+ "<param name=\"color\" gui-text=\"" N_("Color") "\" type=\"color\">255</param>\n"
+ "<effect>\n"
+ "<object-type>all</object-type>\n"
+ "<effects-menu>\n"
+ "<submenu name=\"" N_("Filters") "\">\n"
+ "<submenu name=\"" N_("Fill and Transparency") "\"/>\n"
+ "</submenu>\n"
+ "</effects-menu>\n"
+ "<menu-tip>" N_("Repaint anything visible monochrome") "</menu-tip>\n"
+ "</effect>\n"
+ "</inkscape-extension>\n", new Silhouette());
+ };
+
+};
+
+gchar const *
+Silhouette::get_filter_text (Inkscape::Extension::Extension * ext)
+{
+ if (_filter != nullptr) g_free((void *)_filter);
+
+ std::ostringstream a;
+ std::ostringstream r;
+ std::ostringstream g;
+ std::ostringstream b;
+ std::ostringstream cutout;
+ std::ostringstream blur;
+
+ guint32 color = ext->get_param_color("color");
+ r << ((color >> 24) & 0xff);
+ g << ((color >> 16) & 0xff);
+ b << ((color >> 8) & 0xff);
+ a << (color & 0xff) / 255.0F;
+ if (ext->get_param_bool("cutout"))
+ cutout << "out";
+ else
+ cutout << "in";
+ blur << ext->get_param_float("blur");
+
+ _filter = g_strdup_printf(
+ "<filter xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" style=\"color-interpolation-filters:sRGB;\" inkscape:label=\"Silhouette\">\n"
+ "<feFlood flood-opacity=\"%s\" flood-color=\"rgb(%s,%s,%s)\" result=\"flood\" />\n"
+ "<feComposite in=\"flood\" in2=\"SourceGraphic\" operator=\"%s\" result=\"composite\" />\n"
+ "<feGaussianBlur stdDeviation=\"%s\" />\n"
+ "</filter>\n", a.str().c_str(), r.str().c_str(), g.str().c_str(), b.str().c_str(), cutout.str().c_str(), blur.str().c_str());
+
+ return _filter;
+}; /* Silhouette filter */
+
+}; /* namespace Filter */
+}; /* namespace Internal */
+}; /* namespace Extension */
+}; /* namespace Inkscape */
+
+/* Change the 'TRANSPARENCY' below to be your file name */
+#endif /* SEEN_INKSCAPE_EXTENSION_INTERNAL_FILTER_TRANSPARENCY_H__ */