Commit d0ae244f authored by Ell's avatar Ell

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.
parent 10c125c6
......@@ -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
......@@ -1010,60 +986,6 @@ gimp_channel_get_active_mask (GimpDrawable *drawable)
return GIMP_COMPONENT_MASK_ALL;
}
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,
......@@ -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));
}
......
......@@ -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;
}
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment