~ubuntu-branches/ubuntu/hoary/gimp/hoary

« back to all changes in this revision

Viewing changes to app/core/gimpimage-rotate.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2005-04-04 14:51:23 UTC
  • Revision ID: james.westby@ubuntu.com-20050404145123-9py049eeelfymur8
Tags: upstream-2.2.2
ImportĀ upstreamĀ versionĀ 2.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* The GIMP -- an image manipulation program
 
2
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 
3
 *
 
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.
 
8
 *
 
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.
 
13
 *
 
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.
 
17
 */
 
18
 
 
19
#include "config.h"
 
20
 
 
21
#include <glib-object.h>
 
22
 
 
23
#include "core-types.h"
 
24
 
 
25
#include "gimp.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"
 
32
#include "gimpitem.h"
 
33
#include "gimplist.h"
 
34
#include "gimpprogress.h"
 
35
 
 
36
 
 
37
static void  gimp_image_rotate_item_offset (GimpImage        *gimage,
 
38
                                            GimpRotationType  rotate_type,
 
39
                                            GimpItem         *item,
 
40
                                            gint              off_x,
 
41
                                            gint              off_y);
 
42
static void  gimp_image_rotate_guides      (GimpImage        *gimage,
 
43
                                            GimpRotationType  rotate_type);
 
44
 
 
45
 
 
46
void
 
47
gimp_image_rotate (GimpImage        *gimage,
 
48
                   GimpContext      *context,
 
49
                   GimpRotationType  rotate_type,
 
50
                   GimpProgress     *progress)
 
51
{
 
52
  GimpItem *item;
 
53
  GList    *list;
 
54
  gdouble   center_x;
 
55
  gdouble   center_y;
 
56
  gdouble   progress_max;
 
57
  gdouble   progress_current = 1.0;
 
58
  gint      new_image_width;
 
59
  gint      new_image_height;
 
60
  gboolean  size_changed;
 
61
 
 
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));
 
65
 
 
66
  gimp_set_busy (gimage->gimp);
 
67
 
 
68
  center_x = (gdouble) gimage->width  / 2.0;
 
69
  center_y = (gdouble) gimage->height / 2.0;
 
70
 
 
71
  progress_max = (gimage->channels->num_children +
 
72
                  gimage->layers->num_children   +
 
73
                  gimage->vectors->num_children  +
 
74
                  1 /* selection */);
 
75
 
 
76
  g_object_freeze_notify (G_OBJECT (gimage));
 
77
 
 
78
  gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_IMAGE_ROTATE, NULL);
 
79
 
 
80
  /*  Resize the image (if needed)  */
 
81
  switch (rotate_type)
 
82
    {
 
83
    case GIMP_ROTATE_90:
 
84
    case GIMP_ROTATE_270:
 
85
      new_image_width  = gimage->height;
 
86
      new_image_height = gimage->width;
 
87
      size_changed     = TRUE;
 
88
      break;
 
89
 
 
90
    case GIMP_ROTATE_180:
 
91
      new_image_width  = gimage->width;
 
92
      new_image_height = gimage->height;
 
93
      size_changed     = FALSE;
 
94
     break;
 
95
 
 
96
    default:
 
97
      g_assert_not_reached ();
 
98
      return;
 
99
    }
 
100
 
 
101
  /*  Rotate all channels  */
 
102
  for (list = GIMP_LIST (gimage->channels)->list;
 
103
       list;
 
104
       list = g_list_next (list))
 
105
    {
 
106
      item = (GimpItem *) list->data;
 
107
 
 
108
      gimp_item_rotate (item, context, rotate_type, center_x, center_y, FALSE);
 
109
 
 
110
      item->offset_x = 0;
 
111
      item->offset_y = 0;
 
112
 
 
113
      if (progress)
 
114
        gimp_progress_set_value (progress, progress_current++ / progress_max);
 
115
    }
 
116
 
 
117
  /*  Rotate all vectors  */
 
118
  for (list = GIMP_LIST (gimage->vectors)->list;
 
119
       list;
 
120
       list = g_list_next (list))
 
121
    {
 
122
      item = (GimpItem *) list->data;
 
123
 
 
124
      gimp_item_rotate (item, context, rotate_type, center_x, center_y, FALSE);
 
125
 
 
126
      item->width    = new_image_width;
 
127
      item->height   = new_image_height;
 
128
      item->offset_x = 0;
 
129
      item->offset_y = 0;
 
130
 
 
131
      gimp_item_translate (item,
 
132
                           (new_image_width  - gimage->width)  / 2,
 
133
                           (new_image_height - gimage->height) / 2,
 
134
                           FALSE);
 
135
 
 
136
      if (progress)
 
137
        gimp_progress_set_value (progress, progress_current++ / progress_max);
 
138
    }
 
139
 
 
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);
 
143
 
 
144
  GIMP_ITEM (gimage->selection_mask)->offset_x = 0;
 
145
  GIMP_ITEM (gimage->selection_mask)->offset_y = 0;
 
146
 
 
147
  if (progress)
 
148
    gimp_progress_set_value (progress, progress_current++ / progress_max);
 
149
 
 
150
  /*  Rotate all layers  */
 
151
  for (list = GIMP_LIST (gimage->layers)->list;
 
152
       list;
 
153
       list = g_list_next (list))
 
154
    {
 
155
      gint off_x, off_y;
 
156
 
 
157
      item = (GimpItem *) list->data;
 
158
 
 
159
      gimp_item_offsets (item, &off_x, &off_y);
 
160
 
 
161
      gimp_item_rotate (item, context, rotate_type, center_x, center_y, FALSE);
 
162
 
 
163
      gimp_image_rotate_item_offset (gimage, rotate_type, item, off_x, off_y);
 
164
 
 
165
      if (progress)
 
166
        gimp_progress_set_value (progress, progress_current++ / progress_max);
 
167
    }
 
168
 
 
169
  /*  Rotate all Guides  */
 
170
  gimp_image_rotate_guides (gimage, rotate_type);
 
171
 
 
172
  /*  Resize the image (if needed)  */
 
173
  if (size_changed)
 
174
    {
 
175
      gimp_image_undo_push_image_size (gimage, NULL);
 
176
 
 
177
      g_object_set (gimage,
 
178
                    "width",  new_image_width,
 
179
                    "height", new_image_height,
 
180
                    NULL);
 
181
 
 
182
      if (gimage->xresolution != gimage->yresolution)
 
183
        {
 
184
          gdouble tmp;
 
185
 
 
186
          gimp_image_undo_push_image_resolution (gimage, NULL);
 
187
 
 
188
          tmp                 = gimage->xresolution;
 
189
          gimage->yresolution = gimage->xresolution;
 
190
          gimage->xresolution = tmp;
 
191
        }
 
192
    }
 
193
 
 
194
  gimp_image_undo_group_end (gimage);
 
195
 
 
196
  if (size_changed)
 
197
    gimp_viewable_size_changed (GIMP_VIEWABLE (gimage));
 
198
 
 
199
  g_object_thaw_notify (G_OBJECT (gimage));
 
200
 
 
201
  gimp_unset_busy (gimage->gimp);
 
202
}
 
203
 
 
204
 
 
205
static void
 
206
gimp_image_rotate_item_offset (GimpImage        *gimage,
 
207
                               GimpRotationType  rotate_type,
 
208
                               GimpItem         *item,
 
209
                               gint              off_x,
 
210
                               gint              off_y)
 
211
{
 
212
  gint x = 0;
 
213
  gint y = 0;
 
214
 
 
215
  switch (rotate_type)
 
216
    {
 
217
    case GIMP_ROTATE_90:
 
218
      x = gimage->height - off_y - gimp_item_width (item);
 
219
      y = off_x;
 
220
      break;
 
221
 
 
222
    case GIMP_ROTATE_270:
 
223
      x = off_y;
 
224
      y = gimage->width - off_x - gimp_item_height (item);
 
225
      break;
 
226
 
 
227
    case GIMP_ROTATE_180:
 
228
      return;
 
229
    }
 
230
 
 
231
  gimp_item_offsets (item, &off_x, &off_y);
 
232
 
 
233
  x -= off_x;
 
234
  y -= off_y;
 
235
 
 
236
  if (x || y)
 
237
    gimp_item_translate (item, x, y, FALSE);
 
238
}
 
239
 
 
240
static void
 
241
gimp_image_rotate_guides (GimpImage        *gimage,
 
242
                          GimpRotationType  rotate_type)
 
243
{
 
244
  GList *list;
 
245
 
 
246
  /*  Rotate all Guides  */
 
247
  for (list = gimage->guides; list; list = g_list_next (list))
 
248
    {
 
249
      GimpGuide *guide = list->data;
 
250
 
 
251
      switch (rotate_type)
 
252
        {
 
253
        case GIMP_ROTATE_90:
 
254
          switch (guide->orientation)
 
255
            {
 
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;
 
260
              break;
 
261
 
 
262
            case GIMP_ORIENTATION_VERTICAL:
 
263
              gimp_image_undo_push_image_guide (gimage, NULL, guide);
 
264
              guide->orientation = GIMP_ORIENTATION_HORIZONTAL;
 
265
              break;
 
266
 
 
267
            default:
 
268
              break;
 
269
            }
 
270
          break;
 
271
 
 
272
        case GIMP_ROTATE_180:
 
273
          switch (guide->orientation)
 
274
            {
 
275
            case GIMP_ORIENTATION_HORIZONTAL:
 
276
              gimp_image_move_guide (gimage, guide,
 
277
                                     gimage->height - guide->position, TRUE);
 
278
              break;
 
279
 
 
280
            case GIMP_ORIENTATION_VERTICAL:
 
281
              gimp_image_move_guide (gimage, guide,
 
282
                                     gimage->width - guide->position, TRUE);
 
283
              break;
 
284
 
 
285
            default:
 
286
              break;
 
287
            }
 
288
          break;
 
289
 
 
290
        case GIMP_ROTATE_270:
 
291
          switch (guide->orientation)
 
292
            {
 
293
            case GIMP_ORIENTATION_HORIZONTAL:
 
294
              gimp_image_undo_push_image_guide (gimage, NULL, guide);
 
295
              guide->orientation = GIMP_ORIENTATION_VERTICAL;
 
296
              break;
 
297
 
 
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;
 
302
              break;
 
303
 
 
304
            default:
 
305
              break;
 
306
            }
 
307
          break;
 
308
        }
 
309
    }
 
310
}