~ubuntu-branches/ubuntu/jaunty/gimp/jaunty-security

« back to all changes in this revision

Viewing changes to app/tools/gimpscaletool.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2007-05-02 16:33:03 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070502163303-bvzhjzbpw8qglc4y
Tags: 2.3.16-1ubuntu1
* Resynchronized with Debian, remaining Ubuntu changes:
  - debian/rules: i18n magic.
* debian/control.in:
  - Maintainer: Ubuntu Core Developers <ubuntu-devel@lists.ubuntu.com>
* debian/patches/02_help-message.patch,
  debian/patches/03_gimp.desktop.in.in.patch,
  debian/patches/10_dont_show_wizard.patch: updated.
* debian/patches/04_composite-signedness.patch,
  debian/patches/05_add-letter-spacing.patch: dropped, used upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* The GIMP -- an image manipulation program
 
1
/* GIMP - The GNU Image Manipulation Program
2
2
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3
3
 *
4
4
 * This program is free software; you can redistribute it and/or modify
18
18
 
19
19
#include "config.h"
20
20
 
 
21
#include <string.h>
 
22
 
21
23
#include <gtk/gtk.h>
22
24
 
23
 
#include "libgimpbase/gimpbase.h"
24
25
#include "libgimpmath/gimpmath.h"
25
26
#include "libgimpwidgets/gimpwidgets.h"
26
27
 
29
30
#include "core/gimp-transform-utils.h"
30
31
#include "core/gimpimage.h"
31
32
#include "core/gimpdrawable-transform.h"
32
 
#include "core/gimptoolinfo.h"
33
33
#include "core/gimpunit.h"
34
34
 
35
35
#include "widgets/gimphelp-ids.h"
 
36
#include "widgets/gimpsizebox.h"
36
37
 
37
38
#include "display/gimpdisplay.h"
38
39
#include "display/gimpdisplayshell.h"
39
40
 
40
 
#ifdef __GNUC__
41
 
#warning FIXME #include "dialogs/dialogs-types.h"
42
 
#endif
43
 
#include "dialogs/dialogs-types.h"
44
 
#include "dialogs/info-dialog.h"
45
 
 
46
41
#include "gimpscaletool.h"
47
42
#include "gimptoolcontrol.h"
48
43
#include "gimptransformoptions.h"
52
47
 
53
48
/*  local function prototypes  */
54
49
 
55
 
static void   gimp_scale_tool_class_init     (GimpScaleToolClass *klass);
56
 
static void   gimp_scale_tool_init           (GimpScaleTool      *sc_tool);
57
 
 
58
 
static void   gimp_scale_tool_dialog         (GimpTransformTool  *tr_tool);
59
 
static void   gimp_scale_tool_dialog_update  (GimpTransformTool  *tr_tool);
60
 
static void   gimp_scale_tool_prepare        (GimpTransformTool  *tr_tool,
61
 
                                              GimpDisplay        *gdisp);
62
 
static void   gimp_scale_tool_motion         (GimpTransformTool  *tr_tool,
63
 
                                              GimpDisplay        *gdisp);
64
 
static void   gimp_scale_tool_recalc         (GimpTransformTool  *tr_tool,
65
 
                                              GimpDisplay        *gdisp);
66
 
 
67
 
static void   gimp_scale_tool_size_changed   (GtkWidget          *widget,
68
 
                                              GimpTransformTool  *tr_tool);
69
 
static void   gimp_scale_tool_unit_changed   (GtkWidget          *widget,
70
 
                                              GimpTransformTool  *tr_tool);
71
 
static void   gimp_scale_tool_aspect_changed (GtkWidget          *widget,
72
 
                                              GimpTransformTool  *tr_tool);
73
 
 
74
 
 
75
 
/*  private variables  */
76
 
 
77
 
static GimpTransformToolClass *parent_class = NULL;
78
 
 
79
 
 
80
 
/*  public functions  */
 
50
static void   gimp_scale_tool_dialog        (GimpTransformTool  *tr_tool);
 
51
static void   gimp_scale_tool_dialog_update (GimpTransformTool  *tr_tool);
 
52
static void   gimp_scale_tool_prepare       (GimpTransformTool  *tr_tool,
 
53
                                             GimpDisplay        *display);
 
54
static void   gimp_scale_tool_motion        (GimpTransformTool  *tr_tool,
 
55
                                             GimpDisplay        *display);
 
56
static void   gimp_scale_tool_recalc        (GimpTransformTool  *tr_tool,
 
57
                                             GimpDisplay        *display);
 
58
 
 
59
static void   gimp_scale_tool_size_notify   (GtkWidget          *box,
 
60
                                             GParamSpec         *pspec,
 
61
                                             GimpTransformTool  *tr_tool);
 
62
 
 
63
 
 
64
G_DEFINE_TYPE (GimpScaleTool, gimp_scale_tool, GIMP_TYPE_TRANSFORM_TOOL)
 
65
 
 
66
#define parent_class gimp_scale_tool_parent_class
 
67
 
81
68
 
82
69
void
83
70
gimp_scale_tool_register (GimpToolRegisterCallback  callback,
89
76
                0,
90
77
                "gimp-scale-tool",
91
78
                _("Scale"),
92
 
                _("Scale the layer or selection"),
 
79
                _("Scale Tool: Scale the layer, selection or path"),
93
80
                N_("_Scale"), "<shift>T",
94
81
                NULL, GIMP_HELP_TOOL_SCALE,
95
82
                GIMP_STOCK_TOOL_SCALE,
96
83
                data);
97
84
}
98
85
 
99
 
GType
100
 
gimp_scale_tool_get_type (void)
101
 
{
102
 
  static GType tool_type = 0;
103
 
 
104
 
  if (! tool_type)
105
 
    {
106
 
      static const GTypeInfo tool_info =
107
 
      {
108
 
        sizeof (GimpScaleToolClass),
109
 
        (GBaseInitFunc) NULL,
110
 
        (GBaseFinalizeFunc) NULL,
111
 
        (GClassInitFunc) gimp_scale_tool_class_init,
112
 
        NULL,           /* class_finalize */
113
 
        NULL,           /* class_data     */
114
 
        sizeof (GimpScaleTool),
115
 
        0,              /* n_preallocs    */
116
 
        (GInstanceInitFunc) gimp_scale_tool_init,
117
 
      };
118
 
 
119
 
      tool_type = g_type_register_static (GIMP_TYPE_TRANSFORM_TOOL,
120
 
                                          "GimpScaleTool",
121
 
                                          &tool_info, 0);
122
 
    }
123
 
 
124
 
  return tool_type;
125
 
}
126
 
 
127
 
 
128
 
/*  private functions  */
129
 
 
130
86
static void
131
87
gimp_scale_tool_class_init (GimpScaleToolClass *klass)
132
88
{
133
89
  GimpTransformToolClass *trans_class = GIMP_TRANSFORM_TOOL_CLASS (klass);
134
90
 
135
 
  parent_class = g_type_class_peek_parent (klass);
136
 
 
137
 
  trans_class->dialog         = gimp_scale_tool_dialog;
138
 
  trans_class->dialog_update  = gimp_scale_tool_dialog_update;
139
 
  trans_class->prepare        = gimp_scale_tool_prepare;
140
 
  trans_class->motion         = gimp_scale_tool_motion;
141
 
  trans_class->recalc         = gimp_scale_tool_recalc;
 
91
  trans_class->dialog        = gimp_scale_tool_dialog;
 
92
  trans_class->dialog_update = gimp_scale_tool_dialog_update;
 
93
  trans_class->prepare       = gimp_scale_tool_prepare;
 
94
  trans_class->motion        = gimp_scale_tool_motion;
 
95
  trans_class->recalc        = gimp_scale_tool_recalc;
142
96
}
143
97
 
144
98
static void
149
103
 
150
104
  gimp_tool_control_set_tool_cursor (tool->control, GIMP_TOOL_CURSOR_RESIZE);
151
105
 
152
 
  tr_tool->shell_desc    = _("Scaling information");
153
 
  tr_tool->progress_text = _("Scaling...");
 
106
  tr_tool->undo_desc       = Q_("command|Scale");
 
107
  tr_tool->progress_text   = _("Scaling");
 
108
 
 
109
  tr_tool->use_grid        = TRUE;
 
110
  tr_tool->use_handles     = TRUE;
 
111
  tr_tool->use_center      = TRUE;
 
112
  tr_tool->use_mid_handles = TRUE;
154
113
}
155
114
 
156
115
static void
157
116
gimp_scale_tool_dialog (GimpTransformTool *tr_tool)
158
117
{
159
 
  GimpScaleTool *scale = GIMP_SCALE_TOOL (tr_tool);
160
 
  GtkWidget     *spinbutton;
161
 
 
162
 
  info_dialog_add_label (tr_tool->info_dialog,
163
 
                         _("Original Width:"),
164
 
                         scale->orig_width_buf);
165
 
  info_dialog_add_label (tr_tool->info_dialog,
166
 
                         _("Height:"),
167
 
                         scale->orig_height_buf);
168
 
 
169
 
  spinbutton = info_dialog_add_spinbutton (tr_tool->info_dialog,
170
 
                                           _("Current width:"),
171
 
                                           NULL, -1, 1, 1, 10, 1, 1, 2,
172
 
                                           NULL, NULL);
173
 
  scale->sizeentry = info_dialog_add_sizeentry (tr_tool->info_dialog,
174
 
                                                _("Current height:"),
175
 
                                                scale->size_vals, 1,
176
 
                                                GIMP_UNIT_PIXEL, "%a",
177
 
                                                TRUE, TRUE, FALSE,
178
 
                                                GIMP_SIZE_ENTRY_UPDATE_SIZE,
179
 
                                                G_CALLBACK (gimp_scale_tool_size_changed),
180
 
                                                tr_tool);
181
 
  g_signal_connect (scale->sizeentry, "unit_changed",
182
 
                    G_CALLBACK (gimp_scale_tool_unit_changed),
183
 
                    tr_tool);
184
 
 
185
 
  gimp_size_entry_add_field (GIMP_SIZE_ENTRY (scale->sizeentry),
186
 
                             GTK_SPIN_BUTTON (spinbutton), NULL);
187
 
 
188
 
  info_dialog_add_label (tr_tool->info_dialog,
189
 
                         _("Scale ratio X:"),
190
 
                         scale->x_ratio_buf);
191
 
  info_dialog_add_label (tr_tool->info_dialog,
192
 
                         _("Scale ratio Y:"),
193
 
                         scale->y_ratio_buf);
194
 
 
195
 
  spinbutton = info_dialog_add_spinbutton (tr_tool->info_dialog,
196
 
                                           _("Aspect Ratio:"),
197
 
                                           &scale->aspect_ratio_val,
198
 
                                           0, 65536, 0.01, 0.1, 1, 0.5, 2,
199
 
                                           G_CALLBACK (gimp_scale_tool_aspect_changed),
200
 
                                           tr_tool);
201
 
 
202
 
  gtk_table_set_row_spacing (GTK_TABLE (tr_tool->info_dialog->info_table),
203
 
                             1, 4);
204
 
  gtk_table_set_row_spacing (GTK_TABLE (tr_tool->info_dialog->info_table),
205
 
                             2, 0);
206
118
}
207
119
 
208
120
static void
209
121
gimp_scale_tool_dialog_update (GimpTransformTool *tr_tool)
210
122
{
211
 
  GimpTool             *tool  = GIMP_TOOL (tr_tool);
212
 
  GimpScaleTool        *scale = GIMP_SCALE_TOOL (tr_tool);
213
 
  GimpTransformOptions *options;
214
 
  Gimp                 *gimp;
215
 
  gdouble               ratio_x, ratio_y;
216
 
  gint                  x1, y1, x2, y2, x3, y3, x4, y4;
217
 
  GimpUnit              unit;
218
 
  gdouble               unit_factor;
219
 
  gchar                 format_buf[16];
220
 
 
221
 
  static GimpUnit       label_unit = GIMP_UNIT_PIXEL;
222
 
 
223
 
  options = GIMP_TRANSFORM_OPTIONS (tool->tool_info->tool_options);
224
 
 
225
 
  unit = gimp_size_entry_get_unit (GIMP_SIZE_ENTRY (scale->sizeentry));
226
 
 
227
 
  /*  Find original sizes  */
228
 
  x1 = tr_tool->x1;
229
 
  y1 = tr_tool->y1;
230
 
  x2 = tr_tool->x2;
231
 
  y2 = tr_tool->y2;
232
 
 
233
 
  if (unit != GIMP_UNIT_PERCENT)
234
 
    label_unit = unit;
235
 
 
236
 
  gimp = tool->tool_info->gimp;
237
 
 
238
 
  unit_factor = _gimp_unit_get_factor (gimp, label_unit);
239
 
 
240
 
  if (label_unit) /* unit != GIMP_UNIT_PIXEL */
241
 
    {
242
 
      g_snprintf (format_buf, sizeof (format_buf), "%%.%df %s",
243
 
                  _gimp_unit_get_digits (gimp, label_unit) + 1,
244
 
                  _gimp_unit_get_symbol (gimp, label_unit));
245
 
      g_snprintf (scale->orig_width_buf, MAX_INFO_BUF, format_buf,
246
 
                  (x2 - x1) * unit_factor / tool->gdisp->gimage->xresolution);
247
 
      g_snprintf (scale->orig_height_buf, MAX_INFO_BUF, format_buf,
248
 
                  (y2 - y1) * unit_factor / tool->gdisp->gimage->yresolution);
249
 
    }
250
 
  else /* unit == GIMP_UNIT_PIXEL */
251
 
    {
252
 
      g_snprintf (scale->orig_width_buf, MAX_INFO_BUF, "%d", x2 - x1);
253
 
      g_snprintf (scale->orig_height_buf, MAX_INFO_BUF, "%d", y2 - y1);
254
 
    }
255
 
 
256
 
  /*  Find current sizes  */
257
 
  x3 = (gint) tr_tool->trans_info[X0];
258
 
  y3 = (gint) tr_tool->trans_info[Y0];
259
 
  x4 = (gint) tr_tool->trans_info[X1];
260
 
  y4 = (gint) tr_tool->trans_info[Y1];
261
 
 
262
 
  scale->size_vals[0] = x4 - x3;
263
 
  scale->size_vals[1] = y4 - y3;
264
 
 
265
 
  ratio_x = ratio_y = 0.0;
266
 
 
267
 
  if (x2 - x1)
268
 
    ratio_x = (double) (x4 - x3) / (double) (x2 - x1);
269
 
  if (y2 - y1)
270
 
    ratio_y = (double) (y4 - y3) / (double) (y2 - y1);
271
 
 
272
 
  /* Detecting initial update, aspect_ratio reset */
273
 
  if (ratio_x == 1 && ratio_y == 1)
274
 
    scale->aspect_ratio_val = 0.0;
275
 
 
276
 
  /* Only when one or the two options are disabled, is necessary to
277
 
   * update the value Taking care of the initial update too
278
 
   */
279
 
  if (! options->constrain_1 ||
280
 
      ! options->constrain_2 ||
281
 
      scale->aspect_ratio_val == 0 )
282
 
    {
283
 
      scale->aspect_ratio_val =
284
 
        ((tr_tool->trans_info[X1] - tr_tool->trans_info[X0]) /
285
 
         (tr_tool->trans_info[Y1] - tr_tool->trans_info[Y0]));
286
 
    }
287
 
 
288
 
  g_snprintf (scale->x_ratio_buf, sizeof (scale->x_ratio_buf),
289
 
              "%0.2f", ratio_x);
290
 
  g_snprintf (scale->y_ratio_buf, sizeof (scale->y_ratio_buf),
291
 
              "%0.2f", ratio_y);
292
 
 
293
 
  info_dialog_update (tr_tool->info_dialog);
294
 
  info_dialog_show (tr_tool->info_dialog);
 
123
  GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool);
 
124
 
 
125
  gint width  = ROUND (tr_tool->trans_info[X1] - tr_tool->trans_info[X0]);
 
126
  gint height = ROUND (tr_tool->trans_info[Y1] - tr_tool->trans_info[Y0]);
 
127
 
 
128
  g_object_set (GIMP_SCALE_TOOL (tr_tool)->box,
 
129
                "width",       width,
 
130
                "height",      height,
 
131
                "keep-aspect", options->constrain,
 
132
                NULL);
295
133
}
296
134
 
297
135
static void
298
136
gimp_scale_tool_prepare (GimpTransformTool *tr_tool,
299
 
                         GimpDisplay       *gdisp)
 
137
                         GimpDisplay       *display)
300
138
{
301
 
  GimpScaleTool *scale = GIMP_SCALE_TOOL (tr_tool);
302
 
 
303
 
  scale->size_vals[0] = tr_tool->x2 - tr_tool->x1;
304
 
  scale->size_vals[1] = tr_tool->y2 - tr_tool->y1;
305
 
 
306
 
  g_signal_handlers_block_by_func (scale->sizeentry,
307
 
                                   gimp_scale_tool_size_changed,
308
 
                                   tr_tool);
309
 
  g_signal_handlers_block_by_func (scale->sizeentry,
310
 
                                   gimp_scale_tool_unit_changed,
311
 
                                   tr_tool);
312
 
 
313
 
  gimp_size_entry_set_unit (GIMP_SIZE_ENTRY (scale->sizeentry),
314
 
                            GIMP_DISPLAY_SHELL (gdisp->shell)->unit);
315
 
 
316
 
  gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (scale->sizeentry), 0,
317
 
                                  gdisp->gimage->xresolution, FALSE);
318
 
  gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (scale->sizeentry), 1,
319
 
                                  gdisp->gimage->yresolution, FALSE);
320
 
 
321
 
  gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (scale->sizeentry), 0,
322
 
                                         GIMP_MIN_IMAGE_SIZE,
323
 
                                         GIMP_MAX_IMAGE_SIZE);
324
 
  gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (scale->sizeentry), 1,
325
 
                                         GIMP_MIN_IMAGE_SIZE,
326
 
                                         GIMP_MAX_IMAGE_SIZE);
327
 
 
328
 
  gimp_size_entry_set_size (GIMP_SIZE_ENTRY (scale->sizeentry), 0,
329
 
                            0, scale->size_vals[0]);
330
 
  gimp_size_entry_set_size (GIMP_SIZE_ENTRY (scale->sizeentry), 1,
331
 
                            0, scale->size_vals[1]);
332
 
 
333
 
  gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (scale->sizeentry), 0,
334
 
                              scale->size_vals[0]);
335
 
  gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (scale->sizeentry), 1,
336
 
                              scale->size_vals[1]);
337
 
 
338
 
  g_signal_handlers_unblock_by_func (scale->sizeentry,
339
 
                                     gimp_scale_tool_size_changed,
340
 
                                     tr_tool);
341
 
  g_signal_handlers_unblock_by_func (scale->sizeentry,
342
 
                                     gimp_scale_tool_unit_changed,
343
 
                                     tr_tool);
 
139
  GimpScaleTool        *scale   = GIMP_SCALE_TOOL (tr_tool);
 
140
  GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool);
344
141
 
345
142
  tr_tool->trans_info[X0] = (gdouble) tr_tool->x1;
346
143
  tr_tool->trans_info[Y0] = (gdouble) tr_tool->y1;
347
144
  tr_tool->trans_info[X1] = (gdouble) tr_tool->x2;
348
145
  tr_tool->trans_info[Y1] = (gdouble) tr_tool->y2;
 
146
 
 
147
  if (scale->box)
 
148
    {
 
149
      g_signal_handlers_disconnect_by_func (scale->box,
 
150
                                            gimp_scale_tool_size_notify,
 
151
                                            tr_tool);
 
152
      gtk_widget_destroy (scale->box);
 
153
    }
 
154
 
 
155
  /*  Need to create a new GimpSizeBox widget because the initial
 
156
   *  width and height is what counts as 100%.
 
157
   */
 
158
  scale->box =
 
159
    g_object_new (GIMP_TYPE_SIZE_BOX,
 
160
                  "width",       tr_tool->x2 - tr_tool->x1,
 
161
                  "height",      tr_tool->y2 - tr_tool->y1,
 
162
                  "keep-aspect", options->constrain,
 
163
                  "unit",        GIMP_DISPLAY_SHELL (display->shell)->unit,
 
164
                  "xresolution", display->image->xresolution,
 
165
                  "yresolution", display->image->yresolution,
 
166
                  NULL);
 
167
 
 
168
  gtk_container_set_border_width (GTK_CONTAINER (scale->box), 6);
 
169
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (tr_tool->dialog)->vbox), scale->box,
 
170
                      FALSE, FALSE, 0);
 
171
  gtk_widget_show (scale->box);
 
172
 
 
173
  g_signal_connect (scale->box, "notify",
 
174
                    G_CALLBACK (gimp_scale_tool_size_notify),
 
175
                    tr_tool);
349
176
}
350
177
 
351
178
static void
352
179
gimp_scale_tool_motion (GimpTransformTool *tr_tool,
353
 
                        GimpDisplay       *gdisp)
 
180
                        GimpDisplay       *display)
354
181
{
355
 
  GimpTransformOptions *options;
 
182
  GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool);
356
183
  gdouble              *x1;
357
184
  gdouble              *y1;
358
185
  gdouble              *x2;
359
186
  gdouble              *y2;
360
 
  gdouble               mag;
361
 
  gdouble               dot;
362
 
  gint                  dir_x, dir_y;
363
 
  gdouble               diff_x, diff_y;
364
 
 
365
 
  options = GIMP_TRANSFORM_OPTIONS (GIMP_TOOL (tr_tool)->tool_info->tool_options);
366
 
 
367
 
  diff_x = tr_tool->curx - tr_tool->lastx;
368
 
  diff_y = tr_tool->cury - tr_tool->lasty;
 
187
  gint                  dir_x;
 
188
  gint                  dir_y;
 
189
  gdouble               diff_x = tr_tool->curx - tr_tool->lastx;
 
190
  gdouble               diff_y = tr_tool->cury - tr_tool->lasty;
369
191
 
370
192
  switch (tr_tool->function)
371
193
    {
372
 
    case TRANSFORM_HANDLE_1:
 
194
    case TRANSFORM_HANDLE_N:
 
195
      diff_x = 0; /* and fall through */
 
196
    case TRANSFORM_HANDLE_NW:
373
197
      x1 = &tr_tool->trans_info[X0];
374
198
      y1 = &tr_tool->trans_info[Y0];
375
199
      x2 = &tr_tool->trans_info[X1];
377
201
      dir_x = dir_y = 1;
378
202
      break;
379
203
 
380
 
    case TRANSFORM_HANDLE_2:
 
204
    case TRANSFORM_HANDLE_E:
 
205
      diff_y = 0; /* and fall through */
 
206
    case TRANSFORM_HANDLE_NE:
381
207
      x1 = &tr_tool->trans_info[X1];
382
208
      y1 = &tr_tool->trans_info[Y0];
383
209
      x2 = &tr_tool->trans_info[X0];
386
212
      dir_y = 1;
387
213
      break;
388
214
 
389
 
    case TRANSFORM_HANDLE_3:
 
215
    case TRANSFORM_HANDLE_W:
 
216
      diff_y = 0; /* and fall through */
 
217
    case TRANSFORM_HANDLE_SW:
390
218
      x1 = &tr_tool->trans_info[X0];
391
219
      y1 = &tr_tool->trans_info[Y1];
392
220
      x2 = &tr_tool->trans_info[X1];
395
223
      dir_y = -1;
396
224
      break;
397
225
 
398
 
    case TRANSFORM_HANDLE_4:
 
226
    case TRANSFORM_HANDLE_S:
 
227
      diff_x = 0; /* and fall through */
 
228
    case TRANSFORM_HANDLE_SE:
399
229
      x1 = &tr_tool->trans_info[X1];
400
230
      y1 = &tr_tool->trans_info[Y1];
401
231
      x2 = &tr_tool->trans_info[X0];
412
242
      tr_tool->trans_info[Y2] += diff_y;
413
243
      tr_tool->trans_info[X3] += diff_x;
414
244
      tr_tool->trans_info[Y3] += diff_y;
415
 
 
416
245
      return;
417
246
 
418
247
    default:
419
248
      return;
420
249
    }
421
250
 
422
 
  /*  if just the mod1 key is down, affect only the height  */
423
 
  if (options->constrain_2 && ! options->constrain_1)
424
 
    {
425
 
      diff_x = 0;
426
 
    }
427
 
  /*  if just the control key is down, affect only the width  */
428
 
  else if (options->constrain_1 && ! options->constrain_2)
429
 
    {
430
 
      diff_y = 0;
431
 
    }
432
 
  /*  if control and mod1 are both down, constrain the aspect ratio  */
433
 
  else if (options->constrain_1 && options->constrain_2)
434
 
    {
435
 
      mag = hypot ((gdouble) (tr_tool->x2 - tr_tool->x1),
436
 
                   (gdouble) (tr_tool->y2 - tr_tool->y1));
437
 
 
438
 
      dot = (dir_x * diff_x * (tr_tool->x2 - tr_tool->x1) +
439
 
             dir_y * diff_y * (tr_tool->y2 - tr_tool->y1));
440
 
 
441
 
      if (mag > 0.0)
442
 
        {
443
 
          diff_x = dir_x * (tr_tool->x2 - tr_tool->x1) * dot / (mag * mag);
444
 
          diff_y = dir_y * (tr_tool->y2 - tr_tool->y1) * dot / (mag * mag);
445
 
        }
446
 
      else
447
 
        {
448
 
          diff_x = diff_y = 0;
449
 
        }
450
 
    }
451
 
 
452
251
  *x1 += diff_x;
453
252
  *y1 += diff_y;
454
253
 
 
254
  /*  if control is being held, constrain the aspect ratio  */
 
255
  if (options->constrain)
 
256
    {
 
257
      /*  FIXME: improve this  */
 
258
      gdouble w = tr_tool->trans_info[X1] - tr_tool->trans_info[X0];
 
259
      gdouble h = tr_tool->trans_info[Y1] - tr_tool->trans_info[Y0];
 
260
 
 
261
      switch (tr_tool->function)
 
262
        {
 
263
        case TRANSFORM_HANDLE_NW:
 
264
        case TRANSFORM_HANDLE_SW:
 
265
          tr_tool->trans_info[X0] =
 
266
            tr_tool->trans_info[X1] - tr_tool->aspect * h;
 
267
          break;
 
268
 
 
269
        case TRANSFORM_HANDLE_NE:
 
270
        case TRANSFORM_HANDLE_SE:
 
271
          tr_tool->trans_info[X1] =
 
272
            tr_tool->trans_info[X0] + tr_tool->aspect * h;
 
273
          break;
 
274
 
 
275
        default:
 
276
          break;
 
277
        }
 
278
    }
 
279
 
455
280
  if (dir_x > 0)
456
281
    {
457
 
      if (*x1 >= *x2) *x1 = *x2 - 1;
 
282
      if (*x1 >= *x2)
 
283
        *x1 = *x2 - 1;
458
284
    }
459
285
  else
460
286
    {
461
 
      if (*x1 <= *x2) *x1 = *x2 + 1;
 
287
      if (*x1 <= *x2)
 
288
        *x1 = *x2 + 1;
462
289
    }
463
290
 
464
291
  if (dir_y > 0)
465
292
    {
466
 
      if (*y1 >= *y2) *y1 = *y2 - 1;
 
293
      if (*y1 >= *y2)
 
294
        *y1 = *y2 - 1;
467
295
    }
468
296
  else
469
297
    {
470
 
      if (*y1 <= *y2) *y1 = *y2 + 1;
 
298
      if (*y1 <= *y2)
 
299
        *y1 = *y2 + 1;
471
300
    }
472
301
}
473
302
 
474
303
static void
475
304
gimp_scale_tool_recalc (GimpTransformTool *tr_tool,
476
 
                        GimpDisplay       *gdisp)
 
305
                        GimpDisplay       *display)
477
306
{
478
 
  gimp_transform_matrix_scale (tr_tool->x1,
 
307
  gimp_matrix3_identity (&tr_tool->transform);
 
308
  gimp_transform_matrix_scale (&tr_tool->transform,
 
309
                               tr_tool->x1,
479
310
                               tr_tool->y1,
480
311
                               tr_tool->x2 - tr_tool->x1,
481
312
                               tr_tool->y2 - tr_tool->y1,
482
313
                               tr_tool->trans_info[X0],
483
314
                               tr_tool->trans_info[Y0],
484
315
                               tr_tool->trans_info[X1] - tr_tool->trans_info[X0],
485
 
                               tr_tool->trans_info[Y1] - tr_tool->trans_info[Y0],
486
 
                               &tr_tool->transform);
487
 
}
488
 
 
489
 
static void
490
 
gimp_scale_tool_size_changed (GtkWidget         *widget,
491
 
                              GimpTransformTool *tr_tool)
492
 
{
493
 
  GimpTool             *tool  = GIMP_TOOL (tr_tool);
494
 
  GimpScaleTool        *scale = GIMP_SCALE_TOOL (tr_tool);
495
 
  GimpTransformOptions *options;
496
 
  gint                  width;
497
 
  gint                  height;
498
 
 
499
 
  options = GIMP_TRANSFORM_OPTIONS (tool->tool_info->tool_options);
500
 
 
501
 
  width  = RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (widget), 0));
502
 
  height = RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (widget), 1));
503
 
 
504
 
  if ((width  != (tr_tool->trans_info[X1] -
505
 
                  tr_tool->trans_info[X0])) ||
506
 
      (height != (tr_tool->trans_info[Y1] -
507
 
                  tr_tool->trans_info[Y0])))
508
 
    {
509
 
      gimp_draw_tool_pause (GIMP_DRAW_TOOL (tr_tool));
510
 
 
511
 
      if (options->constrain_1 && options->constrain_2)
512
 
        {
513
 
          gdouble ratio = scale->aspect_ratio_val;
514
 
 
515
 
          /* Calculating height and width taking into account the aspect ratio*/
516
 
          if (width != (tr_tool->trans_info[X1] - tr_tool->trans_info[X0]))
517
 
            height = width / ratio;
518
 
          else
519
 
            width = height * ratio;
520
 
        }
521
 
 
522
 
      tr_tool->trans_info[X1] = tr_tool->trans_info[X0] + width;
523
 
      tr_tool->trans_info[Y1] = tr_tool->trans_info[Y0] + height;
524
 
 
525
 
      gimp_transform_tool_recalc (tr_tool, GIMP_TOOL (tr_tool)->gdisp);
526
 
 
527
 
      gimp_transform_tool_expose_preview (tr_tool);
528
 
 
529
 
      gimp_draw_tool_resume (GIMP_DRAW_TOOL (tr_tool));
530
 
    }
531
 
}
532
 
 
533
 
static void
534
 
gimp_scale_tool_unit_changed (GtkWidget         *widget,
535
 
                              GimpTransformTool *tr_tool)
536
 
{
537
 
  gimp_scale_tool_dialog_update (tr_tool);
538
 
}
539
 
 
540
 
static void
541
 
gimp_scale_tool_aspect_changed (GtkWidget         *widget,
542
 
                                GimpTransformTool *tr_tool)
543
 
{
544
 
  GimpScaleTool *scale = GIMP_SCALE_TOOL (tr_tool);
545
 
 
546
 
  scale->aspect_ratio_val = GTK_ADJUSTMENT (widget)->value;
547
 
 
548
 
  gimp_draw_tool_pause (GIMP_DRAW_TOOL (tr_tool));
549
 
 
550
 
  tr_tool->trans_info[Y1] =
551
 
    ((gdouble) (tr_tool->trans_info[X1] - tr_tool->trans_info[X0]) /
552
 
     scale->aspect_ratio_val) +
553
 
    tr_tool->trans_info[Y0];
554
 
 
555
 
  gimp_transform_tool_recalc (tr_tool, GIMP_TOOL (tr_tool)->gdisp);
556
 
 
557
 
  gimp_draw_tool_resume (GIMP_DRAW_TOOL (tr_tool));
 
316
                               tr_tool->trans_info[Y1] - tr_tool->trans_info[Y0]);
 
317
}
 
318
 
 
319
static void
 
320
gimp_scale_tool_size_notify (GtkWidget         *box,
 
321
                             GParamSpec        *pspec,
 
322
                             GimpTransformTool *tr_tool)
 
323
{
 
324
  GimpTransformOptions *options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool);
 
325
 
 
326
  if (! strcmp (pspec->name, "width") ||
 
327
      ! strcmp (pspec->name, "height"))
 
328
    {
 
329
      gint width;
 
330
      gint height;
 
331
      gint old_width;
 
332
      gint old_height;
 
333
 
 
334
      g_object_get (box,
 
335
                    "width",  &width,
 
336
                    "height", &height,
 
337
                    NULL);
 
338
 
 
339
      old_width  = ROUND (tr_tool->trans_info[X1] - tr_tool->trans_info[X0]);
 
340
      old_height = ROUND (tr_tool->trans_info[Y1] - tr_tool->trans_info[Y0]);
 
341
 
 
342
      if ((width != old_width) || (height != old_height))
 
343
        {
 
344
          gimp_draw_tool_pause (GIMP_DRAW_TOOL (tr_tool));
 
345
 
 
346
          tr_tool->trans_info[X1] = tr_tool->trans_info[X0] + width;
 
347
          tr_tool->trans_info[Y1] = tr_tool->trans_info[Y0] + height;
 
348
 
 
349
          gimp_transform_tool_recalc (tr_tool, GIMP_TOOL (tr_tool)->display);
 
350
 
 
351
          gimp_transform_tool_expose_preview (tr_tool);
 
352
 
 
353
          gimp_draw_tool_resume (GIMP_DRAW_TOOL (tr_tool));
 
354
        }
 
355
    }
 
356
  else if (! strcmp (pspec->name, "keep-aspect"))
 
357
    {
 
358
      gboolean constrain;
 
359
 
 
360
      g_object_get (box,
 
361
                    "keep-aspect", &constrain,
 
362
                    NULL);
 
363
 
 
364
      if (constrain != options->constrain)
 
365
        {
 
366
          gint width;
 
367
          gint height;
 
368
 
 
369
          g_object_get (box,
 
370
                        "width",  &width,
 
371
                        "height", &height,
 
372
                        NULL);
 
373
 
 
374
          /*  Take the aspect ratio from the size box when the user
 
375
           *  activates the constraint by pressing the chain button.
 
376
           */
 
377
          tr_tool->aspect = (gdouble) width / (gdouble) height;
 
378
 
 
379
          g_object_set (options,
 
380
                        "constrain", constrain,
 
381
                        NULL);
 
382
        }
 
383
    }
558
384
}