1
/* The GIMP -- an image manipulation program
2
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
7
* (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
#include <glib-object.h>
23
#include "core-types.h"
26
#include "gimpcontext.h"
27
#include "gimpimage.h"
28
#include "gimpimage-rotate.h"
29
#include "gimpimage-guides.h"
30
#include "gimpimage-undo.h"
31
#include "gimpimage-undo-push.h"
34
#include "gimpprogress.h"
37
static void gimp_image_rotate_item_offset (GimpImage *gimage,
38
GimpRotationType rotate_type,
42
static void gimp_image_rotate_guides (GimpImage *gimage,
43
GimpRotationType rotate_type);
47
gimp_image_rotate (GimpImage *gimage,
49
GimpRotationType rotate_type,
50
GimpProgress *progress)
57
gdouble progress_current = 1.0;
59
gint new_image_height;
60
gboolean size_changed;
62
g_return_if_fail (GIMP_IS_IMAGE (gimage));
63
g_return_if_fail (GIMP_IS_CONTEXT (context));
64
g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
66
gimp_set_busy (gimage->gimp);
68
center_x = (gdouble) gimage->width / 2.0;
69
center_y = (gdouble) gimage->height / 2.0;
71
progress_max = (gimage->channels->num_children +
72
gimage->layers->num_children +
73
gimage->vectors->num_children +
76
g_object_freeze_notify (G_OBJECT (gimage));
78
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_IMAGE_ROTATE, NULL);
80
/* Resize the image (if needed) */
85
new_image_width = gimage->height;
86
new_image_height = gimage->width;
91
new_image_width = gimage->width;
92
new_image_height = gimage->height;
97
g_assert_not_reached ();
101
/* Rotate all channels */
102
for (list = GIMP_LIST (gimage->channels)->list;
104
list = g_list_next (list))
106
item = (GimpItem *) list->data;
108
gimp_item_rotate (item, context, rotate_type, center_x, center_y, FALSE);
114
gimp_progress_set_value (progress, progress_current++ / progress_max);
117
/* Rotate all vectors */
118
for (list = GIMP_LIST (gimage->vectors)->list;
120
list = g_list_next (list))
122
item = (GimpItem *) list->data;
124
gimp_item_rotate (item, context, rotate_type, center_x, center_y, FALSE);
126
item->width = new_image_width;
127
item->height = new_image_height;
131
gimp_item_translate (item,
132
(new_image_width - gimage->width) / 2,
133
(new_image_height - gimage->height) / 2,
137
gimp_progress_set_value (progress, progress_current++ / progress_max);
140
/* Don't forget the selection mask! */
141
gimp_item_rotate (GIMP_ITEM (gimp_image_get_mask (gimage)), context,
142
rotate_type, center_x, center_y, FALSE);
144
GIMP_ITEM (gimage->selection_mask)->offset_x = 0;
145
GIMP_ITEM (gimage->selection_mask)->offset_y = 0;
148
gimp_progress_set_value (progress, progress_current++ / progress_max);
150
/* Rotate all layers */
151
for (list = GIMP_LIST (gimage->layers)->list;
153
list = g_list_next (list))
157
item = (GimpItem *) list->data;
159
gimp_item_offsets (item, &off_x, &off_y);
161
gimp_item_rotate (item, context, rotate_type, center_x, center_y, FALSE);
163
gimp_image_rotate_item_offset (gimage, rotate_type, item, off_x, off_y);
166
gimp_progress_set_value (progress, progress_current++ / progress_max);
169
/* Rotate all Guides */
170
gimp_image_rotate_guides (gimage, rotate_type);
172
/* Resize the image (if needed) */
175
gimp_image_undo_push_image_size (gimage, NULL);
177
g_object_set (gimage,
178
"width", new_image_width,
179
"height", new_image_height,
182
if (gimage->xresolution != gimage->yresolution)
186
gimp_image_undo_push_image_resolution (gimage, NULL);
188
tmp = gimage->xresolution;
189
gimage->yresolution = gimage->xresolution;
190
gimage->xresolution = tmp;
194
gimp_image_undo_group_end (gimage);
197
gimp_viewable_size_changed (GIMP_VIEWABLE (gimage));
199
g_object_thaw_notify (G_OBJECT (gimage));
201
gimp_unset_busy (gimage->gimp);
206
gimp_image_rotate_item_offset (GimpImage *gimage,
207
GimpRotationType rotate_type,
218
x = gimage->height - off_y - gimp_item_width (item);
222
case GIMP_ROTATE_270:
224
y = gimage->width - off_x - gimp_item_height (item);
227
case GIMP_ROTATE_180:
231
gimp_item_offsets (item, &off_x, &off_y);
237
gimp_item_translate (item, x, y, FALSE);
241
gimp_image_rotate_guides (GimpImage *gimage,
242
GimpRotationType rotate_type)
246
/* Rotate all Guides */
247
for (list = gimage->guides; list; list = g_list_next (list))
249
GimpGuide *guide = list->data;
254
switch (guide->orientation)
256
case GIMP_ORIENTATION_HORIZONTAL:
257
gimp_image_undo_push_image_guide (gimage, NULL, guide);
258
guide->orientation = GIMP_ORIENTATION_VERTICAL;
259
guide->position = gimage->height - guide->position;
262
case GIMP_ORIENTATION_VERTICAL:
263
gimp_image_undo_push_image_guide (gimage, NULL, guide);
264
guide->orientation = GIMP_ORIENTATION_HORIZONTAL;
272
case GIMP_ROTATE_180:
273
switch (guide->orientation)
275
case GIMP_ORIENTATION_HORIZONTAL:
276
gimp_image_move_guide (gimage, guide,
277
gimage->height - guide->position, TRUE);
280
case GIMP_ORIENTATION_VERTICAL:
281
gimp_image_move_guide (gimage, guide,
282
gimage->width - guide->position, TRUE);
290
case GIMP_ROTATE_270:
291
switch (guide->orientation)
293
case GIMP_ORIENTATION_HORIZONTAL:
294
gimp_image_undo_push_image_guide (gimage, NULL, guide);
295
guide->orientation = GIMP_ORIENTATION_VERTICAL;
298
case GIMP_ORIENTATION_VERTICAL:
299
gimp_image_undo_push_image_guide (gimage, NULL, guide);
300
guide->orientation = GIMP_ORIENTATION_HORIZONTAL;
301
guide->position = gimage->width - guide->position;