diff --git a/ChangeLog b/ChangeLog index 4ed7d96a037f135179fed5f41c05a16d158ca1f8..a14475cdbd144ed12102c4f43cea6be1aaaeab1f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +2003-05-20 Michael Natterer + + * app/core/gimpchannel.c (gimp_channel_rotate): don't default to + clip_result == TRUE (unlike the other transform functions). + + * app/core/gimpdrawable-transform.c + (gimp_drawable_transform_tiles_rotate): fixed offset calculation. + + * app/core/gimpimage-rotate.c: change the image size *after* all items + are rotated. Adjust all items' offsets after rotation. Rotate the + resolutions too. Seems to work now and fixes bug #6101. + + * app/core/gimpimage.c (gimp_image_size_changed): emit + "size_changed" on all vectors. + + * app/core/gimpitem-linked.[ch]: added gimp_item_linked_rotate(). + + * app/gui/drawable-commands.c: flip and rotate linked items too. + + * app/vectors/gimpvectors.c (gimp_vectors_rotate): fixed rotation + angles. + + Unrelated: + + * app/core/gimpimage-merge.c: don't #include "path.h". + 2003-05-20 Sven Neumann * app/core/gimpdrawable-transform.c diff --git a/app/actions/drawable-commands.c b/app/actions/drawable-commands.c index 3dc8cbf4ed14ad870e92ab8713d00999cffc2a21..81b56c1b48d93a65e4940777962d9a350347bb01 100644 --- a/app/actions/drawable-commands.c +++ b/app/actions/drawable-commands.c @@ -33,6 +33,8 @@ #include "core/gimpdrawable-equalize.h" #include "core/gimpdrawable-invert.h" #include "core/gimpimage.h" +#include "core/gimpimage-undo.h" +#include "core/gimpitem-linked.h" #include "widgets/gimpitemtreeview.h" @@ -150,7 +152,18 @@ drawable_flip_cmd_callback (GtkWidget *widget, break; } - gimp_item_flip (item, (GimpOrientationType) action, axis, TRUE); + if (gimp_item_get_linked (item)) + gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_TRANSFORM, + _("Flip Layer")); + + gimp_item_flip (item, (GimpOrientationType) action, axis, FALSE); + + if (gimp_item_get_linked (item)) + { + gimp_item_linked_flip (item, (GimpOrientationType) action, axis, FALSE); + gimp_image_undo_group_end (gimage); + } + gimp_image_flush (gimage); } @@ -173,7 +186,19 @@ drawable_rotate_cmd_callback (GtkWidget *widget, center_x = ((gdouble) off_x + (gdouble) gimp_item_width (item) / 2.0); center_y = ((gdouble) off_y + (gdouble) gimp_item_height (item) / 2.0); - gimp_item_rotate (item, (GimpRotationType) action, center_x, center_y, TRUE); + if (gimp_item_get_linked (item)) + gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_TRANSFORM, + _("Rotate Layer")); + + gimp_item_rotate (item, (GimpRotationType) action, center_x, center_y, FALSE); + + if (gimp_item_get_linked (item)) + { + gimp_item_linked_rotate (item, (GimpRotationType) action, + center_x, center_y, FALSE); + gimp_image_undo_group_end (gimage); + } + gimp_image_flush (gimage); } diff --git a/app/core/gimp-transform-region.c b/app/core/gimp-transform-region.c index 56458ddee33e3b7c1ad48e7fac12cadc4eb285c5..eafde0e4852d641ff739517c8be1c8a6085f6fb4 100644 --- a/app/core/gimp-transform-region.c +++ b/app/core/gimp-transform-region.c @@ -585,22 +585,28 @@ gimp_drawable_transform_tiles_rotate (GimpDrawable *drawable, switch (rotate_type) { case GIMP_ROTATE_90: - new_x = ROUND (center_x + (gdouble) orig_y - center_y); - new_y = ROUND (center_y + (gdouble) orig_x - center_x); + new_x = ROUND (center_x - + (gdouble) (orig_y + orig_height) + center_y); + new_y = ROUND (center_y + + (gdouble) orig_x - center_x); new_width = orig_height; new_height = orig_width; break; case GIMP_ROTATE_180: - new_x = ROUND ((gdouble) orig_x - 2.0 * center_x) + orig_width - 1; - new_y = ROUND ((gdouble) orig_y - 2.0 * center_y) + orig_height - 1; + new_x = ROUND (center_x - + ((gdouble) (orig_x + orig_width) - center_x)); + new_y = ROUND (center_y - + ((gdouble) (orig_y + orig_height) - center_y)); new_width = orig_width; new_height = orig_height; break; case GIMP_ROTATE_270: - new_x = ROUND (center_x - (gdouble) orig_y - center_y); - new_y = ROUND (center_y - (gdouble) orig_x - center_x); + new_x = ROUND (center_x + + (gdouble) orig_y - center_y); + new_y = ROUND (center_y - + (gdouble) (orig_x + orig_width) + center_x); new_width = orig_height; new_height = orig_width; break; diff --git a/app/core/gimpchannel-combine.c b/app/core/gimpchannel-combine.c index 6e3dafb5dc6ac8f75445662196c6d8cfaeed5cd6..6f0a22aa84d145b198318a94447f8db18e4d7e71 100644 --- a/app/core/gimpchannel-combine.c +++ b/app/core/gimpchannel-combine.c @@ -442,8 +442,7 @@ gimp_channel_rotate (GimpItem *item, gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_TRANSFORM, _("Rotate Channel")); - if (G_TYPE_FROM_INSTANCE (item) == GIMP_TYPE_CHANNEL) - clip_result = TRUE; + /* don't default to clip_result == TRUE here */ GIMP_ITEM_CLASS (parent_class)->rotate (item, rotate_type, center_x, center_y, diff --git a/app/core/gimpchannel.c b/app/core/gimpchannel.c index 6e3dafb5dc6ac8f75445662196c6d8cfaeed5cd6..6f0a22aa84d145b198318a94447f8db18e4d7e71 100644 --- a/app/core/gimpchannel.c +++ b/app/core/gimpchannel.c @@ -442,8 +442,7 @@ gimp_channel_rotate (GimpItem *item, gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_TRANSFORM, _("Rotate Channel")); - if (G_TYPE_FROM_INSTANCE (item) == GIMP_TYPE_CHANNEL) - clip_result = TRUE; + /* don't default to clip_result == TRUE here */ GIMP_ITEM_CLASS (parent_class)->rotate (item, rotate_type, center_x, center_y, diff --git a/app/core/gimpdrawable-transform.c b/app/core/gimpdrawable-transform.c index 56458ddee33e3b7c1ad48e7fac12cadc4eb285c5..eafde0e4852d641ff739517c8be1c8a6085f6fb4 100644 --- a/app/core/gimpdrawable-transform.c +++ b/app/core/gimpdrawable-transform.c @@ -585,22 +585,28 @@ gimp_drawable_transform_tiles_rotate (GimpDrawable *drawable, switch (rotate_type) { case GIMP_ROTATE_90: - new_x = ROUND (center_x + (gdouble) orig_y - center_y); - new_y = ROUND (center_y + (gdouble) orig_x - center_x); + new_x = ROUND (center_x - + (gdouble) (orig_y + orig_height) + center_y); + new_y = ROUND (center_y + + (gdouble) orig_x - center_x); new_width = orig_height; new_height = orig_width; break; case GIMP_ROTATE_180: - new_x = ROUND ((gdouble) orig_x - 2.0 * center_x) + orig_width - 1; - new_y = ROUND ((gdouble) orig_y - 2.0 * center_y) + orig_height - 1; + new_x = ROUND (center_x - + ((gdouble) (orig_x + orig_width) - center_x)); + new_y = ROUND (center_y - + ((gdouble) (orig_y + orig_height) - center_y)); new_width = orig_width; new_height = orig_height; break; case GIMP_ROTATE_270: - new_x = ROUND (center_x - (gdouble) orig_y - center_y); - new_y = ROUND (center_y - (gdouble) orig_x - center_x); + new_x = ROUND (center_x + + (gdouble) orig_y - center_y); + new_y = ROUND (center_y - + (gdouble) (orig_x + orig_width) + center_x); new_width = orig_height; new_height = orig_width; break; diff --git a/app/core/gimpimage-merge.c b/app/core/gimpimage-merge.c index 2b71f94c914fab8373cfdb421ce16cbac6a7ecb8..90c430d9e917124639baef3e1d18b55d2a088289 100644 --- a/app/core/gimpimage-merge.c +++ b/app/core/gimpimage-merge.c @@ -46,8 +46,6 @@ #include "gimpparasitelist.h" #include "gimpundostack.h" -#include "path.h" - #include "gimp-intl.h" diff --git a/app/core/gimpimage-rotate.c b/app/core/gimpimage-rotate.c index 82e2c3a4ca63ff37c073c806b254a718237ce782..34ce4d1404c9c554342fe987a71eb2cc59e5663b 100644 --- a/app/core/gimpimage-rotate.c +++ b/app/core/gimpimage-rotate.c @@ -50,11 +50,12 @@ gimp_image_rotate (GimpImage *gimage, GList *list; gdouble center_x; gdouble center_y; - gint tmp; gint num_channels; gint num_layers; gint num_vectors; gint progress_current = 1; + gint new_image_width; + gint new_image_height; gboolean size_changed = FALSE; g_return_if_fail (GIMP_IS_IMAGE (gimage)); @@ -82,17 +83,16 @@ gimp_image_rotate (GimpImage *gimage, { case GIMP_ROTATE_90: case GIMP_ROTATE_270: - gimp_image_undo_push_image_size (gimage, NULL); - - tmp = gimage->width; - gimage->width = gimage->height; - gimage->height = tmp; - - size_changed = TRUE; + new_image_width = gimage->height; + new_image_height = gimage->width; + size_changed = TRUE; break; case GIMP_ROTATE_180: - break; + new_image_width = gimage->width; + new_image_height = gimage->height; + size_changed = FALSE; + break; } /* Rotate all channels */ @@ -102,7 +102,13 @@ gimp_image_rotate (GimpImage *gimage, { item = (GimpItem *) list->data; - gimp_item_rotate (item, rotate_type, center_x, center_y, TRUE); + gimp_item_rotate (item, rotate_type, center_x, center_y, FALSE); + + if (size_changed) + { + item->offset_x = 0; + item->offset_y = 0; + } if (progress_func) (* progress_func) (0, num_vectors + num_channels + num_layers, @@ -119,6 +125,19 @@ gimp_image_rotate (GimpImage *gimage, gimp_item_rotate (item, rotate_type, center_x, center_y, FALSE); + if (size_changed) + { + item->offset_x = 0; + item->offset_y = 0; + item->width = new_image_width; + item->height = new_image_height; + + gimp_item_translate (item, + ROUND (center_y - center_x), + ROUND (center_x - center_y), + FALSE); + } + if (progress_func) (* progress_func) (0, num_vectors + num_channels + num_layers, progress_current++, @@ -127,18 +146,33 @@ gimp_image_rotate (GimpImage *gimage, /* Don't forget the selection mask! */ gimp_item_rotate (GIMP_ITEM (gimage->selection_mask), - rotate_type, center_x, center_y, TRUE); + rotate_type, center_x, center_y, FALSE); + GIMP_ITEM (gimage->selection_mask)->offset_x = 0; + GIMP_ITEM (gimage->selection_mask)->offset_y = 0; gimp_image_mask_invalidate (gimage); /* Rotate all layers */ - for (list = GIMP_LIST (gimage->layers)->list; - list; + for (list = GIMP_LIST (gimage->layers)->list; + list; list = g_list_next (list)) { + gint off_x, off_y; + gint width, height; + item = (GimpItem *) list->data; + gimp_item_offsets (item, &off_x, &off_y); + width = gimp_item_width (item); + height = gimp_item_height (item); + gimp_item_rotate (item, rotate_type, center_x, center_y, FALSE); + if (size_changed) + gimp_item_translate (item, + ROUND (center_y - center_x), + ROUND (center_x - center_y), + FALSE); + if (progress_func) (* progress_func) (0, num_vectors + num_channels + num_layers, progress_current++, @@ -148,6 +182,26 @@ gimp_image_rotate (GimpImage *gimage, /* Rotate all Guides */ gimp_image_rotate_guides (gimage, rotate_type); + /* Resize the image (if needed) */ + if (size_changed) + { + gimp_image_undo_push_image_size (gimage, NULL); + + gimage->width = new_image_width; + gimage->height = new_image_height; + + if (gimage->xresolution != gimage->yresolution) + { + gdouble tmp; + + gimp_image_undo_push_image_resolution (gimage, NULL); + + tmp = gimage->xresolution; + gimage->yresolution = gimage->xresolution; + gimage->xresolution = tmp; + } + } + /* Make sure the projection matches the gimage size */ gimp_image_projection_allocate (gimage); @@ -184,7 +238,7 @@ gimp_image_rotate_guides (GimpImage *gimage, case GIMP_ORIENTATION_HORIZONTAL: gimp_image_undo_push_image_guide (gimage, NULL, guide); guide->orientation = GIMP_ORIENTATION_VERTICAL; - guide->position = gimage->width - guide->position; + guide->position = gimage->height - guide->position; break; case GIMP_ORIENTATION_VERTICAL: @@ -226,7 +280,7 @@ gimp_image_rotate_guides (GimpImage *gimage, case GIMP_ORIENTATION_VERTICAL: gimp_image_undo_push_image_guide (gimage, NULL, guide); guide->orientation = GIMP_ORIENTATION_HORIZONTAL; - guide->position = gimage->height - guide->position; + guide->position = gimage->width - guide->position; break; default: diff --git a/app/core/gimpimage.c b/app/core/gimpimage.c index 978407cf71ed0aa2824a137a62047fb600c07295..8dbfe62ead764306f741b87b79199738039c5b4d 100644 --- a/app/core/gimpimage.c +++ b/app/core/gimpimage.c @@ -688,6 +688,9 @@ gimp_image_size_changed (GimpViewable *viewable) gimp_container_foreach (gimage->channels, (GFunc) gimp_viewable_size_changed, NULL); + gimp_container_foreach (gimage->vectors, + (GFunc) gimp_viewable_size_changed, + NULL); for (list = GIMP_LIST (gimage->layers)->list; list; list = g_list_next (list)) { diff --git a/app/core/gimpitem-linked.c b/app/core/gimpitem-linked.c index 068b0321e0b6cf65223cfe447b53f8bccf0a127e..4f13b8aa87175cf7b6e3c76d92a0f4eca172c63f 100644 --- a/app/core/gimpitem-linked.c +++ b/app/core/gimpitem-linked.c @@ -88,6 +88,33 @@ gimp_item_linked_flip (GimpItem *item, g_list_free (linked_list); } +void +gimp_item_linked_rotate (GimpItem *item, + GimpRotationType rotate_type, + gdouble center_x, + gdouble center_y, + gboolean clip_result) +{ + GimpImage *gimage; + GList *linked_list; + GList *list; + + g_return_if_fail (GIMP_IS_ITEM (item)); + g_return_if_fail (gimp_item_get_linked (item) == TRUE); + + gimage = gimp_item_get_image (item); + + g_return_if_fail (GIMP_IS_IMAGE (gimage)); + + linked_list = gimp_item_linked_get_list (gimage, item); + + for (list = linked_list; list; list = g_list_next (list)) + gimp_item_rotate (GIMP_ITEM (list->data), + rotate_type, center_x, center_y, clip_result); + + g_list_free (linked_list); +} + void gimp_item_linked_transform (GimpItem *item, GimpMatrix3 matrix, diff --git a/app/core/gimpitem-linked.h b/app/core/gimpitem-linked.h index 4fdc47a57cb6f6e54bfa3d5432aaf63e4479d615..10228faa34f3fc9ce9ec35c214483fc36eeecb21 100644 --- a/app/core/gimpitem-linked.h +++ b/app/core/gimpitem-linked.h @@ -28,6 +28,11 @@ void gimp_item_linked_flip (GimpItem *item, GimpOrientationType flip_type, gdouble axis, gboolean clip_result); +void gimp_item_linked_rotate (GimpItem *item, + GimpRotationType rotate_type, + gdouble center_x, + gdouble center_y, + gboolean clip_result); void gimp_item_linked_transform (GimpItem *item, GimpMatrix3 matrix, GimpTransformDirection direction, diff --git a/app/gui/drawable-commands.c b/app/gui/drawable-commands.c index 3dc8cbf4ed14ad870e92ab8713d00999cffc2a21..81b56c1b48d93a65e4940777962d9a350347bb01 100644 --- a/app/gui/drawable-commands.c +++ b/app/gui/drawable-commands.c @@ -33,6 +33,8 @@ #include "core/gimpdrawable-equalize.h" #include "core/gimpdrawable-invert.h" #include "core/gimpimage.h" +#include "core/gimpimage-undo.h" +#include "core/gimpitem-linked.h" #include "widgets/gimpitemtreeview.h" @@ -150,7 +152,18 @@ drawable_flip_cmd_callback (GtkWidget *widget, break; } - gimp_item_flip (item, (GimpOrientationType) action, axis, TRUE); + if (gimp_item_get_linked (item)) + gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_TRANSFORM, + _("Flip Layer")); + + gimp_item_flip (item, (GimpOrientationType) action, axis, FALSE); + + if (gimp_item_get_linked (item)) + { + gimp_item_linked_flip (item, (GimpOrientationType) action, axis, FALSE); + gimp_image_undo_group_end (gimage); + } + gimp_image_flush (gimage); } @@ -173,7 +186,19 @@ drawable_rotate_cmd_callback (GtkWidget *widget, center_x = ((gdouble) off_x + (gdouble) gimp_item_width (item) / 2.0); center_y = ((gdouble) off_y + (gdouble) gimp_item_height (item) / 2.0); - gimp_item_rotate (item, (GimpRotationType) action, center_x, center_y, TRUE); + if (gimp_item_get_linked (item)) + gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_TRANSFORM, + _("Rotate Layer")); + + gimp_item_rotate (item, (GimpRotationType) action, center_x, center_y, FALSE); + + if (gimp_item_get_linked (item)) + { + gimp_item_linked_rotate (item, (GimpRotationType) action, + center_x, center_y, FALSE); + gimp_image_undo_group_end (gimage); + } + gimp_image_flush (gimage); } diff --git a/app/vectors/gimpvectors.c b/app/vectors/gimpvectors.c index ed4b7c64b4b9a18a6b3d6efa47d0cb840af4ee25..d2b41fd5db99288c5e9a4beacd2fa10f460483a7 100644 --- a/app/vectors/gimpvectors.c +++ b/app/vectors/gimpvectors.c @@ -452,13 +452,13 @@ gimp_vectors_rotate (GimpItem *item, switch (rotate_type) { case GIMP_ROTATE_90: - angle = - G_PI_2; + angle = G_PI_2; break; case GIMP_ROTATE_180: angle = G_PI; break; case GIMP_ROTATE_270: - angle = G_PI_2; + angle = - G_PI_2; break; }