Bug 735906 - Transform tools give unexpected results when transforming...
...certain sets of linked layers Fix this bug for flip, rotate and general transforms (not for move yet): gimp_item_linked_flip,rotate,transform(): always transform the passed item too (do not filter it out of the list of items), so these functions do the entire job of transforming a linked group now. Transforming the active item separately didn't work (and is not implementable) if both a layer and its parent layer group were linked. flip tool, transform tool, layer->transform callbacks: don't call gimp_item_foo() *and* (if the item is linked) gimp_item_linked_foo(). Instead call gimp_item_linked_foo() if the item is linked, and gimp_item_foo() otherwise. This commit also kills the mis-feature of transforming the selected pixels of the active layer, and then the linked items completely. We now either only transform the selected area *or* the linked group.
This commit is contained in:
@ -355,18 +355,15 @@ drawable_flip_cmd_callback (GtkAction *action,
|
||||
break;
|
||||
}
|
||||
|
||||
if (gimp_item_get_linked (item))
|
||||
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM,
|
||||
GIMP_ITEM_GET_CLASS (item)->flip_desc);
|
||||
|
||||
gimp_item_flip (item, context,
|
||||
(GimpOrientationType) value, axis, FALSE);
|
||||
|
||||
if (gimp_item_get_linked (item))
|
||||
{
|
||||
gimp_item_linked_flip (item, context,
|
||||
(GimpOrientationType) value, axis, FALSE);
|
||||
gimp_image_undo_group_end (image);
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_item_flip (item, context,
|
||||
(GimpOrientationType) value, axis, FALSE);
|
||||
}
|
||||
|
||||
gimp_image_flush (image);
|
||||
@ -394,21 +391,18 @@ drawable_rotate_cmd_callback (GtkAction *action,
|
||||
center_x = ((gdouble) off_x + (gdouble) gimp_item_get_width (item) / 2.0);
|
||||
center_y = ((gdouble) off_y + (gdouble) gimp_item_get_height (item) / 2.0);
|
||||
|
||||
if (gimp_item_get_linked (item))
|
||||
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM,
|
||||
GIMP_ITEM_GET_CLASS (item)->rotate_desc);
|
||||
|
||||
if (GIMP_IS_CHANNEL (item))
|
||||
clip_result = TRUE;
|
||||
|
||||
gimp_item_rotate (item, context, (GimpRotationType) value,
|
||||
center_x, center_y, clip_result);
|
||||
|
||||
if (gimp_item_get_linked (item))
|
||||
{
|
||||
gimp_item_linked_rotate (item, context, (GimpRotationType) value,
|
||||
center_x, center_y, FALSE);
|
||||
gimp_image_undo_group_end (image);
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_item_rotate (item, context, (GimpRotationType) value,
|
||||
center_x, center_y, clip_result);
|
||||
}
|
||||
|
||||
gimp_image_flush (image);
|
||||
|
||||
@ -25,11 +25,14 @@
|
||||
#include "gimpcontext.h"
|
||||
#include "gimpimage.h"
|
||||
#include "gimpimage-item-list.h"
|
||||
#include "gimpimage-undo.h"
|
||||
#include "gimpitem.h"
|
||||
#include "gimpitem-linked.h"
|
||||
#include "gimplist.h"
|
||||
#include "gimpprogress.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
||||
@ -102,23 +105,25 @@ gimp_item_linked_flip (GimpItem *item,
|
||||
gdouble axis,
|
||||
gboolean clip_result)
|
||||
{
|
||||
GList *list;
|
||||
GimpImage *image;
|
||||
GList *items;
|
||||
|
||||
g_return_if_fail (GIMP_IS_ITEM (item));
|
||||
g_return_if_fail (GIMP_IS_CONTEXT (context));
|
||||
g_return_if_fail (gimp_item_get_linked (item) == TRUE);
|
||||
g_return_if_fail (gimp_item_is_attached (item));
|
||||
|
||||
list = gimp_image_item_list_get_list (gimp_item_get_image (item), item,
|
||||
GIMP_ITEM_TYPE_ALL,
|
||||
GIMP_ITEM_SET_LINKED);
|
||||
image = gimp_item_get_image (item);
|
||||
|
||||
list = gimp_image_item_list_filter (item, list);
|
||||
items = gimp_image_item_list_get_list (image, NULL,
|
||||
GIMP_ITEM_TYPE_ALL,
|
||||
GIMP_ITEM_SET_LINKED);
|
||||
items = gimp_image_item_list_filter (NULL, items);
|
||||
|
||||
gimp_image_item_list_flip (gimp_item_get_image (item), list, context,
|
||||
gimp_image_item_list_flip (image, items, context,
|
||||
flip_type, axis, clip_result);
|
||||
|
||||
g_list_free (list);
|
||||
g_list_free (items);
|
||||
}
|
||||
|
||||
void
|
||||
@ -129,35 +134,42 @@ gimp_item_linked_rotate (GimpItem *item,
|
||||
gdouble center_y,
|
||||
gboolean clip_result)
|
||||
{
|
||||
GList *list;
|
||||
GimpImage *image;
|
||||
GList *items;
|
||||
GList *channels;
|
||||
|
||||
g_return_if_fail (GIMP_IS_ITEM (item));
|
||||
g_return_if_fail (GIMP_IS_CONTEXT (context));
|
||||
g_return_if_fail (gimp_item_get_linked (item) == TRUE);
|
||||
g_return_if_fail (gimp_item_is_attached (item));
|
||||
|
||||
list = gimp_image_item_list_get_list (gimp_item_get_image (item), item,
|
||||
GIMP_ITEM_TYPE_LAYERS |
|
||||
GIMP_ITEM_TYPE_VECTORS,
|
||||
GIMP_ITEM_SET_LINKED);
|
||||
image = gimp_item_get_image (item);
|
||||
|
||||
list = gimp_image_item_list_filter (item, list);
|
||||
items = gimp_image_item_list_get_list (image, NULL,
|
||||
GIMP_ITEM_TYPE_LAYERS |
|
||||
GIMP_ITEM_TYPE_VECTORS,
|
||||
GIMP_ITEM_SET_LINKED);
|
||||
items = gimp_image_item_list_filter (NULL, items);
|
||||
|
||||
gimp_image_item_list_rotate (gimp_item_get_image (item), list, context,
|
||||
channels = gimp_image_item_list_get_list (image, NULL,
|
||||
GIMP_ITEM_TYPE_CHANNELS,
|
||||
GIMP_ITEM_SET_LINKED);
|
||||
channels = gimp_image_item_list_filter (NULL, channels);
|
||||
|
||||
if (items && channels)
|
||||
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TRANSFORM,
|
||||
C_("undo-type", "Rotate Items"));
|
||||
|
||||
gimp_image_item_list_rotate (image, items, context,
|
||||
rotate_type, center_x, center_y, clip_result);
|
||||
|
||||
g_list_free (list);
|
||||
|
||||
list = gimp_image_item_list_get_list (gimp_item_get_image (item), item,
|
||||
GIMP_ITEM_TYPE_CHANNELS,
|
||||
GIMP_ITEM_SET_LINKED);
|
||||
|
||||
list = gimp_image_item_list_filter (item, list);
|
||||
|
||||
gimp_image_item_list_rotate (gimp_item_get_image (item), list, context,
|
||||
gimp_image_item_list_rotate (image, channels, context,
|
||||
rotate_type, center_x, center_y, TRUE);
|
||||
|
||||
g_list_free (list);
|
||||
if (items && channels)
|
||||
gimp_image_undo_group_end (image);
|
||||
|
||||
g_list_free (items);
|
||||
g_list_free (channels);
|
||||
}
|
||||
|
||||
void
|
||||
@ -169,7 +181,8 @@ gimp_item_linked_transform (GimpItem *item,
|
||||
GimpTransformResize clip_result,
|
||||
GimpProgress *progress)
|
||||
{
|
||||
GList *list;
|
||||
GimpImage *image;
|
||||
GList *items;
|
||||
|
||||
g_return_if_fail (GIMP_IS_ITEM (item));
|
||||
g_return_if_fail (GIMP_IS_CONTEXT (context));
|
||||
@ -177,16 +190,18 @@ gimp_item_linked_transform (GimpItem *item,
|
||||
g_return_if_fail (gimp_item_is_attached (item));
|
||||
g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
|
||||
|
||||
list = gimp_image_item_list_get_list (gimp_item_get_image (item), item,
|
||||
GIMP_ITEM_TYPE_ALL,
|
||||
GIMP_ITEM_SET_LINKED);
|
||||
image = gimp_item_get_image (item);
|
||||
|
||||
list = gimp_image_item_list_filter (item, list);
|
||||
items = gimp_image_item_list_get_list (image, NULL,
|
||||
GIMP_ITEM_TYPE_ALL,
|
||||
GIMP_ITEM_SET_LINKED);
|
||||
|
||||
gimp_image_item_list_transform (gimp_item_get_image (item), list, context,
|
||||
items = gimp_image_item_list_filter (NULL, items);
|
||||
|
||||
gimp_image_item_list_transform (image, items, context,
|
||||
matrix, direction,
|
||||
interpolation_type,
|
||||
clip_result, progress);
|
||||
|
||||
g_list_free (list);
|
||||
g_list_free (items);
|
||||
}
|
||||
|
||||
@ -227,10 +227,6 @@ gimp_flip_tool_transform (GimpTransformTool *trans_tool,
|
||||
break;
|
||||
}
|
||||
|
||||
if (gimp_item_get_linked (active_item))
|
||||
gimp_item_linked_flip (active_item, context, options->flip_type, axis,
|
||||
FALSE);
|
||||
|
||||
if (orig_buffer)
|
||||
{
|
||||
/* this happens when transforming a selection cut out of a
|
||||
@ -251,7 +247,16 @@ gimp_flip_tool_transform (GimpTransformTool *trans_tool,
|
||||
{
|
||||
/* this happens for entire drawables, paths and layer groups */
|
||||
|
||||
gimp_item_flip (active_item, context, options->flip_type, axis, FALSE);
|
||||
if (gimp_item_get_linked (active_item))
|
||||
{
|
||||
gimp_item_linked_flip (active_item, context,
|
||||
options->flip_type, axis, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gimp_item_flip (active_item, context,
|
||||
options->flip_type, axis, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@ -1268,14 +1268,6 @@ gimp_transform_tool_real_transform (GimpTransformTool *tr_tool,
|
||||
progress = gimp_progress_start (GIMP_PROGRESS (tool), FALSE,
|
||||
"%s", tr_tool->progress_text);
|
||||
|
||||
if (gimp_item_get_linked (active_item))
|
||||
gimp_item_linked_transform (active_item, context,
|
||||
&tr_tool->transform,
|
||||
options->direction,
|
||||
options->interpolation,
|
||||
clip,
|
||||
progress);
|
||||
|
||||
if (orig_buffer)
|
||||
{
|
||||
/* this happens when transforming a selection cut out of a
|
||||
@ -1306,17 +1298,29 @@ gimp_transform_tool_real_transform (GimpTransformTool *tr_tool,
|
||||
{
|
||||
/* this happens for entire drawables, paths and layer groups */
|
||||
|
||||
/* always clip layer masks so they keep their size
|
||||
*/
|
||||
if (GIMP_IS_CHANNEL (active_item))
|
||||
clip = GIMP_TRANSFORM_RESIZE_CLIP;
|
||||
if (gimp_item_get_linked (active_item))
|
||||
{
|
||||
gimp_item_linked_transform (active_item, context,
|
||||
&tr_tool->transform,
|
||||
options->direction,
|
||||
options->interpolation,
|
||||
clip,
|
||||
progress);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* always clip layer masks so they keep their size
|
||||
*/
|
||||
if (GIMP_IS_CHANNEL (active_item))
|
||||
clip = GIMP_TRANSFORM_RESIZE_CLIP;
|
||||
|
||||
gimp_item_transform (active_item, context,
|
||||
&tr_tool->transform,
|
||||
options->direction,
|
||||
options->interpolation,
|
||||
clip,
|
||||
progress);
|
||||
gimp_item_transform (active_item, context,
|
||||
&tr_tool->transform,
|
||||
options->direction,
|
||||
options->interpolation,
|
||||
clip,
|
||||
progress);
|
||||
}
|
||||
}
|
||||
|
||||
if (progress)
|
||||
|
||||
@ -154,6 +154,7 @@ app/core/gimpimage-undo-push.c
|
||||
app/core/gimpimagefile.c
|
||||
app/core/gimpitem.c
|
||||
app/core/gimpitem-exclusive.c
|
||||
app/core/gimpitem-list.c
|
||||
app/core/gimplayer-floating-sel.c
|
||||
app/core/gimplayer.c
|
||||
app/core/gimplayermask.c
|
||||
|
||||
Reference in New Issue
Block a user