app: port the foreground select tool to the GEGL matting ops

This is work in progress and needs the fixed GEGL ops too.
This commit is contained in:
Miroslav Talasek 2013-05-08 00:00:48 +02:00 committed by Michael Natterer
parent b893993e7b
commit 1cd1541b2d
4 changed files with 566 additions and 511 deletions

View File

@ -26,10 +26,9 @@
#include "tools-types.h"
#if 0
#include "base/siox.h"
#endif
#include "widgets/gimppropwidgets.h"
#include "widgets/gimpspinscale.h"
#include "widgets/gimpwidgets-constructors.h"
#include "widgets/gimpwidgets-utils.h"
#include "gimpforegroundselectoptions.h"
@ -38,22 +37,26 @@
#include "gimp-intl.h"
/*
* for matting-global: iterations int
* for matting-levin: levels int, active levels int
*/
enum
{
PROP_0,
PROP_ANTIALIAS,
PROP_CONTIGUOUS,
PROP_BACKGROUND,
PROP_DRAW_MODE,
PROP_STROKE_WIDTH,
PROP_SMOOTHNESS,
PROP_MASK_COLOR,
PROP_EXPANDED,
PROP_SENSITIVITY_L,
PROP_SENSITIVITY_A,
PROP_SENSITIVITY_B
PROP_ENGINE,
PROP_ITERATIONS,
PROP_LEVELS,
PROP_ACTIVE_LEVELS
};
static void gimp_foreground_select_options_set_property (GObject *object,
guint property_id,
const GValue *value,
@ -63,6 +66,14 @@ static void gimp_foreground_select_options_get_property (GObject *object,
GValue *value,
GParamSpec *pspec);
static void gimp_foreground_select_options_gui_reset_stroke_width (GtkWidget *button,
GimpToolOptions *tool_options);
static void gimp_foreground_select_notify_engine (GimpToolOptions *tool_options,
GParamSpec *pspec,
GtkWidget *table);
G_DEFINE_TYPE (GimpForegroundSelectOptions, gimp_foreground_select_options,
GIMP_TYPE_SELECTION_OPTIONS)
@ -77,41 +88,28 @@ gimp_foreground_select_options_class_init (GimpForegroundSelectOptionsClass *kla
object_class->get_property = gimp_foreground_select_options_get_property;
/* override the antialias default value from GimpSelectionOptions */
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_ANTIALIAS,
"antialias",
N_("Smooth edges"),
FALSE,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_CONTIGUOUS,
"contiguous",
N_("Select a single contiguous area"),
TRUE,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_BACKGROUND,
"background",
GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_DRAW_MODE,
"draw-mode",
N_("Paint over areas to mark color values for "
"inclusion or exclusion from selection"),
FALSE,
GIMP_TYPE_MATTING_DRAW_MODE,
GIMP_MATTING_DRAW_MODE_FOREGROUND,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_ENGINE,
"engine",
N_("Matting engine to use"),
GIMP_TYPE_MATTING_ENGINE,
GIMP_MATTING_ENGINE_MATTING_GLOBAL,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_INSTALL_PROP_INT (object_class, PROP_STROKE_WIDTH,
"stroke-width",
N_("Size of the brush used for refinements"),
1, 80, 18,
1, 6000, 10,
GIMP_PARAM_STATIC_STRINGS);
#if 0
GIMP_CONFIG_INSTALL_PROP_INT (object_class, PROP_SMOOTHNESS,
"smoothness",
N_("Smaller values give a more accurate "
"selection border but may introduce holes "
"in the selection"),
0, 8, SIOX_DEFAULT_SMOOTHNESS,
GIMP_PARAM_STATIC_STRINGS);
#endif
GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_MASK_COLOR,
"mask-color",
N_("Color of selection preview mask"),
@ -119,30 +117,21 @@ gimp_foreground_select_options_class_init (GimpForegroundSelectOptionsClass *kla
GIMP_BLUE_CHANNEL,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_EXPANDED,
"expanded", NULL,
FALSE,
0);
#if 0
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_SENSITIVITY_L,
"sensitivity-l",
N_("Sensitivity for brightness component"),
0.0, 10.0, SIOX_DEFAULT_SENSITIVITY_L,
GIMP_CONFIG_INSTALL_PROP_INT (object_class, PROP_LEVELS,
"levels",
N_("Parameter for matting-levin"),
1, 10, 2,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_SENSITIVITY_A,
"sensitivity-a",
N_("Sensitivity for red/green component"),
0.0, 10.0, SIOX_DEFAULT_SENSITIVITY_A,
GIMP_CONFIG_INSTALL_PROP_INT (object_class, PROP_ACTIVE_LEVELS,
"active-levels",
N_("Parameter for matting-levin"),
1, 10, 2,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_SENSITIVITY_B,
"sensitivity-b",
N_("Sensitivity for yellow/blue component"),
0.0, 10.0, SIOX_DEFAULT_SENSITIVITY_B,
GIMP_CONFIG_INSTALL_PROP_INT (object_class, PROP_ITERATIONS,
"iterations",
N_("Parameter for matting-global"),
1, 10, 2,
GIMP_PARAM_STATIC_STRINGS);
#endif
}
static void
@ -160,44 +149,32 @@ gimp_foreground_select_options_set_property (GObject *object,
switch (property_id)
{
case PROP_ANTIALIAS:
GIMP_SELECTION_OPTIONS (object)->antialias = g_value_get_boolean (value);
case PROP_DRAW_MODE:
options->draw_mode = g_value_get_enum (value);
break;
case PROP_CONTIGUOUS:
options->contiguous = g_value_get_boolean (value);
break;
case PROP_BACKGROUND:
options->background = g_value_get_boolean (value);
case PROP_ENGINE:
options->engine = g_value_get_enum (value);
break;
case PROP_STROKE_WIDTH:
options->stroke_width = g_value_get_int (value);
break;
case PROP_SMOOTHNESS:
options->smoothness = g_value_get_int (value);
break;
case PROP_MASK_COLOR:
options->mask_color = g_value_get_enum (value);
break;
case PROP_EXPANDED:
options->expanded = g_value_get_boolean (value);
case PROP_LEVELS:
options->levels = g_value_get_int (value);
break;
case PROP_SENSITIVITY_L:
options->sensitivity[0] = g_value_get_double (value);
case PROP_ACTIVE_LEVELS:
options->active_levels = g_value_get_int (value);
break;
case PROP_SENSITIVITY_A:
options->sensitivity[1] = g_value_get_double (value);
break;
case PROP_SENSITIVITY_B:
options->sensitivity[2] = g_value_get_double (value);
case PROP_ITERATIONS:
options->iterations = g_value_get_int (value);
break;
default:
@ -216,44 +193,33 @@ gimp_foreground_select_options_get_property (GObject *object,
switch (property_id)
{
case PROP_ANTIALIAS:
g_value_set_boolean (value, GIMP_SELECTION_OPTIONS (object)->antialias);
case PROP_DRAW_MODE:
g_value_set_enum (value, options->draw_mode);
break;
case PROP_CONTIGUOUS:
g_value_set_boolean (value, options->contiguous);
break;
case PROP_BACKGROUND:
g_value_set_boolean (value, options->background);
case PROP_ENGINE:
g_value_set_enum (value, options->engine);
break;
case PROP_STROKE_WIDTH:
g_value_set_int (value, options->stroke_width);
break;
case PROP_SMOOTHNESS:
g_value_set_int (value, options->smoothness);
break;
case PROP_MASK_COLOR:
g_value_set_enum (value, options->mask_color);
break;
case PROP_EXPANDED:
g_value_set_boolean (value, options->expanded);
case PROP_LEVELS:
g_value_set_int (value, options->levels);
break;
case PROP_SENSITIVITY_L:
g_value_set_double (value, options->sensitivity[0]);
case PROP_ACTIVE_LEVELS:
g_value_set_int (value, options->active_levels);
break;
case PROP_SENSITIVITY_A:
g_value_set_double (value, options->sensitivity[1]);
break;
case PROP_SENSITIVITY_B:
g_value_set_double (value, options->sensitivity[2]);
case PROP_ITERATIONS:
g_value_set_int (value, options->iterations);
break;
default:
@ -271,116 +237,175 @@ gimp_foreground_select_options_gui (GimpToolOptions *tool_options)
GtkWidget *button;
GtkWidget *frame;
GtkWidget *scale;
GtkWidget *label;
GtkWidget *menu;
GtkWidget *inner_frame;
GtkWidget *combo;
GtkWidget *table;
gchar *title;
gint row = 0;
GdkModifierType toggle_mask;
toggle_mask = gimp_get_toggle_behavior_mask ();
gtk_widget_set_sensitive (GIMP_SELECTION_OPTIONS (tool_options)->antialias_toggle,
FALSE);
/* single / multiple objects */
button = gimp_prop_check_button_new (config, "contiguous", _("Contiguous"));
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
/* foreground / background */
title = g_strdup_printf (_("Interactive refinement (%s)"),
gimp_get_mod_string (toggle_mask));
frame = gimp_prop_boolean_radio_frame_new (config, "background", title,
_("Mark background"),
_("Mark foreground"));
g_free (title);
GimpForegroundSelectOptions *options = GIMP_FOREGROUND_SELECT_OPTIONS (config);
frame = gimp_prop_enum_radio_frame_new (config, "draw-mode", _("Draw Mode"),
0,0);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
/* stroke width */
inner_frame = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_box_pack_start (GTK_BOX (gtk_bin_get_child (GTK_BIN (frame))),
inner_frame, FALSE, FALSE, 2);
gtk_widget_show (inner_frame);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_box_pack_start (GTK_BOX (inner_frame), hbox, 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);
label = gtk_label_new (_("Small brush"));
gimp_label_set_attributes (GTK_LABEL (label),
PANGO_ATTR_STYLE, PANGO_STYLE_ITALIC,
PANGO_ATTR_SCALE, PANGO_SCALE_SMALL,
-1);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
label = gtk_label_new (_("Large brush"));
gimp_label_set_attributes (GTK_LABEL (label),
PANGO_ATTR_STYLE, PANGO_STYLE_ITALIC,
PANGO_ATTR_SCALE, PANGO_SCALE_SMALL,
-1);
gtk_box_pack_end (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
scale = gimp_prop_hscale_new (config, "stroke-width", 1.0, 5.0, 0);
gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE);
gtk_box_pack_start (GTK_BOX (inner_frame), scale, FALSE, FALSE, 0);
/* stroke width */
scale = gimp_prop_spin_scale_new (config, "stroke-width",
_("Stroke width"),
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);
gtk_widget_show (scale);
/* smoothness */
table = gtk_table_new (2, 3, FALSE);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_table_set_col_spacings (GTK_TABLE (table), 2);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
gtk_widget_show (table);
button = gimp_stock_button_new (GIMP_STOCK_RESET, NULL);
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
gtk_image_set_from_stock (GTK_IMAGE (gtk_bin_get_child (GTK_BIN (button))),
GIMP_STOCK_RESET, GTK_ICON_SIZE_MENU);
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
#if 0
scale = gimp_prop_hscale_new (config, "smoothness", 0.1, 1.0, 0);
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_RIGHT);
gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
_("Smoothing:"), 0.0, 0.5, scale, 2, FALSE);
#endif
g_signal_connect (button, "clicked",
G_CALLBACK (gimp_foreground_select_options_gui_reset_stroke_width),
tool_options);
gimp_help_set_help_data (button,
_("Reset stroke width native size"), NULL);
/* mask color */
menu = gimp_prop_enum_combo_box_new (config, "mask-color",
GIMP_RED_CHANNEL, GIMP_BLUE_CHANNEL);
gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
_("Preview color:"), 0.0, 0.5, menu, 2, FALSE);
#if 0
/* granularity */
frame = gimp_prop_expander_new (config, "expanded", _("Color Sensitivity"));
frame = gimp_frame_new (_("Preview color:"));
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
inner_frame = gimp_frame_new ("<expander>");
gtk_container_add (GTK_CONTAINER (frame), inner_frame);
gtk_widget_show (inner_frame);
combo = gimp_prop_enum_combo_box_new (config, "mask-color",
GIMP_RED_CHANNEL, GIMP_GRAY_CHANNEL);
gtk_container_add (GTK_CONTAINER (frame), combo);
gtk_widget_show (combo);
/* engine */
frame = gimp_frame_new (_("Engine:"));
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
combo = gimp_prop_enum_combo_box_new (config, "engine", 0, 0);
gtk_container_add (GTK_CONTAINER (frame), combo);
gtk_widget_show (combo);
/* parameters */
table = gtk_table_new (3, 3, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 2);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_container_add (GTK_CONTAINER (inner_frame), table);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
gtk_widget_show (table);
gimp_prop_opacity_entry_new (config, "sensitivity-l",
GTK_TABLE (table), 0, row++, "L");
options->dynamic_widgets.levels = (GObject *)
gimp_prop_scale_entry_new (config, "levels",
GTK_TABLE (table), 0, row++,
"Levels", 1, 1, 0, FALSE, 0, 0);
gimp_prop_opacity_entry_new (config, "sensitivity-a",
GTK_TABLE (table), 0, row++, "a");
options->dynamic_widgets.active_levels = (GObject *)
gimp_prop_scale_entry_new (config, "active-levels",
GTK_TABLE (table), 0, row++,
"Act. Levels", 1, 1, 0, FALSE, 0, 0);
gimp_prop_opacity_entry_new (config, "sensitivity-b",
GTK_TABLE (table), 0, row++, "b");
#endif
options->dynamic_widgets.iterations = (GObject *)
gimp_prop_scale_entry_new (config, "iterations",
GTK_TABLE (table), 0, row++,
"Iterations", 1, 1, 0, FALSE, 0, 0);
g_signal_connect_object (config, "notify::engine",
G_CALLBACK (gimp_foreground_select_notify_engine),
NULL, 0);
gimp_foreground_select_notify_engine (tool_options, NULL, NULL);
return vbox;
}
static void
gimp_foreground_select_options_gui_reset_stroke_width (GtkWidget *button,
GimpToolOptions *tool_options)
{
g_object_set (tool_options, "stroke-width", 10, NULL);
}
static void
gimp_foreground_select_show_scale (GObject *object)
{
GtkWidget *spin;
GtkWidget *label;
GtkWidget *scale;
label = g_object_get_data (object, "label");
spin = g_object_get_data (object, "spinbutton");
scale = g_object_get_data (object, "scale");
gtk_widget_show (label);
gtk_widget_show (spin);
gtk_widget_show (scale);
}
static void
gimp_foreground_select_hide_scale (GObject *object)
{
GtkWidget *spin;
GtkWidget *label;
GtkWidget *scale;
label = g_object_get_data (object, "label");
spin = g_object_get_data (object, "spinbutton");
scale = g_object_get_data (object, "scale");
gtk_widget_hide (label);
gtk_widget_hide (spin);
gtk_widget_hide (scale);
}
static void
gimp_foreground_select_notify_engine (GimpToolOptions *tool_options,
GParamSpec *pspec,
GtkWidget *widget)
{
GimpForegroundSelectOptions *options = GIMP_FOREGROUND_SELECT_OPTIONS (tool_options);
switch (options->engine)
{
case GIMP_MATTING_ENGINE_MATTING_GLOBAL:
gimp_foreground_select_show_scale (options->dynamic_widgets.iterations);
gimp_foreground_select_hide_scale (options->dynamic_widgets.levels);
gimp_foreground_select_hide_scale (options->dynamic_widgets.active_levels);
break;
case GIMP_MATTING_ENGINE_MATTING_LEVIN:
gimp_foreground_select_hide_scale (options->dynamic_widgets.iterations);
gimp_foreground_select_show_scale (options->dynamic_widgets.levels);
gimp_foreground_select_show_scale (options->dynamic_widgets.active_levels);
break;
}
}
gdouble
gimp_foreground_select_options_get_opacity (GimpForegroundSelectOptions *options)
{
g_return_val_if_fail (GIMP_IS_FOREGROUND_SELECT_OPTIONS (options), 0.0);
switch (options->draw_mode)
{
case GIMP_MATTING_DRAW_MODE_FOREGROUND:
return 1.0;
case GIMP_MATTING_DRAW_MODE_BACKGROUND:
return 0.0;
case GIMP_MATTING_DRAW_MODE_UNKNOWN:
default:
return 0.5;
}
}
void
gimp_foreground_select_options_get_mask_color (GimpForegroundSelectOptions *options,
GimpRGB *color)
@ -391,15 +416,19 @@ gimp_foreground_select_options_get_mask_color (GimpForegroundSelectOptions *opti
switch (options->mask_color)
{
case GIMP_RED_CHANNEL:
gimp_rgba_set (color, 1, 0, 0, 0.5);
gimp_rgba_set (color, 1, 0, 0, 0.7);
break;
case GIMP_GREEN_CHANNEL:
gimp_rgba_set (color, 0, 1, 0, 0.5);
gimp_rgba_set (color, 0, 1, 0, 0.7);
break;
case GIMP_BLUE_CHANNEL:
gimp_rgba_set (color, 0, 0, 1, 0.5);
gimp_rgba_set (color, 0, 0, 1, 0.7);
break;
case GIMP_GRAY_CHANNEL:
gimp_rgba_set (color, 1, 1, 1, 0.7);
break;
default:

View File

@ -15,6 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GIMP_FOREGROUND_SELECT_OPTIONS_H__
#define __GIMP_FOREGROUND_SELECT_OPTIONS_H__
@ -31,19 +32,34 @@
typedef struct _GimpForegroundSelectOptions GimpForegroundSelectOptions;
typedef GimpSelectionOptionsClass GimpForegroundSelectOptionsClass;
typedef struct _GimpForegroundSelectOptionsClass GimpForegroundSelectOptionsClass;
typedef struct _GimpMattingDynamicWidgets GimpMattingDynamicWidgets;
struct _GimpMattingDynamicWidgets
{
GObject *levels;
GObject *active_levels;
GObject *iterations;
};
struct _GimpForegroundSelectOptions
{
GimpSelectionOptions parent_instance;
gboolean contiguous;
gboolean background;
GimpMattingDrawMode draw_mode;
gint stroke_width;
gint smoothness;
GimpChannelType mask_color;
gboolean expanded;
gdouble sensitivity[3];
GimpMattingEngine engine;
gint levels;
gint active_levels;
gint iterations;
GimpMattingDynamicWidgets dynamic_widgets;
};
struct _GimpForegroundSelectOptionsClass
{
GimpSelectionOptionsClass parent_class;
};
@ -53,6 +69,8 @@ GtkWidget * gimp_foreground_select_options_gui (GimpToolOptions
void gimp_foreground_select_options_get_mask_color (GimpForegroundSelectOptions *options,
GimpRGB *color);
gdouble gimp_foreground_select_options_get_opacity (GimpForegroundSelectOptions *options);
#endif /* __GIMP_FOREGROUND_SELECT_OPTIONS_H__ */

View File

@ -27,16 +27,18 @@
#include <gdk/gdkkeysyms.h>
#include "libgimpmath/gimpmath.h"
#include "libgimpcolor/gimpcolor.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "tools-types.h"
#include "core/gimp.h"
#include "core/gimpchannel.h"
#include "core/gimpchannel-combine.h"
#include "core/gimpchannel-select.h"
#include "core/gimpdrawable-foreground-extract.h"
#include "core/gimpimage.h"
#include "core/gimplayer.h"
#include "core/gimplayermask.h"
#include "core/gimpprogress.h"
#include "core/gimpscanconvert.h"
@ -108,23 +110,26 @@ static void gimp_foreground_select_tool_draw (GimpDrawTool *draw
static void gimp_foreground_select_tool_select (GimpFreeSelectTool *free_sel,
GimpDisplay *display);
static void gimp_foreground_select_tool_set_mask (GimpForegroundSelectTool *fg_select,
GimpDisplay *display,
GimpChannel *mask);
static void gimp_foreground_select_tool_apply (GimpForegroundSelectTool *fg_select,
static void gimp_foreground_select_tool_set_trimap (GimpForegroundSelectTool *fg_select,
GimpDisplay *display);
static void gimp_foreground_select_tool_set_preview (GimpForegroundSelectTool *fg_select,
GimpDisplay *display);
static void gimp_foreground_select_tool_drop_masks (GimpForegroundSelectTool *fg_select,
GimpDisplay *display);
static void gimp_foreground_select_tool_stroke (GimpChannel *mask,
FgSelectStroke *stroke);
static void gimp_foreground_select_tool_push_stroke (GimpForegroundSelectTool *fg_select,
GimpDisplay *display,
GimpForegroundSelectOptions *options);
static void gimp_foreground_select_tool_apply (GimpForegroundSelectTool *fg_select,
GimpDisplay *display);
static void gimp_foreground_select_tool_preview (GimpForegroundSelectTool *fg_select,
GimpDisplay *display);
static void gimp_foreground_select_options_notify (GimpForegroundSelectOptions *options,
GParamSpec *pspec,
GimpForegroundSelectTool *fg_select);
static void gimp_foreground_select_tool_stroke_paint (GimpForegroundSelectTool *fg_select,
GimpDisplay *display,
GimpForegroundSelectOptions *options);
G_DEFINE_TYPE (GimpForegroundSelectTool, gimp_foreground_select_tool,
GIMP_TYPE_FREE_SELECT_TOOL)
@ -194,10 +199,10 @@ gimp_foreground_select_tool_init (GimpForegroundSelectTool *fg_select)
gimp_tool_control_set_action_value_2 (tool->control,
"tools/tools-foreground-select-brush-size-set");
fg_select->idle_id = 0;
fg_select->stroke = NULL;
fg_select->strokes = NULL;
fg_select->mask = NULL;
fg_select->trimap = NULL;
fg_select->state = MATTING_STATE_FREE_SELECT;
}
static void
@ -220,17 +225,12 @@ gimp_foreground_select_tool_finalize (GObject *object)
if (fg_select->stroke)
g_warning ("%s: stroke should be NULL at this point", G_STRLOC);
if (fg_select->strokes)
g_warning ("%s: strokes should be NULL at this point", G_STRLOC);
#if 0
if (fg_select->state)
g_warning ("%s: state should be NULL at this point", G_STRLOC);
#endif
if (fg_select->mask)
g_warning ("%s: mask should be NULL at this point", G_STRLOC);
if (fg_select->trimap)
g_warning ("%s: mask should be NULL at this point", G_STRLOC);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@ -249,29 +249,7 @@ gimp_foreground_select_tool_control (GimpTool *tool,
case GIMP_TOOL_ACTION_HALT:
{
GList *list;
gimp_foreground_select_tool_set_mask (fg_select, display, NULL);
for (list = fg_select->strokes; list; list = list->next)
{
FgSelectStroke *stroke = list->data;
g_free (stroke->points);
g_slice_free (FgSelectStroke, stroke);
}
g_list_free (fg_select->strokes);
fg_select->strokes = NULL;
#if 0
if (fg_select->state)
{
gimp_drawable_foreground_extract_siox_done (fg_select->state);
fg_select->state = NULL;
}
#endif
gimp_foreground_select_tool_drop_masks (fg_select, display);
tool->display = NULL;
}
break;
@ -293,7 +271,7 @@ gimp_foreground_select_tool_oper_update (GimpTool *tool,
GIMP_TOOL_CLASS (parent_class)->oper_update (tool, coords, state, proximity,
display);
if (fg_select->mask && display == tool->display)
if (fg_select->state == MATTING_STATE_PAINT_TRIMAP && display == tool->display)
{
GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);
@ -302,17 +280,17 @@ gimp_foreground_select_tool_oper_update (GimpTool *tool,
fg_select->last_coords = *coords;
gimp_draw_tool_resume (draw_tool);
if (fg_select->strokes)
status = _("Add more strokes or press Enter to accept the selection");
else
status = _("Mark foreground by painting on the object to extract");
status = _("Paint trimap, (background, foreground and unknown) or press Enter to preview");
}
else
else if (fg_select->state == MATTING_STATE_FREE_SELECT)
{
if (GIMP_SELECTION_TOOL (tool)->function == SELECTION_SELECT)
status = _("Roughly outline the object to extract");
}
else
{
status = _("Press escape for return to trimap or Enter to apply");
}
if (proximity && status)
gimp_tool_replace_status (tool, display, "%s", status);
@ -325,6 +303,7 @@ gimp_foreground_select_tool_modifier_key (GimpTool *tool,
GdkModifierType state,
GimpDisplay *display)
{
#if 0
if (key == gimp_get_toggle_behavior_mask ())
{
GimpForegroundSelectOptions *options;
@ -335,6 +314,7 @@ gimp_foreground_select_tool_modifier_key (GimpTool *tool,
"background", ! options->background,
NULL);
}
#endif
}
static void
@ -345,14 +325,8 @@ gimp_foreground_select_tool_cursor_update (GimpTool *tool,
{
GimpForegroundSelectTool *fg_select = GIMP_FOREGROUND_SELECT_TOOL (tool);
if (fg_select->mask)
if (fg_select->state == MATTING_STATE_PAINT_TRIMAP)
{
GimpForegroundSelectOptions *options;
options = GIMP_FOREGROUND_SELECT_TOOL_GET_OPTIONS (tool);
gimp_tool_control_set_toggled (tool->control, options->background);
switch (GIMP_SELECTION_TOOL (tool)->function)
{
case SELECTION_MOVE_MASK:
@ -378,10 +352,25 @@ gimp_foreground_select_tool_key_press (GimpTool *tool,
if (display != tool->display)
return FALSE;
#if 0
if (fg_select->state)
#endif
if (fg_select->mask) /* dunno if that's the right condition */
if (fg_select->state == MATTING_STATE_PAINT_TRIMAP)
{
switch (kevent->keyval)
{
case GDK_KEY_Return:
case GDK_KEY_KP_Enter:
case GDK_KEY_ISO_Enter:
gimp_foreground_select_tool_preview (fg_select, display);
return TRUE;
case GDK_KEY_Escape:
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
return TRUE;
default:
return FALSE;
}
}
else if (fg_select->state == MATTING_STATE_PREVIEW_MASK)
{
switch (kevent->keyval)
{
@ -392,7 +381,7 @@ gimp_foreground_select_tool_key_press (GimpTool *tool,
return TRUE;
case GDK_KEY_Escape:
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
gimp_foreground_select_tool_set_trimap (fg_select, display);
return TRUE;
default:
@ -418,7 +407,7 @@ gimp_foreground_select_tool_button_press (GimpTool *tool,
GimpForegroundSelectTool *fg_select = GIMP_FOREGROUND_SELECT_TOOL (tool);
GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);
if (fg_select->mask)
if (fg_select->state == MATTING_STATE_PAINT_TRIMAP)
{
GimpVector2 point = gimp_vector2_new (coords->x, coords->y);
@ -436,12 +425,12 @@ gimp_foreground_select_tool_button_press (GimpTool *tool,
g_array_append_val (fg_select->stroke, point);
if (! gimp_draw_tool_is_active (draw_tool))
if (!gimp_draw_tool_is_active (draw_tool))
gimp_draw_tool_start (draw_tool, display);
gimp_draw_tool_resume (draw_tool);
}
else
else if (fg_select->state == MATTING_STATE_FREE_SELECT)
{
GIMP_TOOL_CLASS (parent_class)->button_press (tool, coords, time, state,
press_type, display);
@ -458,7 +447,7 @@ gimp_foreground_select_tool_button_release (GimpTool *tool,
{
GimpForegroundSelectTool *fg_select = GIMP_FOREGROUND_SELECT_TOOL (tool);
if (fg_select->mask)
if (fg_select->state == MATTING_STATE_PAINT_TRIMAP)
{
GimpForegroundSelectOptions *options;
@ -468,13 +457,15 @@ gimp_foreground_select_tool_button_release (GimpTool *tool,
gimp_tool_control_halt (tool->control);
gimp_foreground_select_tool_push_stroke (fg_select, display, options);
gimp_foreground_select_tool_stroke_paint (fg_select, display, options);
gimp_foreground_select_tool_set_trimap (fg_select, display);
gimp_free_select_tool_select (GIMP_FREE_SELECT_TOOL (tool), display);
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
}
else
else if (fg_select->state == MATTING_STATE_FREE_SELECT)
{
GIMP_TOOL_CLASS (parent_class)->button_release (tool,
coords, time, state,
@ -492,7 +483,7 @@ gimp_foreground_select_tool_motion (GimpTool *tool,
{
GimpForegroundSelectTool *fg_select = GIMP_FOREGROUND_SELECT_TOOL (tool);
if (fg_select->mask)
if (fg_select->state == MATTING_STATE_PAINT_TRIMAP)
{
GimpVector2 *last = &g_array_index (fg_select->stroke,
GimpVector2,
@ -511,7 +502,7 @@ gimp_foreground_select_tool_motion (GimpTool *tool,
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
}
else
else if (fg_select->state == MATTING_STATE_FREE_SELECT)
{
GIMP_TOOL_CLASS (parent_class)->motion (tool,
coords, time, state, display);
@ -550,24 +541,23 @@ gimp_foreground_select_tool_draw (GimpDrawTool *draw_tool)
if (fg_select->stroke)
{
GimpDisplayShell *shell = gimp_display_get_shell (draw_tool->display);
gimp_draw_tool_add_pen (draw_tool,
(const GimpVector2 *) fg_select->stroke->data,
fg_select->stroke->len,
GIMP_CONTEXT (options),
(options->background ?
GIMP_ACTIVE_COLOR_BACKGROUND :
GIMP_ACTIVE_COLOR_FOREGROUND),
options->stroke_width);
GIMP_ACTIVE_COLOR_FOREGROUND,
options->stroke_width * shell->scale_y);
}
if (fg_select->mask)
if (fg_select->state == MATTING_STATE_PAINT_TRIMAP)
{
GimpDisplayShell *shell = gimp_display_get_shell (draw_tool->display);
gint x = fg_select->last_coords.x;
gint y = fg_select->last_coords.y;
gdouble radius;
radius = (options->stroke_width / shell->scale_y) / 2;
radius = options->stroke_width / 2;
/* warn if the user is drawing outside of the working area */
if (FALSE)
@ -592,7 +582,7 @@ gimp_foreground_select_tool_draw (GimpDrawTool *draw_tool)
2 * radius, 2 * radius,
0.0, 2.0 * G_PI);
}
else
else if (fg_select->state == MATTING_STATE_FREE_SELECT)
{
GIMP_DRAW_TOOL_CLASS (parent_class)->draw (draw_tool);
}
@ -603,27 +593,20 @@ gimp_foreground_select_tool_select (GimpFreeSelectTool *free_sel,
GimpDisplay *display)
{
GimpForegroundSelectTool *fg_select;
GimpForegroundSelectOptions *options;
GimpImage *image = gimp_display_get_image (display);
GimpDrawable *drawable;
GimpScanConvert *scan_convert;
GimpChannel *mask;
const GimpVector2 *points;
gint n_points;
drawable = gimp_image_get_active_drawable (image);
fg_select = GIMP_FOREGROUND_SELECT_TOOL (free_sel);
options = GIMP_FOREGROUND_SELECT_TOOL_GET_OPTIONS (free_sel);
if (fg_select->idle_id)
{
g_source_remove (fg_select->idle_id);
fg_select->idle_id = 0;
}
if (! drawable)
return;
if (fg_select->state == MATTING_STATE_FREE_SELECT)
{
scan_convert = gimp_scan_convert_new ();
gimp_free_select_tool_get_points (free_sel,
@ -635,77 +618,85 @@ gimp_foreground_select_tool_select (GimpFreeSelectTool *free_sel,
points,
TRUE);
mask = gimp_channel_new (image,
fg_select->trimap = gimp_channel_new (image,
gimp_image_get_width (image),
gimp_image_get_height (image),
"foreground-extraction", NULL);
"foreground-extraction",NULL);
gimp_scan_convert_render_value (scan_convert,
gimp_drawable_get_buffer (GIMP_DRAWABLE (mask)),
0, 0, 0.5);
gimp_drawable_get_buffer (GIMP_DRAWABLE (fg_select->trimap)),
0, 0, 1.0);
gimp_scan_convert_free (scan_convert);
if (fg_select->strokes)
{
GList *list;
gimp_set_busy (image->gimp);
/* apply foreground and background markers */
for (list = fg_select->strokes; list; list = list->next)
gimp_foreground_select_tool_stroke (mask, list->data);
#if 0
if (fg_select->state)
gimp_drawable_foreground_extract_siox (GIMP_DRAWABLE (mask),
fg_select->state,
fg_select->refinement,
options->smoothness,
options->sensitivity,
! options->contiguous,
GIMP_PROGRESS (fg_select));
#endif
fg_select->refinement = SIOX_REFINEMENT_NO_CHANGE;
gimp_unset_busy (image->gimp);
gimp_foreground_select_tool_set_trimap (fg_select, display);
}
else
{
gint x1, y1;
gint x2, y2;
g_object_set (options, "background", FALSE, NULL);
gimp_foreground_select_tool_get_area (mask, &x1, &y1, &x2, &y2);
#if 0
if (fg_select->state)
g_warning ("state should be NULL here");
fg_select->state =
gimp_drawable_foreground_extract_siox_init (drawable,
x1, y1, x2 - x1, y2 - y1);
#endif
}
gimp_foreground_select_tool_set_mask (fg_select, display, mask);
g_object_unref (mask);
}
static void
gimp_foreground_select_tool_set_mask (GimpForegroundSelectTool *fg_select,
GimpDisplay *display,
GimpChannel *mask)
gimp_foreground_select_tool_set_trimap (GimpForegroundSelectTool *fg_select,
GimpDisplay *display)
{
GimpTool *tool = GIMP_TOOL (fg_select);
GimpForegroundSelectOptions *options;
GimpRGB color;
g_return_if_fail (fg_select->trimap != NULL);
options = GIMP_FOREGROUND_SELECT_TOOL_GET_OPTIONS (tool);
if (fg_select->mask == mask)
return;
gimp_foreground_select_options_get_mask_color (options, &color);
gimp_display_shell_set_mask (gimp_display_get_shell (display),
GIMP_DRAWABLE (fg_select->trimap), &color);
gimp_tool_control_set_tool_cursor (tool->control,
GIMP_TOOL_CURSOR_PAINTBRUSH);
gimp_tool_control_set_toggle_tool_cursor (tool->control,
GIMP_TOOL_CURSOR_PAINTBRUSH);
gimp_tool_control_set_toggled (tool->control, FALSE);
fg_select->state = MATTING_STATE_PAINT_TRIMAP;
}
static void
gimp_foreground_select_tool_set_preview (GimpForegroundSelectTool *fg_select,
GimpDisplay *display)
{
GimpTool *tool = GIMP_TOOL (fg_select);
GimpForegroundSelectOptions *options;
GimpRGB color;
g_return_if_fail (fg_select->mask != NULL);
options = GIMP_FOREGROUND_SELECT_TOOL_GET_OPTIONS (tool);
gimp_foreground_select_options_get_mask_color (options, &color);
gimp_rgb_set_alpha (&color, 1.0);
gimp_display_shell_set_mask (gimp_display_get_shell (display),
GIMP_DRAWABLE (fg_select->mask), &color);
gimp_tool_control_set_tool_cursor (tool->control,
GIMP_TOOL_CURSOR_PAINTBRUSH);
gimp_tool_control_set_toggle_tool_cursor (tool->control,
GIMP_TOOL_CURSOR_PAINTBRUSH);
gimp_tool_control_set_toggled (tool->control, FALSE);
fg_select->state = MATTING_STATE_PREVIEW_MASK;
}
static void
gimp_foreground_select_tool_drop_masks (GimpForegroundSelectTool *fg_select,
GimpDisplay *display)
{
GimpTool *tool = GIMP_TOOL (fg_select);
if (fg_select->trimap)
{
g_object_unref (fg_select->trimap);
fg_select->trimap = NULL;
}
if (fg_select->mask)
{
@ -713,40 +704,115 @@ gimp_foreground_select_tool_set_mask (GimpForegroundSelectTool *fg_select,
fg_select->mask = NULL;
}
if (mask)
{
GimpRGB color;
fg_select->mask = g_object_ref (mask);
gimp_foreground_select_options_get_mask_color (options, &color);
gimp_display_shell_set_mask (gimp_display_get_shell (display),
GIMP_DRAWABLE (mask), &color);
}
else
if (GIMP_IS_DISPLAY (display))
{
gimp_display_shell_set_mask (gimp_display_get_shell (display),
NULL, NULL);
}
if (mask)
{
gimp_tool_control_set_tool_cursor (tool->control,
GIMP_TOOL_CURSOR_PAINTBRUSH);
gimp_tool_control_set_toggle_tool_cursor (tool->control,
GIMP_TOOL_CURSOR_ERASER);
gimp_tool_control_set_toggled (tool->control, options->background);
}
else
{
gimp_tool_control_set_tool_cursor (tool->control,
GIMP_TOOL_CURSOR_FREE_SELECT);
gimp_tool_control_set_toggle_tool_cursor (tool->control,
GIMP_TOOL_CURSOR_FREE_SELECT);
gimp_tool_control_set_toggled (tool->control, FALSE);
fg_select->state = MATTING_STATE_FREE_SELECT;
}
static void
gimp_foreground_select_tool_preview (GimpForegroundSelectTool *fg_select,
GimpDisplay *display)
{
GimpTool *tool = GIMP_TOOL (fg_select);
GimpForegroundSelectOptions *options = GIMP_FOREGROUND_SELECT_TOOL_GET_OPTIONS (tool);
GimpImage *image = gimp_display_get_image (display);
GimpDrawable *drawable = gimp_image_get_active_drawable (image);
GeglBuffer *trimap_buffer;
GeglBuffer *drawable_buffer;
GeglNode *gegl;
GeglNode *matting_node;
GeglNode *input_image;
GeglNode *input_trimap;
GeglNode *output_mask;
GeglBuffer *buffer;
GimpProgress *progress;
GeglProcessor *processor;
gdouble value;
if (fg_select->mask)
{
g_object_unref (fg_select->mask);
fg_select->mask = NULL;
}
progress = gimp_progress_start (GIMP_PROGRESS (fg_select),
_("Computing alpha of unknown pixels"),
FALSE);
trimap_buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (fg_select->trimap));
drawable_buffer = gimp_drawable_get_buffer (drawable);
gegl = gegl_node_new ();
input_trimap = gegl_node_new_child (gegl,
"operation", "gegl:buffer-source",
"buffer", trimap_buffer,
NULL);
input_image = gegl_node_new_child (gegl,
"operation", "gegl:buffer-source",
"buffer", drawable_buffer,
NULL);
output_mask = gegl_node_new_child (gegl,
"operation", "gegl:buffer-sink",
"buffer", &buffer,
"format", NULL,
NULL);
if (options->engine == GIMP_MATTING_ENGINE_MATTING_GLOBAL)
{
matting_node = gegl_node_new_child (gegl,
"operation", "gegl:matting-global",
"iterations", options->iterations,
NULL);
}
else
{
matting_node = gegl_node_new_child (gegl,
"operation", "gegl:matting-levin",
"levels", options->levels,
"active_levels", options->active_levels,
NULL);
}
gegl_node_connect_to (input_image, "output",
matting_node, "input");
gegl_node_connect_to (input_trimap, "output",
matting_node, "aux");
gegl_node_connect_to (matting_node, "output",
output_mask, "input");
processor = gegl_node_new_processor (output_mask, NULL);
while (gegl_processor_work (processor, &value))
{
if (progress)
gimp_progress_set_value (progress, value);
}
if (progress)
gimp_progress_end (progress);
g_object_unref (processor);
fg_select->mask = gimp_channel_new_from_buffer (buffer, image,
"preview-mask", NULL);
gimp_foreground_select_tool_set_preview (fg_select, display);
g_object_unref (gegl);
if (buffer)
g_object_unref (buffer);
}
static void
@ -754,18 +820,20 @@ gimp_foreground_select_tool_apply (GimpForegroundSelectTool *fg_select,
GimpDisplay *display)
{
GimpTool *tool = GIMP_TOOL (fg_select);
GimpSelectionOptions *options = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);
GimpImage *image = gimp_display_get_image (display);
GimpLayer *layer = gimp_image_get_active_layer (image);
GeglBuffer *buffer;
GimpLayerMask *layer_mask;
GimpRGB color = { 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE };
g_return_if_fail (fg_select->mask != NULL);
gimp_channel_select_channel (gimp_image_get_mask (image),
C_("command", "Foreground Select"),
fg_select->mask, 0, 0,
options->operation,
options->feather,
options->feather_radius,
options->feather_radius);
buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (fg_select->mask));
layer_mask = gimp_layer_mask_new_from_buffer (buffer, image,
"mask", &color);
gimp_layer_add_mask (layer, layer_mask, TRUE, NULL);
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
@ -773,16 +841,22 @@ gimp_foreground_select_tool_apply (GimpForegroundSelectTool *fg_select,
}
static void
gimp_foreground_select_tool_stroke (GimpChannel *mask,
FgSelectStroke *stroke)
gimp_foreground_select_tool_stroke_paint (GimpForegroundSelectTool *fg_select,
GimpDisplay *display,
GimpForegroundSelectOptions *options)
{
GimpScanConvert *scan_convert = gimp_scan_convert_new ();
GimpScanConvert *scan_convert;
gint width;
if (stroke->num_points == 1)
g_return_if_fail (fg_select->stroke != NULL);
scan_convert = gimp_scan_convert_new ();
if (fg_select->stroke->len == 1)
{
GimpVector2 points[2];
points[0] = points[1] = stroke->points[0];
points[0] = points[1] = ((GimpVector2 *) fg_select->stroke->data)[0];
points[1].x += 0.01;
points[1].y += 0.01;
@ -792,111 +866,50 @@ gimp_foreground_select_tool_stroke (GimpChannel *mask,
else
{
gimp_scan_convert_add_polyline (scan_convert,
stroke->num_points, stroke->points,
fg_select->stroke->len,
(GimpVector2 *) fg_select->stroke->data,
FALSE);
}
width = ROUND ((gdouble) options->stroke_width);
gimp_scan_convert_stroke (scan_convert,
stroke->width,
width,
GIMP_JOIN_ROUND, GIMP_CAP_ROUND, 10.0,
0.0, NULL);
gimp_scan_convert_compose_value (scan_convert,
gimp_drawable_get_buffer (GIMP_DRAWABLE (mask)),
0, 0, stroke->background ? 0.0 : 1.0);
gimp_drawable_get_buffer (GIMP_DRAWABLE (fg_select->trimap)),
0, 0,
gimp_foreground_select_options_get_opacity (options));
gimp_scan_convert_free (scan_convert);
}
static void
gimp_foreground_select_tool_push_stroke (GimpForegroundSelectTool *fg_select,
GimpDisplay *display,
GimpForegroundSelectOptions *options)
{
GimpDisplayShell *shell = gimp_display_get_shell (display);
FgSelectStroke *stroke;
g_return_if_fail (fg_select->stroke != NULL);
stroke = g_slice_new (FgSelectStroke);
stroke->background = options->background;
stroke->width = ROUND ((gdouble) options->stroke_width / shell->scale_y);
stroke->num_points = fg_select->stroke->len;
stroke->points = (GimpVector2 *) g_array_free (fg_select->stroke, FALSE);
g_array_free (fg_select->stroke, TRUE);
fg_select->stroke = NULL;
fg_select->strokes = g_list_append (fg_select->strokes, stroke);
fg_select->refinement |= (stroke->background ?
SIOX_REFINEMENT_ADD_BACKGROUND :
SIOX_REFINEMENT_ADD_FOREGROUND);
}
static gboolean
gimp_foreground_select_tool_idle_select (GimpForegroundSelectTool *fg_select)
{
GimpTool *tool = GIMP_TOOL (fg_select);
fg_select->idle_id = 0;
if (tool->display)
gimp_free_select_tool_select (GIMP_FREE_SELECT_TOOL (tool), tool->display);
return FALSE;
}
/* To compress close notify signals, the process is delayed by */
#define MINIMUM_DELAY 300
static void
gimp_foreground_select_options_notify (GimpForegroundSelectOptions *options,
GParamSpec *pspec,
GimpForegroundSelectTool *fg_select)
{
SioxRefinementType refinement = 0;
if (! fg_select->mask)
return;
#if 0
if (strcmp (pspec->name, "smoothness") == 0)
{
refinement = SIOX_REFINEMENT_CHANGE_SMOOTHNESS;
}
else if (strcmp (pspec->name, "contiguous") == 0)
{
refinement = SIOX_REFINEMENT_CHANGE_MULTIBLOB;
}
else if (g_str_has_prefix (pspec->name, "sensitivity"))
{
refinement = SIOX_REFINEMENT_CHANGE_SENSITIVITY;
}
#endif
if (refinement && fg_select->strokes)
{
fg_select->refinement |= refinement;
if (fg_select->idle_id)
g_source_remove (fg_select->idle_id);
fg_select->idle_id =
g_timeout_add_full (G_PRIORITY_LOW, MINIMUM_DELAY,
(GSourceFunc) gimp_foreground_select_tool_idle_select,
fg_select, NULL);
}
if (g_str_has_prefix (pspec->name, "mask-color"))
{
GimpTool *tool = GIMP_TOOL (fg_select);
if (tool->display && fg_select->mask)
if (tool->display)
{
GimpRGB color;
if (fg_select->state == MATTING_STATE_PAINT_TRIMAP)
{
gimp_foreground_select_tool_set_trimap (fg_select, tool->display);
}
gimp_foreground_select_options_get_mask_color (options, &color);
gimp_display_shell_set_mask (gimp_display_get_shell (tool->display),
GIMP_DRAWABLE (fg_select->mask), &color);
if (fg_select->state == MATTING_STATE_PREVIEW_MASK)
{
gimp_foreground_select_tool_set_preview (fg_select, tool->display);
}
}
}
}

View File

@ -22,13 +22,12 @@
#include "gimpfreeselecttool.h"
typedef enum /*< pdb-skip, skip >*/
typedef enum
{
SIOX_REFINEMENT_NO_CHANGE = 0,
SIOX_REFINEMENT_ADD_FOREGROUND = (1 << 0),
SIOX_REFINEMENT_ADD_BACKGROUND = (1 << 1),
SIOX_REFINEMENT_RECALCULATE = 0xFF
} SioxRefinementType;
MATTING_STATE_FREE_SELECT = 0,
MATTING_STATE_PAINT_TRIMAP,
MATTING_STATE_PREVIEW_MASK,
} MattingState;
#define GIMP_TYPE_FOREGROUND_SELECT_TOOL (gimp_foreground_select_tool_get_type ())
@ -49,14 +48,10 @@ struct _GimpForegroundSelectTool
GimpFreeSelectTool parent_instance;
GimpCoords last_coords;
guint idle_id;
GArray *stroke;
GList *strokes;
GimpChannel *trimap;
GimpChannel *mask;
#if 0
SioxState *state;
#endif
SioxRefinementType refinement;
MattingState state;
};
struct _GimpForegroundSelectToolClass