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"
|
||||
|
||||
#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,40 +88,27 @@ 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_ENUM (object_class, PROP_DRAW_MODE,
|
||||
"draw-mode",
|
||||
N_("Paint over areas to mark color values for "
|
||||
"inclusion or exclusion from selection"),
|
||||
GIMP_TYPE_MATTING_DRAW_MODE,
|
||||
GIMP_MATTING_DRAW_MODE_FOREGROUND,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_BACKGROUND,
|
||||
"background",
|
||||
N_("Paint over areas to mark color values for "
|
||||
"inclusion or exclusion from selection"),
|
||||
FALSE,
|
||||
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,
|
||||
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_INT (object_class, PROP_STROKE_WIDTH,
|
||||
"stroke-width",
|
||||
N_("Size of the brush used for refinements"),
|
||||
1, 6000, 10,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_MASK_COLOR,
|
||||
"mask-color",
|
||||
|
@ -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_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_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_PARAM_STATIC_STRINGS);
|
||||
#endif
|
||||
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_INT (object_class, PROP_ACTIVE_LEVELS,
|
||||
"active-levels",
|
||||
N_("Parameter for matting-levin"),
|
||||
1, 10, 2,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
GIMP_CONFIG_INSTALL_PROP_INT (object_class, PROP_ITERATIONS,
|
||||
"iterations",
|
||||
N_("Parameter for matting-global"),
|
||||
1, 10, 2,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -159,51 +148,39 @@ gimp_foreground_select_options_set_property (GObject *object,
|
|||
GimpForegroundSelectOptions *options = GIMP_FOREGROUND_SELECT_OPTIONS (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:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -215,51 +192,40 @@ gimp_foreground_select_options_get_property (GObject *object,
|
|||
GimpForegroundSelectOptions *options = GIMP_FOREGROUND_SELECT_OPTIONS (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:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
|
@ -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:
|
||||
|
|
|
@ -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__
|
||||
|
||||
|
@ -30,20 +31,35 @@
|
|||
#define GIMP_FOREGROUND_SELECT_OPTIONS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_FOREGROUND_SELECT_OPTIONS, GimpForegroundSelectOptionsClass))
|
||||
|
||||
|
||||
typedef struct _GimpForegroundSelectOptions GimpForegroundSelectOptions;
|
||||
typedef GimpSelectionOptionsClass GimpForegroundSelectOptionsClass;
|
||||
typedef struct _GimpForegroundSelectOptions GimpForegroundSelectOptions;
|
||||
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;
|
||||
gint stroke_width;
|
||||
gint smoothness;
|
||||
GimpChannelType mask_color;
|
||||
gboolean expanded;
|
||||
gdouble sensitivity[3];
|
||||
GimpMattingDrawMode draw_mode;
|
||||
gint stroke_width;
|
||||
GimpChannelType mask_color;
|
||||
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__ */
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
@ -105,25 +107,28 @@ static void gimp_foreground_select_tool_motion (GimpTool *tool
|
|||
|
||||
static void gimp_foreground_select_tool_draw (GimpDrawTool *draw_tool);
|
||||
|
||||
static void gimp_foreground_select_tool_select (GimpFreeSelectTool *free_sel,
|
||||
GimpDisplay *display);
|
||||
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,
|
||||
GimpDisplay *display);
|
||||
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_apply (GimpForegroundSelectTool *fg_select,
|
||||
GimpDisplay *display);
|
||||
static void gimp_foreground_select_tool_preview (GimpForegroundSelectTool *fg_select,
|
||||
GimpDisplay *display);
|
||||
|
||||
static void gimp_foreground_select_tool_push_stroke (GimpForegroundSelectTool *fg_select,
|
||||
GimpDisplay *display,
|
||||
GimpForegroundSelectOptions *options);
|
||||
static void gimp_foreground_select_options_notify (GimpForegroundSelectOptions *options,
|
||||
GParamSpec *pspec,
|
||||
GimpForegroundSelectTool *fg_select);
|
||||
|
||||
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,
|
||||
|
@ -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
|
||||
|
@ -218,18 +223,13 @@ gimp_foreground_select_tool_finalize (GObject *object)
|
|||
GimpForegroundSelectTool *fg_select = GIMP_FOREGROUND_SELECT_TOOL (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
|
||||
g_warning ("%s: stroke should be NULL at this point", G_STRLOC);
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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;
|
||||
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);
|
||||
}
|
||||
|
@ -602,110 +592,111 @@ static void
|
|||
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;
|
||||
GimpForegroundSelectTool *fg_select;
|
||||
GimpImage *image = gimp_display_get_image (display);
|
||||
GimpDrawable *drawable;
|
||||
GimpScanConvert *scan_convert;
|
||||
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;
|
||||
|
||||
scan_convert = gimp_scan_convert_new ();
|
||||
|
||||
gimp_free_select_tool_get_points (free_sel,
|
||||
&points,
|
||||
&n_points);
|
||||
|
||||
gimp_scan_convert_add_polyline (scan_convert,
|
||||
n_points,
|
||||
points,
|
||||
TRUE);
|
||||
|
||||
mask = gimp_channel_new (image,
|
||||
gimp_image_get_width (image),
|
||||
gimp_image_get_height (image),
|
||||
"foreground-extraction", NULL);
|
||||
|
||||
gimp_scan_convert_render_value (scan_convert,
|
||||
gimp_drawable_get_buffer (GIMP_DRAWABLE (mask)),
|
||||
0, 0, 0.5);
|
||||
gimp_scan_convert_free (scan_convert);
|
||||
|
||||
if (fg_select->strokes)
|
||||
if (fg_select->state == MATTING_STATE_FREE_SELECT)
|
||||
{
|
||||
GList *list;
|
||||
scan_convert = gimp_scan_convert_new ();
|
||||
|
||||
gimp_set_busy (image->gimp);
|
||||
gimp_free_select_tool_get_points (free_sel,
|
||||
&points,
|
||||
&n_points);
|
||||
|
||||
/* apply foreground and background markers */
|
||||
for (list = fg_select->strokes; list; list = list->next)
|
||||
gimp_foreground_select_tool_stroke (mask, list->data);
|
||||
gimp_scan_convert_add_polyline (scan_convert,
|
||||
n_points,
|
||||
points,
|
||||
TRUE);
|
||||
|
||||
#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->trimap = gimp_channel_new (image,
|
||||
gimp_image_get_width (image),
|
||||
gimp_image_get_height (image),
|
||||
"foreground-extraction",NULL);
|
||||
|
||||
fg_select->refinement = SIOX_REFINEMENT_NO_CHANGE;
|
||||
gimp_scan_convert_render_value (scan_convert,
|
||||
gimp_drawable_get_buffer (GIMP_DRAWABLE (fg_select->trimap)),
|
||||
0, 0, 1.0);
|
||||
gimp_scan_convert_free (scan_convert);
|
||||
|
||||
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,59 +704,136 @@ 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_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, options->background);
|
||||
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
|
||||
{
|
||||
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);
|
||||
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
|
||||
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);
|
||||
GimpTool *tool = GIMP_TOOL (fg_select);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue