[gimp] app: invalidate channel boundary upon buffer "changed" signal
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: invalidate channel boundary upon buffer "changed" signal
- Date: Sat, 10 Feb 2018 10:38:17 +0000 (UTC)
commit d0ae244fe85a502446fe9c7b82afdf1b89498966
Author: Ell <ell_se yahoo com>
Date: Sat Feb 10 05:26:26 2018 -0500
app: invalidate channel boundary upon buffer "changed" signal
Have GimpChannel connect to the drawable buffer's "changed" signal,
so that we can invalidate the channel's boundary whenever the
buffer contents change. Currently, the calls to
gimp_drawable_invalidate_boundary() dispersed throughout the code
are not enough.
Moreover, invalidate both the boundary and the bounds in
gimp_channel_invalidate_boundary(), since both are necessary when
the buffer changes.
app/core/gimpchannel.c | 165 ++++++++--------------------------------------
app/core/gimpdrawable.c | 31 +++++----
app/core/gimplayer.c | 8 ++-
3 files changed, 53 insertions(+), 151 deletions(-)
---
diff --git a/app/core/gimpchannel.c b/app/core/gimpchannel.c
index b6947b3..956a80a 100644
--- a/app/core/gimpchannel.c
+++ b/app/core/gimpchannel.c
@@ -157,39 +157,12 @@ static void gimp_channel_get_active_components (GimpDrawable *drawable,
static GimpComponentMask
gimp_channel_get_active_mask (GimpDrawable *drawable);
-static void gimp_channel_apply_buffer (GimpDrawable *drawable,
- GeglBuffer *buffer,
- const GeglRectangle *buffer_region,
- gboolean push_undo,
- const gchar *undo_desc,
- gdouble opacity,
- GimpLayerMode mode,
- GimpLayerColorSpace blend_space,
- GimpLayerColorSpace composite_space,
- GimpLayerCompositeMode composite_mode,
- GeglBuffer *base_buffer,
- gint base_x,
- gint base_y);
-static void gimp_channel_replace_buffer (GimpDrawable *drawable,
- GeglBuffer *buffer,
- const GeglRectangle *buffer_region,
- gboolean push_undo,
- const gchar *undo_desc,
- gdouble opacity,
- GeglBuffer *mask,
- const GeglRectangle *mask_region,
- gint x,
- gint y);
static void gimp_channel_set_buffer (GimpDrawable *drawable,
gboolean push_undo,
const gchar *undo_desc,
GeglBuffer *buffer,
gint offset_x,
gint offset_y);
-static void gimp_channel_swap_pixels (GimpDrawable *drawable,
- GeglBuffer *buffer,
- gint x,
- gint y);
static gdouble gimp_channel_get_opacity_at (GimpPickable *pickable,
gint x,
@@ -237,6 +210,11 @@ static void gimp_channel_real_flood (GimpChannel *channel,
gboolean push_undo);
+static void gimp_channel_buffer_changed (GeglBuffer *buffer,
+ const GeglRectangle *rect,
+ GimpChannel *channel);
+
+
G_DEFINE_TYPE_WITH_CODE (GimpChannel, gimp_channel, GIMP_TYPE_DRAWABLE,
G_IMPLEMENT_INTERFACE (GIMP_TYPE_PICKABLE,
gimp_channel_pickable_iface_init))
@@ -311,10 +289,7 @@ gimp_channel_class_init (GimpChannelClass *klass)
drawable_class->invalidate_boundary = gimp_channel_invalidate_boundary;
drawable_class->get_active_components = gimp_channel_get_active_components;
drawable_class->get_active_mask = gimp_channel_get_active_mask;
- drawable_class->apply_buffer = gimp_channel_apply_buffer;
- drawable_class->replace_buffer = gimp_channel_replace_buffer;
drawable_class->set_buffer = gimp_channel_set_buffer;
- drawable_class->swap_pixels = gimp_channel_swap_pixels;
klass->boundary = gimp_channel_real_boundary;
klass->is_empty = gimp_channel_real_is_empty;
@@ -645,8 +620,6 @@ gimp_channel_translate (GimpItem *item,
if (push_undo)
gimp_channel_push_undo (channel, NULL);
- else
- gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
x1 = CLAMP ((x1 + off_x), 0, gimp_item_get_width (GIMP_ITEM (channel)));
y1 = CLAMP ((y1 + off_y), 0, gimp_item_get_height (GIMP_ITEM (channel)));
@@ -991,7 +964,10 @@ gimp_channel_convert_type (GimpDrawable *drawable,
static void
gimp_channel_invalidate_boundary (GimpDrawable *drawable)
{
- GIMP_CHANNEL (drawable)->boundary_known = FALSE;
+ GimpChannel *channel = GIMP_CHANNEL (drawable);
+
+ channel->boundary_known = FALSE;
+ channel->bounds_known = FALSE;
}
static void
@@ -1011,60 +987,6 @@ gimp_channel_get_active_mask (GimpDrawable *drawable)
}
static void
-gimp_channel_apply_buffer (GimpDrawable *drawable,
- GeglBuffer *buffer,
- const GeglRectangle *buffer_region,
- gboolean push_undo,
- const gchar *undo_desc,
- gdouble opacity,
- GimpLayerMode mode,
- GimpLayerColorSpace blend_space,
- GimpLayerColorSpace composite_space,
- GimpLayerCompositeMode composite_mode,
- GeglBuffer *base_buffer,
- gint base_x,
- gint base_y)
-{
- gimp_drawable_invalidate_boundary (drawable);
-
- GIMP_DRAWABLE_CLASS (parent_class)->apply_buffer (drawable, buffer,
- buffer_region,
- push_undo, undo_desc,
- opacity, mode,
- blend_space,
- composite_space,
- composite_mode,
- base_buffer,
- base_x, base_y);
-
- GIMP_CHANNEL (drawable)->bounds_known = FALSE;
-}
-
-static void
-gimp_channel_replace_buffer (GimpDrawable *drawable,
- GeglBuffer *buffer,
- const GeglRectangle *buffer_region,
- gboolean push_undo,
- const gchar *undo_desc,
- gdouble opacity,
- GeglBuffer *mask,
- const GeglRectangle *mask_region,
- gint x,
- gint y)
-{
- gimp_drawable_invalidate_boundary (drawable);
-
- GIMP_DRAWABLE_CLASS (parent_class)->replace_buffer (drawable, buffer,
- buffer_region,
- push_undo, undo_desc,
- opacity,
- mask, mask_region,
- x, y);
-
- GIMP_CHANNEL (drawable)->bounds_known = FALSE;
-}
-
-static void
gimp_channel_set_buffer (GimpDrawable *drawable,
gboolean push_undo,
const gchar *undo_desc,
@@ -1072,14 +994,24 @@ gimp_channel_set_buffer (GimpDrawable *drawable,
gint offset_x,
gint offset_y)
{
- GimpChannel *channel = GIMP_CHANNEL (drawable);
+ GimpChannel *channel = GIMP_CHANNEL (drawable);
+ GeglBuffer *old_buffer = gimp_drawable_get_buffer (drawable);
+
+ if (old_buffer)
+ {
+ g_signal_handlers_disconnect_by_func (old_buffer,
+ gimp_channel_buffer_changed,
+ channel);
+ }
GIMP_DRAWABLE_CLASS (parent_class)->set_buffer (drawable,
push_undo, undo_desc,
buffer,
offset_x, offset_y);
- channel->bounds_known = FALSE;
+ gegl_buffer_signal_connect (buffer, "changed",
+ G_CALLBACK (gimp_channel_buffer_changed),
+ channel);
if (gimp_filter_peek_node (GIMP_FILTER (channel)))
{
@@ -1096,19 +1028,6 @@ gimp_channel_set_buffer (GimpDrawable *drawable,
}
}
-static void
-gimp_channel_swap_pixels (GimpDrawable *drawable,
- GeglBuffer *buffer,
- gint x,
- gint y)
-{
- gimp_drawable_invalidate_boundary (drawable);
-
- GIMP_DRAWABLE_CLASS (parent_class)->swap_pixels (drawable, buffer, x, y);
-
- GIMP_CHANNEL (drawable)->bounds_known = FALSE;
-}
-
static gdouble
gimp_channel_get_opacity_at (GimpPickable *pickable,
gint x,
@@ -1273,8 +1192,6 @@ gimp_channel_real_feather (GimpChannel *channel,
if (push_undo)
gimp_channel_push_undo (channel,
GIMP_CHANNEL_GET_CLASS (channel)->feather_desc);
- else
- gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
gimp_gegl_apply_feather (gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
NULL, NULL,
@@ -1283,8 +1200,6 @@ gimp_channel_real_feather (GimpChannel *channel,
radius_x,
radius_y);
- channel->bounds_known = FALSE;
-
gimp_drawable_update (GIMP_DRAWABLE (channel), 0, 0, -1, -1);
}
@@ -1297,16 +1212,12 @@ gimp_channel_real_sharpen (GimpChannel *channel,
if (push_undo)
gimp_channel_push_undo (channel,
GIMP_CHANNEL_GET_CLASS (channel)->sharpen_desc);
- else
- gimp_drawable_invalidate_boundary (drawable);
gimp_gegl_apply_threshold (gimp_drawable_get_buffer (drawable),
NULL, NULL,
gimp_drawable_get_buffer (drawable),
0.5);
- channel->bounds_known = FALSE;
-
gimp_drawable_update (GIMP_DRAWABLE (channel), 0, 0, -1, -1);
}
@@ -1322,10 +1233,6 @@ gimp_channel_real_clear (GimpChannel *channel,
gimp_channel_push_undo (channel, undo_desc);
}
- else
- {
- gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
- }
if (channel->bounds_known && ! channel->empty)
{
@@ -1360,8 +1267,6 @@ gimp_channel_real_all (GimpChannel *channel,
if (push_undo)
gimp_channel_push_undo (channel,
GIMP_CHANNEL_GET_CLASS (channel)->all_desc);
- else
- gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
/* clear the channel */
color = gegl_color_new ("#fff");
@@ -1389,8 +1294,6 @@ gimp_channel_real_invert (GimpChannel *channel,
if (push_undo)
gimp_channel_push_undo (channel,
GIMP_CHANNEL_GET_CLASS (channel)->invert_desc);
- else
- gimp_drawable_invalidate_boundary (drawable);
if (channel->bounds_known && channel->empty)
{
@@ -1402,8 +1305,6 @@ gimp_channel_real_invert (GimpChannel *channel,
NULL, NULL,
gimp_drawable_get_buffer (drawable));
- channel->bounds_known = FALSE;
-
gimp_drawable_update (GIMP_DRAWABLE (channel), 0, 0, -1, -1);
}
}
@@ -1469,8 +1370,6 @@ gimp_channel_real_border (GimpChannel *channel,
if (push_undo)
gimp_channel_push_undo (channel,
GIMP_CHANNEL_GET_CLASS (channel)->border_desc);
- else
- gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
gimp_gegl_apply_border (gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
NULL, NULL,
@@ -1478,8 +1377,6 @@ gimp_channel_real_border (GimpChannel *channel,
GEGL_RECTANGLE (x1, y1, x2 - x1, y2 - y1),
radius_x, radius_y, style, edge_lock);
- channel->bounds_known = FALSE;
-
gimp_drawable_update (GIMP_DRAWABLE (channel), 0, 0, -1, -1);
}
@@ -1535,8 +1432,6 @@ gimp_channel_real_grow (GimpChannel *channel,
if (push_undo)
gimp_channel_push_undo (channel,
GIMP_CHANNEL_GET_CLASS (channel)->grow_desc);
- else
- gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
gimp_gegl_apply_grow (gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
NULL, NULL,
@@ -1544,8 +1439,6 @@ gimp_channel_real_grow (GimpChannel *channel,
GEGL_RECTANGLE (x1, y1, x2 - x1, y2 - y1),
radius_x, radius_y);
- channel->bounds_known = FALSE;
-
gimp_drawable_update (GIMP_DRAWABLE (channel), 0, 0, -1, -1);
}
@@ -1591,8 +1484,6 @@ gimp_channel_real_shrink (GimpChannel *channel,
if (push_undo)
gimp_channel_push_undo (channel,
GIMP_CHANNEL_GET_CLASS (channel)->shrink_desc);
- else
- gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
gimp_gegl_apply_shrink (gimp_drawable_get_buffer (GIMP_DRAWABLE (channel)),
NULL, NULL,
@@ -1600,8 +1491,6 @@ gimp_channel_real_shrink (GimpChannel *channel,
GEGL_RECTANGLE (x1, y1, x2 - x1, y2 - y1),
radius_x, radius_y, edge_lock);
- channel->bounds_known = FALSE;
-
gimp_drawable_update (GIMP_DRAWABLE (channel), 0, 0, -1, -1);
}
@@ -1629,6 +1518,14 @@ gimp_channel_real_flood (GimpChannel *channel,
gimp_drawable_update (GIMP_DRAWABLE (channel), x, y, width, height);
}
+static void
+gimp_channel_buffer_changed (GeglBuffer *buffer,
+ const GeglRectangle *rect,
+ GimpChannel *channel)
+{
+ gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
+}
+
/* public functions */
@@ -1716,8 +1613,6 @@ gimp_channel_new_from_alpha (GimpImage *image,
dest_buffer, NULL);
gegl_buffer_set_format (dest_buffer, NULL);
- channel->bounds_known = FALSE;
-
return channel;
}
@@ -1901,8 +1796,6 @@ gimp_channel_push_undo (GimpChannel *channel,
gimp_image_undo_push_mask (gimp_item_get_image (GIMP_ITEM (channel)),
undo_desc, channel);
-
- gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
}
diff --git a/app/core/gimpdrawable.c b/app/core/gimpdrawable.c
index 95c44d7..7a5c71e 100644
--- a/app/core/gimpdrawable.c
+++ b/app/core/gimpdrawable.c
@@ -438,12 +438,12 @@ gimp_drawable_duplicate (GimpItem *item,
{
GimpDrawable *drawable = GIMP_DRAWABLE (item);
GimpDrawable *new_drawable = GIMP_DRAWABLE (new_item);
+ GeglBuffer *new_buffer;
- if (new_drawable->private->buffer)
- g_object_unref (new_drawable->private->buffer);
+ new_buffer = gegl_buffer_dup (gimp_drawable_get_buffer (drawable));
- new_drawable->private->buffer =
- gegl_buffer_dup (gimp_drawable_get_buffer (drawable));
+ gimp_drawable_set_buffer (new_drawable, FALSE, NULL, new_buffer);
+ g_object_unref (new_buffer);
}
return new_item;
@@ -770,10 +770,8 @@ gimp_drawable_real_set_buffer (GimpDrawable *drawable,
gint offset_x,
gint offset_y)
{
- GimpItem *item = GIMP_ITEM (drawable);
- gboolean old_has_alpha;
-
- old_has_alpha = gimp_drawable_has_alpha (drawable);
+ GimpItem *item = GIMP_ITEM (drawable);
+ gint old_has_alpha = -1;
g_object_freeze_notify (G_OBJECT (drawable));
@@ -787,7 +785,11 @@ gimp_drawable_real_set_buffer (GimpDrawable *drawable,
g_object_ref (buffer);
if (drawable->private->buffer)
- g_object_unref (drawable->private->buffer);
+ {
+ old_has_alpha = gimp_drawable_has_alpha (drawable);
+
+ g_object_unref (drawable->private->buffer);
+ }
drawable->private->buffer = buffer;
@@ -801,7 +803,8 @@ gimp_drawable_real_set_buffer (GimpDrawable *drawable,
gegl_buffer_get_width (buffer),
gegl_buffer_get_height (buffer));
- if (old_has_alpha != gimp_drawable_has_alpha (drawable))
+ if (old_has_alpha >= 0 &&
+ old_has_alpha != gimp_drawable_has_alpha (drawable))
gimp_drawable_alpha_changed (drawable);
g_object_notify (G_OBJECT (drawable), "buffer");
@@ -894,6 +897,7 @@ gimp_drawable_new (GType type,
const Babl *format)
{
GimpDrawable *drawable;
+ GeglBuffer *buffer;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (g_type_is_a (type, GIMP_TYPE_DRAWABLE), NULL);
@@ -905,9 +909,10 @@ gimp_drawable_new (GType type,
offset_x, offset_y,
width, height));
- drawable->private->buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
- width, height),
- format);
+ buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0, width, height), format);
+
+ gimp_drawable_set_buffer (drawable, FALSE, NULL, buffer);
+ g_object_unref (buffer);
return drawable;
}
diff --git a/app/core/gimplayer.c b/app/core/gimplayer.c
index a7455a9..9939169 100644
--- a/app/core/gimplayer.c
+++ b/app/core/gimplayer.c
@@ -1382,14 +1382,18 @@ gimp_layer_set_buffer (GimpDrawable *drawable,
gint offset_x,
gint offset_y)
{
- gboolean old_linear = gimp_drawable_get_linear (drawable);
+ GeglBuffer *old_buffer = gimp_drawable_get_buffer (drawable);
+ gint old_linear = -1;
+
+ if (old_buffer)
+ old_linear = gimp_drawable_get_linear (drawable);
GIMP_DRAWABLE_CLASS (parent_class)->set_buffer (drawable,
push_undo, undo_desc,
buffer,
offset_x, offset_y);
- if (gimp_filter_peek_node (GIMP_FILTER (drawable)))
+ if (old_linear >= 0 && gimp_filter_peek_node (GIMP_FILTER (drawable)))
{
gboolean new_linear = gimp_drawable_get_linear (drawable);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]