diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:24:48 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:24:48 +0000 |
commit | cca66b9ec4e494c1d919bff0f71a820d8afab1fa (patch) | |
tree | 146f39ded1c938019e1ed42d30923c2ac9e86789 /src/extension/internal/filter | |
parent | Initial commit. (diff) | |
download | inkscape-cca66b9ec4e494c1d919bff0f71a820d8afab1fa.tar.xz inkscape-cca66b9ec4e494c1d919bff0f71a820d8afab1fa.zip |
Adding upstream version 1.2.2.upstream/1.2.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/extension/internal/filter')
-rw-r--r-- | src/extension/internal/filter/BUILD_YOUR_OWN | 2 | ||||
-rw-r--r-- | src/extension/internal/filter/bevels.h | 289 | ||||
-rw-r--r-- | src/extension/internal/filter/blurs.h | 440 | ||||
-rw-r--r-- | src/extension/internal/filter/bumps.h | 494 | ||||
-rw-r--r-- | src/extension/internal/filter/color.h | 1963 | ||||
-rw-r--r-- | src/extension/internal/filter/distort.h | 258 | ||||
-rw-r--r-- | src/extension/internal/filter/filter-all.cpp | 128 | ||||
-rw-r--r-- | src/extension/internal/filter/filter-file.cpp | 139 | ||||
-rw-r--r-- | src/extension/internal/filter/filter.cpp | 236 | ||||
-rw-r--r-- | src/extension/internal/filter/filter.h | 62 | ||||
-rw-r--r-- | src/extension/internal/filter/image.h | 118 | ||||
-rw-r--r-- | src/extension/internal/filter/morphology.h | 334 | ||||
-rw-r--r-- | src/extension/internal/filter/overlays.h | 150 | ||||
-rw-r--r-- | src/extension/internal/filter/paint.h | 1061 | ||||
-rw-r--r-- | src/extension/internal/filter/protrusions.h | 104 | ||||
-rw-r--r-- | src/extension/internal/filter/shadows.h | 194 | ||||
-rw-r--r-- | src/extension/internal/filter/textures.h | 163 | ||||
-rw-r--r-- | src/extension/internal/filter/transparency.h | 420 |
18 files changed, 6555 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..7598499 --- /dev/null +++ b/src/extension/internal/filter/BUILD_YOUR_OWN @@ -0,0 +1,2 @@ +This directory contains filter effects. They're designed to be simple. +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..a8382ba --- /dev/null +++ b/src/extension/internal/filter/bevels.h @@ -0,0 +1,289 @@ +// 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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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..85f99fd --- /dev/null +++ b/src/extension/internal/filter/blurs.h @@ -0,0 +1,440 @@ +// 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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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 << "" ; + } + + + // clang-format off + _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() ); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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"); + + // clang-format off + _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()); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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"); + + // clang-format off + _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()); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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"); + + // clang-format off + _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()); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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" ; + } + + // clang-format off + _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()); + // clang-format on + + 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..4db33d6 --- /dev/null +++ b/src/extension/internal/filter/bumps.h @@ -0,0 +1,494 @@ +// 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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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" ; + } + + // clang-format off + _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()); + // clang-format on + + 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 + * Transparency 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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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"); + + // clang-format off + _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() ); + // clang-format on + + 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..9f4f872 --- /dev/null +++ b/src/extension/internal/filter/color.h @@ -0,0 +1,1963 @@ +// 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 () { + // clang-format off + 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()); + // clang-format on + }; +}; + +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"); + } + + // clang-format off + _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() ); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; +}; + +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"; + } + + // clang-format off + _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() ); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; +}; + +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"); + + // clang-format off + _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()); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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"); + + // clang-format off + _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() ); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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"; + } + + // clang-format off + _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() ); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; +}; + +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"; + } + // clang-format off + _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()); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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"); + double 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; + } + + // clang-format off + _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() ); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; +}; + +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"; + } + } + + // clang-format off + _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() ); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; +}; + +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"; + } + + // clang-format off + _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() ); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; +}; + +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"; + } + + // clang-format off + _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() ); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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"; + } + + // clang-format off + _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() ); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; +}; + +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"); + + // clang-format off + _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() ); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; +}; + +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; + + double 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); + + // clang-format off + _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() ); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; +}; + +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; + + // clang-format off + _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() ); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; +}; + +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; + + // clang-format off + _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() ); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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"); + + // clang-format off + _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() ); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; +}; + +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"); + + // clang-format off + _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()); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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"; + } + + // clang-format off + _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() ); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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"; + } + + // clang-format off + _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() ); + // clang-format on + + 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..c27dba5 --- /dev/null +++ b/src/extension/internal/filter/distort.h @@ -0,0 +1,258 @@ +// 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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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"; + } + + // clang-format off + _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() ); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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"); + + // clang-format off + _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()); + // clang-format on + + 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..0776350 --- /dev/null +++ b/src/extension/internal/filter/filter-file.cpp @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2008 Authors: + * Ted Gould <ted@gould.cx> + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include "filter.h" + +#include "io/sys.h" +#include "io/resource.h" +#include "io/stream/inkscapestream.h" + +/* Directory includes */ +#include "path-prefix.h" +#include "inkscape.h" + +/* Extension */ +#include "extension/extension.h" +#include "extension/system.h" + +/* System includes */ +#include <glibmm/i18n.h> +#include <glibmm/fileutils.h> + +using namespace Inkscape::IO::Resource; + +namespace Inkscape { +namespace Extension { +namespace Internal { +namespace Filter { + +void +filters_load_file (Glib::ustring filename, gchar * menuname) +{ + Inkscape::XML::Document *doc = sp_repr_read_file(filename.c_str(), INKSCAPE_EXTENSION_URI); + if (doc == nullptr) { + g_warning("File (%s) is not parseable as XML. Ignored.", filename.c_str()); + return; + } + + Inkscape::XML::Node * root = doc->root(); + if (strcmp(root->name(), "svg:svg")) { + Inkscape::GC::release(doc); + g_warning("File (%s) is not SVG. Ignored.", filename.c_str()); + return; + } + + for (Inkscape::XML::Node * child = root->firstChild(); + child != nullptr; child = child->next()) { + if (!strcmp(child->name(), "svg:defs")) { + for (Inkscape::XML::Node * defs = child->firstChild(); + defs != nullptr; defs = defs->next()) { + if (!strcmp(defs->name(), "svg:filter")) { + Filter::filters_load_node(defs, menuname); + } // oh! a filter + } //defs + } // is defs + } // children of root + + Inkscape::GC::release(doc); + return; +} + +void Filter::filters_all_files() +{ + for(auto &filename: get_filenames(USER, FILTERS, {".svg"})) { + filters_load_file(filename, _("Personal")); + } + for(auto &filename: get_filenames(SYSTEM, FILTERS, {".svg"})) { + filters_load_file(filename, _("Bundled")); + } +} + + +#include "extension/internal/clear-n_.h" + +class mywriter : public Inkscape::IO::BasicWriter { + Glib::ustring _str; +public: + void close() override; + void flush() override; + void put (char ch) override; + gchar const * c_str () { return _str.c_str(); } +}; + +void mywriter::close () { return; } +void mywriter::flush () { return; } +void mywriter::put (char ch) { _str += ch; } + + +void +Filter::filters_load_node (Inkscape::XML::Node *node, gchar * menuname) +{ + gchar const * label = node->attribute("inkscape:label"); + gchar const * menu = node->attribute("inkscape:menu"); + gchar const * menu_tooltip = node->attribute("inkscape:menu-tooltip"); + gchar const * id = node->attribute("id"); + + if (label == nullptr) { + label = id; + } + + // clang-format off + gchar * xml_str = g_strdup_printf( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>%s</name>\n" + "<id>org.inkscape.effect.filter.%s</id>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\">\n" + "<submenu name=\"%s\"/>\n" + "</submenu>\n" + "</effects-menu>\n" + "<menu-tip>%s</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", label, id, menu? menu : menuname, menu_tooltip? menu_tooltip : label); + // clang-format on + + // FIXME: Bad hack: since we pull out a single filter node out of SVG file and + // serialize it, it loses the namespace declarations from the root, so we must provide + // one right here for our inkscape attributes + node->setAttribute("xmlns:inkscape", SP_INKSCAPE_NS_URI); + + mywriter writer; + sp_repr_write_stream(node, writer, 0, FALSE, g_quark_from_static_string("svg"), 0, 0); + + Inkscape::Extension::build_from_mem(xml_str, new Filter(g_strdup(writer.c_str()))); + g_free(xml_str); + return; +} + +}; /* namespace Filter */ +}; /* namespace Internal */ +}; /* namespace Extension */ +}; /* namespace Inkscape */ + diff --git a/src/extension/internal/filter/filter.cpp b/src/extension/internal/filter/filter.cpp new file mode 100644 index 0000000..c9779c7 --- /dev/null +++ b/src/extension/internal/filter/filter.cpp @@ -0,0 +1,236 @@ +// 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 ( const auto & iter : from->attributeList()) { + 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) +{ + // clang-format off + gchar * xml_str = g_strdup_printf( + "<inkscape-extension xmlns=\"" INKSCAPE_EXTENSION_URI "\">\n" + "<name>%s</name>\n" + "<id>org.inkscape.effect.filter.%s</id>\n" + "<effect>\n" + "<object-type>all</object-type>\n" + "<effects-menu>\n" + "<submenu name=\"" N_("Filters") "\" />\n" + "<submenu name=\"%s\"/>\n" + "</effects-menu>\n" + "<menu-tip>%s</menu-tip>\n" + "</effect>\n" + "</inkscape-extension>\n", name, id, submenu, tip); + // clang-format on + 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..8820122 --- /dev/null +++ b/src/extension/internal/filter/image.h @@ -0,0 +1,118 @@ +// 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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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"; + } + + // clang-format off + _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()); + // clang-format on + + 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..e2bfa15 --- /dev/null +++ b/src/extension/internal/filter/morphology.h @@ -0,0 +1,334 @@ +// 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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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"; + } + + // clang-format off + _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()); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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)) { + // Inside + 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"; + } + + // clang-format off + _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() ); + // clang-format on + + 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..b93c070 --- /dev/null +++ b/src/extension/internal/filter/overlays.h @@ -0,0 +1,150 @@ +// 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 () { + // clang-format off + 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\" max=\"100.00\">20</param>\n" + "<param name=\"vfreq\" gui-text=\"" N_("Vertical frequency:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"100.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()); + // clang-format on + }; + +}; + +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")); + vfreq << (ext->get_param_float("vfreq")); + 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..920b275 --- /dev/null +++ b/src/extension/internal/filter/paint.h @@ -0,0 +1,1061 @@ +// 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 () { + // clang-format off + 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()); + // clang-format on + }; +}; + +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"; + + // clang-format off + _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()); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; +}; + +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"; + + // clang-format off + _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()); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; +}; + +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"; + + // clang-format off + _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()); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; +}; + +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; + } + + // clang-format off + _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()); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; +}; + +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"); + + // clang-format off + _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()); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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"; + + // clang-format off + _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() ); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; +}; + +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"; + + // clang-format off + _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()); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; +}; + +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"; + + // clang-format off + _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()); + // clang-format on + + 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..ccf54b4 --- /dev/null +++ b/src/extension/internal/filter/protrusions.h @@ -0,0 +1,104 @@ +// 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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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"); + + // clang-format off + _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()); + // clang-format on + + 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..2616b25 --- /dev/null +++ b/src/extension/internal/filter/shadows.h @@ -0,0 +1,194 @@ +// 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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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"; + } + + // clang-format off + _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()); + // clang-format on + + 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..66066ae --- /dev/null +++ b/src/extension/internal/filter/textures.h @@ -0,0 +1,163 @@ +// 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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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"); + + // clang-format off + _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() ); + // clang-format on + + 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..39cd240 --- /dev/null +++ b/src/extension/internal/filter/transparency.h @@ -0,0 +1,420 @@ +// 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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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"); + + // clang-format off + _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() ); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; +}; + +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"; + } + + // clang-format off + _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()); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; +}; + +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"); + } + + // clang-format off + _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()); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; +}; + +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")); + + // clang-format off + _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()); + // clang-format on + + 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 () { + // clang-format off + 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()); + // clang-format on + }; + +}; + +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"); + + // clang-format off + _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()); + // clang-format on + + 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__ */ |