app: fix merging filters with negative top-left point.
When merging filters whose rendering was expanding in negative ccordinates, I realized that the drawable was not properly resized (it was resized properly when the width/height increased, but not when the x or y points became negative, even though this "cropped" part still showed… until you saved and reloaded your XCF!). The problem is that drawable buffers are always stored with (0, 0) top-left and this was just confusing our existing code. So let's check when trying to set a buffer with a non-(0, 0) origin, and update the offset subsequently. I hesitated with an alternative implementation which was to edit the buffer applied to the drawable in gimp_drawable_merge_filters(). But I figured this would be more future-proof for other similar cases, though I hope I did not break any use case where this was actually considered a normal case.
This commit is contained in:
parent
018eafc146
commit
4c15be6a56
1 changed files with 25 additions and 4 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue