mirror of https://github.com/GNOME/gimp.git
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:
parent
b893993e7b
commit
1cd1541b2d
|
@ -26,10 +26,9 @@
|
||||||
|
|
||||||
#include "tools-types.h"
|
#include "tools-types.h"
|
||||||
|
|
||||||
#if 0
|
#include "widgets/gimppropwidgets.h"
|
||||||
#include "base/siox.h"
|
#include "widgets/gimpspinscale.h"
|
||||||
#endif
|
#include "widgets/gimpwidgets-constructors.h"
|
||||||
|
|
||||||
#include "widgets/gimpwidgets-utils.h"
|
#include "widgets/gimpwidgets-utils.h"
|
||||||
|
|
||||||
#include "gimpforegroundselectoptions.h"
|
#include "gimpforegroundselectoptions.h"
|
||||||
|
@ -38,22 +37,26 @@
|
||||||
#include "gimp-intl.h"
|
#include "gimp-intl.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* for matting-global: iterations int
|
||||||
|
* for matting-levin: levels int, active levels int
|
||||||
|
*/
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_ANTIALIAS,
|
PROP_DRAW_MODE,
|
||||||
PROP_CONTIGUOUS,
|
|
||||||
PROP_BACKGROUND,
|
|
||||||
PROP_STROKE_WIDTH,
|
PROP_STROKE_WIDTH,
|
||||||
PROP_SMOOTHNESS,
|
|
||||||
PROP_MASK_COLOR,
|
PROP_MASK_COLOR,
|
||||||
PROP_EXPANDED,
|
PROP_ENGINE,
|
||||||
PROP_SENSITIVITY_L,
|
PROP_ITERATIONS,
|
||||||
PROP_SENSITIVITY_A,
|
PROP_LEVELS,
|
||||||
PROP_SENSITIVITY_B
|
PROP_ACTIVE_LEVELS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void gimp_foreground_select_options_set_property (GObject *object,
|
static void gimp_foreground_select_options_set_property (GObject *object,
|
||||||
guint property_id,
|
guint property_id,
|
||||||
const GValue *value,
|
const GValue *value,
|
||||||
|
@ -63,6 +66,14 @@ static void gimp_foreground_select_options_get_property (GObject *object,
|
||||||
GValue *value,
|
GValue *value,
|
||||||
GParamSpec *pspec);
|
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,
|
G_DEFINE_TYPE (GimpForegroundSelectOptions, gimp_foreground_select_options,
|
||||||
GIMP_TYPE_SELECTION_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;
|
object_class->get_property = gimp_foreground_select_options_get_property;
|
||||||
|
|
||||||
/* override the antialias default value from GimpSelectionOptions */
|
/* 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,
|
GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_DRAW_MODE,
|
||||||
"contiguous",
|
"draw-mode",
|
||||||
N_("Select a single contiguous area"),
|
|
||||||
TRUE,
|
|
||||||
GIMP_PARAM_STATIC_STRINGS);
|
|
||||||
|
|
||||||
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_BACKGROUND,
|
|
||||||
"background",
|
|
||||||
N_("Paint over areas to mark color values for "
|
N_("Paint over areas to mark color values for "
|
||||||
"inclusion or exclusion from selection"),
|
"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_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
GIMP_CONFIG_INSTALL_PROP_INT (object_class, PROP_STROKE_WIDTH,
|
GIMP_CONFIG_INSTALL_PROP_INT (object_class, PROP_STROKE_WIDTH,
|
||||||
"stroke-width",
|
"stroke-width",
|
||||||
N_("Size of the brush used for refinements"),
|
N_("Size of the brush used for refinements"),
|
||||||
1, 80, 18,
|
1, 6000, 10,
|
||||||
GIMP_PARAM_STATIC_STRINGS);
|
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,
|
GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_MASK_COLOR,
|
||||||
"mask-color",
|
"mask-color",
|
||||||
N_("Color of selection preview mask"),
|
N_("Color of selection preview mask"),
|
||||||
|
@ -119,30 +117,21 @@ gimp_foreground_select_options_class_init (GimpForegroundSelectOptionsClass *kla
|
||||||
GIMP_BLUE_CHANNEL,
|
GIMP_BLUE_CHANNEL,
|
||||||
GIMP_PARAM_STATIC_STRINGS);
|
GIMP_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_EXPANDED,
|
GIMP_CONFIG_INSTALL_PROP_INT (object_class, PROP_LEVELS,
|
||||||
"expanded", NULL,
|
"levels",
|
||||||
FALSE,
|
N_("Parameter for matting-levin"),
|
||||||
0);
|
1, 10, 2,
|
||||||
|
|
||||||
#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_PARAM_STATIC_STRINGS);
|
GIMP_PARAM_STATIC_STRINGS);
|
||||||
|
GIMP_CONFIG_INSTALL_PROP_INT (object_class, PROP_ACTIVE_LEVELS,
|
||||||
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_SENSITIVITY_A,
|
"active-levels",
|
||||||
"sensitivity-a",
|
N_("Parameter for matting-levin"),
|
||||||
N_("Sensitivity for red/green component"),
|
1, 10, 2,
|
||||||
0.0, 10.0, SIOX_DEFAULT_SENSITIVITY_A,
|
|
||||||
GIMP_PARAM_STATIC_STRINGS);
|
GIMP_PARAM_STATIC_STRINGS);
|
||||||
|
GIMP_CONFIG_INSTALL_PROP_INT (object_class, PROP_ITERATIONS,
|
||||||
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_SENSITIVITY_B,
|
"iterations",
|
||||||
"sensitivity-b",
|
N_("Parameter for matting-global"),
|
||||||
N_("Sensitivity for yellow/blue component"),
|
1, 10, 2,
|
||||||
0.0, 10.0, SIOX_DEFAULT_SENSITIVITY_B,
|
|
||||||
GIMP_PARAM_STATIC_STRINGS);
|
GIMP_PARAM_STATIC_STRINGS);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -160,44 +149,32 @@ gimp_foreground_select_options_set_property (GObject *object,
|
||||||
|
|
||||||
switch (property_id)
|
switch (property_id)
|
||||||
{
|
{
|
||||||
case PROP_ANTIALIAS:
|
case PROP_DRAW_MODE:
|
||||||
GIMP_SELECTION_OPTIONS (object)->antialias = g_value_get_boolean (value);
|
options->draw_mode = g_value_get_enum (value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_CONTIGUOUS:
|
case PROP_ENGINE:
|
||||||
options->contiguous = g_value_get_boolean (value);
|
options->engine = g_value_get_enum (value);
|
||||||
break;
|
|
||||||
|
|
||||||
case PROP_BACKGROUND:
|
|
||||||
options->background = g_value_get_boolean (value);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_STROKE_WIDTH:
|
case PROP_STROKE_WIDTH:
|
||||||
options->stroke_width = g_value_get_int (value);
|
options->stroke_width = g_value_get_int (value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_SMOOTHNESS:
|
|
||||||
options->smoothness = g_value_get_int (value);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PROP_MASK_COLOR:
|
case PROP_MASK_COLOR:
|
||||||
options->mask_color = g_value_get_enum (value);
|
options->mask_color = g_value_get_enum (value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_EXPANDED:
|
case PROP_LEVELS:
|
||||||
options->expanded = g_value_get_boolean (value);
|
options->levels = g_value_get_int (value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_SENSITIVITY_L:
|
case PROP_ACTIVE_LEVELS:
|
||||||
options->sensitivity[0] = g_value_get_double (value);
|
options->active_levels = g_value_get_int (value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_SENSITIVITY_A:
|
case PROP_ITERATIONS:
|
||||||
options->sensitivity[1] = g_value_get_double (value);
|
options->iterations = g_value_get_int (value);
|
||||||
break;
|
|
||||||
|
|
||||||
case PROP_SENSITIVITY_B:
|
|
||||||
options->sensitivity[2] = g_value_get_double (value);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -216,44 +193,33 @@ gimp_foreground_select_options_get_property (GObject *object,
|
||||||
|
|
||||||
switch (property_id)
|
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;
|
break;
|
||||||
|
|
||||||
case PROP_CONTIGUOUS:
|
case PROP_ENGINE:
|
||||||
g_value_set_boolean (value, options->contiguous);
|
g_value_set_enum (value, options->engine);
|
||||||
break;
|
|
||||||
|
|
||||||
case PROP_BACKGROUND:
|
|
||||||
g_value_set_boolean (value, options->background);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_STROKE_WIDTH:
|
case PROP_STROKE_WIDTH:
|
||||||
g_value_set_int (value, options->stroke_width);
|
g_value_set_int (value, options->stroke_width);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_SMOOTHNESS:
|
|
||||||
g_value_set_int (value, options->smoothness);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PROP_MASK_COLOR:
|
case PROP_MASK_COLOR:
|
||||||
g_value_set_enum (value, options->mask_color);
|
g_value_set_enum (value, options->mask_color);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_EXPANDED:
|
case PROP_LEVELS:
|
||||||
g_value_set_boolean (value, options->expanded);
|
g_value_set_int (value, options->levels);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_SENSITIVITY_L:
|
case PROP_ACTIVE_LEVELS:
|
||||||
g_value_set_double (value, options->sensitivity[0]);
|
g_value_set_int (value, options->active_levels);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_SENSITIVITY_A:
|
case PROP_ITERATIONS:
|
||||||
g_value_set_double (value, options->sensitivity[1]);
|
g_value_set_int (value, options->iterations);
|
||||||
break;
|
|
||||||
|
|
||||||
case PROP_SENSITIVITY_B:
|
|
||||||
g_value_set_double (value, options->sensitivity[2]);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -271,116 +237,175 @@ gimp_foreground_select_options_gui (GimpToolOptions *tool_options)
|
||||||
GtkWidget *button;
|
GtkWidget *button;
|
||||||
GtkWidget *frame;
|
GtkWidget *frame;
|
||||||
GtkWidget *scale;
|
GtkWidget *scale;
|
||||||
GtkWidget *label;
|
GtkWidget *combo;
|
||||||
GtkWidget *menu;
|
|
||||||
GtkWidget *inner_frame;
|
|
||||||
GtkWidget *table;
|
GtkWidget *table;
|
||||||
gchar *title;
|
|
||||||
gint row = 0;
|
gint row = 0;
|
||||||
GdkModifierType toggle_mask;
|
GimpForegroundSelectOptions *options = GIMP_FOREGROUND_SELECT_OPTIONS (config);
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
|
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_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
|
||||||
gtk_widget_show (frame);
|
gtk_widget_show (frame);
|
||||||
|
|
||||||
/* stroke width */
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
|
||||||
inner_frame = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 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);
|
|
||||||
gtk_widget_show (hbox);
|
gtk_widget_show (hbox);
|
||||||
|
|
||||||
label = gtk_label_new (_("Small brush"));
|
/* stroke width */
|
||||||
gimp_label_set_attributes (GTK_LABEL (label),
|
scale = gimp_prop_spin_scale_new (config, "stroke-width",
|
||||||
PANGO_ATTR_STYLE, PANGO_STYLE_ITALIC,
|
_("Stroke width"),
|
||||||
PANGO_ATTR_SCALE, PANGO_SCALE_SMALL,
|
1.0, 10.0, 2);
|
||||||
-1);
|
gimp_spin_scale_set_scale_limits (GIMP_SPIN_SCALE (scale), 1.0, 1000.0);
|
||||||
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
gimp_spin_scale_set_gamma (GIMP_SPIN_SCALE (scale), 1.7);
|
||||||
gtk_widget_show (label);
|
gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
|
||||||
|
|
||||||
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);
|
|
||||||
gtk_widget_show (scale);
|
gtk_widget_show (scale);
|
||||||
|
|
||||||
/* smoothness */
|
button = gimp_stock_button_new (GIMP_STOCK_RESET, NULL);
|
||||||
table = gtk_table_new (2, 3, FALSE);
|
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
|
||||||
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
|
gtk_image_set_from_stock (GTK_IMAGE (gtk_bin_get_child (GTK_BIN (button))),
|
||||||
gtk_table_set_col_spacings (GTK_TABLE (table), 2);
|
GIMP_STOCK_RESET, GTK_ICON_SIZE_MENU);
|
||||||
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
|
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
|
||||||
gtk_widget_show (table);
|
gtk_widget_show (button);
|
||||||
|
|
||||||
#if 0
|
g_signal_connect (button, "clicked",
|
||||||
scale = gimp_prop_hscale_new (config, "smoothness", 0.1, 1.0, 0);
|
G_CALLBACK (gimp_foreground_select_options_gui_reset_stroke_width),
|
||||||
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_RIGHT);
|
tool_options);
|
||||||
gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
|
|
||||||
_("Smoothing:"), 0.0, 0.5, scale, 2, FALSE);
|
gimp_help_set_help_data (button,
|
||||||
#endif
|
_("Reset stroke width native size"), NULL);
|
||||||
|
|
||||||
/* mask color */
|
/* mask color */
|
||||||
menu = gimp_prop_enum_combo_box_new (config, "mask-color",
|
frame = gimp_frame_new (_("Preview 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"));
|
|
||||||
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
|
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
|
||||||
gtk_widget_show (frame);
|
gtk_widget_show (frame);
|
||||||
|
|
||||||
inner_frame = gimp_frame_new ("<expander>");
|
combo = gimp_prop_enum_combo_box_new (config, "mask-color",
|
||||||
gtk_container_add (GTK_CONTAINER (frame), inner_frame);
|
GIMP_RED_CHANNEL, GIMP_GRAY_CHANNEL);
|
||||||
gtk_widget_show (inner_frame);
|
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);
|
table = gtk_table_new (3, 3, FALSE);
|
||||||
gtk_table_set_col_spacings (GTK_TABLE (table), 2);
|
gtk_table_set_col_spacings (GTK_TABLE (table), 2);
|
||||||
gtk_table_set_row_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);
|
gtk_widget_show (table);
|
||||||
|
|
||||||
gimp_prop_opacity_entry_new (config, "sensitivity-l",
|
options->dynamic_widgets.levels = (GObject *)
|
||||||
GTK_TABLE (table), 0, row++, "L");
|
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",
|
options->dynamic_widgets.active_levels = (GObject *)
|
||||||
GTK_TABLE (table), 0, row++, "a");
|
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",
|
options->dynamic_widgets.iterations = (GObject *)
|
||||||
GTK_TABLE (table), 0, row++, "b");
|
gimp_prop_scale_entry_new (config, "iterations",
|
||||||
#endif
|
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;
|
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
|
void
|
||||||
gimp_foreground_select_options_get_mask_color (GimpForegroundSelectOptions *options,
|
gimp_foreground_select_options_get_mask_color (GimpForegroundSelectOptions *options,
|
||||||
GimpRGB *color)
|
GimpRGB *color)
|
||||||
|
@ -391,15 +416,19 @@ gimp_foreground_select_options_get_mask_color (GimpForegroundSelectOptions *opti
|
||||||
switch (options->mask_color)
|
switch (options->mask_color)
|
||||||
{
|
{
|
||||||
case GIMP_RED_CHANNEL:
|
case GIMP_RED_CHANNEL:
|
||||||
gimp_rgba_set (color, 1, 0, 0, 0.5);
|
gimp_rgba_set (color, 1, 0, 0, 0.7);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GIMP_GREEN_CHANNEL:
|
case GIMP_GREEN_CHANNEL:
|
||||||
gimp_rgba_set (color, 0, 1, 0, 0.5);
|
gimp_rgba_set (color, 0, 1, 0, 0.7);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GIMP_BLUE_CHANNEL:
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __GIMP_FOREGROUND_SELECT_OPTIONS_H__
|
#ifndef __GIMP_FOREGROUND_SELECT_OPTIONS_H__
|
||||||
#define __GIMP_FOREGROUND_SELECT_OPTIONS_H__
|
#define __GIMP_FOREGROUND_SELECT_OPTIONS_H__
|
||||||
|
|
||||||
|
@ -31,19 +32,34 @@
|
||||||
|
|
||||||
|
|
||||||
typedef struct _GimpForegroundSelectOptions GimpForegroundSelectOptions;
|
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
|
struct _GimpForegroundSelectOptions
|
||||||
{
|
{
|
||||||
GimpSelectionOptions parent_instance;
|
GimpSelectionOptions parent_instance;
|
||||||
|
|
||||||
gboolean contiguous;
|
GimpMattingDrawMode draw_mode;
|
||||||
gboolean background;
|
|
||||||
gint stroke_width;
|
gint stroke_width;
|
||||||
gint smoothness;
|
|
||||||
GimpChannelType mask_color;
|
GimpChannelType mask_color;
|
||||||
gboolean expanded;
|
GimpMattingEngine engine;
|
||||||
gdouble sensitivity[3];
|
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,
|
void gimp_foreground_select_options_get_mask_color (GimpForegroundSelectOptions *options,
|
||||||
GimpRGB *color);
|
GimpRGB *color);
|
||||||
|
gdouble gimp_foreground_select_options_get_opacity (GimpForegroundSelectOptions *options);
|
||||||
|
|
||||||
|
|
||||||
#endif /* __GIMP_FOREGROUND_SELECT_OPTIONS_H__ */
|
#endif /* __GIMP_FOREGROUND_SELECT_OPTIONS_H__ */
|
||||||
|
|
||||||
|
|
|
@ -27,16 +27,18 @@
|
||||||
#include <gdk/gdkkeysyms.h>
|
#include <gdk/gdkkeysyms.h>
|
||||||
|
|
||||||
#include "libgimpmath/gimpmath.h"
|
#include "libgimpmath/gimpmath.h"
|
||||||
|
#include "libgimpcolor/gimpcolor.h"
|
||||||
#include "libgimpwidgets/gimpwidgets.h"
|
#include "libgimpwidgets/gimpwidgets.h"
|
||||||
|
|
||||||
#include "tools-types.h"
|
#include "tools-types.h"
|
||||||
|
|
||||||
#include "core/gimp.h"
|
#include "core/gimp.h"
|
||||||
#include "core/gimpchannel.h"
|
|
||||||
#include "core/gimpchannel-combine.h"
|
#include "core/gimpchannel-combine.h"
|
||||||
#include "core/gimpchannel-select.h"
|
#include "core/gimpchannel-select.h"
|
||||||
#include "core/gimpdrawable-foreground-extract.h"
|
#include "core/gimpdrawable-foreground-extract.h"
|
||||||
#include "core/gimpimage.h"
|
#include "core/gimpimage.h"
|
||||||
|
#include "core/gimplayer.h"
|
||||||
|
#include "core/gimplayermask.h"
|
||||||
#include "core/gimpprogress.h"
|
#include "core/gimpprogress.h"
|
||||||
#include "core/gimpscanconvert.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,
|
static void gimp_foreground_select_tool_select (GimpFreeSelectTool *free_sel,
|
||||||
GimpDisplay *display);
|
GimpDisplay *display);
|
||||||
|
|
||||||
static void gimp_foreground_select_tool_set_mask (GimpForegroundSelectTool *fg_select,
|
static void gimp_foreground_select_tool_set_trimap (GimpForegroundSelectTool *fg_select,
|
||||||
GimpDisplay *display,
|
GimpDisplay *display);
|
||||||
GimpChannel *mask);
|
static void gimp_foreground_select_tool_set_preview (GimpForegroundSelectTool *fg_select,
|
||||||
static void gimp_foreground_select_tool_apply (GimpForegroundSelectTool *fg_select,
|
GimpDisplay *display);
|
||||||
|
static void gimp_foreground_select_tool_drop_masks (GimpForegroundSelectTool *fg_select,
|
||||||
GimpDisplay *display);
|
GimpDisplay *display);
|
||||||
|
|
||||||
static void gimp_foreground_select_tool_stroke (GimpChannel *mask,
|
static void gimp_foreground_select_tool_apply (GimpForegroundSelectTool *fg_select,
|
||||||
FgSelectStroke *stroke);
|
GimpDisplay *display);
|
||||||
|
static void gimp_foreground_select_tool_preview (GimpForegroundSelectTool *fg_select,
|
||||||
static void gimp_foreground_select_tool_push_stroke (GimpForegroundSelectTool *fg_select,
|
GimpDisplay *display);
|
||||||
GimpDisplay *display,
|
|
||||||
GimpForegroundSelectOptions *options);
|
|
||||||
|
|
||||||
static void gimp_foreground_select_options_notify (GimpForegroundSelectOptions *options,
|
static void gimp_foreground_select_options_notify (GimpForegroundSelectOptions *options,
|
||||||
GParamSpec *pspec,
|
GParamSpec *pspec,
|
||||||
GimpForegroundSelectTool *fg_select);
|
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,
|
G_DEFINE_TYPE (GimpForegroundSelectTool, gimp_foreground_select_tool,
|
||||||
GIMP_TYPE_FREE_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,
|
gimp_tool_control_set_action_value_2 (tool->control,
|
||||||
"tools/tools-foreground-select-brush-size-set");
|
"tools/tools-foreground-select-brush-size-set");
|
||||||
|
|
||||||
fg_select->idle_id = 0;
|
|
||||||
fg_select->stroke = NULL;
|
fg_select->stroke = NULL;
|
||||||
fg_select->strokes = NULL;
|
|
||||||
fg_select->mask = NULL;
|
fg_select->mask = NULL;
|
||||||
|
fg_select->trimap = NULL;
|
||||||
|
fg_select->state = MATTING_STATE_FREE_SELECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -220,17 +225,12 @@ gimp_foreground_select_tool_finalize (GObject *object)
|
||||||
if (fg_select->stroke)
|
if (fg_select->stroke)
|
||||||
g_warning ("%s: stroke should be NULL at this point", G_STRLOC);
|
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)
|
if (fg_select->mask)
|
||||||
g_warning ("%s: mask should be NULL at this point", G_STRLOC);
|
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);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,29 +249,7 @@ gimp_foreground_select_tool_control (GimpTool *tool,
|
||||||
|
|
||||||
case GIMP_TOOL_ACTION_HALT:
|
case GIMP_TOOL_ACTION_HALT:
|
||||||
{
|
{
|
||||||
GList *list;
|
gimp_foreground_select_tool_drop_masks (fg_select, display);
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
tool->display = NULL;
|
tool->display = NULL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -293,7 +271,7 @@ gimp_foreground_select_tool_oper_update (GimpTool *tool,
|
||||||
GIMP_TOOL_CLASS (parent_class)->oper_update (tool, coords, state, proximity,
|
GIMP_TOOL_CLASS (parent_class)->oper_update (tool, coords, state, proximity,
|
||||||
display);
|
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);
|
GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);
|
||||||
|
|
||||||
|
@ -302,17 +280,17 @@ gimp_foreground_select_tool_oper_update (GimpTool *tool,
|
||||||
fg_select->last_coords = *coords;
|
fg_select->last_coords = *coords;
|
||||||
|
|
||||||
gimp_draw_tool_resume (draw_tool);
|
gimp_draw_tool_resume (draw_tool);
|
||||||
|
status = _("Paint trimap, (background, foreground and unknown) or press Enter to preview");
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
else
|
else if (fg_select->state == MATTING_STATE_FREE_SELECT)
|
||||||
{
|
{
|
||||||
if (GIMP_SELECTION_TOOL (tool)->function == SELECTION_SELECT)
|
if (GIMP_SELECTION_TOOL (tool)->function == SELECTION_SELECT)
|
||||||
status = _("Roughly outline the object to extract");
|
status = _("Roughly outline the object to extract");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = _("Press escape for return to trimap or Enter to apply");
|
||||||
|
}
|
||||||
|
|
||||||
if (proximity && status)
|
if (proximity && status)
|
||||||
gimp_tool_replace_status (tool, display, "%s", status);
|
gimp_tool_replace_status (tool, display, "%s", status);
|
||||||
|
@ -325,6 +303,7 @@ gimp_foreground_select_tool_modifier_key (GimpTool *tool,
|
||||||
GdkModifierType state,
|
GdkModifierType state,
|
||||||
GimpDisplay *display)
|
GimpDisplay *display)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
if (key == gimp_get_toggle_behavior_mask ())
|
if (key == gimp_get_toggle_behavior_mask ())
|
||||||
{
|
{
|
||||||
GimpForegroundSelectOptions *options;
|
GimpForegroundSelectOptions *options;
|
||||||
|
@ -335,6 +314,7 @@ gimp_foreground_select_tool_modifier_key (GimpTool *tool,
|
||||||
"background", ! options->background,
|
"background", ! options->background,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -345,14 +325,8 @@ gimp_foreground_select_tool_cursor_update (GimpTool *tool,
|
||||||
{
|
{
|
||||||
GimpForegroundSelectTool *fg_select = GIMP_FOREGROUND_SELECT_TOOL (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)
|
switch (GIMP_SELECTION_TOOL (tool)->function)
|
||||||
{
|
{
|
||||||
case SELECTION_MOVE_MASK:
|
case SELECTION_MOVE_MASK:
|
||||||
|
@ -378,10 +352,25 @@ gimp_foreground_select_tool_key_press (GimpTool *tool,
|
||||||
if (display != tool->display)
|
if (display != tool->display)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
#if 0
|
if (fg_select->state == MATTING_STATE_PAINT_TRIMAP)
|
||||||
if (fg_select->state)
|
{
|
||||||
#endif
|
switch (kevent->keyval)
|
||||||
if (fg_select->mask) /* dunno if that's the right condition */
|
{
|
||||||
|
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)
|
switch (kevent->keyval)
|
||||||
{
|
{
|
||||||
|
@ -392,7 +381,7 @@ gimp_foreground_select_tool_key_press (GimpTool *tool,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
case GDK_KEY_Escape:
|
case GDK_KEY_Escape:
|
||||||
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
|
gimp_foreground_select_tool_set_trimap (fg_select, display);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -418,7 +407,7 @@ gimp_foreground_select_tool_button_press (GimpTool *tool,
|
||||||
GimpForegroundSelectTool *fg_select = GIMP_FOREGROUND_SELECT_TOOL (tool);
|
GimpForegroundSelectTool *fg_select = GIMP_FOREGROUND_SELECT_TOOL (tool);
|
||||||
GimpDrawTool *draw_tool = GIMP_DRAW_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);
|
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);
|
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_start (draw_tool, display);
|
||||||
|
|
||||||
gimp_draw_tool_resume (draw_tool);
|
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,
|
GIMP_TOOL_CLASS (parent_class)->button_press (tool, coords, time, state,
|
||||||
press_type, display);
|
press_type, display);
|
||||||
|
@ -458,7 +447,7 @@ gimp_foreground_select_tool_button_release (GimpTool *tool,
|
||||||
{
|
{
|
||||||
GimpForegroundSelectTool *fg_select = GIMP_FOREGROUND_SELECT_TOOL (tool);
|
GimpForegroundSelectTool *fg_select = GIMP_FOREGROUND_SELECT_TOOL (tool);
|
||||||
|
|
||||||
if (fg_select->mask)
|
if (fg_select->state == MATTING_STATE_PAINT_TRIMAP)
|
||||||
{
|
{
|
||||||
GimpForegroundSelectOptions *options;
|
GimpForegroundSelectOptions *options;
|
||||||
|
|
||||||
|
@ -468,13 +457,15 @@ gimp_foreground_select_tool_button_release (GimpTool *tool,
|
||||||
|
|
||||||
gimp_tool_control_halt (tool->control);
|
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_free_select_tool_select (GIMP_FREE_SELECT_TOOL (tool), display);
|
||||||
|
|
||||||
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
|
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,
|
GIMP_TOOL_CLASS (parent_class)->button_release (tool,
|
||||||
coords, time, state,
|
coords, time, state,
|
||||||
|
@ -492,7 +483,7 @@ gimp_foreground_select_tool_motion (GimpTool *tool,
|
||||||
{
|
{
|
||||||
GimpForegroundSelectTool *fg_select = GIMP_FOREGROUND_SELECT_TOOL (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 *last = &g_array_index (fg_select->stroke,
|
||||||
GimpVector2,
|
GimpVector2,
|
||||||
|
@ -511,7 +502,7 @@ gimp_foreground_select_tool_motion (GimpTool *tool,
|
||||||
|
|
||||||
gimp_draw_tool_resume (GIMP_DRAW_TOOL (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,
|
GIMP_TOOL_CLASS (parent_class)->motion (tool,
|
||||||
coords, time, state, display);
|
coords, time, state, display);
|
||||||
|
@ -550,24 +541,23 @@ gimp_foreground_select_tool_draw (GimpDrawTool *draw_tool)
|
||||||
|
|
||||||
if (fg_select->stroke)
|
if (fg_select->stroke)
|
||||||
{
|
{
|
||||||
|
GimpDisplayShell *shell = gimp_display_get_shell (draw_tool->display);
|
||||||
|
|
||||||
gimp_draw_tool_add_pen (draw_tool,
|
gimp_draw_tool_add_pen (draw_tool,
|
||||||
(const GimpVector2 *) fg_select->stroke->data,
|
(const GimpVector2 *) fg_select->stroke->data,
|
||||||
fg_select->stroke->len,
|
fg_select->stroke->len,
|
||||||
GIMP_CONTEXT (options),
|
GIMP_CONTEXT (options),
|
||||||
(options->background ?
|
GIMP_ACTIVE_COLOR_FOREGROUND,
|
||||||
GIMP_ACTIVE_COLOR_BACKGROUND :
|
options->stroke_width * shell->scale_y);
|
||||||
GIMP_ACTIVE_COLOR_FOREGROUND),
|
|
||||||
options->stroke_width);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 x = fg_select->last_coords.x;
|
||||||
gint y = fg_select->last_coords.y;
|
gint y = fg_select->last_coords.y;
|
||||||
gdouble radius;
|
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 */
|
/* warn if the user is drawing outside of the working area */
|
||||||
if (FALSE)
|
if (FALSE)
|
||||||
|
@ -592,7 +582,7 @@ gimp_foreground_select_tool_draw (GimpDrawTool *draw_tool)
|
||||||
2 * radius, 2 * radius,
|
2 * radius, 2 * radius,
|
||||||
0.0, 2.0 * G_PI);
|
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);
|
GIMP_DRAW_TOOL_CLASS (parent_class)->draw (draw_tool);
|
||||||
}
|
}
|
||||||
|
@ -603,27 +593,20 @@ gimp_foreground_select_tool_select (GimpFreeSelectTool *free_sel,
|
||||||
GimpDisplay *display)
|
GimpDisplay *display)
|
||||||
{
|
{
|
||||||
GimpForegroundSelectTool *fg_select;
|
GimpForegroundSelectTool *fg_select;
|
||||||
GimpForegroundSelectOptions *options;
|
|
||||||
GimpImage *image = gimp_display_get_image (display);
|
GimpImage *image = gimp_display_get_image (display);
|
||||||
GimpDrawable *drawable;
|
GimpDrawable *drawable;
|
||||||
GimpScanConvert *scan_convert;
|
GimpScanConvert *scan_convert;
|
||||||
GimpChannel *mask;
|
|
||||||
const GimpVector2 *points;
|
const GimpVector2 *points;
|
||||||
gint n_points;
|
gint n_points;
|
||||||
|
|
||||||
drawable = gimp_image_get_active_drawable (image);
|
drawable = gimp_image_get_active_drawable (image);
|
||||||
fg_select = GIMP_FOREGROUND_SELECT_TOOL (free_sel);
|
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)
|
if (! drawable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (fg_select->state == MATTING_STATE_FREE_SELECT)
|
||||||
|
{
|
||||||
scan_convert = gimp_scan_convert_new ();
|
scan_convert = gimp_scan_convert_new ();
|
||||||
|
|
||||||
gimp_free_select_tool_get_points (free_sel,
|
gimp_free_select_tool_get_points (free_sel,
|
||||||
|
@ -635,77 +618,85 @@ gimp_foreground_select_tool_select (GimpFreeSelectTool *free_sel,
|
||||||
points,
|
points,
|
||||||
TRUE);
|
TRUE);
|
||||||
|
|
||||||
mask = gimp_channel_new (image,
|
fg_select->trimap = gimp_channel_new (image,
|
||||||
gimp_image_get_width (image),
|
gimp_image_get_width (image),
|
||||||
gimp_image_get_height (image),
|
gimp_image_get_height (image),
|
||||||
"foreground-extraction", NULL);
|
"foreground-extraction",NULL);
|
||||||
|
|
||||||
gimp_scan_convert_render_value (scan_convert,
|
gimp_scan_convert_render_value (scan_convert,
|
||||||
gimp_drawable_get_buffer (GIMP_DRAWABLE (mask)),
|
gimp_drawable_get_buffer (GIMP_DRAWABLE (fg_select->trimap)),
|
||||||
0, 0, 0.5);
|
0, 0, 1.0);
|
||||||
gimp_scan_convert_free (scan_convert);
|
gimp_scan_convert_free (scan_convert);
|
||||||
|
|
||||||
if (fg_select->strokes)
|
gimp_foreground_select_tool_set_trimap (fg_select, display);
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
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
|
static void
|
||||||
gimp_foreground_select_tool_set_mask (GimpForegroundSelectTool *fg_select,
|
gimp_foreground_select_tool_set_trimap (GimpForegroundSelectTool *fg_select,
|
||||||
GimpDisplay *display,
|
GimpDisplay *display)
|
||||||
GimpChannel *mask)
|
|
||||||
{
|
{
|
||||||
GimpTool *tool = GIMP_TOOL (fg_select);
|
GimpTool *tool = GIMP_TOOL (fg_select);
|
||||||
GimpForegroundSelectOptions *options;
|
GimpForegroundSelectOptions *options;
|
||||||
|
GimpRGB color;
|
||||||
|
|
||||||
|
g_return_if_fail (fg_select->trimap != NULL);
|
||||||
|
|
||||||
options = GIMP_FOREGROUND_SELECT_TOOL_GET_OPTIONS (tool);
|
options = GIMP_FOREGROUND_SELECT_TOOL_GET_OPTIONS (tool);
|
||||||
|
|
||||||
if (fg_select->mask == mask)
|
gimp_foreground_select_options_get_mask_color (options, &color);
|
||||||
return;
|
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)
|
if (fg_select->mask)
|
||||||
{
|
{
|
||||||
|
@ -713,40 +704,115 @@ gimp_foreground_select_tool_set_mask (GimpForegroundSelectTool *fg_select,
|
||||||
fg_select->mask = NULL;
|
fg_select->mask = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask)
|
if (GIMP_IS_DISPLAY (display))
|
||||||
{
|
|
||||||
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
|
|
||||||
{
|
{
|
||||||
gimp_display_shell_set_mask (gimp_display_get_shell (display),
|
gimp_display_shell_set_mask (gimp_display_get_shell (display),
|
||||||
NULL, NULL);
|
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_control_set_tool_cursor (tool->control,
|
||||||
GIMP_TOOL_CURSOR_FREE_SELECT);
|
GIMP_TOOL_CURSOR_FREE_SELECT);
|
||||||
gimp_tool_control_set_toggle_tool_cursor (tool->control,
|
gimp_tool_control_set_toggle_tool_cursor (tool->control,
|
||||||
GIMP_TOOL_CURSOR_FREE_SELECT);
|
GIMP_TOOL_CURSOR_FREE_SELECT);
|
||||||
|
|
||||||
gimp_tool_control_set_toggled (tool->control, FALSE);
|
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
|
static void
|
||||||
|
@ -754,18 +820,20 @@ gimp_foreground_select_tool_apply (GimpForegroundSelectTool *fg_select,
|
||||||
GimpDisplay *display)
|
GimpDisplay *display)
|
||||||
{
|
{
|
||||||
GimpTool *tool = GIMP_TOOL (fg_select);
|
GimpTool *tool = GIMP_TOOL (fg_select);
|
||||||
GimpSelectionOptions *options = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);
|
|
||||||
GimpImage *image = gimp_display_get_image (display);
|
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);
|
g_return_if_fail (fg_select->mask != NULL);
|
||||||
|
|
||||||
gimp_channel_select_channel (gimp_image_get_mask (image),
|
buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (fg_select->mask));
|
||||||
C_("command", "Foreground Select"),
|
|
||||||
fg_select->mask, 0, 0,
|
layer_mask = gimp_layer_mask_new_from_buffer (buffer, image,
|
||||||
options->operation,
|
"mask", &color);
|
||||||
options->feather,
|
|
||||||
options->feather_radius,
|
gimp_layer_add_mask (layer, layer_mask, TRUE, NULL);
|
||||||
options->feather_radius);
|
|
||||||
|
|
||||||
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
|
gimp_tool_control (tool, GIMP_TOOL_ACTION_HALT, display);
|
||||||
|
|
||||||
|
@ -773,16 +841,22 @@ gimp_foreground_select_tool_apply (GimpForegroundSelectTool *fg_select,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gimp_foreground_select_tool_stroke (GimpChannel *mask,
|
gimp_foreground_select_tool_stroke_paint (GimpForegroundSelectTool *fg_select,
|
||||||
FgSelectStroke *stroke)
|
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];
|
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].x += 0.01;
|
||||||
points[1].y += 0.01;
|
points[1].y += 0.01;
|
||||||
|
@ -792,111 +866,50 @@ gimp_foreground_select_tool_stroke (GimpChannel *mask,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gimp_scan_convert_add_polyline (scan_convert,
|
gimp_scan_convert_add_polyline (scan_convert,
|
||||||
stroke->num_points, stroke->points,
|
fg_select->stroke->len,
|
||||||
|
(GimpVector2 *) fg_select->stroke->data,
|
||||||
FALSE);
|
FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
width = ROUND ((gdouble) options->stroke_width);
|
||||||
|
|
||||||
gimp_scan_convert_stroke (scan_convert,
|
gimp_scan_convert_stroke (scan_convert,
|
||||||
stroke->width,
|
width,
|
||||||
GIMP_JOIN_ROUND, GIMP_CAP_ROUND, 10.0,
|
GIMP_JOIN_ROUND, GIMP_CAP_ROUND, 10.0,
|
||||||
0.0, NULL);
|
0.0, NULL);
|
||||||
|
|
||||||
gimp_scan_convert_compose_value (scan_convert,
|
gimp_scan_convert_compose_value (scan_convert,
|
||||||
gimp_drawable_get_buffer (GIMP_DRAWABLE (mask)),
|
gimp_drawable_get_buffer (GIMP_DRAWABLE (fg_select->trimap)),
|
||||||
0, 0, stroke->background ? 0.0 : 1.0);
|
0, 0,
|
||||||
|
gimp_foreground_select_options_get_opacity (options));
|
||||||
|
|
||||||
gimp_scan_convert_free (scan_convert);
|
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->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
|
static void
|
||||||
gimp_foreground_select_options_notify (GimpForegroundSelectOptions *options,
|
gimp_foreground_select_options_notify (GimpForegroundSelectOptions *options,
|
||||||
GParamSpec *pspec,
|
GParamSpec *pspec,
|
||||||
GimpForegroundSelectTool *fg_select)
|
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"))
|
if (g_str_has_prefix (pspec->name, "mask-color"))
|
||||||
{
|
{
|
||||||
GimpTool *tool = GIMP_TOOL (fg_select);
|
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);
|
if (fg_select->state == MATTING_STATE_PREVIEW_MASK)
|
||||||
gimp_display_shell_set_mask (gimp_display_get_shell (tool->display),
|
{
|
||||||
GIMP_DRAWABLE (fg_select->mask), &color);
|
gimp_foreground_select_tool_set_preview (fg_select, tool->display);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,13 +22,12 @@
|
||||||
#include "gimpfreeselecttool.h"
|
#include "gimpfreeselecttool.h"
|
||||||
|
|
||||||
|
|
||||||
typedef enum /*< pdb-skip, skip >*/
|
typedef enum
|
||||||
{
|
{
|
||||||
SIOX_REFINEMENT_NO_CHANGE = 0,
|
MATTING_STATE_FREE_SELECT = 0,
|
||||||
SIOX_REFINEMENT_ADD_FOREGROUND = (1 << 0),
|
MATTING_STATE_PAINT_TRIMAP,
|
||||||
SIOX_REFINEMENT_ADD_BACKGROUND = (1 << 1),
|
MATTING_STATE_PREVIEW_MASK,
|
||||||
SIOX_REFINEMENT_RECALCULATE = 0xFF
|
} MattingState;
|
||||||
} SioxRefinementType;
|
|
||||||
|
|
||||||
|
|
||||||
#define GIMP_TYPE_FOREGROUND_SELECT_TOOL (gimp_foreground_select_tool_get_type ())
|
#define GIMP_TYPE_FOREGROUND_SELECT_TOOL (gimp_foreground_select_tool_get_type ())
|
||||||
|
@ -49,14 +48,10 @@ struct _GimpForegroundSelectTool
|
||||||
GimpFreeSelectTool parent_instance;
|
GimpFreeSelectTool parent_instance;
|
||||||
|
|
||||||
GimpCoords last_coords;
|
GimpCoords last_coords;
|
||||||
guint idle_id;
|
|
||||||
GArray *stroke;
|
GArray *stroke;
|
||||||
GList *strokes;
|
GimpChannel *trimap;
|
||||||
GimpChannel *mask;
|
GimpChannel *mask;
|
||||||
#if 0
|
MattingState state;
|
||||||
SioxState *state;
|
|
||||||
#endif
|
|
||||||
SioxRefinementType refinement;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GimpForegroundSelectToolClass
|
struct _GimpForegroundSelectToolClass
|
||||||
|
|
Loading…
Reference in New Issue