// 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) * * 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( "\n" "" N_("Brilliance") "\n" "org.inkscape.effect.filter.Brilliance\n" "2\n" "0.5\n" "0\n" "false\n" "\n" "all\n" "\n" "\n" "\n" "\n" "\n" "" N_("Brightness filter") "\n" "\n" "\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( "\n" "\n" "\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( "\n" "" N_("Channel Painting") "\n" "org.inkscape.effect.filter.ChannelPaint\n" "\n" "\n" "1\n" "-1\n" "0.5\n" "0.5\n" "1\n" "false\n" "\n" "\n" "16777215\n" "\n" "\n" "\n" "all\n" "\n" "\n" "\n" "\n" "\n" "" N_("Replace RGB by any color") "\n" "\n" "\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( "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\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( "\n" "" N_("Color Blindness") "\n" "org.inkscape.effect.filter.ColorBlindness\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "all\n" "\n" "\n" "\n" "\n" "\n" "" N_("Simulate color blindness") "\n" "\n" "\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( "\n" "\n" "\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( "\n" "" N_("Color Shift") "\n" "org.inkscape.effect.filter.ColorShift\n" "330\n" "0.6\n" "\n" "all\n" "\n" "\n" "\n" "\n" "\n" "" N_("Rotate and desaturate hue") "\n" "\n" "\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( "\n" "\n" "\n" "\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( "\n" "" N_("Colorize") "\n" "org.inkscape.effect.filter.Colorize\n" "\n" "\n" "0\n" "1\n" "false\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "-1639776001\n" "\n" "\n" "\n" "all\n" "\n" "\n" "\n" "\n" "\n" "" N_("Blend image or object with a flood color") "\n" "\n" "\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( "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\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( "\n" "" N_("Component Transfer") "\n" "org.inkscape.effect.filter.ComponentTransfer\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "all\n" "\n" "\n" "\n" "\n" "\n" "" N_("Basic component transfer structure") "\n" "\n" "\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 << "\n" << "\n" << "\n" << "\n"; } else if ((g_ascii_strcasecmp("table", type) == 0)) { CTfunction << "\n" << "\n" << "\n"; } else if ((g_ascii_strcasecmp("discrete", type) == 0)) { CTfunction << "\n" << "\n" << "\n"; } else if ((g_ascii_strcasecmp("linear", type) == 0)) { CTfunction << "\n" << "\n" << "\n"; } else { //Gamma CTfunction << "\n" << "\n" << "\n"; } // clang-format off _filter = g_strdup_printf( "\n" "\n" "%s\n" "\n" "\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( "\n" "" N_("Duochrome") "\n" "org.inkscape.effect.filter.Duochrome\n" "\n" "\n" "0\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "1364325887\n" "\n" "\n" "-65281\n" "\n" "\n" "\n" "all\n" "\n" "\n" "\n" "\n" "\n" "" N_("Convert luminance values to a duochrome palette") "\n" "\n" "\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( "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\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( "\n" "" N_("Extract Channel") "\n" "org.inkscape.effect.filter.ExtractChannel\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "false\n" "\n" "all\n" "\n" "\n" "\n" "\n" "\n" "" N_("Extract color channel as a transparent image") "\n" "\n" "\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( "\n" "\n" "\n" "\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( "\n" "" N_("Fade to Black or White") "\n" "org.inkscape.effect.filter.FadeToBW\n" "1\n" "\n" "\n" "\n" "\n" "\n" "all\n" "\n" "\n" "\n" "\n" "\n" "" N_("Fade to black or white") "\n" "\n" "\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( "\n" "\n" "\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( "\n" "" N_("Greyscale") "\n" "org.inkscape.effect.filter.Greyscale\n" "0.21\n" "0.72\n" "0.072\n" "0\n" "false\n" "\n" "all\n" "\n" "\n" "\n" "\n" "\n" "" N_("Customize greyscale components") "\n" "\n" "\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( "\n" "\n" "\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( "\n" "" N_("Invert") "\n" "org.inkscape.effect.filter.Invert\n" "\n" "\n" "\n" "\n" "\n" "\n" "0\n" "false\n" "false\n" "false\n" "\n" "all\n" "\n" "\n" "\n" "\n" "\n" "" N_("Manage hue, lightness and transparency inversions") "\n" "\n" "\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 << "\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( "\n" "%s" "\n" "\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( "\n" "" N_("Lighting") "\n" "org.inkscape.effect.filter.Lighting\n" "1\n" "1\n" "0\n" "\n" "all\n" "\n" "\n" "\n" "\n" "\n" "" N_("Modify lights and shadows separately") "\n" "\n" "\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( "\n" "\n" "\n" "\n" "\n" "\n" "\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( "\n" "" N_("Lightness-Contrast") "\n" "org.inkscape.effect.filter.LightnessContrast\n" "0\n" "0\n" "\n" "all\n" "\n" "\n" "\n" "\n" "\n" "" N_("Modify lightness and contrast separately") "\n" "\n" "\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( "\n" "\n" "\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( "\n" "" N_("Nudge RGB") "\n" "org.inkscape.effect.filter.NudgeRGB\n" "\n" "\n" "\n" "-6\n" "-6\n" "\n" "6\n" "7\n" "\n" "1\n" "-16\n" "\n" "\n" "255\n" "\n" "\n" "\n" "all\n" "\n" "\n" "\n" "\n" "\n" "" N_("Nudge RGB channels separately and blend them to different types of backgrounds") "\n" "\n" "\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( "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\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( "\n" "" N_("Nudge CMY") "\n" "org.inkscape.effect.filter.NudgeCMY\n" "\n" "\n" "\n" "-6\n" "-6\n" "\n" "6\n" "7\n" "\n" "1\n" "-16\n" "\n" "\n" "-1\n" "\n" "\n" "\n" "all\n" "\n" "\n" "\n" "\n" "\n" "" N_("Nudge CMY channels separately and blend them to different types of backgrounds") "\n" "\n" "\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( "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\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( "\n" "" N_("Quadritone Fantasy") "\n" "org.inkscape.effect.filter.Quadritone\n" "280\n" "100\n" "\n" "\n" "\n" "\n" "\n" "0\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "all\n" "\n" "\n" "\n" "\n" "\n" "" N_("Replace hue by two colors") "\n" "\n" "\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( "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\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( "\n" "" N_("Simple blend") "\n" "org.inkscape.effect.filter.SimpleBlend\n" "16777215\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "all\n" "\n" "\n" "\n" "\n" "\n" "" N_("Simple blend filter") "\n" "\n" "\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( "\n" "\n" "\n" "\n" "\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( "\n" "" N_("Solarize") "\n" "org.inkscape.effect.filter.Solarize\n" "0\n" "\n" "\n" "\n" "\n" "\n" "all\n" "\n" "\n" "\n" "\n" "\n" "" N_("Classic photographic solarization effect") "\n" "\n" "\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( "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\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( "\n" "" N_("Tritone") "\n" "org.inkscape.effect.filter.Tritone\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "0.01\n" "\n" "\n" "\n" "\n" "\n" "0\n" "1\n" "\n" "\n" "0\n" "-73203457\n" "\n" "\n" "\n" "all\n" "\n" "\n" "\n" "\n" "\n" "" N_("Create a custom tritone palette with additional glow, blend modes and hue moving") "\n" "\n" "\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( "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\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__ */