[gimp] Bug 586462 - Layer inserts misplaced
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] Bug 586462 - Layer inserts misplaced
- Date: Mon, 30 Jul 2012 14:26:30 +0000 (UTC)
commit eda6fa1c14777a534711fe05821ef308023fe4e7
Author: Michael Natterer <mitch gimp org>
Date: Mon Jul 30 16:20:11 2012 +0200
Bug 586462 - Layer inserts misplaced
Another attempt to fix paste/drop positions for good.
Paste/drop target is either the selected area of a drawable, the
drawable itself, or the image:
- if the paste is larger than the target, center on the target
- if there is a viewport, and the viewport intersects with the
target, center on the intersection
- otherwise, center on the target
Finally, if we did viewport-centered pasting, make sure the paste is
as completely within image bounds as possible.
app/core/gimp-edit.c | 92 ++++++++++++++++++++++++------------
app/display/gimpdisplayshell-dnd.c | 34 +++++++++-----
2 files changed, 84 insertions(+), 42 deletions(-)
---
diff --git a/app/core/gimp-edit.c b/app/core/gimp-edit.c
index 8bca73d..86d8923 100644
--- a/app/core/gimp-edit.c
+++ b/app/core/gimp-edit.c
@@ -156,12 +156,13 @@ gimp_edit_paste (GimpImage *image,
{
GimpLayer *layer;
const Babl *format;
- gint center_x;
- gint center_y;
- gint offset_x;
- gint offset_y;
+ gint image_width;
+ gint image_height;
gint width;
gint height;
+ gint offset_x;
+ gint offset_y;
+ gboolean clamp_to_image = TRUE;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (drawable == NULL || GIMP_IS_DRAWABLE (drawable), NULL);
@@ -187,6 +188,23 @@ gimp_edit_paste (GimpImage *image,
if (! layer)
return NULL;
+ image_width = gimp_image_get_width (image);
+ image_height = gimp_image_get_height (image);
+
+ width = gimp_item_get_width (GIMP_ITEM (layer));
+ height = gimp_item_get_height (GIMP_ITEM (layer));
+
+ if (viewport_width == image_width &&
+ viewport_height == image_height)
+ {
+ /* if the whole image is visible, act as if there was no viewport */
+
+ viewport_x = 0;
+ viewport_y = 0;
+ viewport_width = 0;
+ viewport_height = 0;
+ }
+
if (drawable)
{
/* if pasting to a drawable */
@@ -201,9 +219,13 @@ gimp_edit_paste (GimpImage *image,
have_mask = gimp_item_mask_bounds (GIMP_ITEM (drawable),
&x1, &y1, &x2, &y2);
- if (! have_mask &&
- viewport_width > 0 &&
+ if (! have_mask && /* if we have no mask */
+ viewport_width > 0 && /* and we have a viewport */
viewport_height > 0 &&
+ (width < (x2 - x1) || /* and the paste is smaller than the target */
+ height < (y2 - y1)) &&
+
+ /* and the viewport intersects with the target */
gimp_rectangle_intersect (viewport_x, viewport_y,
viewport_width, viewport_height,
off_x, off_y,
@@ -211,43 +233,53 @@ gimp_edit_paste (GimpImage *image,
&paste_x, &paste_y,
&paste_width, &paste_height))
{
- center_x = paste_x + paste_width / 2;
- center_y = paste_y + paste_height / 2;
+ /* center on the viewport */
+
+ offset_x = paste_x + (paste_width - width) / 2;
+ offset_y = paste_y + (paste_height- height) / 2;
}
else
{
- center_x = off_x + (x1 + x2) / 2;
- center_y = off_y + (y1 + y2) / 2;
+ /* otherwise center on the target */
+
+ offset_x = off_x + ((x1 + x2) - width) / 2;
+ offset_y = off_y + ((y1 + y2) - height) / 2;
+
+ /* and keep it that way */
+ clamp_to_image = FALSE;
}
}
- else if (viewport_width > 0 && viewport_height > 0)
+ else if (viewport_width > 0 && /* if we have a viewport */
+ viewport_height > 0 &&
+ (width < image_width || /* and the paste is */
+ height < image_height)) /* smaller than the image */
{
- /* if we got a viewport set the offsets to the center of the viewport */
+ /* center on the viewport */
- center_x = viewport_x + viewport_width / 2;
- center_y = viewport_y + viewport_height / 2;
+ offset_x = viewport_x + (viewport_width - width) / 2;
+ offset_y = viewport_y + (viewport_height - height) / 2;
}
else
{
- /* otherwise the offsets to the center of the image */
-
- center_x = gimp_image_get_width (image) / 2;
- center_y = gimp_image_get_height (image) / 2;
- }
+ /* otherwise center on the image */
- width = gimp_item_get_width (GIMP_ITEM (layer));
- height = gimp_item_get_height (GIMP_ITEM (layer));
+ offset_x = (image_width - width) / 2;
+ offset_y = (image_height - height) / 2;
- offset_x = center_x - width / 2;
- offset_y = center_y - height / 2;
+ /* and keep it that way */
+ clamp_to_image = FALSE;
+ }
- /* Ensure that the pasted layer is always within the image, if it
- * fits and aligned at top left if it doesn't. (See bug #142944).
- */
- offset_x = MIN (offset_x, gimp_image_get_width (image) - width);
- offset_y = MIN (offset_y, gimp_image_get_height (image) - height);
- offset_x = MAX (offset_x, 0);
- offset_y = MAX (offset_y, 0);
+ if (clamp_to_image)
+ {
+ /* Ensure that the pasted layer is always within the image, if it
+ * fits and aligned at top left if it doesn't. (See bug #142944).
+ */
+ offset_x = MIN (offset_x, image_width - width);
+ offset_y = MIN (offset_y, image_height - height);
+ offset_x = MAX (offset_x, 0);
+ offset_y = MAX (offset_y, 0);
+ }
gimp_item_set_offset (GIMP_ITEM (layer), offset_x, offset_y);
diff --git a/app/display/gimpdisplayshell-dnd.c b/app/display/gimpdisplayshell-dnd.c
index 259553e..cdb64e7 100644
--- a/app/display/gimpdisplayshell-dnd.c
+++ b/app/display/gimpdisplayshell-dnd.c
@@ -161,20 +161,30 @@ gimp_display_shell_dnd_init (GimpDisplayShell *shell)
*/
static void
gimp_display_shell_dnd_position_item (GimpDisplayShell *shell,
+ GimpImage *image,
GimpItem *item)
{
- gint x, y;
- gint width, height;
- gint off_x, off_y;
+ gint item_width = gimp_item_get_width (item);
+ gint item_height = gimp_item_get_height (item);
- gimp_display_shell_untransform_viewport (shell, &x, &y, &width, &height);
-
- gimp_item_get_offset (item, &off_x, &off_y);
+ if (item_width >= gimp_image_get_width (image) &&
+ item_height >= gimp_image_get_height (image))
+ {
+ gimp_item_set_offset (item,
+ (gimp_image_get_width (image) - item_width) / 2,
+ (gimp_image_get_height (image) - item_height) / 2);
+ }
+ else
+ {
+ gint x, y;
+ gint width, height;
- off_x = x + (width - gimp_item_get_width (item)) / 2 - off_x;
- off_y = y + (height - gimp_item_get_height (item)) / 2 - off_y;
+ gimp_display_shell_untransform_viewport (shell, &x, &y, &width, &height);
- gimp_item_translate (item, off_x, off_y, FALSE);
+ gimp_item_set_offset (item,
+ x + (width - item_width) / 2,
+ y + (height - item_height) / 2);
+ }
}
static void
@@ -230,7 +240,7 @@ gimp_display_shell_drop_drawable (GtkWidget *widget,
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
_("Drop New Layer"));
- gimp_display_shell_dnd_position_item (shell, new_item);
+ gimp_display_shell_dnd_position_item (shell, image, new_item);
gimp_item_set_visible (new_item, TRUE, FALSE);
gimp_item_set_linked (new_item, FALSE, FALSE);
@@ -630,7 +640,7 @@ gimp_display_shell_drop_component (GtkWidget *widget,
gimp_image_undo_group_start (dest_image, GIMP_UNDO_GROUP_EDIT_PASTE,
_("Drop New Layer"));
- gimp_display_shell_dnd_position_item (shell, new_item);
+ gimp_display_shell_dnd_position_item (shell, image, new_item);
gimp_image_add_layer (dest_image, new_layer,
GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
@@ -687,7 +697,7 @@ gimp_display_shell_drop_pixbuf (GtkWidget *widget,
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_EDIT_PASTE,
_("Drop New Layer"));
- gimp_display_shell_dnd_position_item (shell, new_item);
+ gimp_display_shell_dnd_position_item (shell, image, new_item);
gimp_image_add_layer (image, new_layer,
GIMP_IMAGE_ACTIVE_PARENT, -1, TRUE);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]