1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995-2003 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 3 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, see <https://www.gnu.org/licenses/>.
16 */
17
18 /* NOTE: This file is auto-generated by pdbgen.pl. */
19
20 #include "config.h"
21
22 #include <gegl.h>
23
24 #include <gdk-pixbuf/gdk-pixbuf.h>
25
26 #include "libgimpmath/gimpmath.h"
27
28 #include "libgimpbase/gimpbase.h"
29
30 #include "pdb-types.h"
31
32 #include "core/gimp-transform-utils.h"
33 #include "core/gimpchannel.h"
34 #include "core/gimpdrawable-transform.h"
35 #include "core/gimpdrawable.h"
36 #include "core/gimpimage.h"
37 #include "core/gimpitem-linked.h"
38 #include "core/gimpitem.h"
39 #include "core/gimpparamspecs.h"
40 #include "core/gimpprogress.h"
41
42 #include "gimppdb.h"
43 #include "gimppdb-utils.h"
44 #include "gimppdbcontext.h"
45 #include "gimpprocedure.h"
46 #include "internal-procs.h"
47
48 #include "gimp-intl.h"
49
50
51 static GimpValueArray *
item_transform_translate_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)52 item_transform_translate_invoker (GimpProcedure *procedure,
53 Gimp *gimp,
54 GimpContext *context,
55 GimpProgress *progress,
56 const GimpValueArray *args,
57 GError **error)
58 {
59 gboolean success = TRUE;
60 GimpValueArray *return_vals;
61 GimpItem *item;
62 gdouble off_x;
63 gdouble off_y;
64
65 item = gimp_value_get_item (gimp_value_array_index (args, 0), gimp);
66 off_x = g_value_get_double (gimp_value_array_index (args, 1));
67 off_y = g_value_get_double (gimp_value_array_index (args, 2));
68
69 if (success)
70 {
71 if (gimp_pdb_item_is_modifiable (item,
72 GIMP_PDB_ITEM_POSITION, error))
73 {
74 if (gimp_item_get_linked (item) && gimp_item_is_attached (item))
75 {
76 gimp_item_linked_translate (item, off_x, off_y, TRUE);
77 }
78 else
79 {
80 gimp_item_translate (item, off_x, off_y, TRUE);
81 }
82 }
83 else
84 success = FALSE;
85 }
86
87 return_vals = gimp_procedure_get_return_values (procedure, success,
88 error ? *error : NULL);
89
90 if (success)
91 gimp_value_set_item (gimp_value_array_index (return_vals, 1), item);
92
93 return return_vals;
94 }
95
96 static GimpValueArray *
item_transform_flip_simple_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)97 item_transform_flip_simple_invoker (GimpProcedure *procedure,
98 Gimp *gimp,
99 GimpContext *context,
100 GimpProgress *progress,
101 const GimpValueArray *args,
102 GError **error)
103 {
104 gboolean success = TRUE;
105 GimpValueArray *return_vals;
106 GimpItem *item;
107 gint32 flip_type;
108 gboolean auto_center;
109 gdouble axis;
110
111 item = gimp_value_get_item (gimp_value_array_index (args, 0), gimp);
112 flip_type = g_value_get_enum (gimp_value_array_index (args, 1));
113 auto_center = g_value_get_boolean (gimp_value_array_index (args, 2));
114 axis = g_value_get_double (gimp_value_array_index (args, 3));
115
116 if (success)
117 {
118 gint x, y, width, height;
119
120 success = gimp_pdb_item_is_attached (item, NULL,
121 GIMP_PDB_ITEM_CONTENT |
122 GIMP_PDB_ITEM_POSITION, error);
123
124 if (success &&
125 gimp_item_mask_intersect (item, &x, &y, &width, &height))
126 {
127 GimpPDBContext *pdb_context = GIMP_PDB_CONTEXT (context);
128 GimpImage *image = gimp_item_get_image (item);
129 GimpChannel *mask = gimp_image_get_mask (image);
130 gint off_x, off_y;
131
132 gimp_item_get_offset (item, &off_x, &off_y);
133 x += off_x;
134 y += off_y;
135
136 gimp_transform_get_flip_axis (x, y, width, height,
137 flip_type, auto_center, &axis);
138
139 if (GIMP_IS_DRAWABLE (item) &&
140 item != GIMP_ITEM (mask) &&
141 ! gimp_viewable_get_children (GIMP_VIEWABLE (item)) &&
142 ! gimp_channel_is_empty (mask))
143 {
144 GimpDrawable *drawable;
145
146 drawable = gimp_drawable_transform_flip (GIMP_DRAWABLE (item), context,
147 flip_type, axis,
148 pdb_context->transform_resize);
149
150 if (drawable)
151 item = GIMP_ITEM (drawable);
152 else
153 success = FALSE;
154 }
155 else if (gimp_item_get_linked (item))
156 {
157 gimp_item_linked_flip (item, context,
158 flip_type, axis,
159 pdb_context->transform_resize);
160 }
161 else
162 {
163 gimp_item_flip (item, context,
164 flip_type, axis,
165 gimp_item_get_clip (
166 item, pdb_context->transform_resize));
167 }
168 }
169 }
170
171 return_vals = gimp_procedure_get_return_values (procedure, success,
172 error ? *error : NULL);
173
174 if (success)
175 gimp_value_set_item (gimp_value_array_index (return_vals, 1), item);
176
177 return return_vals;
178 }
179
180 static GimpValueArray *
item_transform_flip_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)181 item_transform_flip_invoker (GimpProcedure *procedure,
182 Gimp *gimp,
183 GimpContext *context,
184 GimpProgress *progress,
185 const GimpValueArray *args,
186 GError **error)
187 {
188 gboolean success = TRUE;
189 GimpValueArray *return_vals;
190 GimpItem *item;
191 gdouble x0;
192 gdouble y0;
193 gdouble x1;
194 gdouble y1;
195
196 item = gimp_value_get_item (gimp_value_array_index (args, 0), gimp);
197 x0 = g_value_get_double (gimp_value_array_index (args, 1));
198 y0 = g_value_get_double (gimp_value_array_index (args, 2));
199 x1 = g_value_get_double (gimp_value_array_index (args, 3));
200 y1 = g_value_get_double (gimp_value_array_index (args, 4));
201
202 if (success)
203 {
204 gint x, y, width, height;
205
206 success = gimp_pdb_item_is_attached (item, NULL,
207 GIMP_PDB_ITEM_CONTENT |
208 GIMP_PDB_ITEM_POSITION, error);
209
210 if (success &&
211 gimp_item_mask_intersect (item, &x, &y, &width, &height))
212 {
213 GimpPDBContext *pdb_context = GIMP_PDB_CONTEXT (context);
214 GimpImage *image = gimp_item_get_image (item);
215 GimpChannel *mask = gimp_image_get_mask (image);
216 GimpMatrix3 matrix;
217 gint off_x, off_y;
218
219 gimp_item_get_offset (item, &off_x, &off_y);
220 x += off_x;
221 y += off_y;
222
223 /* Assemble the transformation matrix */
224 gimp_matrix3_identity (&matrix);
225 gimp_transform_matrix_flip_free (&matrix, x0, y0, x1, y1);
226
227 if (progress)
228 gimp_progress_start (progress, FALSE, _("Flipping"));
229
230 if (GIMP_IS_DRAWABLE (item) &&
231 item != GIMP_ITEM (mask) &&
232 ! gimp_viewable_get_children (GIMP_VIEWABLE (item)) &&
233 ! gimp_channel_is_empty (mask))
234 {
235 GimpDrawable *drawable;
236
237 drawable = gimp_drawable_transform_affine (GIMP_DRAWABLE (item),
238 context, &matrix,
239 pdb_context->transform_direction,
240 pdb_context->interpolation,
241 pdb_context->transform_resize,
242 progress);
243
244 if (drawable)
245 item = GIMP_ITEM (drawable);
246 else
247 success = FALSE;
248 }
249 else if (gimp_item_get_linked (item))
250 {
251 gimp_item_linked_transform (item, context, &matrix,
252 pdb_context->transform_direction,
253 pdb_context->interpolation,
254 pdb_context->transform_resize,
255 progress);
256 }
257 else
258 {
259 gimp_item_transform (item, context, &matrix,
260 pdb_context->transform_direction,
261 pdb_context->interpolation,
262 gimp_item_get_clip (
263 item, pdb_context->transform_resize),
264 progress);
265 }
266
267 if (progress)
268 gimp_progress_end (progress);
269 }
270 }
271
272 return_vals = gimp_procedure_get_return_values (procedure, success,
273 error ? *error : NULL);
274
275 if (success)
276 gimp_value_set_item (gimp_value_array_index (return_vals, 1), item);
277
278 return return_vals;
279 }
280
281 static GimpValueArray *
item_transform_perspective_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)282 item_transform_perspective_invoker (GimpProcedure *procedure,
283 Gimp *gimp,
284 GimpContext *context,
285 GimpProgress *progress,
286 const GimpValueArray *args,
287 GError **error)
288 {
289 gboolean success = TRUE;
290 GimpValueArray *return_vals;
291 GimpItem *item;
292 gdouble x0;
293 gdouble y0;
294 gdouble x1;
295 gdouble y1;
296 gdouble x2;
297 gdouble y2;
298 gdouble x3;
299 gdouble y3;
300
301 item = gimp_value_get_item (gimp_value_array_index (args, 0), gimp);
302 x0 = g_value_get_double (gimp_value_array_index (args, 1));
303 y0 = g_value_get_double (gimp_value_array_index (args, 2));
304 x1 = g_value_get_double (gimp_value_array_index (args, 3));
305 y1 = g_value_get_double (gimp_value_array_index (args, 4));
306 x2 = g_value_get_double (gimp_value_array_index (args, 5));
307 y2 = g_value_get_double (gimp_value_array_index (args, 6));
308 x3 = g_value_get_double (gimp_value_array_index (args, 7));
309 y3 = g_value_get_double (gimp_value_array_index (args, 8));
310
311 if (success)
312 {
313 gint x, y, width, height;
314
315 success = gimp_pdb_item_is_attached (item, NULL,
316 GIMP_PDB_ITEM_CONTENT |
317 GIMP_PDB_ITEM_POSITION, error);
318
319 if (success &&
320 gimp_item_mask_intersect (item, &x, &y, &width, &height))
321 {
322 GimpPDBContext *pdb_context = GIMP_PDB_CONTEXT (context);
323 GimpImage *image = gimp_item_get_image (item);
324 GimpChannel *mask = gimp_image_get_mask (image);
325 GimpMatrix3 matrix;
326 gint off_x, off_y;
327
328 gimp_item_get_offset (item, &off_x, &off_y);
329 x += off_x;
330 y += off_y;
331
332 /* Assemble the transformation matrix */
333 gimp_matrix3_identity (&matrix);
334 gimp_transform_matrix_perspective (&matrix,
335 x, y, width, height,
336 x0, y0, x1, y1,
337 x2, y2, x3, y3);
338
339 if (progress)
340 gimp_progress_start (progress, FALSE, _("Perspective"));
341
342 if (GIMP_IS_DRAWABLE (item) &&
343 item != GIMP_ITEM (mask) &&
344 ! gimp_viewable_get_children (GIMP_VIEWABLE (item)) &&
345 ! gimp_channel_is_empty (mask))
346 {
347 GimpDrawable *drawable;
348
349 drawable = gimp_drawable_transform_affine (GIMP_DRAWABLE (item),
350 context, &matrix,
351 pdb_context->transform_direction,
352 pdb_context->interpolation,
353 pdb_context->transform_resize,
354 progress);
355
356 if (drawable)
357 item = GIMP_ITEM (drawable);
358 else
359 success = FALSE;
360 }
361 else if (gimp_item_get_linked (item))
362 {
363 gimp_item_linked_transform (item, context, &matrix,
364 pdb_context->transform_direction,
365 pdb_context->interpolation,
366 pdb_context->transform_resize,
367 progress);
368 }
369 else
370 {
371 gimp_item_transform (item, context, &matrix,
372 pdb_context->transform_direction,
373 pdb_context->interpolation,
374 gimp_item_get_clip (
375 item, pdb_context->transform_resize),
376 progress);
377 }
378
379 if (progress)
380 gimp_progress_end (progress);
381 }
382 }
383
384 return_vals = gimp_procedure_get_return_values (procedure, success,
385 error ? *error : NULL);
386
387 if (success)
388 gimp_value_set_item (gimp_value_array_index (return_vals, 1), item);
389
390 return return_vals;
391 }
392
393 static GimpValueArray *
item_transform_rotate_simple_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)394 item_transform_rotate_simple_invoker (GimpProcedure *procedure,
395 Gimp *gimp,
396 GimpContext *context,
397 GimpProgress *progress,
398 const GimpValueArray *args,
399 GError **error)
400 {
401 gboolean success = TRUE;
402 GimpValueArray *return_vals;
403 GimpItem *item;
404 gint32 rotate_type;
405 gboolean auto_center;
406 gdouble center_x;
407 gdouble center_y;
408
409 item = gimp_value_get_item (gimp_value_array_index (args, 0), gimp);
410 rotate_type = g_value_get_enum (gimp_value_array_index (args, 1));
411 auto_center = g_value_get_boolean (gimp_value_array_index (args, 2));
412 center_x = g_value_get_double (gimp_value_array_index (args, 3));
413 center_y = g_value_get_double (gimp_value_array_index (args, 4));
414
415 if (success)
416 {
417 gint x, y, width, height;
418
419 success = gimp_pdb_item_is_attached (item, NULL,
420 GIMP_PDB_ITEM_CONTENT |
421 GIMP_PDB_ITEM_POSITION, error);
422
423 if (success &&
424 gimp_item_mask_intersect (item, &x, &y, &width, &height))
425 {
426 GimpPDBContext *pdb_context = GIMP_PDB_CONTEXT (context);
427 GimpImage *image = gimp_item_get_image (item);
428 GimpChannel *mask = gimp_image_get_mask (image);
429 gint off_x, off_y;
430
431 gimp_item_get_offset (item, &off_x, &off_y);
432 x += off_x;
433 y += off_y;
434
435 gimp_transform_get_rotate_center (x, y, width, height,
436 auto_center, ¢er_x, ¢er_y);
437
438 if (GIMP_IS_DRAWABLE (item) &&
439 item != GIMP_ITEM (mask) &&
440 ! gimp_viewable_get_children (GIMP_VIEWABLE (item)) &&
441 ! gimp_channel_is_empty (mask))
442 {
443 GimpDrawable *drawable;
444
445 drawable = gimp_drawable_transform_rotate (GIMP_DRAWABLE (item),
446 context,
447 rotate_type,
448 center_x, center_y,
449 pdb_context->transform_resize);
450
451 if (drawable)
452 item = GIMP_ITEM (drawable);
453 else
454 success = FALSE;
455 }
456 else if (gimp_item_get_linked (item))
457 {
458 gimp_item_linked_rotate (item, context,
459 rotate_type,
460 center_x, center_y,
461 pdb_context->transform_resize);
462 }
463 else
464 {
465 gimp_item_rotate (item, context,
466 rotate_type,
467 center_x, center_y,
468 gimp_item_get_clip (
469 item, pdb_context->transform_resize));
470 }
471 }
472 }
473
474 return_vals = gimp_procedure_get_return_values (procedure, success,
475 error ? *error : NULL);
476
477 if (success)
478 gimp_value_set_item (gimp_value_array_index (return_vals, 1), item);
479
480 return return_vals;
481 }
482
483 static GimpValueArray *
item_transform_rotate_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)484 item_transform_rotate_invoker (GimpProcedure *procedure,
485 Gimp *gimp,
486 GimpContext *context,
487 GimpProgress *progress,
488 const GimpValueArray *args,
489 GError **error)
490 {
491 gboolean success = TRUE;
492 GimpValueArray *return_vals;
493 GimpItem *item;
494 gdouble angle;
495 gboolean auto_center;
496 gdouble center_x;
497 gdouble center_y;
498
499 item = gimp_value_get_item (gimp_value_array_index (args, 0), gimp);
500 angle = g_value_get_double (gimp_value_array_index (args, 1));
501 auto_center = g_value_get_boolean (gimp_value_array_index (args, 2));
502 center_x = g_value_get_double (gimp_value_array_index (args, 3));
503 center_y = g_value_get_double (gimp_value_array_index (args, 4));
504
505 if (success)
506 {
507 gint x, y, width, height;
508
509 success = gimp_pdb_item_is_attached (item, NULL,
510 GIMP_PDB_ITEM_CONTENT |
511 GIMP_PDB_ITEM_POSITION, error);
512
513 if (success &&
514 gimp_item_mask_intersect (item, &x, &y, &width, &height))
515 {
516 GimpPDBContext *pdb_context = GIMP_PDB_CONTEXT (context);
517 GimpImage *image = gimp_item_get_image (item);
518 GimpChannel *mask = gimp_image_get_mask (image);
519 GimpMatrix3 matrix;
520 gint off_x, off_y;
521
522 gimp_item_get_offset (item, &off_x, &off_y);
523 x += off_x;
524 y += off_y;
525
526 /* Assemble the transformation matrix */
527 gimp_matrix3_identity (&matrix);
528 if (auto_center)
529 gimp_transform_matrix_rotate_rect (&matrix,
530 x, y, width, height, angle);
531 else
532 gimp_transform_matrix_rotate_center (&matrix,
533 center_x, center_y, angle);
534
535 if (progress)
536 gimp_progress_start (progress, FALSE, _("Rotating"));
537
538 if (GIMP_IS_DRAWABLE (item) &&
539 item != GIMP_ITEM (mask) &&
540 ! gimp_viewable_get_children (GIMP_VIEWABLE (item)) &&
541 ! gimp_channel_is_empty (mask))
542 {
543 GimpDrawable *drawable;
544
545 drawable = gimp_drawable_transform_affine (GIMP_DRAWABLE (item),
546 context, &matrix,
547 pdb_context->transform_direction,
548 pdb_context->interpolation,
549 pdb_context->transform_resize,
550 progress);
551
552 if (drawable)
553 item = GIMP_ITEM (drawable);
554 else
555 success = FALSE;
556 }
557 else if (gimp_item_get_linked (item))
558 {
559 gimp_item_linked_transform (item, context, &matrix,
560 pdb_context->transform_direction,
561 pdb_context->interpolation,
562 pdb_context->transform_resize,
563 progress);
564 }
565 else
566 {
567 gimp_item_transform (item, context, &matrix,
568 pdb_context->transform_direction,
569 pdb_context->interpolation,
570 gimp_item_get_clip (
571 item, pdb_context->transform_resize),
572 progress);
573 }
574
575 if (progress)
576 gimp_progress_end (progress);
577 }
578 }
579
580 return_vals = gimp_procedure_get_return_values (procedure, success,
581 error ? *error : NULL);
582
583 if (success)
584 gimp_value_set_item (gimp_value_array_index (return_vals, 1), item);
585
586 return return_vals;
587 }
588
589 static GimpValueArray *
item_transform_scale_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)590 item_transform_scale_invoker (GimpProcedure *procedure,
591 Gimp *gimp,
592 GimpContext *context,
593 GimpProgress *progress,
594 const GimpValueArray *args,
595 GError **error)
596 {
597 gboolean success = TRUE;
598 GimpValueArray *return_vals;
599 GimpItem *item;
600 gdouble x0;
601 gdouble y0;
602 gdouble x1;
603 gdouble y1;
604
605 item = gimp_value_get_item (gimp_value_array_index (args, 0), gimp);
606 x0 = g_value_get_double (gimp_value_array_index (args, 1));
607 y0 = g_value_get_double (gimp_value_array_index (args, 2));
608 x1 = g_value_get_double (gimp_value_array_index (args, 3));
609 y1 = g_value_get_double (gimp_value_array_index (args, 4));
610
611 if (success)
612 {
613 gint x, y, width, height;
614
615 success = (gimp_pdb_item_is_attached (item, NULL,
616 GIMP_PDB_ITEM_CONTENT |
617 GIMP_PDB_ITEM_POSITION, error) &&
618 x0 < x1 && y0 < y1);
619
620 if (success &&
621 gimp_item_mask_intersect (item, &x, &y, &width, &height))
622 {
623 GimpPDBContext *pdb_context = GIMP_PDB_CONTEXT (context);
624 GimpImage *image = gimp_item_get_image (item);
625 GimpChannel *mask = gimp_image_get_mask (image);
626 GimpMatrix3 matrix;
627 gint off_x, off_y;
628
629 gimp_item_get_offset (item, &off_x, &off_y);
630 x += off_x;
631 y += off_y;
632
633 /* Assemble the transformation matrix */
634 gimp_matrix3_identity (&matrix);
635 gimp_transform_matrix_scale (&matrix,
636 x, y, width, height,
637 x0, y0, x1 - x0, y1 - y0);
638
639 if (progress)
640 gimp_progress_start (progress, FALSE, _("Scaling"));
641
642 if (GIMP_IS_DRAWABLE (item) &&
643 item != GIMP_ITEM (mask) &&
644 ! gimp_viewable_get_children (GIMP_VIEWABLE (item)) &&
645 ! gimp_channel_is_empty (mask))
646 {
647 GimpDrawable *drawable;
648
649 drawable = gimp_drawable_transform_affine (GIMP_DRAWABLE (item),
650 context, &matrix,
651 pdb_context->transform_direction,
652 pdb_context->interpolation,
653 pdb_context->transform_resize,
654 progress);
655
656 if (drawable)
657 item = GIMP_ITEM (drawable);
658 else
659 success = FALSE;
660 }
661 else if (gimp_item_get_linked (item))
662 {
663 gimp_item_linked_transform (item, context, &matrix,
664 pdb_context->transform_direction,
665 pdb_context->interpolation,
666 pdb_context->transform_resize,
667 progress);
668 }
669 else
670 {
671 gimp_item_transform (item, context, &matrix,
672 pdb_context->transform_direction,
673 pdb_context->interpolation,
674 gimp_item_get_clip (
675 item, pdb_context->transform_resize),
676 progress);
677 }
678
679 if (progress)
680 gimp_progress_end (progress);
681 }
682 }
683
684 return_vals = gimp_procedure_get_return_values (procedure, success,
685 error ? *error : NULL);
686
687 if (success)
688 gimp_value_set_item (gimp_value_array_index (return_vals, 1), item);
689
690 return return_vals;
691 }
692
693 static GimpValueArray *
item_transform_shear_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)694 item_transform_shear_invoker (GimpProcedure *procedure,
695 Gimp *gimp,
696 GimpContext *context,
697 GimpProgress *progress,
698 const GimpValueArray *args,
699 GError **error)
700 {
701 gboolean success = TRUE;
702 GimpValueArray *return_vals;
703 GimpItem *item;
704 gint32 shear_type;
705 gdouble magnitude;
706
707 item = gimp_value_get_item (gimp_value_array_index (args, 0), gimp);
708 shear_type = g_value_get_enum (gimp_value_array_index (args, 1));
709 magnitude = g_value_get_double (gimp_value_array_index (args, 2));
710
711 if (success)
712 {
713 gint x, y, width, height;
714
715 success = gimp_pdb_item_is_attached (item, NULL,
716 GIMP_PDB_ITEM_CONTENT |
717 GIMP_PDB_ITEM_POSITION, error);
718
719 if (success &&
720 gimp_item_mask_intersect (item, &x, &y, &width, &height))
721 {
722 GimpPDBContext *pdb_context = GIMP_PDB_CONTEXT (context);
723 GimpImage *image = gimp_item_get_image (item);
724 GimpChannel *mask = gimp_image_get_mask (image);
725 GimpMatrix3 matrix;
726 gint off_x, off_y;
727
728 gimp_item_get_offset (item, &off_x, &off_y);
729 x += off_x;
730 y += off_y;
731
732 /* Assemble the transformation matrix */
733 gimp_matrix3_identity (&matrix);
734 gimp_transform_matrix_shear (&matrix,
735 x, y, width, height,
736 shear_type, magnitude);
737
738 if (progress)
739 gimp_progress_start (progress, FALSE, _("Shearing"));
740
741 if (GIMP_IS_DRAWABLE (item) &&
742 item != GIMP_ITEM (mask) &&
743 ! gimp_viewable_get_children (GIMP_VIEWABLE (item)) &&
744 ! gimp_channel_is_empty (mask))
745 {
746 GimpDrawable *drawable;
747
748 drawable = gimp_drawable_transform_affine (GIMP_DRAWABLE (item),
749 context, &matrix,
750 pdb_context->transform_direction,
751 pdb_context->interpolation,
752 pdb_context->transform_resize,
753 progress);
754
755 if (drawable)
756 item = GIMP_ITEM (drawable);
757 else
758 success = FALSE;
759 }
760 else if (gimp_item_get_linked (item))
761 {
762 gimp_item_linked_transform (item, context, &matrix,
763 pdb_context->transform_direction,
764 pdb_context->interpolation,
765 pdb_context->transform_resize,
766 progress);
767 }
768 else
769 {
770 gimp_item_transform (item, context, &matrix,
771 pdb_context->transform_direction,
772 pdb_context->interpolation,
773 gimp_item_get_clip (
774 item, pdb_context->transform_resize),
775 progress);
776 }
777
778 if (progress)
779 gimp_progress_end (progress);
780 }
781 }
782
783 return_vals = gimp_procedure_get_return_values (procedure, success,
784 error ? *error : NULL);
785
786 if (success)
787 gimp_value_set_item (gimp_value_array_index (return_vals, 1), item);
788
789 return return_vals;
790 }
791
792 static GimpValueArray *
item_transform_2d_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)793 item_transform_2d_invoker (GimpProcedure *procedure,
794 Gimp *gimp,
795 GimpContext *context,
796 GimpProgress *progress,
797 const GimpValueArray *args,
798 GError **error)
799 {
800 gboolean success = TRUE;
801 GimpValueArray *return_vals;
802 GimpItem *item;
803 gdouble source_x;
804 gdouble source_y;
805 gdouble scale_x;
806 gdouble scale_y;
807 gdouble angle;
808 gdouble dest_x;
809 gdouble dest_y;
810
811 item = gimp_value_get_item (gimp_value_array_index (args, 0), gimp);
812 source_x = g_value_get_double (gimp_value_array_index (args, 1));
813 source_y = g_value_get_double (gimp_value_array_index (args, 2));
814 scale_x = g_value_get_double (gimp_value_array_index (args, 3));
815 scale_y = g_value_get_double (gimp_value_array_index (args, 4));
816 angle = g_value_get_double (gimp_value_array_index (args, 5));
817 dest_x = g_value_get_double (gimp_value_array_index (args, 6));
818 dest_y = g_value_get_double (gimp_value_array_index (args, 7));
819
820 if (success)
821 {
822 gint x, y, width, height;
823
824 success = gimp_pdb_item_is_attached (item, NULL,
825 GIMP_PDB_ITEM_CONTENT |
826 GIMP_PDB_ITEM_POSITION, error);
827
828 if (success &&
829 gimp_item_mask_intersect (item, &x, &y, &width, &height))
830 {
831 GimpPDBContext *pdb_context = GIMP_PDB_CONTEXT (context);
832 GimpImage *image = gimp_item_get_image (item);
833 GimpChannel *mask = gimp_image_get_mask (image);
834 GimpMatrix3 matrix;
835 gint off_x, off_y;
836
837 gimp_item_get_offset (item, &off_x, &off_y);
838 x += off_x;
839 y += off_y;
840
841 /* Assemble the transformation matrix */
842 gimp_matrix3_identity (&matrix);
843 gimp_matrix3_translate (&matrix, -source_x, -source_y);
844 gimp_matrix3_scale (&matrix, scale_x, scale_y);
845 gimp_matrix3_rotate (&matrix, angle);
846 gimp_matrix3_translate (&matrix, dest_x, dest_y);
847
848 if (progress)
849 gimp_progress_start (progress, FALSE, _("2D Transform"));
850
851 if (GIMP_IS_DRAWABLE (item) &&
852 item != GIMP_ITEM (mask) &&
853 ! gimp_viewable_get_children (GIMP_VIEWABLE (item)) &&
854 ! gimp_channel_is_empty (mask))
855 {
856 GimpDrawable *drawable;
857
858 drawable = gimp_drawable_transform_affine (GIMP_DRAWABLE (item),
859 context, &matrix,
860 pdb_context->transform_direction,
861 pdb_context->interpolation,
862 pdb_context->transform_resize,
863 progress);
864
865 if (drawable)
866 item = GIMP_ITEM (drawable);
867 else
868 success = FALSE;
869 }
870 else if (gimp_item_get_linked (item))
871 {
872 gimp_item_linked_transform (item, context, &matrix,
873 pdb_context->transform_direction,
874 pdb_context->interpolation,
875 pdb_context->transform_resize,
876 progress);
877 }
878 else
879 {
880 gimp_item_transform (item, context, &matrix,
881 pdb_context->transform_direction,
882 pdb_context->interpolation,
883 gimp_item_get_clip (
884 item, pdb_context->transform_resize),
885 progress);
886 }
887
888 if (progress)
889 gimp_progress_end (progress);
890 }
891 }
892
893 return_vals = gimp_procedure_get_return_values (procedure, success,
894 error ? *error : NULL);
895
896 if (success)
897 gimp_value_set_item (gimp_value_array_index (return_vals, 1), item);
898
899 return return_vals;
900 }
901
902 static GimpValueArray *
item_transform_matrix_invoker(GimpProcedure * procedure,Gimp * gimp,GimpContext * context,GimpProgress * progress,const GimpValueArray * args,GError ** error)903 item_transform_matrix_invoker (GimpProcedure *procedure,
904 Gimp *gimp,
905 GimpContext *context,
906 GimpProgress *progress,
907 const GimpValueArray *args,
908 GError **error)
909 {
910 gboolean success = TRUE;
911 GimpValueArray *return_vals;
912 GimpItem *item;
913 gdouble coeff_0_0;
914 gdouble coeff_0_1;
915 gdouble coeff_0_2;
916 gdouble coeff_1_0;
917 gdouble coeff_1_1;
918 gdouble coeff_1_2;
919 gdouble coeff_2_0;
920 gdouble coeff_2_1;
921 gdouble coeff_2_2;
922
923 item = gimp_value_get_item (gimp_value_array_index (args, 0), gimp);
924 coeff_0_0 = g_value_get_double (gimp_value_array_index (args, 1));
925 coeff_0_1 = g_value_get_double (gimp_value_array_index (args, 2));
926 coeff_0_2 = g_value_get_double (gimp_value_array_index (args, 3));
927 coeff_1_0 = g_value_get_double (gimp_value_array_index (args, 4));
928 coeff_1_1 = g_value_get_double (gimp_value_array_index (args, 5));
929 coeff_1_2 = g_value_get_double (gimp_value_array_index (args, 6));
930 coeff_2_0 = g_value_get_double (gimp_value_array_index (args, 7));
931 coeff_2_1 = g_value_get_double (gimp_value_array_index (args, 8));
932 coeff_2_2 = g_value_get_double (gimp_value_array_index (args, 9));
933
934 if (success)
935 {
936 gint x, y, width, height;
937
938 success = gimp_pdb_item_is_attached (item, NULL,
939 GIMP_PDB_ITEM_CONTENT |
940 GIMP_PDB_ITEM_POSITION, error);
941
942 if (success &&
943 gimp_item_mask_intersect (item, &x, &y, &width, &height))
944 {
945 GimpPDBContext *pdb_context = GIMP_PDB_CONTEXT (context);
946 GimpImage *image = gimp_item_get_image (item);
947 GimpChannel *mask = gimp_image_get_mask (image);
948 GimpMatrix3 matrix;
949 gint off_x, off_y;
950
951 gimp_item_get_offset (item, &off_x, &off_y);
952 x += off_x;
953 y += off_y;
954
955 /* Assemble the transformation matrix */
956 matrix.coeff[0][0] = coeff_0_0;
957 matrix.coeff[0][1] = coeff_0_1;
958 matrix.coeff[0][2] = coeff_0_2;
959 matrix.coeff[1][0] = coeff_1_0;
960 matrix.coeff[1][1] = coeff_1_1;
961 matrix.coeff[1][2] = coeff_1_2;
962 matrix.coeff[2][0] = coeff_2_0;
963 matrix.coeff[2][1] = coeff_2_1;
964 matrix.coeff[2][2] = coeff_2_2;
965
966 if (progress)
967 gimp_progress_start (progress, FALSE, _("2D Transforming"));
968
969 if (GIMP_IS_DRAWABLE (item) &&
970 item != GIMP_ITEM (mask) &&
971 ! gimp_viewable_get_children (GIMP_VIEWABLE (item)) &&
972 ! gimp_channel_is_empty (mask))
973 {
974 GimpDrawable *drawable;
975
976 drawable = gimp_drawable_transform_affine (GIMP_DRAWABLE (item),
977 context, &matrix,
978 pdb_context->transform_direction,
979 pdb_context->interpolation,
980 pdb_context->transform_resize,
981 progress);
982
983 if (drawable)
984 item = GIMP_ITEM (drawable);
985 else
986 success = FALSE;
987 }
988 else if (gimp_item_get_linked (item))
989 {
990 gimp_item_linked_transform (item, context, &matrix,
991 pdb_context->transform_direction,
992 pdb_context->interpolation,
993 pdb_context->transform_resize,
994 progress);
995 }
996 else
997 {
998 gimp_item_transform (item, context, &matrix,
999 pdb_context->transform_direction,
1000 pdb_context->interpolation,
1001 gimp_item_get_clip (
1002 item, pdb_context->transform_resize),
1003 progress);
1004 }
1005
1006 if (progress)
1007 gimp_progress_end (progress);
1008 }
1009 }
1010
1011 return_vals = gimp_procedure_get_return_values (procedure, success,
1012 error ? *error : NULL);
1013
1014 if (success)
1015 gimp_value_set_item (gimp_value_array_index (return_vals, 1), item);
1016
1017 return return_vals;
1018 }
1019
1020 void
register_item_transform_procs(GimpPDB * pdb)1021 register_item_transform_procs (GimpPDB *pdb)
1022 {
1023 GimpProcedure *procedure;
1024
1025 /*
1026 * gimp-item-transform-translate
1027 */
1028 procedure = gimp_procedure_new (item_transform_translate_invoker);
1029 gimp_object_set_static_name (GIMP_OBJECT (procedure),
1030 "gimp-item-transform-translate");
1031 gimp_procedure_set_static_strings (procedure,
1032 "gimp-item-transform-translate",
1033 "Translate the item by the specified offsets.",
1034 "This procedure translates the item by the amounts specified in the off_x and off_y arguments. These can be negative, and are considered offsets from the current position. The offsets will be rounded to the nearest pixel unless the item is a path.\n"
1035 "\n"
1036 "If the item is attached to an image and has its linked flag set to TRUE, all additional items contained in the image which have the linked flag set to TRUE will also be translated by the specified offsets.",
1037 "Michael Natterer <mitch@gimp.org>",
1038 "Michael Natterer",
1039 "2018",
1040 NULL);
1041 gimp_procedure_add_argument (procedure,
1042 gimp_param_spec_item_id ("item",
1043 "item",
1044 "The item",
1045 pdb->gimp, FALSE,
1046 GIMP_PARAM_READWRITE));
1047 gimp_procedure_add_argument (procedure,
1048 g_param_spec_double ("off-x",
1049 "off x",
1050 "Offset in x direction",
1051 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1052 GIMP_PARAM_READWRITE));
1053 gimp_procedure_add_argument (procedure,
1054 g_param_spec_double ("off-y",
1055 "off y",
1056 "Offset in y direction",
1057 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1058 GIMP_PARAM_READWRITE));
1059 gimp_procedure_add_return_value (procedure,
1060 gimp_param_spec_item_id ("item",
1061 "item",
1062 "The translated item",
1063 pdb->gimp, FALSE,
1064 GIMP_PARAM_READWRITE));
1065 gimp_pdb_register_procedure (pdb, procedure);
1066 g_object_unref (procedure);
1067
1068 /*
1069 * gimp-item-transform-flip-simple
1070 */
1071 procedure = gimp_procedure_new (item_transform_flip_simple_invoker);
1072 gimp_object_set_static_name (GIMP_OBJECT (procedure),
1073 "gimp-item-transform-flip-simple");
1074 gimp_procedure_set_static_strings (procedure,
1075 "gimp-item-transform-flip-simple",
1076 "Flip the specified item either vertically or horizontally.",
1077 "This procedure flips the specified item.\n"
1078 "\n"
1079 "If a selection exists and the item is a drawable, the portion of the drawable which lies under the selection is cut from the drawable and made into a floating selection which is then flipped. If auto_center is set to TRUE, the flip is around the selection's center. Otherwise, the coordinate of the axis needs to be specified. The return value is the ID of the flipped floating selection.\n"
1080 "\n"
1081 "If there is no selection or the item is not a drawable, the entire item will be flipped around its center if auto_center is set to TRUE, otherwise the coordinate of the axis needs to be specified. Additionally, if the item has its linked flag set to TRUE, all additional items contained in the image which have the linked flag set to TRUE will also be flipped around the same axis. The return value will be equal to the item ID supplied as input.\n"
1082 "\n"
1083 "This procedure is affected by the following context setters: 'gimp-context-set-transform-resize'.",
1084 "Michael Natterer <mitch@gimp.org>",
1085 "Michael Natterer",
1086 "2004",
1087 NULL);
1088 gimp_procedure_add_argument (procedure,
1089 gimp_param_spec_item_id ("item",
1090 "item",
1091 "The affected item",
1092 pdb->gimp, FALSE,
1093 GIMP_PARAM_READWRITE));
1094 gimp_procedure_add_argument (procedure,
1095 gimp_param_spec_enum ("flip-type",
1096 "flip type",
1097 "Type of flip",
1098 GIMP_TYPE_ORIENTATION_TYPE,
1099 GIMP_ORIENTATION_HORIZONTAL,
1100 GIMP_PARAM_READWRITE));
1101 gimp_param_spec_enum_exclude_value (GIMP_PARAM_SPEC_ENUM (procedure->args[1]),
1102 GIMP_ORIENTATION_UNKNOWN);
1103 gimp_procedure_add_argument (procedure,
1104 g_param_spec_boolean ("auto-center",
1105 "auto center",
1106 "Whether to automatically position the axis in the selection center",
1107 FALSE,
1108 GIMP_PARAM_READWRITE));
1109 gimp_procedure_add_argument (procedure,
1110 g_param_spec_double ("axis",
1111 "axis",
1112 "coord. of flip axis",
1113 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1114 GIMP_PARAM_READWRITE));
1115 gimp_procedure_add_return_value (procedure,
1116 gimp_param_spec_item_id ("item",
1117 "item",
1118 "The flipped item",
1119 pdb->gimp, FALSE,
1120 GIMP_PARAM_READWRITE));
1121 gimp_pdb_register_procedure (pdb, procedure);
1122 g_object_unref (procedure);
1123
1124 /*
1125 * gimp-item-transform-flip
1126 */
1127 procedure = gimp_procedure_new (item_transform_flip_invoker);
1128 gimp_object_set_static_name (GIMP_OBJECT (procedure),
1129 "gimp-item-transform-flip");
1130 gimp_procedure_set_static_strings (procedure,
1131 "gimp-item-transform-flip",
1132 "Flip the specified item around a given line.",
1133 "This procedure flips the specified item.\n"
1134 "\n"
1135 "If a selection exists and the item is a drawable, the portion of the drawable which lies under the selection is cut from the drawable and made into a floating selection which is then flipped. The axis to flip around is specified by specifying two points from that line. The return value is the ID of the flipped floating selection.\n"
1136 "\n"
1137 "If there is no selection or the item is not a drawable, the entire item will be flipped around the specified axis. Additionally, if the item has its linked flag set to TRUE, all additional items contained in the image which have the linked flag set to TRUE will also be flipped around the same axis. The return value will be equal to the item ID supplied as input.\n"
1138 "\n"
1139 "This procedure is affected by the following context setters: 'gimp-context-set-interpolation', 'gimp-context-set-transform-direction', 'gimp-context-set-transform-resize'.",
1140 "Michael Natterer <mitch@gimp.org>",
1141 "Michael Natterer",
1142 "2010",
1143 NULL);
1144 gimp_procedure_add_argument (procedure,
1145 gimp_param_spec_item_id ("item",
1146 "item",
1147 "The affected item",
1148 pdb->gimp, FALSE,
1149 GIMP_PARAM_READWRITE));
1150 gimp_procedure_add_argument (procedure,
1151 g_param_spec_double ("x0",
1152 "x0",
1153 "horz. coord. of one end of axis",
1154 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1155 GIMP_PARAM_READWRITE));
1156 gimp_procedure_add_argument (procedure,
1157 g_param_spec_double ("y0",
1158 "y0",
1159 "vert. coord. of one end of axis",
1160 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1161 GIMP_PARAM_READWRITE));
1162 gimp_procedure_add_argument (procedure,
1163 g_param_spec_double ("x1",
1164 "x1",
1165 "horz. coord. of other end of axis",
1166 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1167 GIMP_PARAM_READWRITE));
1168 gimp_procedure_add_argument (procedure,
1169 g_param_spec_double ("y1",
1170 "y1",
1171 "vert. coord. of other end of axis",
1172 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1173 GIMP_PARAM_READWRITE));
1174 gimp_procedure_add_return_value (procedure,
1175 gimp_param_spec_item_id ("item",
1176 "item",
1177 "The flipped item",
1178 pdb->gimp, FALSE,
1179 GIMP_PARAM_READWRITE));
1180 gimp_pdb_register_procedure (pdb, procedure);
1181 g_object_unref (procedure);
1182
1183 /*
1184 * gimp-item-transform-perspective
1185 */
1186 procedure = gimp_procedure_new (item_transform_perspective_invoker);
1187 gimp_object_set_static_name (GIMP_OBJECT (procedure),
1188 "gimp-item-transform-perspective");
1189 gimp_procedure_set_static_strings (procedure,
1190 "gimp-item-transform-perspective",
1191 "Perform a possibly non-affine transformation on the specified item.",
1192 "This procedure performs a possibly non-affine transformation on the specified item by allowing the corners of the original bounding box to be arbitrarily remapped to any values.\n"
1193 "\n"
1194 "The 4 coordinates specify the new locations of each corner of the original bounding box. By specifying these values, any affine transformation (rotation, scaling, translation) can be affected. Additionally, these values can be specified such that the resulting transformed item will appear to have been projected via a perspective transform.\n"
1195 "\n"
1196 "If a selection exists and the item is a drawable, the portion of the drawable which lies under the selection is cut from the drawable and made into a floating selection which is then transformed as specified. The return value is the ID of the transformed floating selection.\n"
1197 "\n"
1198 "If there is no selection or the item is not a drawable, the entire item will be transformed according to the specified mapping. Additionally, if the item has its linked flag set to TRUE, all additional items contained in the image which have the linked flag set to TRUE will also be transformed the same way. The return value will be equal to the item ID supplied as input.\n"
1199 "\n"
1200 "This procedure is affected by the following context setters: 'gimp-context-set-interpolation', 'gimp-context-set-transform-direction', 'gimp-context-set-transform-resize'.",
1201 "Michael Natterer <mitch@gimp.org>",
1202 "Michael Natterer",
1203 "2010",
1204 NULL);
1205 gimp_procedure_add_argument (procedure,
1206 gimp_param_spec_item_id ("item",
1207 "item",
1208 "The affected item",
1209 pdb->gimp, FALSE,
1210 GIMP_PARAM_READWRITE));
1211 gimp_procedure_add_argument (procedure,
1212 g_param_spec_double ("x0",
1213 "x0",
1214 "The new x coordinate of upper-left corner of original bounding box",
1215 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1216 GIMP_PARAM_READWRITE));
1217 gimp_procedure_add_argument (procedure,
1218 g_param_spec_double ("y0",
1219 "y0",
1220 "The new y coordinate of upper-left corner of original bounding box",
1221 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1222 GIMP_PARAM_READWRITE));
1223 gimp_procedure_add_argument (procedure,
1224 g_param_spec_double ("x1",
1225 "x1",
1226 "The new x coordinate of upper-right corner of original bounding box",
1227 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1228 GIMP_PARAM_READWRITE));
1229 gimp_procedure_add_argument (procedure,
1230 g_param_spec_double ("y1",
1231 "y1",
1232 "The new y coordinate of upper-right corner of original bounding box",
1233 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1234 GIMP_PARAM_READWRITE));
1235 gimp_procedure_add_argument (procedure,
1236 g_param_spec_double ("x2",
1237 "x2",
1238 "The new x coordinate of lower-left corner of original bounding box",
1239 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1240 GIMP_PARAM_READWRITE));
1241 gimp_procedure_add_argument (procedure,
1242 g_param_spec_double ("y2",
1243 "y2",
1244 "The new y coordinate of lower-left corner of original bounding box",
1245 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1246 GIMP_PARAM_READWRITE));
1247 gimp_procedure_add_argument (procedure,
1248 g_param_spec_double ("x3",
1249 "x3",
1250 "The new x coordinate of lower-right corner of original bounding box",
1251 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1252 GIMP_PARAM_READWRITE));
1253 gimp_procedure_add_argument (procedure,
1254 g_param_spec_double ("y3",
1255 "y3",
1256 "The new y coordinate of lower-right corner of original bounding box",
1257 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1258 GIMP_PARAM_READWRITE));
1259 gimp_procedure_add_return_value (procedure,
1260 gimp_param_spec_item_id ("item",
1261 "item",
1262 "The transformed item",
1263 pdb->gimp, FALSE,
1264 GIMP_PARAM_READWRITE));
1265 gimp_pdb_register_procedure (pdb, procedure);
1266 g_object_unref (procedure);
1267
1268 /*
1269 * gimp-item-transform-rotate-simple
1270 */
1271 procedure = gimp_procedure_new (item_transform_rotate_simple_invoker);
1272 gimp_object_set_static_name (GIMP_OBJECT (procedure),
1273 "gimp-item-transform-rotate-simple");
1274 gimp_procedure_set_static_strings (procedure,
1275 "gimp-item-transform-rotate-simple",
1276 "Rotate the specified item about given coordinates through the specified angle.",
1277 "This function rotates the specified item.\n"
1278 "\n"
1279 "If a selection exists and the item is a drawable, the portion of the drawable which lies under the selection is cut from the drawable and made into a floating selection which is then rotated by the specified amount. If auto_center is set to TRUE, the rotation is around the selection's center. Otherwise, the coordinate of the center point needs to be specified. The return value is the ID of the rotated floating selection.\n"
1280 "\n"
1281 "If there is no selection or the item is not a drawable, the entire item will be rotated around its center if auto_center is set to TRUE, otherwise the coordinate of the center point needs to be specified. Additionally, if the item has its linked flag set to TRUE, all additional items contained in the image which have the linked flag set to TRUE will also be rotated around the same center point. The return value will be equal to the item ID supplied as input.\n"
1282 "\n"
1283 "This procedure is affected by the following context setters: 'gimp-context-set-transform-resize'.",
1284 "Michael Natterer <mitch@gimp.org>",
1285 "Michael Natterer",
1286 "2010",
1287 NULL);
1288 gimp_procedure_add_argument (procedure,
1289 gimp_param_spec_item_id ("item",
1290 "item",
1291 "The affected item",
1292 pdb->gimp, FALSE,
1293 GIMP_PARAM_READWRITE));
1294 gimp_procedure_add_argument (procedure,
1295 g_param_spec_enum ("rotate-type",
1296 "rotate type",
1297 "Type of rotation",
1298 GIMP_TYPE_ROTATION_TYPE,
1299 GIMP_ROTATE_90,
1300 GIMP_PARAM_READWRITE));
1301 gimp_procedure_add_argument (procedure,
1302 g_param_spec_boolean ("auto-center",
1303 "auto center",
1304 "Whether to automatically rotate around the selection center",
1305 FALSE,
1306 GIMP_PARAM_READWRITE));
1307 gimp_procedure_add_argument (procedure,
1308 g_param_spec_double ("center-x",
1309 "center x",
1310 "The hor. coordinate of the center of rotation",
1311 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1312 GIMP_PARAM_READWRITE));
1313 gimp_procedure_add_argument (procedure,
1314 g_param_spec_double ("center-y",
1315 "center y",
1316 "The vert. coordinate of the center of rotation",
1317 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1318 GIMP_PARAM_READWRITE));
1319 gimp_procedure_add_return_value (procedure,
1320 gimp_param_spec_item_id ("item",
1321 "item",
1322 "The rotated item",
1323 pdb->gimp, FALSE,
1324 GIMP_PARAM_READWRITE));
1325 gimp_pdb_register_procedure (pdb, procedure);
1326 g_object_unref (procedure);
1327
1328 /*
1329 * gimp-item-transform-rotate
1330 */
1331 procedure = gimp_procedure_new (item_transform_rotate_invoker);
1332 gimp_object_set_static_name (GIMP_OBJECT (procedure),
1333 "gimp-item-transform-rotate");
1334 gimp_procedure_set_static_strings (procedure,
1335 "gimp-item-transform-rotate",
1336 "Rotate the specified item about given coordinates through the specified angle.",
1337 "This function rotates the specified item.\n"
1338 "\n"
1339 "If a selection exists and the item is a drawable, the portion of the drawable which lies under the selection is cut from the drawable and made into a floating selection which is then rotated by the specified amount. If auto_center is set to TRUE, the rotation is around the selection's center. Otherwise, the coordinate of the center point needs to be specified. The return value is the ID of the rotated floating selection.\n"
1340 "\n"
1341 "If there is no selection or the item is not a drawable, the entire item will be rotated around its center if auto_center is set to TRUE, otherwise the coordinate of the center point needs to be specified. Additionally, if the item has its linked flag set to TRUE, all additional items contained in the image which have the linked flag set to TRUE will also be rotated around the same center point. The return value will be equal to the item ID supplied as input.\n"
1342 "\n"
1343 "This procedure is affected by the following context setters: 'gimp-context-set-interpolation', 'gimp-context-set-transform-direction', 'gimp-context-set-transform-resize'.",
1344 "Michael Natterer <mitch@gimp.org>",
1345 "Michael Natterer",
1346 "2010",
1347 NULL);
1348 gimp_procedure_add_argument (procedure,
1349 gimp_param_spec_item_id ("item",
1350 "item",
1351 "The affected item",
1352 pdb->gimp, FALSE,
1353 GIMP_PARAM_READWRITE));
1354 gimp_procedure_add_argument (procedure,
1355 g_param_spec_double ("angle",
1356 "angle",
1357 "The angle of rotation (radians)",
1358 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1359 GIMP_PARAM_READWRITE));
1360 gimp_procedure_add_argument (procedure,
1361 g_param_spec_boolean ("auto-center",
1362 "auto center",
1363 "Whether to automatically rotate around the selection center",
1364 FALSE,
1365 GIMP_PARAM_READWRITE));
1366 gimp_procedure_add_argument (procedure,
1367 g_param_spec_double ("center-x",
1368 "center x",
1369 "The hor. coordinate of the center of rotation",
1370 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1371 GIMP_PARAM_READWRITE));
1372 gimp_procedure_add_argument (procedure,
1373 g_param_spec_double ("center-y",
1374 "center y",
1375 "The vert. coordinate of the center of rotation",
1376 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1377 GIMP_PARAM_READWRITE));
1378 gimp_procedure_add_return_value (procedure,
1379 gimp_param_spec_item_id ("item",
1380 "item",
1381 "The rotated item",
1382 pdb->gimp, FALSE,
1383 GIMP_PARAM_READWRITE));
1384 gimp_pdb_register_procedure (pdb, procedure);
1385 g_object_unref (procedure);
1386
1387 /*
1388 * gimp-item-transform-scale
1389 */
1390 procedure = gimp_procedure_new (item_transform_scale_invoker);
1391 gimp_object_set_static_name (GIMP_OBJECT (procedure),
1392 "gimp-item-transform-scale");
1393 gimp_procedure_set_static_strings (procedure,
1394 "gimp-item-transform-scale",
1395 "Scale the specified item.",
1396 "This procedure scales the specified item.\n"
1397 "\n"
1398 "The 2 coordinates specify the new locations of the top-left and bottom-roght corners of the original bounding box.\n"
1399 "\n"
1400 "If a selection exists and the item is a drawable, the portion of the drawable which lies under the selection is cut from the drawable and made into a floating selection which is then scaled as specified. The return value is the ID of the scaled floating selection.\n"
1401 "\n"
1402 "If there is no selection or the item is not a drawable, the entire item will be scaled according to the specified coordinates. Additionally, if the item has its linked flag set to TRUE, all additional items contained in the image which have the linked flag set to TRUE will also be scaled the same way. The return value will be equal to the item ID supplied as input.\n"
1403 "\n"
1404 "This procedure is affected by the following context setters: 'gimp-context-set-interpolation', 'gimp-context-set-transform-direction', 'gimp-context-set-transform-resize'.",
1405 "Michael Natterer <mitch@gimp.org>",
1406 "Michael Natterer",
1407 "2010",
1408 NULL);
1409 gimp_procedure_add_argument (procedure,
1410 gimp_param_spec_item_id ("item",
1411 "item",
1412 "The affected item",
1413 pdb->gimp, FALSE,
1414 GIMP_PARAM_READWRITE));
1415 gimp_procedure_add_argument (procedure,
1416 g_param_spec_double ("x0",
1417 "x0",
1418 "The new x coordinate of the upper-left corner of the scaled region",
1419 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1420 GIMP_PARAM_READWRITE));
1421 gimp_procedure_add_argument (procedure,
1422 g_param_spec_double ("y0",
1423 "y0",
1424 "The new y coordinate of the upper-left corner of the scaled region",
1425 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1426 GIMP_PARAM_READWRITE));
1427 gimp_procedure_add_argument (procedure,
1428 g_param_spec_double ("x1",
1429 "x1",
1430 "The new x coordinate of the lower-right corner of the scaled region",
1431 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1432 GIMP_PARAM_READWRITE));
1433 gimp_procedure_add_argument (procedure,
1434 g_param_spec_double ("y1",
1435 "y1",
1436 "The new y coordinate of the lower-right corner of the scaled region",
1437 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1438 GIMP_PARAM_READWRITE));
1439 gimp_procedure_add_return_value (procedure,
1440 gimp_param_spec_item_id ("item",
1441 "item",
1442 "The scaled item",
1443 pdb->gimp, FALSE,
1444 GIMP_PARAM_READWRITE));
1445 gimp_pdb_register_procedure (pdb, procedure);
1446 g_object_unref (procedure);
1447
1448 /*
1449 * gimp-item-transform-shear
1450 */
1451 procedure = gimp_procedure_new (item_transform_shear_invoker);
1452 gimp_object_set_static_name (GIMP_OBJECT (procedure),
1453 "gimp-item-transform-shear");
1454 gimp_procedure_set_static_strings (procedure,
1455 "gimp-item-transform-shear",
1456 "Shear the specified item about its center by the specified magnitude.",
1457 "This procedure shears the specified item.\n"
1458 "\n"
1459 "The shear type parameter indicates whether the shear will be applied horizontally or vertically. The magnitude can be either positive or negative and indicates the extent (in pixels) to shear by.\n"
1460 "\n"
1461 "If a selection exists and the item is a drawable, the portion of the drawable which lies under the selection is cut from the drawable and made into a floating selection which is then sheared as specified. The return value is the ID of the sheared floating selection.\n"
1462 "\n"
1463 "If there is no selection or the item is not a drawable, the entire item will be sheared according to the specified parameters. Additionally, if the item has its linked flag set to TRUE, all additional items contained in the image which have the linked flag set to TRUE will also be sheared the same way. The return value will be equal to the item ID supplied as input.\n"
1464 "\n"
1465 "This procedure is affected by the following context setters: 'gimp-context-set-interpolation', 'gimp-context-set-transform-direction', 'gimp-context-set-transform-resize'.",
1466 "Michael Natterer <mitch@gimp.org>",
1467 "Michael Natterer",
1468 "2010",
1469 NULL);
1470 gimp_procedure_add_argument (procedure,
1471 gimp_param_spec_item_id ("item",
1472 "item",
1473 "The affected item",
1474 pdb->gimp, FALSE,
1475 GIMP_PARAM_READWRITE));
1476 gimp_procedure_add_argument (procedure,
1477 gimp_param_spec_enum ("shear-type",
1478 "shear type",
1479 "Type of shear",
1480 GIMP_TYPE_ORIENTATION_TYPE,
1481 GIMP_ORIENTATION_HORIZONTAL,
1482 GIMP_PARAM_READWRITE));
1483 gimp_param_spec_enum_exclude_value (GIMP_PARAM_SPEC_ENUM (procedure->args[1]),
1484 GIMP_ORIENTATION_UNKNOWN);
1485 gimp_procedure_add_argument (procedure,
1486 g_param_spec_double ("magnitude",
1487 "magnitude",
1488 "The magnitude of the shear",
1489 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1490 GIMP_PARAM_READWRITE));
1491 gimp_procedure_add_return_value (procedure,
1492 gimp_param_spec_item_id ("item",
1493 "item",
1494 "The sheared item",
1495 pdb->gimp, FALSE,
1496 GIMP_PARAM_READWRITE));
1497 gimp_pdb_register_procedure (pdb, procedure);
1498 g_object_unref (procedure);
1499
1500 /*
1501 * gimp-item-transform-2d
1502 */
1503 procedure = gimp_procedure_new (item_transform_2d_invoker);
1504 gimp_object_set_static_name (GIMP_OBJECT (procedure),
1505 "gimp-item-transform-2d");
1506 gimp_procedure_set_static_strings (procedure,
1507 "gimp-item-transform-2d",
1508 "Transform the specified item in 2d.",
1509 "This procedure transforms the specified item.\n"
1510 "\n"
1511 "The transformation is done by scaling by the x and y scale factors about the point (source_x, source_y), then rotating around the same point, then translating that point to the new position (dest_x, dest_y).\n"
1512 "\n"
1513 "If a selection exists and the item is a drawable, the portion of the drawable which lies under the selection is cut from the drawable and made into a floating selection which is then transformed as specified. The return value is the ID of the transformed floating selection.\n"
1514 "\n"
1515 "If there is no selection or the item is not a drawable, the entire item will be transformed according to the specified parameters. Additionally, if the item has its linked flag set to TRUE, all additional items contained in the image which have the linked flag set to TRUE will also be transformed the same way. The return value will be equal to the item ID supplied as input.\n"
1516 "\n"
1517 "This procedure is affected by the following context setters: 'gimp-context-set-interpolation', 'gimp-context-set-transform-direction', 'gimp-context-set-transform-resize'.",
1518 "Michael Natterer <mitch@gimp.org>",
1519 "Michael Natterer",
1520 "2010",
1521 NULL);
1522 gimp_procedure_add_argument (procedure,
1523 gimp_param_spec_item_id ("item",
1524 "item",
1525 "The affected item",
1526 pdb->gimp, FALSE,
1527 GIMP_PARAM_READWRITE));
1528 gimp_procedure_add_argument (procedure,
1529 g_param_spec_double ("source-x",
1530 "source x",
1531 "X coordinate of the transformation center",
1532 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1533 GIMP_PARAM_READWRITE));
1534 gimp_procedure_add_argument (procedure,
1535 g_param_spec_double ("source-y",
1536 "source y",
1537 "Y coordinate of the transformation center",
1538 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1539 GIMP_PARAM_READWRITE));
1540 gimp_procedure_add_argument (procedure,
1541 g_param_spec_double ("scale-x",
1542 "scale x",
1543 "Amount to scale in x direction",
1544 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1545 GIMP_PARAM_READWRITE));
1546 gimp_procedure_add_argument (procedure,
1547 g_param_spec_double ("scale-y",
1548 "scale y",
1549 "Amount to scale in y direction",
1550 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1551 GIMP_PARAM_READWRITE));
1552 gimp_procedure_add_argument (procedure,
1553 g_param_spec_double ("angle",
1554 "angle",
1555 "The angle of rotation (radians)",
1556 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1557 GIMP_PARAM_READWRITE));
1558 gimp_procedure_add_argument (procedure,
1559 g_param_spec_double ("dest-x",
1560 "dest x",
1561 "X coordinate of where the center goes",
1562 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1563 GIMP_PARAM_READWRITE));
1564 gimp_procedure_add_argument (procedure,
1565 g_param_spec_double ("dest-y",
1566 "dest y",
1567 "Y coordinate of where the center goes",
1568 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1569 GIMP_PARAM_READWRITE));
1570 gimp_procedure_add_return_value (procedure,
1571 gimp_param_spec_item_id ("item",
1572 "item",
1573 "The transformed item",
1574 pdb->gimp, FALSE,
1575 GIMP_PARAM_READWRITE));
1576 gimp_pdb_register_procedure (pdb, procedure);
1577 g_object_unref (procedure);
1578
1579 /*
1580 * gimp-item-transform-matrix
1581 */
1582 procedure = gimp_procedure_new (item_transform_matrix_invoker);
1583 gimp_object_set_static_name (GIMP_OBJECT (procedure),
1584 "gimp-item-transform-matrix");
1585 gimp_procedure_set_static_strings (procedure,
1586 "gimp-item-transform-matrix",
1587 "Transform the specified item in 2d.",
1588 "This procedure transforms the specified item.\n"
1589 "\n"
1590 "The transformation is done by assembling a 3x3 matrix from the coefficients passed.\n"
1591 "\n"
1592 "If a selection exists and the item is a drawable, the portion of the drawable which lies under the selection is cut from the drawable and made into a floating selection which is then transformed as specified. The return value is the ID of the transformed floating selection.\n"
1593 "\n"
1594 "If there is no selection or the item is not a drawable, the entire item will be transformed according to the specified matrix. Additionally, if the item has its linked flag set to TRUE, all additional items contained in the image which have the linked flag set to TRUE will also be transformed the same way. The return value will be equal to the item ID supplied as input.\n"
1595 "\n"
1596 "This procedure is affected by the following context setters: 'gimp-context-set-interpolation', 'gimp-context-set-transform-direction', 'gimp-context-set-transform-resize'.",
1597 "Michael Natterer <mitch@gimp.org>",
1598 "Michael Natterer",
1599 "2010",
1600 NULL);
1601 gimp_procedure_add_argument (procedure,
1602 gimp_param_spec_item_id ("item",
1603 "item",
1604 "The affected item",
1605 pdb->gimp, FALSE,
1606 GIMP_PARAM_READWRITE));
1607 gimp_procedure_add_argument (procedure,
1608 g_param_spec_double ("coeff-0-0",
1609 "coeff 0 0",
1610 "coefficient (0,0) of the transformation matrix",
1611 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1612 GIMP_PARAM_READWRITE));
1613 gimp_procedure_add_argument (procedure,
1614 g_param_spec_double ("coeff-0-1",
1615 "coeff 0 1",
1616 "coefficient (0,1) of the transformation matrix",
1617 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1618 GIMP_PARAM_READWRITE));
1619 gimp_procedure_add_argument (procedure,
1620 g_param_spec_double ("coeff-0-2",
1621 "coeff 0 2",
1622 "coefficient (0,2) of the transformation matrix",
1623 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1624 GIMP_PARAM_READWRITE));
1625 gimp_procedure_add_argument (procedure,
1626 g_param_spec_double ("coeff-1-0",
1627 "coeff 1 0",
1628 "coefficient (1,0) of the transformation matrix",
1629 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1630 GIMP_PARAM_READWRITE));
1631 gimp_procedure_add_argument (procedure,
1632 g_param_spec_double ("coeff-1-1",
1633 "coeff 1 1",
1634 "coefficient (1,1) of the transformation matrix",
1635 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1636 GIMP_PARAM_READWRITE));
1637 gimp_procedure_add_argument (procedure,
1638 g_param_spec_double ("coeff-1-2",
1639 "coeff 1 2",
1640 "coefficient (1,2) of the transformation matrix",
1641 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1642 GIMP_PARAM_READWRITE));
1643 gimp_procedure_add_argument (procedure,
1644 g_param_spec_double ("coeff-2-0",
1645 "coeff 2 0",
1646 "coefficient (2,0) of the transformation matrix",
1647 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1648 GIMP_PARAM_READWRITE));
1649 gimp_procedure_add_argument (procedure,
1650 g_param_spec_double ("coeff-2-1",
1651 "coeff 2 1",
1652 "coefficient (2,1) of the transformation matrix",
1653 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1654 GIMP_PARAM_READWRITE));
1655 gimp_procedure_add_argument (procedure,
1656 g_param_spec_double ("coeff-2-2",
1657 "coeff 2 2",
1658 "coefficient (2,2) of the transformation matrix",
1659 -G_MAXDOUBLE, G_MAXDOUBLE, 0,
1660 GIMP_PARAM_READWRITE));
1661 gimp_procedure_add_return_value (procedure,
1662 gimp_param_spec_item_id ("item",
1663 "item",
1664 "The transformed item",
1665 pdb->gimp, FALSE,
1666 GIMP_PARAM_READWRITE));
1667 gimp_pdb_register_procedure (pdb, procedure);
1668 g_object_unref (procedure);
1669 }
1670