~ubuntu-branches/ubuntu/maverick/gimp/maverick-updates

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2005-12-09 19:44:52 UTC
  • Revision ID: james.westby@ubuntu.com-20051209194452-yggpemjlofpjqyf4
Tags: upstream-2.2.9
ImportĀ upstreamĀ versionĀ 2.2.9

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 "gimpimage.h"
 
27
#include "gimpimage-grid.h"
 
28
#include "gimpimage-guides.h"
 
29
#include "gimpimage-snap.h"
 
30
 
 
31
#include "gimp-intl.h"
 
32
 
 
33
 
 
34
/*  public functions  */
 
35
 
 
36
 
 
37
gboolean
 
38
gimp_image_snap_x (GimpImage *gimage,
 
39
                   gdouble    x,
 
40
                   gdouble   *tx,
 
41
                   gdouble    epsilon_x,
 
42
                   gboolean   snap_to_guides,
 
43
                   gboolean   snap_to_grid)
 
44
{
 
45
  GList     *list;
 
46
  GimpGuide *guide;
 
47
  GimpGrid  *grid;
 
48
  gdouble    xspacing;
 
49
  gdouble    xoffset;
 
50
  gdouble    mindist = G_MAXDOUBLE;
 
51
  gdouble    dist;
 
52
  gdouble    i;
 
53
  gboolean   snapped = FALSE;
 
54
 
 
55
  g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
 
56
  g_return_val_if_fail (tx != NULL, FALSE);
 
57
 
 
58
  if (! snap_to_guides && ! snap_to_grid)
 
59
    return FALSE;
 
60
 
 
61
  *tx = x;
 
62
 
 
63
  if (x < 0 || x >= gimage->width)
 
64
    return FALSE;
 
65
 
 
66
  if (snap_to_guides && gimage->guides != NULL)
 
67
    {
 
68
      for (list = gimage->guides; list; list = g_list_next (list))
 
69
        {
 
70
          guide = (GimpGuide *) list->data;
 
71
 
 
72
          if (guide->position < 0)
 
73
            continue;
 
74
 
 
75
          if (guide->orientation == GIMP_ORIENTATION_VERTICAL)
 
76
            {
 
77
              dist = ABS (guide->position - x);
 
78
 
 
79
              if (dist < MIN (epsilon_x, mindist))
 
80
                {
 
81
                  mindist = dist;
 
82
                  *tx = guide->position;
 
83
                  snapped = TRUE;
 
84
                }
 
85
            }
 
86
        }
 
87
    }
 
88
 
 
89
  if (snap_to_grid && gimage->grid != NULL)
 
90
    {
 
91
      grid = gimp_image_get_grid (gimage);
 
92
 
 
93
      g_object_get (grid,
 
94
                    "xspacing", &xspacing,
 
95
                    "xoffset",  &xoffset,
 
96
                    NULL);
 
97
 
 
98
      for (i = xoffset; i <= gimage->width; i += xspacing)
 
99
        {
 
100
          if (i < 0)
 
101
            continue;
 
102
 
 
103
          dist = ABS (i - x);
 
104
 
 
105
          if (dist < MIN (epsilon_x, mindist))
 
106
            {
 
107
              mindist = dist;
 
108
              *tx = i;
 
109
              snapped = TRUE;
 
110
            }
 
111
        }
 
112
    }
 
113
 
 
114
  return snapped;
 
115
}
 
116
 
 
117
gboolean
 
118
gimp_image_snap_y (GimpImage *gimage,
 
119
                   gdouble    y,
 
120
                   gdouble   *ty,
 
121
                   gdouble    epsilon_y,
 
122
                   gboolean   snap_to_guides,
 
123
                   gboolean   snap_to_grid)
 
124
{
 
125
  GList     *list;
 
126
  GimpGuide *guide;
 
127
  GimpGrid  *grid;
 
128
  gdouble    yspacing;
 
129
  gdouble    yoffset;
 
130
  gdouble    mindist = G_MAXDOUBLE;
 
131
  gdouble    dist;
 
132
  gdouble    i;
 
133
  gboolean   snapped = FALSE;
 
134
 
 
135
  g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
 
136
  g_return_val_if_fail (ty != NULL, FALSE);
 
137
 
 
138
  if (! snap_to_guides && ! snap_to_grid)
 
139
    return FALSE;
 
140
 
 
141
  *ty = y;
 
142
 
 
143
  if (y < 0 || y >= gimage->height)
 
144
    return FALSE;
 
145
 
 
146
  if (snap_to_guides && gimage->guides != NULL)
 
147
    {
 
148
      for (list = gimage->guides; list; list = g_list_next (list))
 
149
        {
 
150
          guide = (GimpGuide *) list->data;
 
151
 
 
152
          if (guide->position < 0)
 
153
            continue;
 
154
 
 
155
          if (guide->orientation == GIMP_ORIENTATION_HORIZONTAL)
 
156
            {
 
157
              dist = ABS (guide->position - y);
 
158
 
 
159
              if (dist < MIN (epsilon_y, mindist))
 
160
                {
 
161
                  mindist = dist;
 
162
                  *ty = guide->position;
 
163
                  snapped = TRUE;
 
164
                }
 
165
            }
 
166
        }
 
167
    }
 
168
 
 
169
  if (snap_to_grid && gimage->grid != NULL)
 
170
    {
 
171
      grid = gimp_image_get_grid (gimage);
 
172
 
 
173
      g_object_get (grid,
 
174
                    "yspacing", &yspacing,
 
175
                    "yoffset",  &yoffset,
 
176
                    NULL);
 
177
 
 
178
      for (i = yoffset; i <= gimage->height; i += yspacing)
 
179
        {
 
180
          if (i < 0)
 
181
            continue;
 
182
 
 
183
          dist = ABS (i - y);
 
184
 
 
185
          if (dist < MIN (epsilon_y, mindist))
 
186
            {
 
187
              mindist = dist;
 
188
              *ty = i;
 
189
              snapped = TRUE;
 
190
            }
 
191
        }
 
192
    }
 
193
 
 
194
  return snapped;
 
195
}
 
196
 
 
197
gboolean
 
198
gimp_image_snap_point (GimpImage *gimage,
 
199
                       gdouble    x,
 
200
                       gdouble    y,
 
201
                       gdouble   *tx,
 
202
                       gdouble   *ty,
 
203
                       gdouble    epsilon_x,
 
204
                       gdouble    epsilon_y,
 
205
                       gboolean   snap_to_guides,
 
206
                       gboolean   snap_to_grid)
 
207
{
 
208
  GList     *list;
 
209
  GimpGuide *guide;
 
210
  GimpGrid  *grid;
 
211
  gdouble    xspacing, yspacing;
 
212
  gdouble    xoffset, yoffset;
 
213
  gdouble    minxdist, minydist;
 
214
  gdouble    dist;
 
215
  gdouble    i;
 
216
  gboolean   snapped = FALSE;
 
217
 
 
218
  g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
 
219
  g_return_val_if_fail (tx != NULL, FALSE);
 
220
  g_return_val_if_fail (ty != NULL, FALSE);
 
221
 
 
222
  if (! snap_to_guides && ! snap_to_grid)
 
223
    return FALSE;
 
224
 
 
225
  *tx = x;
 
226
  *ty = y;
 
227
 
 
228
  if (x < 0 || x >= gimage->width ||
 
229
      y < 0 || y >= gimage->height)
 
230
    {
 
231
      return FALSE;
 
232
    }
 
233
 
 
234
  minxdist = G_MAXDOUBLE;
 
235
  minydist = G_MAXDOUBLE;
 
236
 
 
237
  if (snap_to_guides && gimage->guides != NULL)
 
238
    {
 
239
      for (list = gimage->guides; list; list = g_list_next (list))
 
240
        {
 
241
          guide = (GimpGuide *) list->data;
 
242
 
 
243
          if (guide->position < 0)
 
244
            continue;
 
245
 
 
246
          switch (guide->orientation)
 
247
            {
 
248
            case GIMP_ORIENTATION_HORIZONTAL:
 
249
              dist = ABS (guide->position - y);
 
250
 
 
251
              if (dist < MIN (epsilon_y, minydist))
 
252
                {
 
253
                  minydist = dist;
 
254
                  *ty = guide->position;
 
255
                  snapped = TRUE;
 
256
                }
 
257
              break;
 
258
 
 
259
            case GIMP_ORIENTATION_VERTICAL:
 
260
              dist = ABS (guide->position - x);
 
261
 
 
262
              if (dist < MIN (epsilon_x, minxdist))
 
263
                {
 
264
                  minxdist = dist;
 
265
                  *tx = guide->position;
 
266
                  snapped = TRUE;
 
267
                }
 
268
              break;
 
269
 
 
270
            default:
 
271
              break;
 
272
            }
 
273
        }
 
274
    }
 
275
 
 
276
  if (snap_to_grid && gimage->grid != NULL)
 
277
    {
 
278
      grid = gimp_image_get_grid (gimage);
 
279
 
 
280
      g_object_get (grid,
 
281
                    "xspacing", &xspacing,
 
282
                    "yspacing", &yspacing,
 
283
                    "xoffset",  &xoffset,
 
284
                    "yoffset",  &yoffset,
 
285
                    NULL);
 
286
 
 
287
      for (i = xoffset; i <= gimage->width; i += xspacing)
 
288
        {
 
289
          if (i < 0)
 
290
            continue;
 
291
 
 
292
          dist = ABS (i - x);
 
293
 
 
294
          if (dist < MIN (epsilon_x, minxdist))
 
295
            {
 
296
              minxdist = dist;
 
297
              *tx = i;
 
298
              snapped = TRUE;
 
299
            }
 
300
        }
 
301
 
 
302
      for (i = yoffset; i <= gimage->height; i += yspacing)
 
303
        {
 
304
          if (i < 0)
 
305
            continue;
 
306
 
 
307
          dist = ABS (i - y);
 
308
 
 
309
          if (dist < MIN (epsilon_y, minydist))
 
310
            {
 
311
              minydist = dist;
 
312
              *ty = i;
 
313
              snapped = TRUE;
 
314
            }
 
315
        }
 
316
    }
 
317
 
 
318
  return snapped;
 
319
}
 
320
 
 
321
gboolean
 
322
gimp_image_snap_rectangle (GimpImage *gimage,
 
323
                           gdouble    x1,
 
324
                           gdouble    y1,
 
325
                           gdouble    x2,
 
326
                           gdouble    y2,
 
327
                           gdouble   *tx1,
 
328
                           gdouble   *ty1,
 
329
                           gdouble    epsilon_x,
 
330
                           gdouble    epsilon_y,
 
331
                           gboolean   snap_to_guides,
 
332
                           gboolean   snap_to_grid)
 
333
{
 
334
  gdouble  nx1, ny1;
 
335
  gdouble  nx2, ny2;
 
336
  gboolean snap1, snap2, snap3, snap4;
 
337
 
 
338
  g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
 
339
  g_return_val_if_fail (tx1 != NULL, FALSE);
 
340
  g_return_val_if_fail (ty1 != NULL, FALSE);
 
341
 
 
342
  if (! snap_to_guides && ! snap_to_grid)
 
343
    return FALSE;
 
344
 
 
345
  *tx1 = x1;
 
346
  *ty1 = y1;
 
347
 
 
348
  snap1 = gimp_image_snap_x (gimage, x1, &nx1,
 
349
                             epsilon_x,
 
350
                             snap_to_guides,
 
351
                             snap_to_grid);
 
352
  snap2 = gimp_image_snap_x (gimage, x2, &nx2,
 
353
                             epsilon_x,
 
354
                             snap_to_guides,
 
355
                             snap_to_grid);
 
356
  snap3 = gimp_image_snap_y (gimage, y1, &ny1,
 
357
                             epsilon_y,
 
358
                             snap_to_guides,
 
359
                             snap_to_grid);
 
360
  snap4 = gimp_image_snap_y (gimage, y2, &ny2,
 
361
                             epsilon_y,
 
362
                             snap_to_guides,
 
363
                             snap_to_grid);
 
364
 
 
365
  if (snap1 && snap2)
 
366
    {
 
367
      if (ABS (x1 - nx1) > ABS (x2 - nx2))
 
368
        snap1 = FALSE;
 
369
      else
 
370
        snap2 = FALSE;
 
371
    }
 
372
 
 
373
  if (snap1)
 
374
    *tx1 = nx1;
 
375
  else if (snap2)
 
376
    *tx1 = RINT (x1 + (nx2 - x2));
 
377
 
 
378
  if (snap3 && snap4)
 
379
    {
 
380
      if (ABS (y1 - ny1) > ABS (y2 - ny2))
 
381
        snap3 = FALSE;
 
382
      else
 
383
        snap4 = FALSE;
 
384
    }
 
385
 
 
386
  if (snap3)
 
387
    *ty1 = ny1;
 
388
  else if (snap4)
 
389
    *ty1 = RINT (y1 + (ny2 - y2));
 
390
 
 
391
  return (snap1 || snap2 || snap3 || snap4);
 
392
}