[gimp/wip/passthrough: 5/10] app: implement pass-through mode in GimpGroupLayer
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/wip/passthrough: 5/10] app: implement pass-through mode in GimpGroupLayer
- Date: Sat, 22 Apr 2017 23:58:58 +0000 (UTC)
commit 1f29b487473050adf4cce9c61daaf6b85452916f
Author: Ell <ell_se yahoo com>
Date: Fri Apr 21 18:04:49 2017 -0400
app: implement pass-through mode in GimpGroupLayer
Override GimpDrawable::get_source_node() for GimpGroupLayer. Use
a node that contains both the drawable's buffer-source node, and the
layer stack's graph node. Choose which one of these to connect to
the source node's output based on the group's layer mode: the stack
graph for pass-through mode, and the buffer-source node for all the
rest.
When in pass-through mode, connect the source node's input (which
receives the backdrop) to the stack graph's input. Keep maintaining
the projection in pass-through mode. ATM, the projection uses the
same graph as the source node, so it's rendered against the group's
backdrop -- we don't want that. The next few commits fix it.
Update the group's drawable directly upon filter stack update in
pass-though mode, because the group's graph doesn't go through the
projection.
TODO: if any of the group's children (or a child of a nested pass-
through group, etc.) uses dst-atop/src-in, this needs special
attention.
app/core/gimpgrouplayer.c | 124 ++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 117 insertions(+), 7 deletions(-)
---
diff --git a/app/core/gimpgrouplayer.c b/app/core/gimpgrouplayer.c
index 3ac678b..cb590d2 100644
--- a/app/core/gimpgrouplayer.c
+++ b/app/core/gimpgrouplayer.c
@@ -49,6 +49,8 @@ struct _GimpGroupLayerPrivate
{
GimpContainer *children;
GimpProjection *projection;
+ GeglNode *source_node;
+ GeglNode *parent_source_node;
GeglNode *graph;
GeglNode *offset_node;
gint suspend_resize;
@@ -145,6 +147,9 @@ static void gimp_group_layer_convert_type (GimpDrawable *drawabl
GeglDitherMethod mask_dither_type,
gboolean push_undo,
GimpProgress *progress);
+static GeglNode * gimp_group_layer_get_source_node (GimpDrawable *drawable);
+
+static void gimp_group_layer_mode_changed (GimpLayer *layer);
static const Babl * gimp_group_layer_get_format (GimpProjectable *projectable);
static GeglNode * gimp_group_layer_get_graph (GimpProjectable *projectable);
@@ -167,6 +172,7 @@ static void gimp_group_layer_child_resize (GimpLayer *child,
static void gimp_group_layer_update (GimpGroupLayer *group);
static void gimp_group_layer_update_size (GimpGroupLayer *group);
+static void gimp_group_layer_update_source_node (GimpGroupLayer *group);
static void gimp_group_layer_stack_update (GimpDrawableStack *stack,
gint x,
@@ -201,6 +207,7 @@ gimp_group_layer_class_init (GimpGroupLayerClass *klass)
GimpViewableClass *viewable_class = GIMP_VIEWABLE_CLASS (klass);
GimpItemClass *item_class = GIMP_ITEM_CLASS (klass);
GimpDrawableClass *drawable_class = GIMP_DRAWABLE_CLASS (klass);
+ GimpLayerClass *layer_class = GIMP_LAYER_CLASS (klass);
object_class->set_property = gimp_group_layer_set_property;
object_class->get_property = gimp_group_layer_get_property;
@@ -235,6 +242,9 @@ gimp_group_layer_class_init (GimpGroupLayerClass *klass)
drawable_class->estimate_memsize = gimp_group_layer_estimate_memsize;
drawable_class->convert_type = gimp_group_layer_convert_type;
+ drawable_class->get_source_node = gimp_group_layer_get_source_node;
+
+ layer_class->mode_changed = gimp_group_layer_mode_changed;
g_type_class_add_private (klass, sizeof (GimpGroupLayerPrivate));
}
@@ -319,6 +329,12 @@ gimp_group_layer_finalize (GObject *object)
private->projection = NULL;
}
+ if (private->source_node)
+ {
+ g_object_unref (private->source_node);
+ private->source_node = NULL;
+ }
+
if (private->graph)
{
g_object_unref (private->graph);
@@ -941,6 +957,51 @@ gimp_group_layer_convert_type (GimpDrawable *drawable,
}
}
+static GeglNode *
+gimp_group_layer_get_source_node (GimpDrawable *drawable)
+{
+ GimpGroupLayerPrivate *private = GET_PRIVATE (drawable);
+ GeglNode *input;
+
+ g_warn_if_fail (private->source_node == NULL);
+
+ private->source_node = gegl_node_new ();
+
+ input = gegl_node_get_input_proxy (private->source_node, "input");
+
+ private->parent_source_node =
+ GIMP_DRAWABLE_CLASS (parent_class)->get_source_node (drawable);
+
+ gegl_node_add_child (private->source_node, private->parent_source_node);
+
+ g_object_unref (private->parent_source_node);
+
+ if (gegl_node_has_pad (private->parent_source_node, "input"))
+ {
+ gegl_node_connect_to (input, "output",
+ private->parent_source_node, "input");
+ }
+
+ gimp_group_layer_get_graph (GIMP_PROJECTABLE (drawable));
+
+ gegl_node_add_child (private->source_node, private->graph);
+
+ gimp_group_layer_update_source_node (GIMP_GROUP_LAYER (drawable));
+
+ return g_object_ref (private->source_node);
+}
+
+static void
+gimp_group_layer_mode_changed (GimpLayer *layer)
+{
+ GimpGroupLayer *group = GIMP_GROUP_LAYER (layer);
+
+ gimp_group_layer_update_source_node (group);
+
+ if (GIMP_LAYER_CLASS (parent_class)->mode_changed)
+ GIMP_LAYER_CLASS (parent_class)->mode_changed (layer);
+}
+
static const Babl *
gimp_group_layer_get_format (GimpProjectable *projectable)
{
@@ -962,6 +1023,7 @@ gimp_group_layer_get_graph (GimpProjectable *projectable)
{
GimpGroupLayer *group = GIMP_GROUP_LAYER (projectable);
GimpGroupLayerPrivate *private = GET_PRIVATE (projectable);
+ GeglNode *input;
GeglNode *layers_node;
GeglNode *output;
gint off_x;
@@ -972,11 +1034,16 @@ gimp_group_layer_get_graph (GimpProjectable *projectable)
private->graph = gegl_node_new ();
+ input = gegl_node_get_input_proxy (private->graph, "input");
+
layers_node =
gimp_filter_stack_get_graph (GIMP_FILTER_STACK (private->children));
gegl_node_add_child (private->graph, layers_node);
+ gegl_node_connect_to (input, "output",
+ layers_node, "input");
+
gimp_item_get_offset (GIMP_ITEM (group), &off_x, &off_y);
private->offset_node = gegl_node_new_child (private->graph,
@@ -1243,6 +1310,35 @@ gimp_group_layer_update_size (GimpGroupLayer *group)
}
static void
+gimp_group_layer_update_source_node (GimpGroupLayer *group)
+{
+ GimpGroupLayerPrivate *private = GET_PRIVATE (group);
+ GeglNode *input;
+ GeglNode *output;
+
+ if (private->source_node == NULL)
+ return;
+
+ input = gegl_node_get_input_proxy (private->source_node, "input");
+ output = gegl_node_get_output_proxy (private->source_node, "output");
+
+ if (gimp_layer_get_mode (GIMP_LAYER (group)) == GIMP_LAYER_MODE_PASS_THROUGH)
+ {
+ gegl_node_connect_to (input, "output",
+ private->graph, "input");
+ gegl_node_connect_to (private->graph, "output",
+ output, "input");
+ }
+ else
+ {
+ gegl_node_disconnect (private->graph, "input");
+
+ gegl_node_connect_to (private->parent_source_node, "output",
+ output, "input");
+ }
+}
+
+static void
gimp_group_layer_stack_update (GimpDrawableStack *stack,
gint x,
gint y,
@@ -1256,6 +1352,17 @@ gimp_group_layer_stack_update (GimpDrawableStack *stack,
x, y, width, height);
#endif
+ if (gimp_layer_get_mode (GIMP_LAYER (group)) == GIMP_LAYER_MODE_PASS_THROUGH)
+ {
+ /* the layer stack's update signal speaks in image coordinates,
+ * transform to layer coordinates when emitting our own update signal.
+ */
+ gimp_drawable_update (GIMP_DRAWABLE (group),
+ x - gimp_item_get_offset_x (GIMP_ITEM (group)),
+ y - gimp_item_get_offset_y (GIMP_ITEM (group)),
+ width, height);
+ }
+
/* the layer stack's update signal speaks in image coordinates,
* pass to the projection as-is.
*/
@@ -1286,11 +1393,14 @@ gimp_group_layer_proj_update (GimpProjection *proj,
x, y, width, height);
#endif
- /* the projection speaks in image coordinates, transform to layer
- * coordinates when emitting our own update signal.
- */
- gimp_drawable_update (GIMP_DRAWABLE (group),
- x - gimp_item_get_offset_x (GIMP_ITEM (group)),
- y - gimp_item_get_offset_y (GIMP_ITEM (group)),
- width, height);
+ if (gimp_layer_get_mode (GIMP_LAYER (group)) != GIMP_LAYER_MODE_PASS_THROUGH)
+ {
+ /* the projection speaks in image coordinates, transform to layer
+ * coordinates when emitting our own update signal.
+ */
+ gimp_drawable_update (GIMP_DRAWABLE (group),
+ x - gimp_item_get_offset_x (GIMP_ITEM (group)),
+ y - gimp_item_get_offset_y (GIMP_ITEM (group)),
+ width, height);
+ }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]