diff --git a/app/core/gimpdrawable.c b/app/core/gimpdrawable.c index 646c960af9..92d3da3577 100644 --- a/app/core/gimpdrawable.c +++ b/app/core/gimpdrawable.c @@ -1013,9 +1013,11 @@ gimp_drawable_real_set_buffer (GimpDrawable *drawable, GeglBuffer *buffer, const GeglRectangle *bounds) { - GimpItem *item = GIMP_ITEM (drawable); - const Babl *old_format = NULL; - gint old_has_alpha = -1; + GimpItem *item = GIMP_ITEM (drawable); + const Babl *old_format = NULL; + gint old_has_alpha = -1; + const GeglRectangle *extent = gegl_buffer_get_extent (buffer); + gboolean free_buffer = FALSE; g_object_freeze_notify (G_OBJECT (drawable)); @@ -1031,6 +1033,22 @@ gimp_drawable_real_set_buffer (GimpDrawable *drawable, old_has_alpha = gimp_drawable_has_alpha (drawable); } + if (extent->x != 0 || extent->y != 0) + { + /* Drawable buffers are always stored with a (0, 0) origin. When + * setting a buffer with a different origin, we will assume we + * instead want to update the offset a bit. + * This may happen for instance when merging filters which may + * render in negative coordinates. + */ + buffer = g_object_new (GEGL_TYPE_BUFFER, + "source", buffer, + "shift-x", extent->x, + "shift-y", extent->y, + NULL); + free_buffer = TRUE; + } + g_set_object (&drawable->private->buffer, buffer); if (gimp_drawable_is_painting (drawable)) @@ -1043,7 +1061,7 @@ gimp_drawable_real_set_buffer (GimpDrawable *drawable, "buffer", gimp_drawable_get_buffer (drawable), NULL); - gimp_item_set_offset (item, bounds->x, bounds->y); + gimp_item_set_offset (item, bounds->x + extent->x, bounds->y + extent->y); gimp_item_set_size (item, bounds->width ? bounds->width : gegl_buffer_get_width (buffer), @@ -1061,6 +1079,9 @@ gimp_drawable_real_set_buffer (GimpDrawable *drawable, g_object_notify (G_OBJECT (drawable), "buffer"); g_object_thaw_notify (G_OBJECT (drawable)); + + if (free_buffer) + g_object_unref (buffer); } static GeglRectangle