[gimp] app, icons: add Paint Select tool in the playground
- From: Thomas Manni <tmanni src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app, icons: add Paint Select tool in the playground
- Date: Tue, 24 Nov 2020 11:11:18 +0000 (UTC)
commit e1cdb9f54e1ee385b78190b9c5a60126ea6b29e2
Author: Thomas Manni <thomas manni free fr>
Date: Sat Nov 7 12:59:45 2020 +0100
app, icons: add Paint Select tool in the playground
A -quick done- first step towards the addition of a smart selection tool.
Require the gegl:paint-select workshop operation.
Still LOT of work to do (wip):
- fluctuations removal (GEGL side)
- multilevels pyramid approach + banded graphcut for instant result on large
image (GEGL ? GIMP ?)
- Gaussian Mixtures for color models (GEGL side)
- drawable offsets (GIMP side)
- undo / redo (GIMP side)
- scribbles edition mode (GIMP side)
- dedicated icons
- ...
app/config/gimpguiconfig.c | 16 +
app/config/gimpguiconfig.h | 1 +
app/config/gimprc-blurbs.h | 3 +
app/dialogs/preferences-dialog.c | 3 +
app/tools/Makefile.am | 4 +
app/tools/gimp-tools.c | 2 +
app/tools/gimppaintselectoptions.c | 188 ++++++
app/tools/gimppaintselectoptions.h | 57 ++
app/tools/gimppaintselecttool.c | 728 +++++++++++++++++++++
app/tools/gimppaintselecttool.h | 67 ++
app/tools/meson.build | 2 +
app/tools/tools-enums.c | 17 +
app/tools/tools-enums.h | 10 +
icons/Color/16/gimp-tool-paint-select.png | Bin 0 -> 718 bytes
icons/Color/24/gimp-tool-paint-select.png | Bin 0 -> 1071 bytes
icons/Color/24/gimp-tool-paint-select.svg | 235 +++++++
icons/Color/icon-list.mk | 4 +
icons/Color/scalable/gimp-tool-paint-select.svg | 263 ++++++++
.../24/gimp-tool-paint-select-symbolic.svg | 137 ++++
icons/Symbolic/icon-list.mk | 2 +
.../scalable/gimp-tool-paint-select-symbolic.svg | 153 +++++
libgimpwidgets/gimpicons.h | 1 +
menus/image-menu.xml.in | 1 +
23 files changed, 1894 insertions(+)
---
diff --git a/app/config/gimpguiconfig.c b/app/config/gimpguiconfig.c
index 83b3b51745..c49e6897ab 100644
--- a/app/config/gimpguiconfig.c
+++ b/app/config/gimpguiconfig.c
@@ -86,6 +86,7 @@ enum
PROP_PLAYGROUND_NPD_TOOL,
PROP_PLAYGROUND_SEAMLESS_CLONE_TOOL,
+ PROP_PLAYGROUND_PAINT_SELECT_TOOL,
PROP_HIDE_DOCKS,
PROP_SINGLE_WINDOW_MODE,
@@ -417,6 +418,15 @@ gimp_gui_config_class_init (GimpGuiConfigClass *klass)
GIMP_PARAM_STATIC_STRINGS |
GIMP_CONFIG_PARAM_RESTART);
+ GIMP_CONFIG_PROP_BOOLEAN (object_class,
+ PROP_PLAYGROUND_PAINT_SELECT_TOOL,
+ "playground-paint-select-tool",
+ "Playground Paint Select tool",
+ PLAYGROUND_PAINT_SELECT_TOOL_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_RESTART);
+
g_object_class_install_property (object_class, PROP_HIDE_DOCKS,
g_param_spec_boolean ("hide-docks",
NULL,
@@ -683,6 +693,9 @@ gimp_gui_config_set_property (GObject *object,
case PROP_PLAYGROUND_SEAMLESS_CLONE_TOOL:
gui_config->playground_seamless_clone_tool = g_value_get_boolean (value);
break;
+ case PROP_PLAYGROUND_PAINT_SELECT_TOOL:
+ gui_config->playground_paint_select_tool = g_value_get_boolean (value);
+ break;
case PROP_HIDE_DOCKS:
gui_config->hide_docks = g_value_get_boolean (value);
@@ -846,6 +859,9 @@ gimp_gui_config_get_property (GObject *object,
case PROP_PLAYGROUND_SEAMLESS_CLONE_TOOL:
g_value_set_boolean (value, gui_config->playground_seamless_clone_tool);
break;
+ case PROP_PLAYGROUND_PAINT_SELECT_TOOL:
+ g_value_set_boolean (value, gui_config->playground_paint_select_tool);
+ break;
case PROP_HIDE_DOCKS:
g_value_set_boolean (value, gui_config->hide_docks);
diff --git a/app/config/gimpguiconfig.h b/app/config/gimpguiconfig.h
index ac1c6b59df..ce0997443c 100644
--- a/app/config/gimpguiconfig.h
+++ b/app/config/gimpguiconfig.h
@@ -82,6 +82,7 @@ struct _GimpGuiConfig
/* experimental playground */
gboolean playground_npd_tool;
gboolean playground_seamless_clone_tool;
+ gboolean playground_paint_select_tool;
/* saved in sessionrc */
gboolean hide_docks;
diff --git a/app/config/gimprc-blurbs.h b/app/config/gimprc-blurbs.h
index 507b59234b..daa5b0fe9f 100644
--- a/app/config/gimprc-blurbs.h
+++ b/app/config/gimprc-blurbs.h
@@ -478,6 +478,9 @@ _("Enable the MyPaint Brush tool.")
#define PLAYGROUND_SEAMLESS_CLONE_TOOL_BLURB \
_("Enable the Seamless Clone tool.")
+#define PLAYGROUND_PAINT_SELECT_TOOL_BLURB \
+_("Enable the Paint Select tool.")
+
#define SPACE_BAR_ACTION_BLURB \
_("What to do when the space bar is pressed in the image window.")
diff --git a/app/dialogs/preferences-dialog.c b/app/dialogs/preferences-dialog.c
index 2aafa0a26c..8187be7825 100644
--- a/app/dialogs/preferences-dialog.c
+++ b/app/dialogs/preferences-dialog.c
@@ -1648,6 +1648,9 @@ prefs_dialog_new (Gimp *gimp,
button = prefs_check_button_add (object, "playground-seamless-clone-tool",
_("_Seamless Clone tool"),
GTK_BOX (vbox2));
+ button = prefs_check_button_add (object, "playground-paint-select-tool",
+ _("_Paint Select tool"),
+ GTK_BOX (vbox2));
}
diff --git a/app/tools/Makefile.am b/app/tools/Makefile.am
index bbe45841cd..a9e7221c9e 100644
--- a/app/tools/Makefile.am
+++ b/app/tools/Makefile.am
@@ -152,6 +152,10 @@ libapptools_a_sources = \
gimppaintbrushtool.h \
gimppaintoptions-gui.c \
gimppaintoptions-gui.h \
+ gimppaintselectoptions.c \
+ gimppaintselectoptions.h \
+ gimppaintselecttool.c \
+ gimppaintselecttool.h \
gimppainttool.c \
gimppainttool.h \
gimppainttool-paint.c \
diff --git a/app/tools/gimp-tools.c b/app/tools/gimp-tools.c
index 94d22a81ee..067af787ee 100644
--- a/app/tools/gimp-tools.c
+++ b/app/tools/gimp-tools.c
@@ -75,6 +75,7 @@
#include "gimpnpointdeformationtool.h"
#include "gimpoffsettool.h"
#include "gimppaintbrushtool.h"
+#include "gimppaintselecttool.h"
#include "gimppenciltool.h"
#include "gimpperspectiveclonetool.h"
#include "gimpperspectivetool.h"
@@ -140,6 +141,7 @@ gimp_tools_init (Gimp *gimp)
gimp_by_color_select_tool_register,
gimp_iscissors_tool_register,
gimp_foreground_select_tool_register,
+ gimp_paint_select_tool_register,
/* path tool */
diff --git a/app/tools/gimppaintselectoptions.c b/app/tools/gimppaintselectoptions.c
new file mode 100644
index 0000000000..9c707036a4
--- /dev/null
+++ b/app/tools/gimppaintselectoptions.c
@@ -0,0 +1,188 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <gegl.h>
+#include <gtk/gtk.h>
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpconfig/gimpconfig.h"
+#include "libgimpwidgets/gimpwidgets.h"
+
+#include "tools-types.h"
+
+#include "widgets/gimppropwidgets.h"
+#include "widgets/gimpspinscale.h"
+#include "widgets/gimpwidgets-constructors.h"
+#include "widgets/gimpwidgets-utils.h"
+
+#include "core/gimptooloptions.h"
+#include "gimppaintselectoptions.h"
+#include "gimptooloptions-gui.h"
+
+#include "gimp-intl.h"
+
+
+enum
+{
+ PROP_0,
+ PROP_MODE,
+ PROP_STROKE_WIDTH,
+};
+
+
+static void gimp_paint_select_options_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_paint_select_options_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+
+G_DEFINE_TYPE (GimpPaintSelectOptions, gimp_paint_select_options,
+ GIMP_TYPE_TOOL_OPTIONS)
+
+
+static void
+gimp_paint_select_options_class_init (GimpPaintSelectOptionsClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->set_property = gimp_paint_select_options_set_property;
+ object_class->get_property = gimp_paint_select_options_get_property;
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_MODE,
+ "mode",
+ _("Mode"),
+ _("Paint over areas to mark pixels for "
+ "inclusion or exclusion from selection"),
+ GIMP_TYPE_PAINT_SELECT_MODE,
+ GIMP_PAINT_SELECT_MODE_ADD,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_INT (object_class, PROP_STROKE_WIDTH,
+ "stroke-width",
+ _("Stroke width"),
+ _("Size of the brush used for refinements"),
+ 1, 6000, 50,
+ GIMP_PARAM_STATIC_STRINGS);
+}
+
+static void
+gimp_paint_select_options_init (GimpPaintSelectOptions *options)
+{
+}
+
+static void
+gimp_paint_select_options_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GimpPaintSelectOptions *options = GIMP_PAINT_SELECT_OPTIONS (object);
+
+ switch (property_id)
+ {
+ case PROP_MODE:
+ options->mode = g_value_get_enum (value);
+ break;
+
+ case PROP_STROKE_WIDTH:
+ options->stroke_width = g_value_get_int (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_paint_select_options_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GimpPaintSelectOptions *options = GIMP_PAINT_SELECT_OPTIONS (object);
+
+ switch (property_id)
+ {
+ case PROP_MODE:
+ g_value_set_enum (value, options->mode);
+ break;
+
+ case PROP_STROKE_WIDTH:
+ g_value_set_int (value, options->stroke_width);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_paint_select_options_reset_stroke_width (GtkWidget *button,
+ GimpToolOptions *tool_options)
+{
+ g_object_set (tool_options, "stroke-width", 10, NULL);
+}
+
+GtkWidget *
+gimp_paint_select_options_gui (GimpToolOptions *tool_options)
+{
+ GObject *config = G_OBJECT (tool_options);
+ GtkWidget *vbox = gimp_tool_options_gui (tool_options);
+ GtkWidget *hbox;
+ GtkWidget *button;
+ GtkWidget *frame;
+ GtkWidget *scale;
+
+ frame = gimp_prop_enum_radio_frame_new (config, "mode", NULL,
+ 0, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+ gtk_widget_show (hbox);
+
+ /* stroke width */
+ scale = gimp_prop_spin_scale_new (config, "stroke-width", NULL,
+ 1.0, 10.0, 2);
+ gimp_spin_scale_set_scale_limits (GIMP_SPIN_SCALE (scale), 1.0, 1000.0);
+ gimp_spin_scale_set_gamma (GIMP_SPIN_SCALE (scale), 1.7);
+ gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
+
+ button = gimp_icon_button_new (GIMP_ICON_RESET, NULL);
+ gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
+ gtk_image_set_from_icon_name (GTK_IMAGE (gtk_bin_get_child (GTK_BIN (button))),
+ GIMP_ICON_RESET, GTK_ICON_SIZE_MENU);
+ gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+ gtk_widget_show (button);
+
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (gimp_paint_select_options_reset_stroke_width),
+ tool_options);
+
+ gimp_help_set_help_data (button,
+ _("Reset stroke width native size"), NULL);
+
+ return vbox;
+}
diff --git a/app/tools/gimppaintselectoptions.h b/app/tools/gimppaintselectoptions.h
new file mode 100644
index 0000000000..7c5cb201b6
--- /dev/null
+++ b/app/tools/gimppaintselectoptions.h
@@ -0,0 +1,57 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __GIMP_PAINT_SELECT_OPTIONS_H__
+#define __GIMP_PAINT_SELECT_OPTIONS_H__
+
+
+#include "core/gimptooloptions.h"
+
+
+#define GIMP_TYPE_PAINT_SELECT_OPTIONS (gimp_paint_select_options_get_type ())
+#define GIMP_PAINT_SELECT_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
GIMP_TYPE_PAINT_SELECT_OPTIONS, GimpPaintSelectOptions))
+#define GIMP_PAINT_SELECT_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),
GIMP_TYPE_PAINT_SELECT_OPTIONS, GimpPaintSelectOptionsClass))
+#define GIMP_IS_PAINT_SELECT_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),
GIMP_TYPE_PAINT_SELECT_OPTIONS))
+#define GIMP_IS_PAINT_SELECT_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
GIMP_TYPE_PAINT_SELECT_OPTIONS))
+#define GIMP_PAINT_SELECT_OPTIONS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
GIMP_TYPE_PAINT_SELECT_OPTIONS, GimpPaintSelectOptionsClass))
+
+
+typedef struct _GimpPaintSelectOptions GimpPaintSelectOptions;
+typedef struct _GimpPaintSelectOptionsClass GimpPaintSelectOptionsClass;
+
+struct _GimpPaintSelectOptions
+{
+ GimpToolOptions parent_instance;
+
+ GimpPaintSelectMode mode;
+ gint stroke_width;
+};
+
+struct _GimpPaintSelectOptionsClass
+{
+ GimpToolOptionsClass parent_class;
+};
+
+
+GType gimp_paint_select_options_get_type (void) G_GNUC_CONST;
+
+GtkWidget * gimp_paint_select_options_gui (GimpToolOptions *tool_options);
+
+
+
+#endif /* __GIMP_PAINT_SELECT_OPTIONS_H__ */
\ No newline at end of file
diff --git a/app/tools/gimppaintselecttool.c b/app/tools/gimppaintselecttool.c
new file mode 100644
index 0000000000..e154563bb5
--- /dev/null
+++ b/app/tools/gimppaintselecttool.c
@@ -0,0 +1,728 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpPaintSelectTool
+ * Copyright (C) 2020 Thomas Manni <thomas manni free fr>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <math.h>
+
+#include <gegl.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+
+
+#include "libgimpmath/gimpmath.h"
+#include "libgimpbase/gimpbase.h"
+#include "libgimpcolor/gimpcolor.h"
+#include "libgimpwidgets/gimpwidgets.h"
+
+#include "tools-types.h"
+
+#include "config/gimpguiconfig.h"
+
+#include "gegl/gimp-gegl-loops.h"
+#include "gegl/gimp-gegl-mask.h"
+#include "gegl/gimp-gegl-utils.h"
+
+#include "core/gimp.h"
+#include "core/gimpchannel-select.h"
+#include "core/gimperror.h"
+#include "core/gimpimage.h"
+#include "core/gimplayer.h"
+#include "core/gimplayermask.h"
+#include "core/gimpprogress.h"
+#include "core/gimpscanconvert.h"
+
+#include "widgets/gimphelp-ids.h"
+#include "widgets/gimpwidgets-utils.h"
+
+#include "display/gimpdisplay.h"
+#include "display/gimpdisplayshell.h"
+#include "display/gimptoolgui.h"
+
+#include "core/gimptooloptions.h"
+#include "gimppaintselecttool.h"
+#include "gimppaintselectoptions.h"
+#include "gimptoolcontrol.h"
+
+#include "gimp-intl.h"
+
+#include "config/gimpguiconfig.h" /* playground */
+
+
+static gboolean gimp_paint_select_tool_initialize (GimpTool *tool,
+ GimpDisplay *display,
+ GError **error);
+ static void gimp_paint_select_tool_control (GimpTool *tool,
+ GimpToolAction action,
+ GimpDisplay *display);
+static void gimp_paint_select_tool_button_press (GimpTool *tool,
+ const GimpCoords *coords,
+ guint32 time,
+ GdkModifierType state,
+ GimpButtonPressType press_type,
+ GimpDisplay *display);
+static void gimp_paint_select_tool_button_release (GimpTool *tool,
+ const GimpCoords *coords,
+ guint32 time,
+ GdkModifierType state,
+ GimpButtonReleaseType release_type,
+ GimpDisplay *display);
+static void gimp_paint_select_tool_motion (GimpTool *tool,
+ const GimpCoords *coords,
+ guint32 time,
+ GdkModifierType state,
+ GimpDisplay *display);
+static gboolean gimp_paint_select_tool_key_press (GimpTool *tool,
+ GdkEventKey *kevent,
+ GimpDisplay *display);
+static void gimp_paint_select_tool_modifier_key (GimpTool *tool,
+ GdkModifierType key,
+ gboolean press,
+ GdkModifierType state,
+ GimpDisplay *display);
+static void gimp_paint_select_tool_oper_update (GimpTool *tool,
+ const GimpCoords *coords,
+ GdkModifierType state,
+ gboolean proximity,
+ GimpDisplay *display);
+static void gimp_paint_select_tool_options_notify (GimpTool *tool,
+ GimpToolOptions *options,
+ const GParamSpec *pspec);
+static void gimp_paint_select_tool_cursor_update (GimpTool *tool,
+ const GimpCoords *coords,
+ GdkModifierType state,
+ GimpDisplay *display);
+static void gimp_paint_select_tool_draw (GimpDrawTool *draw_tool);
+
+static void gimp_paint_select_tool_halt (GimpPaintSelectTool *ps_tool);
+static void gimp_paint_select_tool_update_image_mask (GimpPaintSelectTool *ps_tool);
+static void gimp_paint_select_tool_init_buffers (GimpPaintSelectTool *ps_tool,
+ GimpImage *image,
+ GimpDrawable *drawable);
+static void gimp_paint_select_tool_init_scribble (GimpPaintSelectTool *ps_tool);
+static void gimp_paint_select_tool_create_graph (GimpPaintSelectTool *ps_tool);
+static gboolean gimp_paint_select_tool_paint_scribble (GimpPaintSelectTool *ps_tool);
+
+static gfloat euclidean_distance (gint x1,
+ gint y1,
+ gint x2,
+ gint y2);
+
+
+G_DEFINE_TYPE (GimpPaintSelectTool, gimp_paint_select_tool,
+ GIMP_TYPE_DRAW_TOOL)
+
+#define parent_class gimp_paint_select_tool_parent_class
+
+
+void
+gimp_paint_select_tool_register (GimpToolRegisterCallback callback,
+ gpointer data)
+{
+ if (gegl_has_operation ("gegl:paint-select") &&
+ GIMP_GUI_CONFIG (GIMP (data)->config)->playground_paint_select_tool)
+ (* callback) (GIMP_TYPE_PAINT_SELECT_TOOL,
+ GIMP_TYPE_PAINT_SELECT_OPTIONS,
+ gimp_paint_select_options_gui,
+ 0,
+ "gimp-paint-select-tool",
+ _("Paint Select"),
+ _("Paint Select Tool: Scult selection by painting"),
+ N_("P_aint Select"), NULL,
+ NULL, GIMP_HELP_TOOL_FOREGROUND_SELECT,
+ GIMP_ICON_TOOL_PAINT_SELECT,
+ data);
+}
+
+static void
+gimp_paint_select_tool_class_init (GimpPaintSelectToolClass *klass)
+{
+ GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass);
+ GimpDrawToolClass *draw_tool_class = GIMP_DRAW_TOOL_CLASS (klass);
+
+ tool_class->button_press = gimp_paint_select_tool_button_press;
+ tool_class->button_release = gimp_paint_select_tool_button_release;
+ tool_class->control = gimp_paint_select_tool_control;
+ tool_class->cursor_update = gimp_paint_select_tool_cursor_update;
+ tool_class->initialize = gimp_paint_select_tool_initialize;
+ tool_class->key_press = gimp_paint_select_tool_key_press;
+ tool_class->modifier_key = gimp_paint_select_tool_modifier_key;
+ tool_class->motion = gimp_paint_select_tool_motion;
+ tool_class->oper_update = gimp_paint_select_tool_oper_update;
+ tool_class->options_notify = gimp_paint_select_tool_options_notify;
+
+ draw_tool_class->draw = gimp_paint_select_tool_draw;
+}
+
+static void
+gimp_paint_select_tool_init (GimpPaintSelectTool *ps_tool)
+{
+ GimpTool *tool = GIMP_TOOL (ps_tool);
+
+ gimp_tool_control_set_motion_mode (tool->control, GIMP_MOTION_MODE_EXACT);
+ gimp_tool_control_set_scroll_lock (tool->control, FALSE);
+ gimp_tool_control_set_preserve (tool->control, FALSE);
+ gimp_tool_control_set_dirty_mask (tool->control,
+ GIMP_DIRTY_IMAGE |
+ GIMP_DIRTY_ACTIVE_DRAWABLE);
+ gimp_tool_control_set_dirty_action (tool->control,
+ GIMP_TOOL_ACTION_HALT);
+ gimp_tool_control_set_precision (tool->control,
+ GIMP_CURSOR_PRECISION_SUBPIXEL);
+ gimp_tool_control_set_tool_cursor (tool->control,
+ GIMP_TOOL_CURSOR_PAINTBRUSH);
+ gimp_tool_control_set_cursor_modifier (tool->control,
+ GIMP_CURSOR_MODIFIER_PLUS);
+ gimp_tool_control_set_action_size (tool->control,
+ "tools/tools-paint-select-brush-size-set");
+ ps_tool->result_mask = NULL;
+ ps_tool->image_mask = NULL;
+ ps_tool->trimap = NULL;
+ ps_tool->drawable = NULL;
+ ps_tool->scribble = NULL;
+ ps_tool->graph = NULL;
+ ps_tool->ps_node = NULL;
+ ps_tool->render_node = NULL;
+}
+
+static void
+gimp_paint_select_tool_button_press (GimpTool *tool,
+ const GimpCoords *coords,
+ guint32 time,
+ GdkModifierType state,
+ GimpButtonPressType press_type,
+ GimpDisplay *display)
+{
+ GimpPaintSelectTool *ps_tool = GIMP_PAINT_SELECT_TOOL (tool);
+ GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);
+
+ if (gimp_draw_tool_is_active (draw_tool) && draw_tool->display != display)
+ gimp_draw_tool_stop (draw_tool);
+
+ gimp_draw_tool_pause (draw_tool);
+ gimp_tool_control_activate (tool->control);
+
+ ps_tool->last_pos.x = coords->x;
+ ps_tool->last_pos.y = coords->y;
+
+ if (gimp_paint_select_tool_paint_scribble (ps_tool))
+ {
+ if (tool->display)
+ {
+ GimpPaintSelectOptions *options = GIMP_PAINT_SELECT_TOOL_GET_OPTIONS (ps_tool);
+ GimpImage *image = gimp_display_get_image (tool->display);
+ GimpChannelOps op;
+ gint x_offset = ps_tool->last_pos.x - options->stroke_width / 2;
+ gint y_offset = ps_tool->last_pos.y - options->stroke_width / 2;
+
+ if (options->mode == GIMP_PAINT_SELECT_MODE_ADD)
+ op = GIMP_CHANNEL_OP_ADD;
+ else
+ op = GIMP_CHANNEL_OP_SUBTRACT;
+
+ gimp_channel_select_buffer (gimp_image_get_mask (image),
+ C_("command", "Paint Select"),
+ ps_tool->scribble,
+ x_offset,
+ y_offset,
+ op,
+ FALSE,
+ 0,
+ 0);
+ gimp_image_flush (image);
+ }
+ }
+
+ if (! gimp_draw_tool_is_active (draw_tool))
+ gimp_draw_tool_start (draw_tool, display);
+
+ gimp_draw_tool_resume (draw_tool);
+}
+
+static void
+gimp_paint_select_tool_button_release (GimpTool *tool,
+ const GimpCoords *coords,
+ guint32 time,
+ GdkModifierType state,
+ GimpButtonReleaseType release_type,
+ GimpDisplay *display)
+{
+ GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);
+ gimp_draw_tool_stop (draw_tool);
+ gimp_tool_control_halt (tool->control);
+}
+
+static void
+gimp_paint_select_tool_control (GimpTool *tool,
+ GimpToolAction action,
+ GimpDisplay *display)
+{
+ GimpPaintSelectTool *paint_select = GIMP_PAINT_SELECT_TOOL (tool);
+
+ switch (action)
+ {
+ case GIMP_TOOL_ACTION_PAUSE:
+ break;
+
+ case GIMP_TOOL_ACTION_RESUME:
+ break;
+
+ case GIMP_TOOL_ACTION_HALT:
+ gimp_paint_select_tool_halt (paint_select);
+ break;
+
+ case GIMP_TOOL_ACTION_COMMIT:
+ break;
+ }
+
+ GIMP_TOOL_CLASS (parent_class)->control (tool, action, display);
+}
+
+static void
+gimp_paint_select_tool_cursor_update (GimpTool *tool,
+ const GimpCoords *coords,
+ GdkModifierType state,
+ GimpDisplay *display)
+{
+ GimpPaintSelectOptions *options = GIMP_PAINT_SELECT_TOOL_GET_OPTIONS (tool);
+ GimpCursorModifier modifier = GIMP_CURSOR_MODIFIER_NONE;
+
+ if (options->mode == GIMP_PAINT_SELECT_MODE_ADD)
+ {
+ modifier = GIMP_CURSOR_MODIFIER_PLUS;
+ }
+ else
+ {
+ modifier = GIMP_CURSOR_MODIFIER_MINUS;
+ }
+
+ gimp_tool_control_set_cursor_modifier (tool->control, modifier);
+
+ GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
+}
+
+static gboolean
+gimp_paint_select_tool_initialize (GimpTool *tool,
+ GimpDisplay *display,
+ GError **error)
+{
+ GimpPaintSelectTool *ps_tool = GIMP_PAINT_SELECT_TOOL (tool);
+ GimpGuiConfig *config = GIMP_GUI_CONFIG (display->gimp->config);
+ GimpImage *image = gimp_display_get_image (display);
+ GList *drawables = gimp_image_get_selected_drawables (image);
+ GimpDrawable *drawable;
+
+ if (g_list_length (drawables) != 1)
+ {
+ if (g_list_length (drawables) > 1)
+ g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
+ _("Cannot select from multiple layers."));
+ else
+ g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, _("No selected drawables."));
+
+ g_list_free (drawables);
+ return FALSE;
+ }
+
+ drawable = drawables->data;
+ g_list_free (drawables);
+
+ if (! gimp_item_is_visible (GIMP_ITEM (drawable)) &&
+ ! config->edit_non_visible)
+ {
+ g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
+ _("The active layer is not visible."));
+ return FALSE;
+ }
+
+ tool->display = display;
+
+ gimp_paint_select_tool_init_buffers (ps_tool, image, drawable);
+ gimp_paint_select_tool_create_graph (ps_tool);
+
+ return TRUE;
+}
+
+static gboolean
+gimp_paint_select_tool_key_press (GimpTool *tool,
+ GdkEventKey *kevent,
+ GimpDisplay *display)
+{
+ return GIMP_TOOL_CLASS (parent_class)->key_press (tool, kevent, display);
+}
+
+static void
+gimp_paint_select_tool_modifier_key (GimpTool *tool,
+ GdkModifierType key,
+ gboolean press,
+ GdkModifierType state,
+ GimpDisplay *display)
+{
+}
+
+static void
+gimp_paint_select_tool_motion (GimpTool *tool,
+ const GimpCoords *coords,
+ guint32 time,
+ GdkModifierType state,
+ GimpDisplay *display)
+{
+ GimpPaintSelectTool *ps_tool = GIMP_PAINT_SELECT_TOOL (tool);
+ GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);
+
+ static guint32 last_time = 0;
+
+ GIMP_TOOL_CLASS (parent_class)->motion (tool, coords, time, state, display);
+
+ /* don't let the events come in too fast, ignore below a delay of 100 ms */
+ if (time - last_time < 100)
+ return;
+
+ last_time = time;
+
+ if (state & GDK_BUTTON1_MASK)
+ {
+ gfloat distance = euclidean_distance (coords->x,
+ coords->y,
+ ps_tool->last_pos.x,
+ ps_tool->last_pos.y);
+
+ if (distance >= 2.f)
+ {
+ gimp_draw_tool_pause (draw_tool);
+ gimp_tool_control_halt (tool->control);
+ ps_tool->last_pos.x = coords->x;
+ ps_tool->last_pos.y = coords->y;
+
+ if (gimp_paint_select_tool_paint_scribble (ps_tool))
+ {
+ GimpPaintSelectOptions *options = GIMP_PAINT_SELECT_TOOL_GET_OPTIONS (ps_tool);
+ GTimer *timer = g_timer_new ();
+
+ if (options->mode == GIMP_PAINT_SELECT_MODE_ADD)
+ {
+ gegl_node_set (ps_tool->ps_node, "mode", 0, NULL);
+ }
+ else
+ {
+ gegl_node_set (ps_tool->ps_node, "mode", 1, NULL);
+ }
+
+ g_timer_start (timer);
+ gegl_node_process (ps_tool->render_node);
+ g_timer_stop (timer);
+ g_printerr ("processing graph takes %.3f s\n", g_timer_elapsed (timer, NULL));
+ g_timer_destroy (timer);
+
+ gimp_paint_select_tool_update_image_mask (ps_tool);
+ }
+
+ gimp_tool_control_activate (tool->control);
+ gimp_draw_tool_resume (draw_tool);
+ }
+ }
+}
+
+static void
+gimp_paint_select_tool_oper_update (GimpTool *tool,
+ const GimpCoords *coords,
+ GdkModifierType state,
+ gboolean proximity,
+ GimpDisplay *display)
+{
+ GimpPaintSelectTool *ps = GIMP_PAINT_SELECT_TOOL (tool);
+ GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);
+
+ if (proximity)
+ {
+ gimp_draw_tool_pause (draw_tool);
+
+ if (! tool->display || display == tool->display)
+ {
+ ps->last_pos.x = coords->x;
+ ps->last_pos.y = coords->y;
+ }
+
+ if (! gimp_draw_tool_is_active (draw_tool))
+ gimp_draw_tool_start (draw_tool, display);
+
+ gimp_draw_tool_resume (draw_tool);
+ }
+ else if (gimp_draw_tool_is_active (draw_tool))
+ {
+ gimp_draw_tool_stop (draw_tool);
+ }
+}
+
+static void
+gimp_paint_select_tool_draw (GimpDrawTool *draw_tool)
+{
+ GimpPaintSelectTool *paint_select = GIMP_PAINT_SELECT_TOOL (draw_tool);
+ GimpPaintSelectOptions *options = GIMP_PAINT_SELECT_TOOL_GET_OPTIONS (paint_select);
+ gint size = options->stroke_width;
+
+ gimp_draw_tool_add_arc (draw_tool,
+ FALSE,
+ paint_select->last_pos.x - (size / 2.0),
+ paint_select->last_pos.y - (size / 2.0),
+ size, size,
+ 0.0, (2.0 * G_PI));
+}
+
+static void
+gimp_paint_select_tool_options_notify (GimpTool *tool,
+ GimpToolOptions *options,
+ const GParamSpec *pspec)
+{
+ GimpPaintSelectTool *ps_tool = GIMP_PAINT_SELECT_TOOL (tool);
+
+ if (! tool->display)
+ return;
+
+ if (! strcmp (pspec->name, "stroke-width") && ps_tool->scribble)
+ {
+ g_object_unref (ps_tool->scribble);
+ ps_tool->scribble = NULL;
+ }
+}
+
+static void
+gimp_paint_select_tool_halt (GimpPaintSelectTool *ps_tool)
+{
+ GimpTool *tool = GIMP_TOOL (ps_tool);
+
+ g_clear_object (&ps_tool->trimap);
+ g_clear_object (&ps_tool->result_mask);
+ g_clear_object (&ps_tool->graph);
+ g_clear_object (&ps_tool->scribble);
+
+ ps_tool->drawable = NULL;
+ ps_tool->render_node = NULL;
+ ps_tool->ps_node = NULL;
+
+ ps_tool->image_mask = NULL;
+
+ if (tool->display)
+ gimp_image_flush (gimp_display_get_image (tool->display));
+
+ tool->display = NULL;
+ g_list_free (tool->drawables);
+ tool->drawables = NULL;
+}
+
+static void
+gimp_paint_select_tool_update_image_mask (GimpPaintSelectTool *ps_tool)
+{
+ GimpTool *tool = GIMP_TOOL (ps_tool);
+
+ if (tool->display)
+ {
+ GimpImage *image = gimp_display_get_image (tool->display);
+
+ gimp_channel_select_buffer (gimp_image_get_mask (image),
+ C_("command", "Paint Select"),
+ ps_tool->result_mask,
+ 0, /* x offset */
+ 0, /* y offset */
+ GIMP_CHANNEL_OP_REPLACE,
+ FALSE,
+ 0,
+ 0);
+ gimp_image_flush (image);
+ }
+
+ g_clear_object (&ps_tool->result_mask);
+}
+
+static void
+gimp_paint_select_tool_init_buffers (GimpPaintSelectTool *ps_tool,
+ GimpImage *image,
+ GimpDrawable *drawable)
+{
+ GimpChannel *channel;
+ GeglColor *grey = gegl_color_new ("#888");
+
+ g_return_if_fail (ps_tool->result_mask == NULL);
+ g_return_if_fail (ps_tool->trimap == NULL);
+ g_return_if_fail (ps_tool->drawable == NULL);
+
+ ps_tool->drawable = gimp_drawable_get_buffer (drawable);
+
+ channel = gimp_image_get_mask (image);
+ ps_tool->image_mask = gimp_drawable_get_buffer (GIMP_DRAWABLE (channel));
+ ps_tool->trimap = gegl_buffer_new (gegl_buffer_get_extent (ps_tool->image_mask),
+ babl_format ("Y float"));
+ gegl_buffer_set_color (ps_tool->trimap, NULL, grey);
+
+ g_object_unref (grey);
+}
+
+static void
+gimp_paint_select_tool_init_scribble (GimpPaintSelectTool *ps_tool)
+{
+ GimpPaintSelectOptions *options = GIMP_PAINT_SELECT_TOOL_GET_OPTIONS (ps_tool);
+
+ GimpScanConvert *scan_convert;
+ GimpVector2 points[2];
+ gint size = options->stroke_width;
+ gint radius = size / 2;
+ GeglRectangle square = {0, 0, size, size};
+
+ if (ps_tool->scribble)
+ g_object_unref (ps_tool->scribble);
+
+ ps_tool->scribble = gegl_buffer_linear_new (&square, babl_format ("Y float"));
+
+ points[0].x = points[1].x = radius;
+ points[0].y = points[1].y = radius;
+ points[1].x += 0.01;
+ points[1].y += 0.01;
+
+ scan_convert = gimp_scan_convert_new ();
+ gimp_scan_convert_add_polyline (scan_convert, 2, points, FALSE);
+ gimp_scan_convert_stroke (scan_convert, size,
+ GIMP_JOIN_ROUND, GIMP_CAP_ROUND, 10.0,
+ 0.0, NULL);
+ gimp_scan_convert_compose (scan_convert, ps_tool->scribble, 0, 0);
+ gimp_scan_convert_free (scan_convert);
+}
+
+static gboolean
+gimp_paint_select_tool_paint_scribble (GimpPaintSelectTool *ps_tool)
+{
+ GimpPaintSelectOptions *options = GIMP_PAINT_SELECT_TOOL_GET_OPTIONS (ps_tool);
+
+ gint size = options->stroke_width;
+ gint radius = size / 2;
+ GeglRectangle square = {0, 0, size, size};
+
+ GeglBufferIterator *iter;
+ gfloat scribble_value;
+ gboolean overlap = FALSE;
+
+ if (! ps_tool->scribble)
+ {
+ gimp_paint_select_tool_init_scribble (ps_tool);
+ }
+
+ /* add the scribble to the trimap buffer and check the image mask to see if
+ an optimization should be triggered.
+ */
+
+ if (options->mode == GIMP_PAINT_SELECT_MODE_ADD)
+ {
+ scribble_value = 1.f;
+ }
+ else
+ {
+ scribble_value = 0.f;
+ }
+
+ iter = gegl_buffer_iterator_new (ps_tool->scribble, NULL, 0,
+ babl_format ("Y float"),
+ GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 3);
+
+ square = *gegl_buffer_get_extent (ps_tool->scribble);
+ square.x = ps_tool->last_pos.x - radius;
+ square.y = ps_tool->last_pos.y - radius;
+
+ gegl_buffer_iterator_add (iter, ps_tool->trimap, &square, 0,
+ babl_format ("Y float"),
+ GEGL_ACCESS_READWRITE, GEGL_ABYSS_NONE);
+
+ gegl_buffer_iterator_add (iter, ps_tool->image_mask, &square, 0,
+ babl_format ("Y float"),
+ GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
+
+ while (gegl_buffer_iterator_next (iter))
+ {
+ gfloat *scribble_pix = iter->items[0].data;
+ gfloat *trimap_pix = iter->items[1].data;
+ gfloat *mask_pix = iter->items[2].data;
+ gint n_pixels = iter->length;
+
+ while (n_pixels--)
+ {
+ if (*scribble_pix)
+ {
+ *trimap_pix = scribble_value;
+
+ if (*mask_pix != scribble_value)
+ overlap = TRUE;
+ }
+
+ scribble_pix++;
+ trimap_pix++;
+ mask_pix++;
+ }
+ }
+
+ return overlap;
+}
+
+static void
+gimp_paint_select_tool_create_graph (GimpPaintSelectTool *ps_tool)
+{
+ GimpTool *tool = GIMP_TOOL (ps_tool);
+ GimpImage *image = gimp_display_get_image (tool->display);
+ GimpChannel *channel = gimp_image_get_mask (image);
+ GeglNode *t; /* trimap */
+ GeglNode *m; /* mask */
+ GeglNode *d; /* drawable */
+
+ ps_tool->graph = gegl_node_new ();
+
+ m = gegl_node_new_child (ps_tool->graph,
+ "operation", "gegl:buffer-source",
+ "buffer", gimp_drawable_get_buffer (GIMP_DRAWABLE(channel)),
+ NULL);
+ d = gegl_node_new_child (ps_tool->graph,
+ "operation", "gegl:buffer-source",
+ "buffer", ps_tool->drawable,
+ NULL);
+
+ t = gegl_node_new_child (ps_tool->graph,
+ "operation", "gegl:buffer-source",
+ "buffer", ps_tool->trimap,
+ NULL);
+
+ ps_tool->ps_node = gegl_node_new_child (ps_tool->graph,
+ "operation", "gegl:paint-select",
+ NULL);
+
+ ps_tool->render_node = gegl_node_new_child (ps_tool->graph,
+ "operation", "gegl:buffer-sink",
+ "buffer", &ps_tool->result_mask,
+ NULL);
+
+ gegl_node_link_many (m, ps_tool->ps_node, ps_tool->render_node, NULL);
+ gegl_node_connect_to (d, "output", ps_tool->ps_node, "aux");
+ gegl_node_connect_to (t, "output", ps_tool->ps_node, "aux2");
+}
+
+static gfloat
+euclidean_distance (gint x1,
+ gint y1,
+ gint x2,
+ gint y2)
+{
+ return sqrtf ((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
+}
diff --git a/app/tools/gimppaintselecttool.h b/app/tools/gimppaintselecttool.h
new file mode 100644
index 0000000000..ccd7cce52d
--- /dev/null
+++ b/app/tools/gimppaintselecttool.h
@@ -0,0 +1,67 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GIMP_PAINT_SELECT_TOOL_H__
+#define __GIMP_PAINT_SELECT_TOOL_H__
+
+
+#include "gimpdrawtool.h"
+
+
+#define GIMP_TYPE_PAINT_SELECT_TOOL (gimp_paint_select_tool_get_type ())
+#define GIMP_PAINT_SELECT_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
GIMP_TYPE_PAINT_SELECT_TOOL, GimpPaintSelectTool))
+#define GIMP_PAINT_SELECT_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),
GIMP_TYPE_PAINT_SELECT_TOOL, GimpPaintSelectToolClass))
+#define GIMP_IS_PAINT_SELECT_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),
GIMP_TYPE_PAINT_SELECT_TOOL))
+#define GIMP_IS_PAINT_SELECT_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
GIMP_TYPE_PAINT_SELECT_TOOL))
+#define GIMP_PAINT_SELECT_TOOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
GIMP_TYPE_PAINT_SELECT_TOOL, GimpPaintSelectToolClass))
+
+#define GIMP_PAINT_SELECT_TOOL_GET_OPTIONS(t) (GIMP_PAINT_SELECT_OPTIONS (gimp_tool_get_options (GIMP_TOOL
(t))))
+
+
+typedef struct _GimpPaintSelectTool GimpPaintSelectTool;
+typedef struct _GimpPaintSelectToolClass GimpPaintSelectToolClass;
+
+struct _GimpPaintSelectTool
+{
+ GimpDrawTool parent_instance;
+
+ GeglBuffer *trimap;
+ GeglBuffer *image_mask;
+ GeglBuffer *result_mask;
+ GeglBuffer *drawable;
+ GeglBuffer *scribble;
+
+ GeglNode *graph;
+ GeglNode *ps_node;
+ GeglNode *render_node;
+
+ GimpVector2 last_pos;
+};
+
+struct _GimpPaintSelectToolClass
+{
+ GimpDrawToolClass parent_class;
+};
+
+
+void gimp_paint_select_tool_register (GimpToolRegisterCallback callback,
+ gpointer data);
+
+GType gimp_paint_select_tool_get_type (void) G_GNUC_CONST;
+
+
+#endif /* __GIMP_PAINT_SELECT_TOOL_H__ */
diff --git a/app/tools/meson.build b/app/tools/meson.build
index 0c08b97c42..9627bb924e 100644
--- a/app/tools/meson.build
+++ b/app/tools/meson.build
@@ -84,6 +84,8 @@ libapptools_sources = [
'gimpoperationtool.c',
'gimppaintbrushtool.c',
'gimppaintoptions-gui.c',
+ 'gimppaintselectoptions.c',
+ 'gimppaintselecttool.c',
'gimppainttool-paint.c',
'gimppainttool.c',
'gimppenciltool.c',
diff --git a/app/tools/tools-enums.c b/app/tools/tools-enums.c
index 5e637e97e0..ee695858b8 100644
--- a/app/tools/tools-enums.c
+++ b/app/tools/tools-enums.c
@@ -337,6 +337,23 @@ gimp_warp_behavior_get_type (void)
return type;
}
+GType
+gimp_paint_select_mode_get_type (void)
+{
+ static const GEnumValue values[] =
+ {
+ { GIMP_PAINT_SELECT_MODE_ADD, "GIMP_PAINT_SELECT_MODE_ADD", "add" },
+ { GIMP_PAINT_SELECT_MODE_SUBTRACT, "GIMP_PAINT_SELECT_MODE_SUBTRACT", "subtract" },
+ { 0, NULL, NULL }
+ };
+
+ static const GimpEnumDesc descs[] =
+ {
+ { GIMP_PAINT_SELECT_MODE_ADD, NC_("paint-select-mode", "Add to selection"), NULL },
+ { GIMP_PAINT_SELECT_MODE_SUBTRACT, NC_("paint-select-mode", "Subtract from selection"), NULL },
+ { 0, NULL, NULL }
+};
+
/* Generated data ends here */
diff --git a/app/tools/tools-enums.h b/app/tools/tools-enums.h
index f994bc15bd..a7dc3167b6 100644
--- a/app/tools/tools-enums.h
+++ b/app/tools/tools-enums.h
@@ -166,6 +166,16 @@ typedef enum
} GimpWarpBehavior;
+#define GIMP_TYPE_PAINT_SELECT_MODE (gimp_paint_select_mode_get_type ())
+
+GType gimp_paint_select_mode_get_type (void) G_GNUC_CONST;
+
+typedef enum
+{
+ GIMP_PAINT_SELECT_MODE_ADD, /*< desc="Add to selection" >*/
+ GIMP_PAINT_SELECT_MODE_SUBTRACT, /*< desc="Subtract from selection" >*/
+} GimpPaintSelectMode;
+
/*
* non-registered enums; register them if needed
*/
diff --git a/icons/Color/16/gimp-tool-paint-select.png b/icons/Color/16/gimp-tool-paint-select.png
new file mode 100644
index 0000000000..867996bac4
Binary files /dev/null and b/icons/Color/16/gimp-tool-paint-select.png differ
diff --git a/icons/Color/24/gimp-tool-paint-select.png b/icons/Color/24/gimp-tool-paint-select.png
new file mode 100644
index 0000000000..bb47ff6ff7
Binary files /dev/null and b/icons/Color/24/gimp-tool-paint-select.png differ
diff --git a/icons/Color/24/gimp-tool-paint-select.svg b/icons/Color/24/gimp-tool-paint-select.svg
new file mode 100644
index 0000000000..1d2a5dc0b4
--- /dev/null
+++ b/icons/Color/24/gimp-tool-paint-select.svg
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="24"
+ height="24"
+ viewBox="0 0 24 24"
+ id="svg30571"
+ version="1.1"
+ inkscape:version="0.91+devel r"
+ sodipodi:docname="gimp-tool-blur-24.svg"
+ inkscape:export-filename="/home/klaus/Bilder/icons/Symbolic/hicolor/24x24/apps/gimp-channel.png"
+ inkscape:export-xdpi="98.181816"
+ inkscape:export-ydpi="98.181816">
+ <defs
+ id="defs30573">
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6951"
+ id="linearGradient2979-31"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.87935,-0.07437292,0.07703828,0.848926,-18.417151,-18.747073)"
+ x1="28.058632"
+ y1="18.867767"
+ x2="33.436985"
+ y2="23.742767" />
+ <linearGradient
+ id="linearGradient6951">
+ <stop
+ style="stop-color:#6e3d09;stop-opacity:1;"
+ offset="0"
+ id="stop6953" />
+ <stop
+ id="stop6959"
+ offset="0.24242425"
+ style="stop-color:#ea8113;stop-opacity:1;" />
+ <stop
+ style="stop-color:#5c3307;stop-opacity:1;"
+ offset="0.62121212"
+ id="stop6961" />
+ <stop
+ style="stop-color:#e07c12;stop-opacity:1;"
+ offset="1"
+ id="stop6955" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6939"
+ id="linearGradient2975-75"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.356127,-0.219769,0.227645,1.309208,-32.05138,-32.311441)"
+ x1="19.394735"
+ y1="30.001331"
+ x2="23.109331"
+ y2="33.438831" />
+ <linearGradient
+ id="linearGradient6939">
+ <stop
+ style="stop-color:#bdbdbd;stop-opacity:1;"
+ offset="0"
+ id="stop6941" />
+ <stop
+ id="stop6947"
+ offset="0.33333334"
+ style="stop-color:#e2e2e2;stop-opacity:1;" />
+ <stop
+ style="stop-color:#a3a3a3;stop-opacity:1;"
+ offset="0.66666669"
+ id="stop6949" />
+ <stop
+ style="stop-color:#dddddd;stop-opacity:1;"
+ offset="1"
+ id="stop6943" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6963"
+ id="radialGradient2971"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.584317,0,0,0.549734,-12.035061,-8.383133)"
+ cx="15.415101"
+ cy="35.356506"
+ fx="15.415101"
+ fy="35.356506"
+ r="7.5791559" />
+ <linearGradient
+ id="linearGradient6963">
+ <stop
+ style="stop-color:#696969;stop-opacity:1;"
+ offset="0"
+ id="stop6965" />
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="1"
+ id="stop6967" />
+ </linearGradient>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="16"
+ inkscape:cx="-5.416016"
+ inkscape:cy="14.628924"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:snap-page="true"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:object-nodes="true"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:snap-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:snap-text-baseline="true"
+ showborder="false"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:snap-global="false">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4369" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata30576">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Klaus Staedtler</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1028.3622)">
+ <g
+ id="g4733">
+ <g
+ transform="matrix(0.72842778,0,0,0.75240082,10.103955,1039.3154)"
+ id="g4288">
+ <g
+ id="g891-37"
+ transform="matrix(0.186703,0,0,0.186703,-51.137271,27.041497)" />
+ <path
+
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient2979-31);fill-opacity:1;fill-rule:nonzero;stroke:#673907;stroke-width:1.00000048;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ d="m 1.880007,0.390614 6.166172,4.218273 c 5.776248,-6.5301 9.110705,-17.663007
9.110705,-17.663007 0.283343,-1.07141 -0.778668,-1.32072 -1.382605,-0.563567 0,0 -8.9019,7.384103
-13.894272,14.008301 z"
+ id="path6937-9"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ sodipodi:nodetypes="ccssc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccsc"
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ id="path7220-3"
+ d="m 2.906028,0.727447 4.203637,3.360672 c 6.3456,-7.19205 8.687017,-16.297389
8.687017,-16.297389 0,0 -7.406194,5.641032 -12.890654,12.936717 z"
+
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.33333333;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.99999988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ inkscape:connector-curvature="0" />
+ <path
+
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient2975-75);fill-opacity:1;fill-rule:nonzero;stroke:#888a85;stroke-width:1.0000006;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ d="M -2.531061,9.502156 0.955458,11.54026 7.987449,4.840791 C 7.03845,2.891301 3.875427,0.350218
1.332688,0.762284 Z"
+ id="path6935-1"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#radialGradient2971);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ d="m -12.498089,17.325227 c 12.009594,0.0849 14.031177,-0.03171 14.694027,-4.850339
0.542698,-3.94517 -6.498481,-5.648707 -8.88957,-1.235576 -1.930787,3.563572 -5.804457,6.085915
-5.804457,6.085915 z"
+ id="path6933-9"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ sodipodi:nodetypes="cssc"
+ inkscape:connector-curvature="0" />
+ <ellipse
+
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.52777782;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ id="path6971-5"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ cx="-3.2496638"
+ cy="11.638556"
+ rx="1.5320324"
+ ry="1.4790274" />
+ <path
+
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.00000107;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ d="M 2.832601,2.79379 -0.089332,8.294237"
+ id="path6985-0"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ ry="1.8554795"
+ rx="2.5547137"
+ y="1028.3622"
+ x="0"
+ height="24"
+ width="24"
+ id="rect4297"
+
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.30000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
/>
+ </g>
+ </g>
+</svg>
diff --git a/icons/Color/icon-list.mk b/icons/Color/icon-list.mk
index 6c9d2a0739..e4b8d43e2f 100644
--- a/icons/Color/icon-list.mk
+++ b/icons/Color/icon-list.mk
@@ -311,6 +311,7 @@ scalable_images = \
scalable/gimp-tool-offset.svg \
scalable/gimp-tool-options.svg \
scalable/gimp-tool-paintbrush.svg \
+ scalable/gimp-tool-paint-select.svg \
scalable/gimp-tool-path.svg \
scalable/gimp-tool-pencil.svg \
scalable/gimp-tool-perspective-clone.svg \
@@ -491,6 +492,7 @@ vector24_images = \
24/gimp-tool-offset.svg \
24/gimp-tool-options.svg \
24/gimp-tool-paintbrush.svg \
+ 24/gimp-tool-paint-select.svg \
24/gimp-tool-path.svg \
24/gimp-tool-pencil.svg \
24/gimp-tool-perspective.svg \
@@ -791,6 +793,7 @@ icons16_images = \
16/gimp-tool-offset.png \
16/gimp-tool-options.png \
16/gimp-tool-paintbrush.png \
+ 16/gimp-tool-paint-select.png \
16/gimp-tool-path.png \
16/gimp-tool-pencil.png \
16/gimp-tool-perspective-clone.png \
@@ -1006,6 +1009,7 @@ icons24_images = \
24/gimp-tool-n-point-deformation.png \
24/gimp-tool-offset.png \
24/gimp-tool-paintbrush.png \
+ 24/gimp-tool-paint-select.png \
24/gimp-tool-path.png \
24/gimp-tool-pencil.png \
24/gimp-tool-perspective-clone.png \
diff --git a/icons/Color/scalable/gimp-tool-paint-select.svg b/icons/Color/scalable/gimp-tool-paint-select.svg
new file mode 100644
index 0000000000..eee38bc7a9
--- /dev/null
+++ b/icons/Color/scalable/gimp-tool-paint-select.svg
@@ -0,0 +1,263 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ inkscape:export-ydpi="90.000000"
+ inkscape:export-xdpi="90.000000"
+ inkscape:export-filename="/home/jimmac/src/cvs/gnome/gimp/themes/Default/images/stock-layers-16.png"
+ width="16"
+ height="16"
+ id="svg11300"
+ sodipodi:version="0.32"
+ inkscape:version="0.91+devel r"
+ sodipodi:docname="gimp-tool-paintbrush.svg"
+ version="1.0"
+ viewBox="0 0 16 16">
+ <sodipodi:namedview
+ inkscape:cy="7.1741021"
+ inkscape:cx="1.3590445"
+ inkscape:zoom="16.269075"
+ inkscape:window-height="752"
+ inkscape:window-width="1440"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ borderopacity="0.17254902"
+ bordercolor="#666"
+ pagecolor="#ffffff"
+ id="base"
+ inkscape:showpageshadow="false"
+ showborder="true"
+ inkscape:window-x="480"
+ inkscape:window-y="290"
+ inkscape:current-layer="layer1"
+ width="16px"
+ height="16px"
+ showgrid="true"
+ inkscape:window-maximized="0"
+ inkscape:document-units="px">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4056" />
+ </sodipodi:namedview>
+ <defs
+ id="defs3">
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6951"
+ id="linearGradient2979-31"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.87935,-0.07437292,0.07703828,0.848926,-18.417151,-18.747073)"
+ x1="28.058632"
+ y1="18.867767"
+ x2="33.436985"
+ y2="23.742767" />
+ <linearGradient
+ id="linearGradient6951">
+ <stop
+ style="stop-color:#6e3d09;stop-opacity:1;"
+ offset="0"
+ id="stop6953" />
+ <stop
+ id="stop6959"
+ offset="0.24242425"
+ style="stop-color:#ea8113;stop-opacity:1;" />
+ <stop
+ style="stop-color:#5c3307;stop-opacity:1;"
+ offset="0.62121212"
+ id="stop6961" />
+ <stop
+ style="stop-color:#e07c12;stop-opacity:1;"
+ offset="1"
+ id="stop6955" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6939"
+ id="linearGradient2975-75"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.356127,-0.219769,0.227645,1.309208,-32.05138,-32.311441)"
+ x1="19.394735"
+ y1="30.001331"
+ x2="23.109331"
+ y2="33.438831" />
+ <linearGradient
+ id="linearGradient6939">
+ <stop
+ style="stop-color:#bdbdbd;stop-opacity:1;"
+ offset="0"
+ id="stop6941" />
+ <stop
+ id="stop6947"
+ offset="0.33333334"
+ style="stop-color:#e2e2e2;stop-opacity:1;" />
+ <stop
+ style="stop-color:#a3a3a3;stop-opacity:1;"
+ offset="0.66666669"
+ id="stop6949" />
+ <stop
+ style="stop-color:#dddddd;stop-opacity:1;"
+ offset="1"
+ id="stop6943" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6963"
+ id="radialGradient2971"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.584317,0,0,0.549734,-12.035061,-8.383133)"
+ cx="15.415101"
+ cy="35.356506"
+ fx="15.415101"
+ fy="35.356506"
+ r="7.5791559" />
+ <linearGradient
+ id="linearGradient6963">
+ <stop
+ style="stop-color:#696969;stop-opacity:1;"
+ offset="0"
+ id="stop6965" />
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="1"
+ id="stop6967" />
+ </linearGradient>
+ </defs>
+ <sodipodi:namedview
+ stroke="#ef2929"
+ fill="#eeeeec"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="0.25490196"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1"
+ inkscape:cx="-14.198652"
+ inkscape:cy="-5.1663457"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:showpageshadow="false"
+ inkscape:window-width="872"
+ inkscape:window-height="659"
+ inkscape:window-x="403"
+ inkscape:window-y="296"
+ width="32px"
+ height="32px"
+ id="namedview73" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://jimmac.musichall.cz</dc:source>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
+ <dc:title />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Reproduction" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Distribution" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Notice" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Attribution" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <g
+ id="g11310">
+ <g
+ transform="matrix(0.4966552,0,0,0.50160171,6.7072409,7.3021503)"
+ id="g4288">
+ <g
+ id="g891-37"
+ transform="matrix(0.186703,0,0,0.186703,-51.137271,27.041497)" />
+ <path
+
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient2979-31);fill-opacity:1;fill-rule:nonzero;stroke:#673907;stroke-width:1.00000048;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ d="m 1.880007,0.390614 6.166172,4.218273 c 5.776248,-6.5301 9.110705,-17.663007
9.110705,-17.663007 0.283343,-1.07141 -0.778668,-1.32072 -1.382605,-0.563567 0,0 -8.9019,7.384103
-13.894272,14.008301 z"
+ id="path6937-9"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ sodipodi:nodetypes="ccssc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccsc"
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ id="path7220-3"
+ d="m 2.906028,0.727447 4.203637,3.360672 c 6.3456,-7.19205 8.687017,-16.297389
8.687017,-16.297389 0,0 -7.406194,5.641032 -12.890654,12.936717 z"
+
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.33333333;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.99999988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ inkscape:connector-curvature="0" />
+ <path
+
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient2975-75);fill-opacity:1;fill-rule:nonzero;stroke:#888a85;stroke-width:1.0000006;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ d="M -2.531061,9.502156 0.955458,11.54026 7.987449,4.840791 C 7.03845,2.891301 3.875427,0.350218
1.332688,0.762284 Z"
+ id="path6935-1"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#radialGradient2971);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ d="m -12.498089,17.325227 c 12.009594,0.0849 14.031177,-0.03171 14.694027,-4.850339
0.542698,-3.94517 -6.498481,-5.648707 -8.88957,-1.235576 -1.930787,3.563572 -5.804457,6.085915
-5.804457,6.085915 z"
+ id="path6933-9"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ sodipodi:nodetypes="cssc"
+ inkscape:connector-curvature="0" />
+ <ellipse
+
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.52777782;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ id="path6971-5"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ cx="-3.2496638"
+ cy="11.638556"
+ rx="1.5320324"
+ ry="1.4790274" />
+ <path
+
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.00000107;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ d="M 2.832601,2.79379 -0.089332,8.294237"
+ id="path6985-0"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ ry="1.2369863"
+ rx="1.7031425"
+ y="0"
+ x="0"
+ height="16"
+ width="16"
+ id="rect4297"
+
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
/>
+ </g>
+ </g>
+</svg>
diff --git a/icons/Symbolic/24/gimp-tool-paint-select-symbolic.svg
b/icons/Symbolic/24/gimp-tool-paint-select-symbolic.svg
new file mode 100644
index 0000000000..20f177ec89
--- /dev/null
+++ b/icons/Symbolic/24/gimp-tool-paint-select-symbolic.svg
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="24"
+ height="24"
+ viewBox="0 0 24 24"
+ id="svg30571"
+ version="1.1"
+ inkscape:version="0.91+devel r"
+ sodipodi:docname="gimp-tool-paintbrush-24.svg"
+ inkscape:export-filename="/home/klaus/Bilder/icons/Symbolic/hicolor/24x24/apps/gimp-channel.png"
+ inkscape:export-xdpi="98.181816"
+ inkscape:export-ydpi="98.181816">
+ <defs
+ id="defs30573">
+ <linearGradient
+ id="linearGradient19282-4"
+ osb:paint="solid"
+ gradientTransform="matrix(0.34682586,0,0,0.30620888,-482.61525,330.965)">
+ <stop
+ style="stop-color:#bebebe;stop-opacity:1;"
+ offset="0"
+ id="stop19284-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19282-4"
+ id="linearGradient10384"
+ x1="-28.5"
+ y1="25.737938"
+ x2="-20.499094"
+ y2="25.737938"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient19282-4"
+ id="linearGradient10378"
+ x1="67.260277"
+ y1="183.23083"
+ x2="76.514008"
+ y2="183.23083"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.5129026,0,0,1.5338414,-92.758245,756.44128)" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="16"
+ inkscape:cx="-7.400391"
+ inkscape:cy="14.628924"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:snap-page="true"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:object-nodes="true"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:snap-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:snap-text-baseline="true"
+ showborder="false"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:snap-global="false">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4369" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata30576">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Klaus Staedtler</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1028.3622)">
+ <g
+ id="g9134">
+ <g
+ style="fill:#bebebe;fill-opacity:1;stroke:none"
+ transform="matrix(1.3748443,0,0,1.4226056,40.183063,1011.7472)"
+ id="g9272">
+ <path
+ style="fill:url(#linearGradient10384);fill-opacity:1;stroke:none"
+ sodipodi:nodetypes="cssac"
+ id="path9274"
+ d="m -28.5,27.5711 c 3.111145,0.0011 2.79359,-3.323359 4.304166,-4.248979 1.750479,-1.072622
3.284496,0.256475 3.590759,1.350292 0.386445,1.380184 -0.337829,2.508685 -1.300323,3.118949
-1.846361,1.170674 -6.300039,0.898712 -6.594602,-0.220262 z"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ id="path9264"
+ d="m 22.852515,1030.0121 c 0.466524,-1.0212 -0.247692,-1.4129 -1.108083,-0.5471 -6.049703,6.0877
-7.086286,5.9984 -12.744432,13.8972 1.518274,0.057 2.823067,1.0638 3.5,2.5 6.698265,-7.3202 7.451812,-11.1222
10.352515,-15.8501 z"
+ style="fill:url(#linearGradient10378);fill-opacity:1;stroke:none;stroke-width:1.52333605"
+ sodipodi:nodetypes="csccc" />
+ </g>
+ </g>
+</svg>
diff --git a/icons/Symbolic/icon-list.mk b/icons/Symbolic/icon-list.mk
index 463aade8bf..a3bb090f90 100644
--- a/icons/Symbolic/icon-list.mk
+++ b/icons/Symbolic/icon-list.mk
@@ -311,6 +311,7 @@ scalable_images = \
scalable/gimp-tool-offset-symbolic.svg \
scalable/gimp-tool-options-symbolic.svg \
scalable/gimp-tool-paintbrush-symbolic.svg \
+ scalable/gimp-tool-paint-select-symbolic.svg \
scalable/gimp-tool-path-symbolic.svg \
scalable/gimp-tool-pencil-symbolic.svg \
scalable/gimp-tool-perspective-clone-symbolic.svg \
@@ -491,6 +492,7 @@ vector24_images = \
24/gimp-tool-offset-symbolic.svg \
24/gimp-tool-options-symbolic.svg \
24/gimp-tool-paintbrush-symbolic.svg \
+ 24/gimp-tool-paint-select-symbolic.svg \
24/gimp-tool-path-symbolic.svg \
24/gimp-tool-pencil-symbolic.svg \
24/gimp-tool-perspective-symbolic.svg \
diff --git a/icons/Symbolic/scalable/gimp-tool-paint-select-symbolic.svg
b/icons/Symbolic/scalable/gimp-tool-paint-select-symbolic.svg
new file mode 100644
index 0000000000..efc55b029d
--- /dev/null
+++ b/icons/Symbolic/scalable/gimp-tool-paint-select-symbolic.svg
@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ viewBox="0 0 16.000001 15.999992"
+ id="svg7384"
+ height="15.999992"
+ width="16.000002"
+ version="1.1"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="gimp-tool-paintbrush.svg">
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="640"
+ inkscape:window-height="480"
+ id="namedview1509"
+ showgrid="false"
+ inkscape:zoom="14.750007"
+ inkscape:cx="-155.21063"
+ inkscape:cy="-46.369966"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="svg7384" />
+ <metadata
+ id="metadata90">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Barbara Muraus, Jakub Steiner, Klaus Staedtler</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ <dc:description>Images originally created as the "Art Libre" icon set. Extended and
adopted for GIMP</dc:description>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs7386">
+ <linearGradient
+ osb:paint="solid"
+ id="linearGradient8074">
+ <stop
+ id="stop8072"
+ offset="0"
+ style="stop-color:#be00be;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ osb:paint="solid"
+ id="linearGradient7561">
+ <stop
+ id="stop7558"
+ offset="0"
+ style="stop-color:#a5a5a5;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ osb:paint="solid"
+ id="linearGradient7548">
+ <stop
+ id="stop7546"
+ offset="0"
+ style="stop-color:#ebebeb;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ osb:paint="solid"
+ id="linearGradient7542">
+ <stop
+ id="stop7538"
+ offset="0"
+ style="stop-color:#c9c9c9;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="matrix(0,-735328.32,170712.69,0,2464326300,577972450)"
+ osb:paint="solid"
+ id="linearGradient19282">
+ <stop
+ id="stop19284"
+ offset="0"
+ style="stop-color:#b4b4b4;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="matrix(0.34682586,0,0,0.30620888,-93.351872,584.01677)"
+ osb:paint="solid"
+ id="linearGradient19282-4">
+ <stop
+ id="stop19284-0"
+ offset="0"
+ style="stop-color:#bebebe;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="translate(224.21083,191.51971)"
+ gradientUnits="userSpaceOnUse"
+ y2="183.23083"
+ x2="76.514008"
+ y1="183.23083"
+ x1="67.260277"
+ id="linearGradient10378"
+ xlink:href="#linearGradient19282-4" />
+ <linearGradient
+ gradientTransform="translate(256.35128,214.76037)"
+ gradientUnits="userSpaceOnUse"
+ y2="25.737938"
+ x2="-20.499094"
+ y1="25.737938"
+ x1="-28.5"
+ id="linearGradient10384"
+ xlink:href="#linearGradient19282-4" />
+ </defs>
+ <g
+ transform="translate(66.422852,-256.0432)"
+ style="display:inline"
+ id="tools">
+ <g
+ transform="translate(-127.42305,79.021454)"
+ id="gimp-tool-paintbrush"
+ style="display:inline">
+ <g
+ id="g9272"
+ transform="matrix(0.8746234,0,0,0.89178327,86.926967,167.56161)"
+ style="fill:#bebebe;fill-opacity:1;stroke:none">
+ <path
+ d="m -28.5,27.5711 c 3.111145,0.0011 2.79359,-3.323359 4.304166,-4.248979 1.750479,-1.072622
3.284496,0.256475 3.590759,1.350292 0.386445,1.380184 -0.337829,2.508685 -1.300323,3.118949
-1.846361,1.170674 -6.300039,0.898712 -6.594602,-0.220262 z"
+ id="path9274"
+ style="fill:url(#linearGradient10384);fill-opacity:1;stroke:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:url(#linearGradient10378);fill-opacity:1;stroke:none"
+ d="m 76.416523,178.35668 c 0.308363,-0.6658 -0.16372,-0.92113 -0.732422,-0.35668 -3.998739,3.96884
-4.683901,4 -8.423828,9.14967 1.00355,0.0377 1.86506,0.68644 2.3125,1.62279 4.427427,-4.77246
4.92644,-7.33336 6.84375,-10.41578 z"
+ id="path9264"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+</svg>
diff --git a/libgimpwidgets/gimpicons.h b/libgimpwidgets/gimpicons.h
index e47fb7acc5..92415965fe 100644
--- a/libgimpwidgets/gimpicons.h
+++ b/libgimpwidgets/gimpicons.h
@@ -374,6 +374,7 @@ G_BEGIN_DECLS
#define GIMP_ICON_TOOL_N_POINT_DEFORMATION "gimp-tool-n-point-deformation"
#define GIMP_ICON_TOOL_OFFSET "gimp-tool-offset"
#define GIMP_ICON_TOOL_PAINTBRUSH "gimp-tool-paintbrush"
+#define GIMP_ICON_TOOL_PAINT_SELECT "gimp-tool-paint-select"
#define GIMP_ICON_TOOL_PATH "gimp-tool-path"
#define GIMP_ICON_TOOL_PENCIL "gimp-tool-pencil"
#define GIMP_ICON_TOOL_PERSPECTIVE "gimp-tool-perspective"
diff --git a/menus/image-menu.xml.in b/menus/image-menu.xml.in
index e0e320b1cb..6f61854b81 100644
--- a/menus/image-menu.xml.in
+++ b/menus/image-menu.xml.in
@@ -643,6 +643,7 @@
<menuitem action="tools-fuzzy-select" />
<menuitem action="tools-by-color-select" />
<menuitem action="tools-iscissors" />
+ <menuitem action="tools-paint-select" />
</menu>
<menu action="tools-paint-menu" name="Paint Tools">
<menuitem action="tools-bucket-fill" />
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]