# The GIMP -- an image manipulation program # Copyright (C) 1995 Spencer Kimball and Peter Mattis # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # "Perlized" from C source by Manish Singh # Transform Tools # shortcuts sub drawable_arg () {{ name => 'drawable', type => 'drawable', desc => 'The affected drawable', }} sub drawable_out_arg { my $type = shift; my $arg = &drawable_arg; $arg->{desc} = "The $type drawable"; $arg->{no_declare} = 1; $arg; } # The defs sub flip { $blurb = <<'BLURB'; Flip the specified drawable about its center either vertically or horizontally. BLURB $help = <<'HELP'; This tool flips the specified drawable if no selection exists. If a selection exists, the portion of the drawable which lies under the selection is cut from the drawable and made into a floating selection which is then flipd by the specified amount. The return value is the ID of the flipped drawable. If there was no selection, this will be equal to the drawable ID supplied as input. Otherwise, this will be the newly created and flipped drawable. The flip type parameter indicates whether the flip will be applied horizontally or vertically. HELP &std_pdb_misc; @inargs = ( &drawable_arg, { name => 'flip_type', type => &std_orientation_enum, desc => 'Type of flip: %%desc%%' } ); @outargs = ( &drawable_out_arg('flipped') ); %invoke = ( code => <<'CODE' { success = gimp_drawable_transform_flip (drawable, flip_type); } CODE ); } sub perspective { $blurb = <<'BLURB'; Perform a possibly non-affine transformation on the specified drawable. BLURB $help = <<'HELP'; This tool performs a possibly non-affine transformation on the specified drawable by allowing the corners of the original bounding box to be arbitrarily remapped to any values. The specified drawable is remapped if no selection exists. However, if a selection exists, the portion of the drawable which lies under the selection is cut from the drawable and made into a floating selection which is then remapped as specified. The interpolation parameter can be set to TRUE to indicate that either linear or cubic interpolation should be used to smooth the resulting remapped drawable. The return value is the ID of the remapped drawable. If there was no selection, this will be equal to the drawable ID supplied as input. Otherwise, this will be the newly created and remapped drawable. 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 drawable will appear to have been projected via a perspective transform. HELP &std_pdb_misc; @inargs = ( &drawable_arg, { name => 'interpolation', type => 'boolean', desc => 'Whether to use interpolation' } ); my $pos = 0; foreach $where (qw(upper-left upper-right lower-left lower-right)) { foreach (qw(x y)) { push @inargs, { name => "$_$pos", type => 'float', desc => "The new $_ coordinate of $where corner of original bounding box", alias => "trans_info[\U$_\E$pos]", no_declare => 1 } } $pos++; } @outargs = ( &drawable_out_arg('newly mapped') ); %invoke = ( vars => [ 'gint x1, y1, x2, y2', 'gdouble trans_info[8]', 'GimpMatrix3 matrix', 'GimpInterpolationType interpolation_type' ], code => <<'CODE' { gimp_drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2); /* Assemble the transformation matrix */ gimp_drawable_transform_matrix_perspective (x1, y1, x2, y2, trans_info[X0], trans_info[Y0], trans_info[X1], trans_info[Y1], trans_info[X2], trans_info[Y2], trans_info[X3], trans_info[Y3], matrix); if (interpolation) interpolation_type = gimp->config->interpolation_type; else interpolation_type = GIMP_INTERPOLATION_NONE; /* Perspective the selection */ success = gimp_drawable_transform_affine (drawable, interpolation_type, FALSE, matrix, GIMP_TRANSFORM_FORWARD); } CODE ); } sub rotate { $blurb = <<'BLURB'; Rotate the specified drawable about its center through the specified angle. BLURB $help = <<'HELP'; This tool rotates the specified drawable if no selection exists. If a selection exists, 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. The interpolation parameter can be set to TRUE to indicate that either linear or cubic interpolation should be used to smooth the resulting rotated drawable. The return value is the ID of the rotated drawable. If there was no selection, this will be equal to the drawable ID supplied as input. Otherwise, this will be the newly created and rotated drawable. HELP &std_pdb_misc; @inargs = ( &drawable_arg, { name => 'interpolation', type => 'boolean', desc => 'Whether to use interpolation' }, { name => 'angle', type => 'float', desc => 'The angle of rotation (radians)' } ); @outargs = ( &drawable_out_arg('rotated') ); %invoke = ( vars => [ 'gint x1, y1, x2, y2', 'GimpMatrix3 matrix', 'GimpInterpolationType interpolation_type' ], code => <<'CODE' { gimp_drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2); /* Assemble the transformation matrix */ gimp_drawable_transform_matrix_rotate (x1, y1, x2, y2, angle, matrix); if (interpolation) interpolation_type = gimp->config->interpolation_type; else interpolation_type = GIMP_INTERPOLATION_NONE; /* Rotate the selection */ success = gimp_drawable_transform_affine (drawable, interpolation_type, FALSE, matrix, GIMP_TRANSFORM_FORWARD); } CODE ); } sub scale { $blurb = 'Scale the specified drawable.'; $help = <<'HELP'; This tool scales the specified drawable if no selection exists. If a selection exists, 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 by the specified amount. The interpolation parameter can be set to TRUE to indicate that either linear or cubic interpolation should be used to smooth the resulting scaled drawable. The return value is the ID of the scaled drawable. If there was no selection, this will be equal to the drawable ID supplied as input. Otherwise, this will be the newly created and scaled drawable. HELP &std_pdb_misc; @inargs = ( &drawable_arg, { name => 'interpolation', type => 'boolean', desc => 'Whether to use interpolation' } ); my $pos = 0; foreach $where (qw(upper-left lower-right)) { foreach (qw(x y)) { push @inargs, { name => "$_$pos", type => 'float', desc => "The new $_ coordinate of $where corner of newly scaled region", alias => "trans_info[\U$_\E$pos]", no_declare => 1 } } $pos++; } @outargs = ( &drawable_out_arg('scaled') ); %invoke = ( vars => [ 'gint x1, y1, x2, y2', 'gdouble trans_info[4]', 'GimpMatrix3 matrix', 'GimpInterpolationType interpolation_type' ], code => <<'CODE' { if (trans_info[X0] < trans_info[X1] && trans_info[Y0] < trans_info[X1]) { gimp_drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2); /* Assemble the transformation matrix */ gimp_drawable_transform_matrix_scale (x1, y1, x2, y2, trans_info[X0], trans_info[Y0], trans_info[X1], trans_info[Y1], matrix); if (interpolation) interpolation_type = gimp->config->interpolation_type; else interpolation_type = GIMP_INTERPOLATION_NONE; /* Scale the selection */ success = gimp_drawable_transform_affine (drawable, interpolation_type, FALSE, matrix, GIMP_TRANSFORM_FORWARD); } else { success = FALSE; } } CODE ); } sub shear { $blurb = <<'BLURB'; Shear the specified drawable about its center by the specified magnitude. BLURB $help = <<'HELP'; This tool shears the specified drawable if no selection exists. If a selection exists, the portion of the drawable which lies under the selection is cut from the drawable and made into a floating selection which is then sheard by the specified amount. The interpolation parameter can be set to TRUE to indicate that either linear or cubic interpolation should be used to smooth the resulting sheared drawable. The return value is the ID of the sheard drawable. If there was no selection, this will be equal to the drawable ID supplied as input. Otherwise, this will be the newly created and sheard drawable. 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. HELP &std_pdb_misc; @inargs = ( &drawable_arg, { name => 'interpolation', type => 'boolean', desc => 'Whether to use interpolation' }, { name => 'shear_type', type => &std_orientation_enum, desc => 'Type of shear: %%desc%%' }, { name => 'magnitude', type => 'float', desc => 'The magnitude of the shear' } ); @outargs = ( &drawable_out_arg('sheared') ); %invoke = ( vars => [ 'gint x1, y1, x2, y2', 'GimpMatrix3 matrix', 'GimpInterpolationType interpolation_type' ], code => <<'CODE' { gimp_drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2); /* Assemble the transformation matrix */ gimp_drawable_transform_matrix_shear (x1, y1, x2, y2, shear_type, magnitude, matrix); if (interpolation) interpolation_type = gimp->config->interpolation_type; else interpolation_type = GIMP_INTERPOLATION_NONE; /* Shear the selection */ success = gimp_drawable_transform_affine (drawable, interpolation_type, FALSE, matrix, GIMP_TRANSFORM_FORWARD); } CODE ); } sub transform_2d { $blurb = <<'BLURB'; Transform the specified drawable in 2d. BLURB $help = <<'HELP'; This tool transforms the specified drawable if no selection exists. If a selection exists, 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. The interpolation parameter can be set to TRUE to indicate that either linear or cubic interpolation should be used to smooth the resulting drawable. The transformation is done by scaling the image 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). The return value is the ID of the rotated drawable. If there was no selection, this will be equal to the drawable ID supplied as input. Otherwise, this will be the newly created and transformed drawable. HELP &std_pdb_misc; @inargs = ( &drawable_arg, { name => 'interpolation', type => 'boolean', desc => 'Whether to use interpolation' }, { name => 'source_x', type => 'float', desc => 'X coordinate of the transformation center' }, { name => 'source_y', type => 'float', desc => 'Y coordinate of the transformation center' }, { name => 'scale_x', type => 'float', desc => 'Amount to scale in x direction' }, { name => 'scale_y', type => 'float', desc => 'Amount to scale in y direction' }, { name => 'angle', type => 'float', desc => 'The angle of rotation (radians)' }, { name => 'dest_x', type => 'float', desc => 'X coordinate of where the centre goes' }, { name => 'dest_y', type => 'float', desc => 'Y coordinate of where the centre goes' } ); @outargs = ( &drawable_out_arg('transformed') ); %invoke = ( vars => [ 'GimpMatrix3 matrix', 'GimpInterpolationType interpolation_type' ], code => <<'CODE' { /* Assemble the transformation matrix */ gimp_matrix3_identity (matrix); gimp_matrix3_translate (matrix, -source_x, -source_y); gimp_matrix3_scale (matrix, scale_x, scale_y); gimp_matrix3_rotate (matrix, angle); gimp_matrix3_translate (matrix, dest_x, dest_y); if (interpolation) interpolation_type = gimp->config->interpolation_type; else interpolation_type = GIMP_INTERPOLATION_NONE; /* Transform the selection */ success = gimp_drawable_transform_affine (drawable, interpolation_type, FALSE, matrix, GIMP_TRANSFORM_FORWARD); } CODE ); } @headers = qw("libgimpmath/gimpmath.h" "config/gimpcoreconfig.h" "core/gimp.h" "core/gimpdrawable-transform.h" "core/gimpdrawable-transform-utils.h" "core/gimpdrawable.h"); @procs = qw(flip perspective rotate scale shear transform_2d); %exports = (app => [@procs], lib => [@procs]); $desc = 'Transform Tool procedures'; 1;