mirror of https://github.com/GNOME/gimp.git
app: cleanup in GimpImageMap
- don't allow to create a GimpImageMap of an operation without output - make "region", "mode" and "gamma-hack" settable on a map that already has a graph - don't insert a useless "over" if the operation is a source op - do the gamma-hack always on formats with alpha, so we don't lose intermediate alpha results on source ops - simplify graph connection a lot - in GimpImageMap tool, don't recreate the map when reconfiguring "region" and "gamma-hack"
This commit is contained in:
parent
1ff1c687f4
commit
6eba4c716b
|
@ -86,6 +86,10 @@ struct _GimpImageMap
|
|||
static void gimp_image_map_dispose (GObject *object);
|
||||
static void gimp_image_map_finalize (GObject *object);
|
||||
|
||||
static void gimp_image_map_sync_region (GimpImageMap *image_map);
|
||||
static void gimp_image_map_sync_mode (GimpImageMap *image_map);
|
||||
static void gimp_image_map_sync_gamma_hack (GimpImageMap *image_map);
|
||||
|
||||
static gboolean gimp_image_map_is_filtering (GimpImageMap *image_map);
|
||||
static gboolean gimp_image_map_add_filter (GimpImageMap *image_map);
|
||||
static gboolean gimp_image_map_remove_filter (GimpImageMap *image_map);
|
||||
|
@ -194,6 +198,7 @@ gimp_image_map_new (GimpDrawable *drawable,
|
|||
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
|
||||
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
|
||||
g_return_val_if_fail (GEGL_IS_NODE (operation), NULL);
|
||||
g_return_val_if_fail (gegl_node_has_pad (operation, "output"), NULL);
|
||||
|
||||
image_map = g_object_new (GIMP_TYPE_IMAGE_MAP, NULL);
|
||||
|
||||
|
@ -214,16 +219,12 @@ gimp_image_map_set_region (GimpImageMap *image_map,
|
|||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE_MAP (image_map));
|
||||
|
||||
if (region != image_map->region)
|
||||
{
|
||||
image_map->region = region;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_map_set_gamma_hack (GimpImageMap *image_map,
|
||||
gboolean gamma_hack)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE_MAP (image_map));
|
||||
|
||||
image_map->gamma_hack = gamma_hack;
|
||||
gimp_image_map_sync_region (image_map);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -239,10 +240,21 @@ gimp_image_map_set_mode (GimpImageMap *image_map,
|
|||
image_map->opacity = opacity;
|
||||
image_map->paint_mode = paint_mode;
|
||||
|
||||
if (image_map->applicator)
|
||||
gimp_applicator_set_mode (image_map->applicator,
|
||||
image_map->opacity,
|
||||
image_map->paint_mode);
|
||||
gimp_image_map_sync_mode (image_map);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_map_set_gamma_hack (GimpImageMap *image_map,
|
||||
gboolean gamma_hack)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE_MAP (image_map));
|
||||
|
||||
if (gamma_hack != image_map->gamma_hack)
|
||||
{
|
||||
image_map->gamma_hack = gamma_hack;
|
||||
|
||||
gimp_image_map_sync_gamma_hack (image_map);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -300,8 +312,6 @@ gimp_image_map_apply (GimpImageMap *image_map,
|
|||
if (! image_map->filter)
|
||||
{
|
||||
GeglNode *filter_node;
|
||||
GeglNode *filter_output;
|
||||
GeglNode *input;
|
||||
|
||||
image_map->filter = gimp_filter_new (image_map->undo_desc);
|
||||
gimp_viewable_set_icon_name (GIMP_VIEWABLE (image_map->filter),
|
||||
|
@ -326,131 +336,35 @@ gimp_image_map_apply (GimpImageMap *image_map,
|
|||
"operation", "gegl:crop",
|
||||
NULL);
|
||||
|
||||
if (image_map->gamma_hack)
|
||||
{
|
||||
const Babl *drawable_format;
|
||||
const Babl *cast_format;
|
||||
|
||||
drawable_format = gimp_drawable_get_format (image_map->drawable);
|
||||
|
||||
cast_format =
|
||||
gimp_babl_format (gimp_babl_format_get_base_type (drawable_format),
|
||||
gimp_babl_precision (gimp_babl_format_get_component_type (drawable_format),
|
||||
! gimp_babl_format_get_linear (drawable_format)),
|
||||
babl_format_has_alpha (drawable_format));
|
||||
|
||||
image_map->cast_before = gegl_node_new_child (filter_node,
|
||||
"operation", "gegl:cast-format",
|
||||
"input-format", drawable_format,
|
||||
"output-format", cast_format,
|
||||
NULL);
|
||||
image_map->cast_after = gegl_node_new_child (filter_node,
|
||||
"operation", "gegl:cast-format",
|
||||
"input-format", cast_format,
|
||||
"output-format", drawable_format,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
image_map->cast_before = gegl_node_new_child (filter_node,
|
||||
"operation", "gegl:nop",
|
||||
NULL);
|
||||
image_map->cast_after = gegl_node_new_child (filter_node,
|
||||
"operation", "gegl:nop",
|
||||
NULL);
|
||||
}
|
||||
|
||||
input = gegl_node_get_input_proxy (filter_node, "input");
|
||||
gimp_image_map_sync_region (image_map);
|
||||
gimp_image_map_sync_mode (image_map);
|
||||
gimp_image_map_sync_gamma_hack (image_map);
|
||||
|
||||
if (gegl_node_has_pad (image_map->operation, "input") &&
|
||||
gegl_node_has_pad (image_map->operation, "output"))
|
||||
if (gegl_node_has_pad (image_map->operation, "input"))
|
||||
{
|
||||
/* if there are input and output pads we probably have a
|
||||
* filter OP, connect it on both ends.
|
||||
*/
|
||||
GeglNode *input = gegl_node_get_input_proxy (filter_node, "input");
|
||||
|
||||
gegl_node_link_many (input,
|
||||
image_map->translate,
|
||||
image_map->crop,
|
||||
image_map->cast_before,
|
||||
image_map->operation,
|
||||
image_map->cast_after,
|
||||
NULL);
|
||||
|
||||
filter_output = image_map->cast_after;
|
||||
}
|
||||
else if (gegl_node_has_pad (image_map->operation, "output"))
|
||||
{
|
||||
/* if there is only an output pad we probably have a
|
||||
* source OP, blend its result on top of the original
|
||||
* pixels.
|
||||
*/
|
||||
GeglNode *over = gegl_node_new_child (filter_node,
|
||||
"operation", "gegl:over",
|
||||
NULL);
|
||||
|
||||
gegl_node_link_many (input,
|
||||
image_map->translate,
|
||||
image_map->crop,
|
||||
over,
|
||||
NULL);
|
||||
|
||||
gegl_node_link_many (image_map->operation,
|
||||
image_map->cast_after,
|
||||
NULL);
|
||||
|
||||
gegl_node_connect_to (image_map->cast_after, "output",
|
||||
over, "aux");
|
||||
|
||||
filter_output = over;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* otherwise we just construct a silly nop pipleline
|
||||
*/
|
||||
gegl_node_link_many (input,
|
||||
image_map->translate,
|
||||
image_map->crop,
|
||||
image_map->cast_before,
|
||||
image_map->cast_after,
|
||||
NULL);
|
||||
|
||||
filter_output = image_map->cast_after;
|
||||
}
|
||||
|
||||
gegl_node_connect_to (filter_output, "output",
|
||||
filter_node, "aux");
|
||||
|
||||
gimp_applicator_set_mode (image_map->applicator,
|
||||
image_map->opacity,
|
||||
image_map->paint_mode);
|
||||
}
|
||||
|
||||
if (image_map->region == GIMP_IMAGE_MAP_REGION_SELECTION)
|
||||
{
|
||||
gegl_node_set (image_map->translate,
|
||||
"x", (gdouble) -image_map->filter_area.x,
|
||||
"y", (gdouble) -image_map->filter_area.y,
|
||||
NULL);
|
||||
|
||||
gegl_node_set (image_map->crop,
|
||||
"width", (gdouble) image_map->filter_area.width,
|
||||
"height", (gdouble) image_map->filter_area.height,
|
||||
NULL);
|
||||
|
||||
gimp_applicator_set_apply_offset (image_map->applicator,
|
||||
image_map->filter_area.x,
|
||||
image_map->filter_area.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
GimpItem *item = GIMP_ITEM (image_map->drawable);
|
||||
gdouble width = gimp_item_get_width (item);
|
||||
gdouble height = gimp_item_get_height (item);
|
||||
|
||||
gegl_node_set (image_map->crop,
|
||||
"width", width,
|
||||
"height", height,
|
||||
NULL);
|
||||
}
|
||||
|
||||
active_mask = gimp_drawable_get_active_mask (image_map->drawable);
|
||||
|
@ -522,6 +436,101 @@ gimp_image_map_abort (GimpImageMap *image_map)
|
|||
|
||||
/* private functions */
|
||||
|
||||
static void
|
||||
gimp_image_map_sync_region (GimpImageMap *image_map)
|
||||
{
|
||||
if (image_map->applicator)
|
||||
{
|
||||
if (image_map->region == GIMP_IMAGE_MAP_REGION_SELECTION)
|
||||
{
|
||||
gegl_node_set (image_map->translate,
|
||||
"x", (gdouble) -image_map->filter_area.x,
|
||||
"y", (gdouble) -image_map->filter_area.y,
|
||||
NULL);
|
||||
|
||||
gegl_node_set (image_map->crop,
|
||||
"width", (gdouble) image_map->filter_area.width,
|
||||
"height", (gdouble) image_map->filter_area.height,
|
||||
NULL);
|
||||
|
||||
gimp_applicator_set_apply_offset (image_map->applicator,
|
||||
image_map->filter_area.x,
|
||||
image_map->filter_area.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
GimpItem *item = GIMP_ITEM (image_map->drawable);
|
||||
gdouble width = gimp_item_get_width (item);
|
||||
gdouble height = gimp_item_get_height (item);
|
||||
|
||||
gegl_node_set (image_map->translate,
|
||||
"x", (gdouble) 0.0,
|
||||
"y", (gdouble) 0.0,
|
||||
NULL);
|
||||
|
||||
gegl_node_set (image_map->crop,
|
||||
"width", width,
|
||||
"height", height,
|
||||
NULL);
|
||||
|
||||
gimp_applicator_set_apply_offset (image_map->applicator, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_image_map_sync_mode (GimpImageMap *image_map)
|
||||
{
|
||||
if (image_map->applicator)
|
||||
gimp_applicator_set_mode (image_map->applicator,
|
||||
image_map->opacity,
|
||||
image_map->paint_mode);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_image_map_sync_gamma_hack (GimpImageMap *image_map)
|
||||
{
|
||||
if (image_map->applicator)
|
||||
{
|
||||
if (image_map->gamma_hack)
|
||||
{
|
||||
const Babl *drawable_format;
|
||||
const Babl *cast_format;
|
||||
|
||||
drawable_format =
|
||||
gimp_drawable_get_format_with_alpha (image_map->drawable);
|
||||
|
||||
cast_format =
|
||||
gimp_babl_format (gimp_babl_format_get_base_type (drawable_format),
|
||||
gimp_babl_precision (gimp_babl_format_get_component_type (drawable_format),
|
||||
! gimp_babl_format_get_linear (drawable_format)),
|
||||
TRUE);
|
||||
|
||||
gegl_node_set (image_map->cast_before,
|
||||
"operation", "gegl:cast-format",
|
||||
"input-format", drawable_format,
|
||||
"output-format", cast_format,
|
||||
NULL);
|
||||
|
||||
gegl_node_set (image_map->cast_after,
|
||||
"operation", "gegl:cast-format",
|
||||
"input-format", cast_format,
|
||||
"output-format", drawable_format,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
gegl_node_set (image_map->cast_before,
|
||||
"operation", "gegl:nop",
|
||||
NULL);
|
||||
|
||||
gegl_node_set (image_map->cast_after,
|
||||
"operation", "gegl:nop",
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_image_map_is_filtering (GimpImageMap *image_map)
|
||||
{
|
||||
|
|
|
@ -56,13 +56,13 @@ GimpImageMap * gimp_image_map_new (GimpDrawable *drawable,
|
|||
|
||||
void gimp_image_map_set_region (GimpImageMap *image_map,
|
||||
GimpImageMapRegion region);
|
||||
void gimp_image_map_set_gamma_hack (GimpImageMap *image_map,
|
||||
gboolean gamma_hack);
|
||||
|
||||
void gimp_image_map_set_mode (GimpImageMap *image_map,
|
||||
gdouble opacity,
|
||||
GimpLayerModeEffects paint_mode);
|
||||
|
||||
void gimp_image_map_set_gamma_hack (GimpImageMap *image_map,
|
||||
gboolean gamma_hack);
|
||||
|
||||
void gimp_image_map_apply (GimpImageMap *image_map,
|
||||
const GeglRectangle *area);
|
||||
|
||||
|
|
|
@ -277,16 +277,9 @@ gamma_hack (GtkToggleButton *button,
|
|||
{
|
||||
if (image_map_tool->image_map)
|
||||
{
|
||||
GimpTool *tool = GIMP_TOOL (image_map_tool);
|
||||
|
||||
gimp_tool_control_push_preserve (tool->control, TRUE);
|
||||
|
||||
gimp_image_map_tool_create_map (image_map_tool);
|
||||
gimp_image_map_set_gamma_hack (image_map_tool->image_map,
|
||||
gtk_toggle_button_get_active (button));
|
||||
gimp_image_map_tool_preview (image_map_tool);
|
||||
|
||||
gimp_tool_control_pop_preserve (tool->control);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -524,12 +517,11 @@ gimp_image_map_tool_options_notify (GimpTool *tool,
|
|||
const GParamSpec *pspec)
|
||||
{
|
||||
GimpImageMapTool *image_map_tool = GIMP_IMAGE_MAP_TOOL (tool);
|
||||
GimpImageMapOptions *im_options = GIMP_IMAGE_MAP_OPTIONS (options);
|
||||
|
||||
if (! strcmp (pspec->name, "preview") &&
|
||||
image_map_tool->image_map)
|
||||
{
|
||||
GimpImageMapOptions *im_options = GIMP_IMAGE_MAP_OPTIONS (options);
|
||||
|
||||
if (im_options->preview)
|
||||
{
|
||||
gimp_tool_control_push_preserve (tool->control, TRUE);
|
||||
|
@ -550,12 +542,8 @@ gimp_image_map_tool_options_notify (GimpTool *tool,
|
|||
else if (! strcmp (pspec->name, "region") &&
|
||||
image_map_tool->image_map)
|
||||
{
|
||||
gimp_tool_control_push_preserve (tool->control, TRUE);
|
||||
|
||||
gimp_image_map_tool_create_map (image_map_tool);
|
||||
gimp_image_map_set_region (image_map_tool->image_map, im_options->region);
|
||||
gimp_image_map_tool_preview (image_map_tool);
|
||||
|
||||
gimp_tool_control_pop_preserve (tool->control);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue