Gimp/tools/pdbgen/pdb/transform_tools.pdb
Michael Natterer d4933b3052 Bug 674160 - Redesign of "Lock panel"
Apply and heavily modify patch from remyDev which adds "lock position"
to GimpItem, similar to "lock content". Lock position disables all
sorts of translation and transform, from the GUI and the PDB.

Cleaned up some aspects of the lock content code as well because a
second instance of similar code always shows what went wrong the first
time.
2012-11-09 11:17:25 +01:00

532 lines
17 KiB
Text

# GIMP - The GNU 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 3 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, see <http://www.gnu.org/licenses/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
sub flip {
&std_pdb_deprecated ('gimp-item-transform-flip-simple');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The affected drawable' },
{ name => 'flip_type',
type => 'enum GimpOrientationType (no GIMP_ORIENTATION_UNKNOWN)',
desc => 'Type of flip' }
);
@outargs = (
{ name => 'drawable', type => 'drawable', no_declare => 1,
desc => 'The flipped drawable' }
);
%invoke = (
code => <<'CODE'
{
gint x, y, width, height;
success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
GIMP_PDB_ITEM_CONTENT |
GIMP_PDB_ITEM_POSITION, error);
if (success &&
gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height))
{
gdouble axis;
gimp_transform_get_flip_axis (x, y, width, height,
flip_type, TRUE, &axis);
if (! gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) &&
! gimp_channel_is_empty (gimp_image_get_mask (gimp_item_get_image (GIMP_ITEM (drawable)))))
{
if (! gimp_drawable_transform_flip (drawable, context,
flip_type, axis, FALSE))
{
success = FALSE;
}
}
else
{
gimp_item_flip (GIMP_ITEM (drawable), context,
flip_type, axis, FALSE);
}
}
}
CODE
);
}
sub perspective {
&std_pdb_deprecated ('gimp-item-transform-perspective');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The affected drawable' },
{ name => 'interpolation', type => 'boolean',
desc => 'Whether to use interpolation' },
{ name => 'x0', type => 'float',
desc => 'The new x coordinate of upper-left corner of original
bounding box' },
{ name => 'y0', type => 'float',
desc => 'The new y coordinate of upper-left corner of original
bounding box' },
{ name => 'x1', type => 'float',
desc => 'The new x coordinate of upper-right corner of original
bounding box' },
{ name => 'y1', type => 'float',
desc => 'The new y coordinate of upper-right corner of original
bounding box' },
{ name => 'x2', type => 'float',
desc => 'The new x coordinate of lower-left corner of original
bounding box' },
{ name => 'y2', type => 'float',
desc => 'The new y coordinate of lower-left corner of original
bounding box' },
{ name => 'x3', type => 'float',
desc => 'The new x coordinate of lower-right corner of original
bounding box' },
{ name => 'y3', type => 'float',
desc => 'The new y coordinate of lower-right corner of original
bounding box' }
);
@outargs = (
{ name => 'drawable', type => 'drawable', no_declare => 1,
desc => 'The newly mapped drawable' }
);
%invoke = (
code => <<'CODE'
{
gint x, y, width, height;
success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
GIMP_PDB_ITEM_CONTENT |
GIMP_PDB_ITEM_POSITION, error);
if (success &&
gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height))
{
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type = GIMP_INTERPOLATION_NONE;
gint off_x, off_y;
gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
x += off_x;
y += off_y;
/* Assemble the transformation matrix */
gimp_matrix3_identity (&matrix);
gimp_transform_matrix_perspective (&matrix,
x, y, width, height,
x0, y0, x1, y1,
x2, y2, x3, y3);
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
if (progress)
gimp_progress_start (progress, _("Perspective"), FALSE);
if (! gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) &&
! gimp_channel_is_empty (gimp_image_get_mask (gimp_item_get_image (GIMP_ITEM (drawable)))))
{
if (! gimp_drawable_transform_affine (drawable, context,
&matrix,
GIMP_TRANSFORM_FORWARD,
interpolation_type, 3,
FALSE, progress))
{
success = FALSE;
}
}
else
{
gimp_item_transform (GIMP_ITEM (drawable), context, &matrix,
GIMP_TRANSFORM_FORWARD,
interpolation, 3,
FALSE, progress);
}
if (progress)
gimp_progress_end (progress);
}
}
CODE
);
}
sub rotate {
&std_pdb_deprecated ('gimp-item-transform-rotate');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The affected drawable' },
{ name => 'interpolation', type => 'boolean',
desc => 'Whether to use interpolation' },
{ name => 'angle', type => 'float',
desc => 'The angle of rotation (radians)' }
);
@outargs = (
{ name => 'drawable', type => 'drawable', no_declare => 1,
desc => 'The rotated drawable' }
);
%invoke = (
code => <<'CODE'
{
gint x, y, width, height;
success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
GIMP_PDB_ITEM_CONTENT |
GIMP_PDB_ITEM_POSITION, error);
if (success &&
gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height))
{
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type = GIMP_INTERPOLATION_NONE;
gint off_x, off_y;
gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
x += off_x;
y += off_y;
/* Assemble the transformation matrix */
gimp_matrix3_identity (&matrix);
gimp_transform_matrix_rotate_rect (&matrix,
x, y, width, height,
angle);
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
if (progress)
gimp_progress_start (progress, _("Rotating"), FALSE);
if (! gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) &&
! gimp_channel_is_empty (gimp_image_get_mask (gimp_item_get_image (GIMP_ITEM (drawable)))))
{
if (! gimp_drawable_transform_affine (drawable, context,
&matrix,
GIMP_TRANSFORM_FORWARD,
interpolation_type, 3,
FALSE, progress))
{
success = FALSE;
}
}
else
{
gimp_item_transform (GIMP_ITEM (drawable), context, &matrix,
GIMP_TRANSFORM_FORWARD,
interpolation, 3,
FALSE, progress);
}
if (progress)
gimp_progress_end (progress);
}
}
CODE
);
}
sub scale {
&std_pdb_deprecated ('gimp-item-transform-scale');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The affected drawable' },
{ name => 'interpolation', type => 'boolean',
desc => 'Whether to use interpolation' },
{ name => 'x0', type => 'float',
desc => 'The new x coordinate of the upper-left corner of the
scaled region' },
{ name => 'y0', type => 'float',
desc => 'The new y coordinate of the upper-left corner of the
scaled region' },
{ name => 'x1', type => 'float',
desc => 'The new x coordinate of the lower-right corner of the
scaled region' },
{ name => 'y1', type => 'float',
desc => 'The new y coordinate of the lower-right corner of the
scaled region' }
);
@outargs = (
{ name => 'drawable', type => 'drawable', no_declare => 1,
desc => 'The scaled drawable' }
);
%invoke = (
code => <<'CODE'
{
gint x, y, width, height;
success = (gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
GIMP_PDB_ITEM_CONTENT |
GIMP_PDB_ITEM_POSITION, error) &&
x0 < x1 && y0 < y1);
if (success &&
gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height))
{
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type = GIMP_INTERPOLATION_NONE;
gint off_x, off_y;
gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
x += off_x;
y += off_y;
/* Assemble the transformation matrix */
gimp_matrix3_identity (&matrix);
gimp_transform_matrix_scale (&matrix,
x, y, width, height,
x0, y0, x1 - x0, y1 - y0);
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
if (progress)
gimp_progress_start (progress, _("Scaling"), FALSE);
if (! gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) &&
! gimp_channel_is_empty (gimp_image_get_mask (gimp_item_get_image (GIMP_ITEM (drawable)))))
{
if (! gimp_drawable_transform_affine (drawable, context,
&matrix,
GIMP_TRANSFORM_FORWARD,
interpolation_type, 3,
FALSE, progress))
{
success = FALSE;
}
}
else
{
gimp_item_transform (GIMP_ITEM (drawable), context, &matrix,
GIMP_TRANSFORM_FORWARD,
interpolation, 3,
FALSE, progress);
}
if (progress)
gimp_progress_end (progress);
}
}
CODE
);
}
sub shear {
&std_pdb_deprecated ('gimp-item-transform-shear');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The affected drawable' },
{ name => 'interpolation', type => 'boolean',
desc => 'Whether to use interpolation' },
{ name => 'shear_type',
type => 'enum GimpOrientationType (no GIMP_ORIENTATION_UNKNOWN)',
desc => 'Type of shear' },
{ name => 'magnitude', type => 'float',
desc => 'The magnitude of the shear' }
);
@outargs = (
{ name => 'drawable', type => 'drawable', no_declare => 1,
desc => 'The sheared drawable' }
);
%invoke = (
code => <<'CODE'
{
gint x, y, width, height;
success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
GIMP_PDB_ITEM_CONTENT |
GIMP_PDB_ITEM_POSITION, error);
if (success &&
gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height))
{
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type = GIMP_INTERPOLATION_NONE;
gint off_x, off_y;
gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
x += off_x;
y += off_y;
/* Assemble the transformation matrix */
gimp_matrix3_identity (&matrix);
gimp_transform_matrix_shear (&matrix,
x, y, width, height,
shear_type, magnitude);
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
if (progress)
gimp_progress_start (progress, _("Shearing"), FALSE);
if (! gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) &&
! gimp_channel_is_empty (gimp_image_get_mask (gimp_item_get_image (GIMP_ITEM (drawable)))))
{
if (! gimp_drawable_transform_affine (drawable, context,
&matrix,
GIMP_TRANSFORM_FORWARD,
interpolation_type, 3,
FALSE, progress))
{
success = FALSE;
}
}
else
{
gimp_item_transform (GIMP_ITEM (drawable), context, &matrix,
GIMP_TRANSFORM_FORWARD,
interpolation, 3,
FALSE, progress);
}
if (progress)
gimp_progress_end (progress);
}
}
CODE
);
}
sub transform_2d {
&std_pdb_deprecated ('gimp-item-transform-2d');
@inargs = (
{ name => 'drawable', type => 'drawable',
desc => 'The affected drawable' },
{ 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 = (
{ name => 'drawable', type => 'drawable', no_declare => 1,
desc => 'The transformed drawable' }
);
%invoke = (
code => <<'CODE'
{
gint x, y, width, height;
success = gimp_pdb_item_is_attached (GIMP_ITEM (drawable), NULL,
GIMP_PDB_ITEM_CONTENT |
GIMP_PDB_ITEM_POSITION, error);
if (success &&
gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height))
{
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type = GIMP_INTERPOLATION_NONE;
/* 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;
if (progress)
gimp_progress_start (progress, _("2D Transform"), FALSE);
if (! gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) &&
! gimp_channel_is_empty (gimp_image_get_mask (gimp_item_get_image (GIMP_ITEM (drawable)))))
{
if (! gimp_drawable_transform_affine (drawable, context,
&matrix, GIMP_TRANSFORM_FORWARD,
interpolation_type, 3,
FALSE, progress))
{
success = FALSE;
}
}
else
{
gimp_item_transform (GIMP_ITEM (drawable), context, &matrix,
GIMP_TRANSFORM_FORWARD,
interpolation, 3,
FALSE, progress);
}
if (progress)
gimp_progress_end (progress);
}
}
CODE
);
}
@headers = qw("libgimpmath/gimpmath.h"
"config/gimpcoreconfig.h"
"core/gimp.h"
"core/gimpchannel.h"
"core/gimp-transform-utils.h"
"core/gimpimage.h"
"core/gimpdrawable.h"
"core/gimpdrawable-transform.h"
"core/gimpprogress.h"
"gimppdb-utils.h"
"gimp-intl.h");
@procs = qw(flip
perspective
rotate
scale
shear
transform_2d);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Transform Tool procedures';
$doc_title = 'gimptransformtools';
$doc_short_desc = 'Access to toolbox transform tools.';
$doc_long_desc = 'Functions giving access to toolbox transform tools.';
1;