[gimp] app: add a GimpFilterStack to each GimpDrawable
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: add a GimpFilterStack to each GimpDrawable
- Date: Thu, 11 Apr 2013 17:09:18 +0000 (UTC)
commit f3308e6ba3c6379075d7ea5938578c07a22db739
Author: Michael Natterer <mitch gimp org>
Date: Thu Apr 11 19:06:23 2013 +0200
app: add a GimpFilterStack to each GimpDrawable
which is part of the drawable's source_node, so we can generically
filter a drawable's pixels. Reading from the source_node will
transparently give the filtered results.
Turn floating selection compositing into a GimpFilter and add it to
the filter stack while we have a floating selection on the drawable.
app/core/gimpdrawable-private.h | 2 +
app/core/gimpdrawable.c | 157 ++++++++++++++++++++++++---------------
2 files changed, 100 insertions(+), 59 deletions(-)
---
diff --git a/app/core/gimpdrawable-private.h b/app/core/gimpdrawable-private.h
index bfe9d38..db1c5ab 100644
--- a/app/core/gimpdrawable-private.h
+++ b/app/core/gimpdrawable-private.h
@@ -25,8 +25,10 @@ struct _GimpDrawablePrivate
GeglNode *source_node;
GeglNode *buffer_source_node;
+ GimpContainer *filter_stack;
GimpLayer *floating_selection;
+ GimpFilter *fs_filter;
GeglNode *fs_crop_node;
GeglNode *fs_offset_node;
GeglNode *fs_mode_node;
diff --git a/app/core/gimpdrawable.c b/app/core/gimpdrawable.c
index 3e12212..8862f5a 100644
--- a/app/core/gimpdrawable.c
+++ b/app/core/gimpdrawable.c
@@ -40,6 +40,7 @@
#include "gimpdrawable-private.h"
#include "gimpdrawable-shadow.h"
#include "gimpdrawable-transform.h"
+#include "gimpfilterstack.h"
#include "gimpimage.h"
#include "gimpimage-colormap.h"
#include "gimpimage-undo-push.h"
@@ -172,7 +173,7 @@ static void gimp_drawable_real_swap_pixels (GimpDrawable *drawable,
gint x,
gint y);
-static void gimp_drawable_sync_source_node (GimpDrawable *drawable,
+static void gimp_drawable_sync_fs_filter (GimpDrawable *drawable,
gboolean detach_fs);
static void gimp_drawable_fs_notify (GimpLayer *fs,
const GParamSpec *pspec,
@@ -269,6 +270,8 @@ gimp_drawable_init (GimpDrawable *drawable)
drawable->private = G_TYPE_INSTANCE_GET_PRIVATE (drawable,
GIMP_TYPE_DRAWABLE,
GimpDrawablePrivate);
+
+ drawable->private->filter_stack = gimp_filter_stack_new (GIMP_TYPE_FILTER);
}
/* sorry for the evil casts */
@@ -313,6 +316,12 @@ gimp_drawable_finalize (GObject *object)
drawable->private->source_node = NULL;
}
+ if (drawable->private->filter_stack)
+ {
+ g_object_unref (drawable->private->filter_stack);
+ drawable->private->filter_stack = NULL;
+ }
+
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -887,24 +896,71 @@ gimp_drawable_real_swap_pixels (GimpDrawable *drawable,
gimp_drawable_update (drawable, x, y, width, height);
}
+static GimpFilter *
+gimp_drawable_create_fs_filter (GimpDrawable *drawable,
+ GimpDrawable *fs)
+{
+ GimpFilter *filter;
+ GeglNode *node;
+ GeglNode *input;
+ GeglNode *output;
+ GeglNode *fs_source;
+
+ filter = gimp_filter_new ("Floating Selection");
+
+ node = gimp_filter_get_node (filter);
+
+ input = gegl_node_get_input_proxy (node, "input");
+ output = gegl_node_get_output_proxy (node, "output");
+
+ fs_source = gimp_drawable_get_source_node (fs);
+
+ drawable->private->fs_crop_node =
+ gegl_node_new_child (node,
+ "operation", "gegl:crop",
+ NULL);
+
+ gegl_node_connect_to (fs_source, "output",
+ drawable->private->fs_crop_node, "input");
+
+ drawable->private->fs_offset_node =
+ gegl_node_new_child (node,
+ "operation", "gegl:translate",
+ NULL);
+
+ gegl_node_connect_to (drawable->private->fs_crop_node, "output",
+ drawable->private->fs_offset_node, "input");
+
+ drawable->private->fs_mode_node =
+ gegl_node_new_child (node,
+ "operation", "gimp:normal-mode",
+ NULL);
+
+ gegl_node_connect_to (input, "output",
+ drawable->private->fs_mode_node, "input");
+ gegl_node_connect_to (drawable->private->fs_offset_node, "output",
+ drawable->private->fs_mode_node, "aux");
+ gegl_node_connect_to (drawable->private->fs_mode_node, "output",
+ output, "input");
+
+ return filter;
+}
+
static void
-gimp_drawable_sync_source_node (GimpDrawable *drawable,
- gboolean detach_fs)
+gimp_drawable_sync_fs_filter (GimpDrawable *drawable,
+ gboolean detach_fs)
{
GimpLayer *fs = gimp_drawable_get_floating_sel (drawable);
- GeglNode *output;
if (! drawable->private->source_node)
return;
- output = gegl_node_get_output_proxy (drawable->private->source_node, "output");
-
if (fs && ! detach_fs)
{
gint off_x, off_y;
gint fs_off_x, fs_off_y;
- if (! drawable->private->fs_crop_node)
+ if (! drawable->private->fs_filter)
{
GeglNode *fs_source;
@@ -920,34 +976,11 @@ gimp_drawable_sync_source_node (GimpDrawable *drawable,
gegl_node_add_child (drawable->private->source_node, fs_source);
- drawable->private->fs_crop_node =
- gegl_node_new_child (drawable->private->source_node,
- "operation", "gegl:crop",
- NULL);
-
- gegl_node_connect_to (fs_source, "output",
- drawable->private->fs_crop_node, "input");
-
- drawable->private->fs_offset_node =
- gegl_node_new_child (drawable->private->source_node,
- "operation", "gegl:translate",
- NULL);
-
- gegl_node_connect_to (drawable->private->fs_crop_node, "output",
- drawable->private->fs_offset_node, "input");
+ drawable->private->fs_filter =
+ gimp_drawable_create_fs_filter (drawable, GIMP_DRAWABLE (fs));
- drawable->private->fs_mode_node =
- gegl_node_new_child (drawable->private->source_node,
- "operation", "gimp:normal-mode",
- NULL);
-
- gegl_node_connect_to (drawable->private->buffer_source_node, "output",
- drawable->private->fs_mode_node, "input");
- gegl_node_connect_to (drawable->private->fs_offset_node, "output",
- drawable->private->fs_mode_node, "aux");
-
- gegl_node_connect_to (drawable->private->fs_mode_node, "output",
- output, "input");
+ gimp_container_add (drawable->private->filter_stack,
+ GIMP_OBJECT (drawable->private->fs_filter));
g_signal_connect (fs, "notify",
G_CALLBACK (gimp_drawable_fs_notify),
@@ -976,16 +1009,19 @@ gimp_drawable_sync_source_node (GimpDrawable *drawable,
}
else
{
- if (drawable->private->fs_crop_node)
+ if (drawable->private->fs_filter)
{
GeglNode *fs_source;
- gegl_node_disconnect (drawable->private->fs_crop_node, "input");
- gegl_node_disconnect (drawable->private->fs_offset_node, "input");
- gegl_node_disconnect (drawable->private->fs_mode_node, "input");
- gegl_node_disconnect (drawable->private->fs_mode_node, "aux");
+ g_signal_handlers_disconnect_by_func (fs,
+ gimp_drawable_fs_notify,
+ drawable);
+
+ gimp_container_remove (drawable->private->filter_stack,
+ GIMP_OBJECT (drawable->private->fs_filter));
fs_source = gimp_drawable_get_source_node (GIMP_DRAWABLE (fs));
+
gegl_node_remove_child (drawable->private->source_node,
fs_source);
@@ -998,25 +1034,13 @@ gimp_drawable_sync_source_node (GimpDrawable *drawable,
fs->layer_offset_node, "input");
}
- gegl_node_remove_child (drawable->private->source_node,
- drawable->private->fs_crop_node);
- drawable->private->fs_crop_node = NULL;
+ g_object_unref (drawable->private->fs_filter);
+ drawable->private->fs_filter = NULL;
- gegl_node_remove_child (drawable->private->source_node,
- drawable->private->fs_offset_node);
+ drawable->private->fs_crop_node = NULL;
drawable->private->fs_offset_node = NULL;
-
- gegl_node_remove_child (drawable->private->source_node,
- drawable->private->fs_mode_node);
- drawable->private->fs_mode_node = NULL;
-
- g_signal_handlers_disconnect_by_func (fs,
- gimp_drawable_fs_notify,
- drawable);
+ drawable->private->fs_mode_node = NULL;
}
-
- gegl_node_connect_to (drawable->private->buffer_source_node, "output",
- output, "input");
}
}
@@ -1031,7 +1055,7 @@ gimp_drawable_fs_notify (GimpLayer *fs,
! strcmp (pspec->name, "mode") ||
! strcmp (pspec->name, "opacity"))
{
- gimp_drawable_sync_source_node (drawable, FALSE);
+ gimp_drawable_sync_fs_filter (drawable, FALSE);
}
}
@@ -1335,6 +1359,9 @@ gimp_drawable_set_buffer_full (GimpDrawable *drawable,
GeglNode *
gimp_drawable_get_source_node (GimpDrawable *drawable)
{
+ GeglNode *filter;
+ GeglNode *output;
+
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
if (drawable->private->source_node)
@@ -1348,7 +1375,19 @@ gimp_drawable_get_source_node (GimpDrawable *drawable)
"buffer", gimp_drawable_get_buffer (drawable),
NULL);
- gimp_drawable_sync_source_node (drawable, FALSE);
+ filter = gimp_filter_stack_get_graph (GIMP_FILTER_STACK (drawable->private->filter_stack));
+
+ gegl_node_add_child (drawable->private->source_node, filter);
+
+ gegl_node_connect_to (drawable->private->buffer_source_node, "output",
+ filter, "input");
+
+ output = gegl_node_get_output_proxy (drawable->private->source_node, "output");
+
+ gegl_node_connect_to (filter, "output",
+ output, "input");
+
+ gimp_drawable_sync_fs_filter (drawable, FALSE);
return drawable->private->source_node;
}
@@ -1622,7 +1661,7 @@ gimp_drawable_attach_floating_sel (GimpDrawable *drawable,
/* clear the selection */
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (floating_sel));
- gimp_drawable_sync_source_node (drawable, FALSE);
+ gimp_drawable_sync_fs_filter (drawable, FALSE);
g_signal_connect (floating_sel, "update",
G_CALLBACK (gimp_drawable_fs_update),
@@ -1649,7 +1688,7 @@ gimp_drawable_detach_floating_sel (GimpDrawable *drawable)
image = gimp_item_get_image (GIMP_ITEM (drawable));
floating_sel = drawable->private->floating_selection;
- gimp_drawable_sync_source_node (drawable, TRUE);
+ gimp_drawable_sync_fs_filter (drawable, TRUE);
g_signal_handlers_disconnect_by_func (floating_sel,
gimp_drawable_fs_update,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]