app/core/gimp-transform-utils.[ch]. switch from x1,y1,x2,y2 bounding boxes

2004-10-27  Michael Natterer  <mitch@gimp.org>

	* app/core/gimp-transform-utils.[ch]. switch from x1,y1,x2,y2
	bounding boxes to x,y,width,height ones. Added
	gimp_transform_matrix_flip_free(). Renamed some parameters to be
	consistent with others. Some internal cleanup.

	* app/tools/gimpperspectivetool.c
	* app/tools/gimpscaletool.c
	* app/tools/gimpsheartool.c
	* tools/pdbgen/pdb/drawable_transform.pdb
	* tools/pdbgen/pdb/transform_tools.pdb: changed accordingly.

	* tools/pdbgen/pdb/drawable_transform.pdb
	* tools/pdbgen/pdb/transform_tools.pdb: guard all transform
	wrappers with if(gimp_drawable_mask_intersect(...)), also the
	ones which don't need the returned bounding box.

	* tools/pdbgen/pdb/drawable_transform.pdb: renamed some parameters
	and added gimp_drawable_transform_matrix() which takes the 9
	coefficients of a 3x3 matrix for ultimate flexibility ;)

	* app/pdb/drawable_transform_cmds.c
	* app/pdb/internal_procs.c
	* app/pdb/transform_tools_cmds.c
	* libgimp/gimpdrawabletransform_pdb.[ch]: regenerated.
This commit is contained in:
Michael Natterer 2004-10-27 17:56:02 +00:00 committed by Michael Natterer
parent 4349469e3c
commit d0ab9a7470
13 changed files with 1188 additions and 733 deletions

View File

@ -1,3 +1,30 @@
2004-10-27 Michael Natterer <mitch@gimp.org>
* app/core/gimp-transform-utils.[ch]. switch from x1,y1,x2,y2
bounding boxes to x,y,width,height ones. Added
gimp_transform_matrix_flip_free(). Renamed some parameters to be
consistent with others. Some internal cleanup.
* app/tools/gimpperspectivetool.c
* app/tools/gimpscaletool.c
* app/tools/gimpsheartool.c
* tools/pdbgen/pdb/drawable_transform.pdb
* tools/pdbgen/pdb/transform_tools.pdb: changed accordingly.
* tools/pdbgen/pdb/drawable_transform.pdb
* tools/pdbgen/pdb/transform_tools.pdb: guard all transform
wrappers with if(gimp_drawable_mask_intersect(...)), also the
ones which don't need the returned bounding box.
* tools/pdbgen/pdb/drawable_transform.pdb: renamed some parameters
and added gimp_drawable_transform_matrix() which takes the 9
coefficients of a 3x3 matrix for ultimate flexibility ;)
* app/pdb/drawable_transform_cmds.c
* app/pdb/internal_procs.c
* app/pdb/transform_tools_cmds.c
* libgimp/gimpdrawabletransform_pdb.[ch]: regenerated.
2004-10-27 Sven Neumann <sven@gimp.org>
* app/actions/dockable-actions.c (dockable_toggle_actions): changed

View File

@ -32,6 +32,8 @@ gimp_transform_matrix_flip (GimpOrientationType flip_type,
gdouble axis,
GimpMatrix3 *result)
{
g_return_if_fail (result != NULL);
gimp_matrix3_identity (result);
switch (flip_type)
@ -54,127 +56,159 @@ gimp_transform_matrix_flip (GimpOrientationType flip_type,
}
void
gimp_transform_matrix_rotate (gint x1,
gint y1,
gint x2,
gint y2,
gimp_transform_matrix_flip_free (gint x,
gint y,
gint width,
gint height,
gdouble x1,
gdouble y1,
gdouble x2,
gdouble y2,
GimpMatrix3 *result)
{
gdouble angle;
gdouble dx, dy;
g_return_if_fail (result != NULL);
angle = atan2 (y2 - y1, x2 - x1);
dx = x - x1;
dy = (x1 + ((y2 - y1) / (x2 - x1) ) * x) - y1;
gimp_matrix3_identity (result);
gimp_matrix3_translate (result, dx, dy);
gimp_matrix3_rotate (result, -angle);
gimp_matrix3_scale (result, 1.0, -1.0);
gimp_matrix3_rotate (result, angle);
gimp_matrix3_translate (result, -dx, -dy);
}
void
gimp_transform_matrix_rotate (gint x,
gint y,
gint width,
gint height,
gdouble angle,
GimpMatrix3 *result)
{
gdouble cx;
gdouble cy;
gdouble center_x;
gdouble center_y;
cx = (gdouble) (x1 + x2) / 2.0;
cy = (gdouble) (y1 + y2) / 2.0;
g_return_if_fail (result != NULL);
center_x = (gdouble) x + (gdouble) width / 2.0;
center_y = (gdouble) y + (gdouble) height / 2.0;
gimp_matrix3_identity (result);
gimp_matrix3_translate (result, -cx, -cy);
gimp_matrix3_translate (result, -center_x, -center_y);
gimp_matrix3_rotate (result, angle);
gimp_matrix3_translate (result, +cx, +cy);
gimp_matrix3_translate (result, +center_x, +center_y);
}
void
gimp_transform_matrix_rotate_center (gdouble cx,
gdouble cy,
gimp_transform_matrix_rotate_center (gdouble center_x,
gdouble center_y,
gdouble angle,
GimpMatrix3 *result)
{
g_return_if_fail (result != NULL);
gimp_matrix3_identity (result);
gimp_matrix3_translate (result, -cx, -cy);
gimp_matrix3_translate (result, -center_x, -center_y);
gimp_matrix3_rotate (result, angle);
gimp_matrix3_translate (result, +cx, +cy);
gimp_matrix3_translate (result, +center_x, +center_y);
}
void
gimp_transform_matrix_scale (gint x1,
gint y1,
gint x2,
gint y2,
gdouble tx1,
gdouble ty1,
gdouble tx2,
gdouble ty2,
gimp_transform_matrix_scale (gint x,
gint y,
gint width,
gint height,
gdouble t_x,
gdouble t_y,
gdouble t_width,
gdouble t_height,
GimpMatrix3 *result)
{
gdouble scalex;
gdouble scaley;
gdouble scale_x = 1.0;
gdouble scale_y = 1.0;
scalex = scaley = 1.0;
g_return_if_fail (result != NULL);
if ((x2 - x1) > 0)
scalex = (tx2 - tx1) / (gdouble) (x2 - x1);
if (width > 0)
scale_x = t_width / (gdouble) width;
if ((y2 - y1) > 0)
scaley = (ty2 - ty1) / (gdouble) (y2 - y1);
if (height > 0)
scale_y = t_height / (gdouble) height;
gimp_matrix3_identity (result);
gimp_matrix3_translate (result, -x1, -y1);
gimp_matrix3_scale (result, scalex, scaley);
gimp_matrix3_translate (result, tx1, ty1);
gimp_matrix3_translate (result, -x, -y);
gimp_matrix3_scale (result, scale_x, scale_y);
gimp_matrix3_translate (result, t_x, t_y);
}
void
gimp_transform_matrix_shear (gint x1,
gint y1,
gint x2,
gint y2,
gimp_transform_matrix_shear (gint x,
gint y,
gint width,
gint height,
GimpOrientationType orientation,
gdouble amount,
GimpMatrix3 *result)
{
gint width;
gint height;
gdouble cx;
gdouble cy;
gdouble center_x;
gdouble center_y;
width = x2 - x1;
height = y2 - y1;
g_return_if_fail (result != NULL);
if (width == 0)
width = 1;
if (height == 0)
height = 1;
cx = (gdouble) (x1 + x2) / 2.0;
cy = (gdouble) (y1 + y2) / 2.0;
center_x = (gdouble) x + (gdouble) width / 2.0;
center_y = (gdouble) y + (gdouble) height / 2.0;
gimp_matrix3_identity (result);
gimp_matrix3_translate (result, -cx, -cy);
gimp_matrix3_translate (result, -center_x, -center_y);
if (orientation == GIMP_ORIENTATION_HORIZONTAL)
gimp_matrix3_xshear (result, amount / height);
else
gimp_matrix3_yshear (result, amount / width);
gimp_matrix3_translate (result, +cx, +cy);
gimp_matrix3_translate (result, +center_x, +center_y);
}
void
gimp_transform_matrix_perspective (gint x1,
gint y1,
gint x2,
gint y2,
gdouble tx1,
gdouble ty1,
gdouble tx2,
gdouble ty2,
gdouble tx3,
gdouble ty3,
gdouble tx4,
gdouble ty4,
gimp_transform_matrix_perspective (gint x,
gint y,
gint width,
gint height,
gdouble t_x1,
gdouble t_y1,
gdouble t_x2,
gdouble t_y2,
gdouble t_x3,
gdouble t_y3,
gdouble t_x4,
gdouble t_y4,
GimpMatrix3 *result)
{
GimpMatrix3 matrix;
gdouble scalex;
gdouble scaley;
g_return_if_fail (result != NULL);
scalex = scaley = 1.0;
if ((x2 - x1) > 0)
scalex = 1.0 / (gdouble) (x2 - x1);
if (width > 0)
scalex = 1.0 / (gdouble) width;
if ((y2 - y1) > 0)
scaley = 1.0 / (gdouble) (y2 - y1);
if (height > 0)
scaley = 1.0 / (gdouble) height;
/* Determine the perspective transform that maps from
* the unit cube to the transformed coordinates
@ -182,23 +216,23 @@ gimp_transform_matrix_perspective (gint x1,
{
gdouble dx1, dx2, dx3, dy1, dy2, dy3;
dx1 = tx2 - tx4;
dx2 = tx3 - tx4;
dx3 = tx1 - tx2 + tx4 - tx3;
dx1 = t_x2 - t_x4;
dx2 = t_x3 - t_x4;
dx3 = t_x1 - t_x2 + t_x4 - t_x3;
dy1 = ty2 - ty4;
dy2 = ty3 - ty4;
dy3 = ty1 - ty2 + ty4 - ty3;
dy1 = t_y2 - t_y4;
dy2 = t_y3 - t_y4;
dy3 = t_y1 - t_y2 + t_y4 - t_y3;
/* Is the mapping affine? */
if ((dx3 == 0.0) && (dy3 == 0.0))
{
matrix.coeff[0][0] = tx2 - tx1;
matrix.coeff[0][1] = tx4 - tx2;
matrix.coeff[0][2] = tx1;
matrix.coeff[1][0] = ty2 - ty1;
matrix.coeff[1][1] = ty4 - ty2;
matrix.coeff[1][2] = ty1;
matrix.coeff[0][0] = t_x2 - t_x1;
matrix.coeff[0][1] = t_x4 - t_x2;
matrix.coeff[0][2] = t_x1;
matrix.coeff[1][0] = t_y2 - t_y1;
matrix.coeff[1][1] = t_y4 - t_y2;
matrix.coeff[1][2] = t_y1;
matrix.coeff[2][0] = 0.0;
matrix.coeff[2][1] = 0.0;
}
@ -221,20 +255,20 @@ gimp_transform_matrix_perspective (gint x1,
else
matrix.coeff[2][1] = det1 / det2;
matrix.coeff[0][0] = tx2 - tx1 + matrix.coeff[2][0] * tx2;
matrix.coeff[0][1] = tx3 - tx1 + matrix.coeff[2][1] * tx3;
matrix.coeff[0][2] = tx1;
matrix.coeff[0][0] = t_x2 - t_x1 + matrix.coeff[2][0] * t_x2;
matrix.coeff[0][1] = t_x3 - t_x1 + matrix.coeff[2][1] * t_x3;
matrix.coeff[0][2] = t_x1;
matrix.coeff[1][0] = ty2 - ty1 + matrix.coeff[2][0] * ty2;
matrix.coeff[1][1] = ty3 - ty1 + matrix.coeff[2][1] * ty3;
matrix.coeff[1][2] = ty1;
matrix.coeff[1][0] = t_y2 - t_y1 + matrix.coeff[2][0] * t_y2;
matrix.coeff[1][1] = t_y3 - t_y1 + matrix.coeff[2][1] * t_y3;
matrix.coeff[1][2] = t_y1;
}
matrix.coeff[2][2] = 1.0;
}
gimp_matrix3_identity (result);
gimp_matrix3_translate (result, -x1, -y1);
gimp_matrix3_translate (result, -x, -y);
gimp_matrix3_scale (result, scalex, scaley);
gimp_matrix3_mult (&matrix, result);
}

View File

@ -21,47 +21,56 @@
void gimp_transform_matrix_flip (GimpOrientationType flip_type,
gdouble axis,
GimpMatrix3 *result);
void gimp_transform_matrix_rotate (gint x1,
gint y1,
gint x2,
gint y2,
gdouble angle,
GimpMatrix3 *result);
void gimp_transform_matrix_rotate_center (gdouble cx,
gdouble cy,
gdouble angle,
GimpMatrix3 *result);
void gimp_transform_matrix_scale (gint x1,
gint y1,
gint x2,
gint y2,
gdouble tx1,
gdouble ty1,
gdouble tx2,
gdouble ty2,
GimpMatrix3 *result);
void gimp_transform_matrix_shear (gint x1,
gint y1,
gint x2,
gint y2,
gdouble axis,
GimpMatrix3 *result);
void gimp_transform_matrix_flip_free (gint x,
gint y,
gint width,
gint height,
gdouble x1,
gdouble y1,
gdouble x2,
gdouble y2,
GimpMatrix3 *result);
void gimp_transform_matrix_rotate (gint x,
gint y,
gint width,
gint height,
gdouble angle,
GimpMatrix3 *result);
void gimp_transform_matrix_rotate_center (gdouble center_x,
gdouble center_y,
gdouble angle,
GimpMatrix3 *result);
void gimp_transform_matrix_scale (gint x,
gint y,
gint width,
gint height,
gdouble t_x,
gdouble t_y,
gdouble t_width,
gdouble t_height,
GimpMatrix3 *result);
void gimp_transform_matrix_shear (gint x,
gint y,
gint width,
gint height,
GimpOrientationType orientation,
gdouble amount,
GimpMatrix3 *result);
void gimp_transform_matrix_perspective (gint x1,
gint y1,
gint x2,
gint y2,
gdouble tx1,
gdouble ty1,
gdouble tx2,
gdouble ty2,
gdouble tx3,
gdouble ty3,
gdouble tx4,
gdouble ty5,
GimpMatrix3 *result);
gdouble amount,
GimpMatrix3 *result);
void gimp_transform_matrix_perspective (gint x,
gint y,
gint width,
gint height,
gdouble t_x1,
gdouble t_y1,
gdouble t_x2,
gdouble t_y2,
gdouble t_x3,
gdouble t_y3,
gdouble t_x4,
gdouble t_y4,
GimpMatrix3 *result);
#endif /* __GIMP_TRANSFORM_UTILS_H__ */

View File

@ -44,6 +44,7 @@ static ProcRecord drawable_transform_rotate_proc;
static ProcRecord drawable_transform_scale_proc;
static ProcRecord drawable_transform_shear_proc;
static ProcRecord drawable_transform_2d_proc;
static ProcRecord drawable_transform_matrix_proc;
void
register_drawable_transform_procs (Gimp *gimp)
@ -55,6 +56,7 @@ register_drawable_transform_procs (Gimp *gimp)
procedural_db_register (gimp, &drawable_transform_scale_proc);
procedural_db_register (gimp, &drawable_transform_shear_proc);
procedural_db_register (gimp, &drawable_transform_2d_proc);
procedural_db_register (gimp, &drawable_transform_matrix_proc);
}
static Argument *
@ -105,14 +107,19 @@ drawable_transform_flip_invoker (Gimp *gimp,
if (success)
{
gint x, y, width, height;
success = gimp_item_is_attached (GIMP_ITEM (drawable));
if (success)
success = gimp_drawable_transform_flip (drawable,
context,
transform_direction,
center, axis,
clip_result);
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
success = gimp_drawable_transform_flip (drawable,
context,
transform_direction,
center, axis,
clip_result);
}
}
return_args = procedural_db_return_args (&drawable_transform_flip_proc, success);
@ -185,7 +192,7 @@ static ProcRecord drawable_transform_flip_proc =
{
"gimp_drawable_transform_flip",
"Flip the specified drawable either vertically or horizontally.",
"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 flipped. If center is set to true, the flip is around the image center. Otherwise, the coordinate of the axis needs to be specified. 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.",
"This procedure 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 flipped. If center is set to true, the flip is around the image center. Otherwise, the coordinate of the axis needs to be specified. 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.",
"João S. O. Bueno Calligaris",
"João S. O. Bueno Calligaris",
"2004",
@ -207,10 +214,10 @@ drawable_transform_flip_free_invoker (Gimp *gimp,
gboolean success = TRUE;
Argument *return_args;
GimpDrawable *drawable;
gdouble x0;
gdouble y0;
gdouble x1;
gdouble y1;
gdouble x2;
gdouble y2;
gint32 transform_direction;
gint32 interpolation;
gboolean supersample;
@ -221,13 +228,13 @@ drawable_transform_flip_free_invoker (Gimp *gimp,
if (! (GIMP_IS_DRAWABLE (drawable) && ! gimp_item_is_removed (GIMP_ITEM (drawable))))
success = FALSE;
x1 = args[1].value.pdb_float;
x0 = args[1].value.pdb_float;
y1 = args[2].value.pdb_float;
y0 = args[2].value.pdb_float;
x2 = args[3].value.pdb_float;
x1 = args[3].value.pdb_float;
y2 = args[4].value.pdb_float;
y1 = args[4].value.pdb_float;
transform_direction = args[5].value.pdb_int;
if (transform_direction < GIMP_TRANSFORM_FORWARD || transform_direction > GIMP_TRANSFORM_BACKWARD)
@ -247,44 +254,34 @@ drawable_transform_flip_free_invoker (Gimp *gimp,
if (success)
{
gint x, y, width, height;
success = gimp_item_is_attached (GIMP_ITEM (drawable));
if (success)
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
gint x, y, width, height;
GimpMatrix3 matrix;
if (gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
gdouble angle;
gdouble dx, dy;
GimpMatrix3 matrix;
/* Assemble the transformation matrix */
gimp_transform_matrix_flip_free (x, y, width, height,
x0, y0, x1, y1,
&matrix);
angle = atan2 ((y2 - y1), (x2 - x1));
dx = x - x1;
dy = (x1 + ( (gdouble) (y2 - y1) / (x2 - x1) ) * x ) - y1;
if (progress)
gimp_progress_start (progress, _("Flip..."), FALSE);
gimp_matrix3_identity (&matrix);
gimp_matrix3_translate (&matrix, dx, dy);
gimp_matrix3_rotate (&matrix, -angle);
gimp_matrix3_scale (&matrix, 1.0, -1.0);
gimp_matrix3_rotate (&matrix, angle);
gimp_matrix3_translate (&matrix, -dx, -dy);
if (progress)
gimp_progress_start (progress, _("Flip..."), FALSE);
/* Transform the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
transform_direction,
interpolation,
supersample,
recursion_level,
clip_result,
progress);
if (progress)
gimp_progress_end (progress);
}
/* Transform the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
transform_direction,
interpolation,
supersample,
recursion_level,
clip_result,
progress);
if (progress)
gimp_progress_end (progress);
}
}
@ -305,22 +302,22 @@ static ProcArg drawable_transform_flip_free_inargs[] =
},
{
GIMP_PDB_FLOAT,
"x1",
"x0",
"horz. coord. of one end of axis"
},
{
GIMP_PDB_FLOAT,
"y1",
"y0",
"vert. coord. of one end of axis"
},
{
GIMP_PDB_FLOAT,
"x2",
"x1",
"horz. coord. of other end of axis"
},
{
GIMP_PDB_FLOAT,
"y2",
"y1",
"vert. coord. of other end of axis"
},
{
@ -363,7 +360,7 @@ static ProcRecord drawable_transform_flip_free_proc =
{
"gimp_drawable_transform_flip_free",
"Flip the specified drawable around a given line.",
"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 flipped. The axis to flip around is specified by specifying two points from that line. 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 clip results parameter specifies wheter current selection will affect the transform.",
"This procedure 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 flipped. The axis to flip around is specified by specifying two points from that line. 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 clip results parameter specifies wheter current selection will affect the transform.",
"João S. O. Bueno Calligaris",
"João S. O. Bueno Calligaris",
"2004",
@ -430,39 +427,37 @@ drawable_transform_perspective_invoker (Gimp *gimp,
if (success)
{
gint x, y, width, height;
success = gimp_item_is_attached (GIMP_ITEM (drawable));
if (success)
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
gint x, y, width, height;
GimpMatrix3 matrix;
if (gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
GimpMatrix3 matrix;
/* Assemble the transformation matrix */
gimp_transform_matrix_perspective (x, y, width, height,
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);
/* Assemble the transformation matrix */
gimp_transform_matrix_perspective (x, y, x + width, y + height,
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 (progress)
gimp_progress_start (progress, _("Perspective..."), FALSE);
if (progress)
gimp_progress_start (progress, _("Perspective..."), FALSE);
/* Perspective the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
transform_direction,
interpolation, supersample,
recursion_level,
clip_result,
progress);
/* Perspective the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
transform_direction,
interpolation, supersample,
recursion_level,
clip_result,
progress);
if (progress)
gimp_progress_end (progress);
}
if (progress)
gimp_progress_end (progress);
}
}
@ -561,7 +556,7 @@ static ProcRecord drawable_transform_perspective_proc =
{
"gimp_drawable_transform_perspective",
"Perform a possibly non-affine transformation on the specified drawable, with extra parameters.",
"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 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.",
"This procedure 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 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.",
"João S. O. Bueno Calligaris",
"João S. O. Bueno Calligaris",
"2004",
@ -584,8 +579,8 @@ drawable_transform_rotate_invoker (Gimp *gimp,
Argument *return_args;
GimpDrawable *drawable;
gdouble angle;
gint32 cx;
gint32 cy;
gint32 center_x;
gint32 center_y;
gint32 transform_direction;
gint32 interpolation;
gboolean supersample;
@ -598,9 +593,9 @@ drawable_transform_rotate_invoker (Gimp *gimp,
angle = args[1].value.pdb_float;
cx = args[2].value.pdb_int;
center_x = args[2].value.pdb_int;
cy = args[3].value.pdb_int;
center_y = args[3].value.pdb_int;
transform_direction = args[4].value.pdb_int;
if (transform_direction < GIMP_TRANSFORM_FORWARD || transform_direction > GIMP_TRANSFORM_BACKWARD)
@ -620,14 +615,18 @@ drawable_transform_rotate_invoker (Gimp *gimp,
if (success)
{
gint x, y, width, height;
success = gimp_item_is_attached (GIMP_ITEM (drawable));
if (success)
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
GimpMatrix3 matrix;
GimpMatrix3 matrix;
/* Assemble the transformation matrix */
gimp_transform_matrix_rotate_center (cx, cy, angle, &matrix);
gimp_transform_matrix_rotate_center (center_x, center_y, angle,
&matrix);
if (progress)
gimp_progress_start (progress, _("Rotating..."), FALSE);
@ -666,12 +665,12 @@ static ProcArg drawable_transform_rotate_inargs[] =
},
{
GIMP_PDB_INT32,
"cx",
"center_x",
"The hor. coordinate of the center of rotation"
},
{
GIMP_PDB_INT32,
"cy",
"center_y",
"The vert. coordinate of the center of rotation"
},
{
@ -714,7 +713,7 @@ static ProcRecord drawable_transform_rotate_proc =
{
"gimp_drawable_transform_rotate",
"Rotate the specified drawable about given coordinates through the specified angle.",
"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 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.",
"This function 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 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.",
"João S. O. Bueno Calligaris",
"João S. O. Bueno Calligaris",
"2004",
@ -773,38 +772,38 @@ drawable_transform_scale_invoker (Gimp *gimp,
if (success)
{
gint x, y, width, height;
success = (gimp_item_is_attached (GIMP_ITEM (drawable)) &&
trans_info[X0] < trans_info[X1] &&
trans_info[Y0] < trans_info[X1]);
if (success)
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
gint x, y, width, height;
GimpMatrix3 matrix;
if (gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
GimpMatrix3 matrix;
/* Assemble the transformation matrix */
gimp_transform_matrix_scale (x, y, width, height,
trans_info[X0],
trans_info[Y0],
trans_info[X1] - trans_info[X0],
trans_info[Y1] - trans_info[Y0],
&matrix);
/* Assemble the transformation matrix */
gimp_transform_matrix_scale (x, y, x + width, y + height,
trans_info[X0], trans_info[Y0],
trans_info[X1], trans_info[Y1],
&matrix);
if (progress)
gimp_progress_start (progress, _("Scaling..."), FALSE);
if (progress)
gimp_progress_start (progress, _("Scaling..."), FALSE);
/* Scale the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
transform_direction,
interpolation, supersample,
recursion_level,
clip_result, progress);
/* Scale the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
transform_direction,
interpolation, supersample,
recursion_level,
clip_result, progress);
if (progress)
gimp_progress_end (progress);
}
if (progress)
gimp_progress_end (progress);
}
}
@ -883,7 +882,7 @@ static ProcRecord drawable_transform_scale_proc =
{
"gimp_drawable_transform_scale",
"Scale the specified drawable with extra parameters",
"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 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.",
"This procedure 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 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.",
"João S. O. Bueno Calligaris",
"João S. O. Bueno Calligaris",
"2004",
@ -941,35 +940,33 @@ drawable_transform_shear_invoker (Gimp *gimp,
if (success)
{
gint x, y, width, height;
success = gimp_item_is_attached (GIMP_ITEM (drawable));
if (success)
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
gint x, y, width, height;
GimpMatrix3 matrix;
if (gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
GimpMatrix3 matrix;
/* Assemble the transformation matrix */
gimp_transform_matrix_shear (x, y, width, height,
shear_type, magnitude,
&matrix);
/* Assemble the transformation matrix */
gimp_transform_matrix_shear (x, y, x + width, y + height,
shear_type, magnitude,
&matrix);
if (progress)
gimp_progress_start (progress, _("Shearing..."), FALSE);
if (progress)
gimp_progress_start (progress, _("Shearing..."), FALSE);
/* Shear the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
transform_direction,
interpolation, supersample,
recursion_level,
clip_result, progress);
/* Shear the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
transform_direction,
interpolation, supersample,
recursion_level,
clip_result, progress);
if (progress)
gimp_progress_end (progress);
}
if (progress)
gimp_progress_end (progress);
}
}
@ -1038,7 +1035,7 @@ static ProcRecord drawable_transform_shear_proc =
{
"gimp_drawable_transform_shear",
"Shear the specified drawable about its center by the specified magnitude, with extra parameters.",
"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 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.",
"This procedure 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 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.",
"João S. O. Bueno Calligaris",
"João S. O. Bueno Calligaris",
"2004",
@ -1109,11 +1106,14 @@ drawable_transform_2d_invoker (Gimp *gimp,
if (success)
{
gint x, y, width, height;
success = gimp_item_is_attached (GIMP_ITEM (drawable));
if (success)
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
GimpMatrix3 matrix;
GimpMatrix3 matrix;
/* Assemble the transformation matrix */
gimp_matrix3_identity (&matrix);
@ -1227,7 +1227,7 @@ static ProcRecord drawable_transform_2d_proc =
{
"gimp_drawable_transform_2d",
"Transform the specified drawable in 2d, with extra parameters.",
"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 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.",
"This procedure 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 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.",
"João S. O. Bueno Calligaris",
"João S. O. Bueno Calligaris",
"2004",
@ -1239,3 +1239,215 @@ static ProcRecord drawable_transform_2d_proc =
drawable_transform_2d_outargs,
{ { drawable_transform_2d_invoker } }
};
static Argument *
drawable_transform_matrix_invoker (Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
Argument *args)
{
gboolean success = TRUE;
Argument *return_args;
GimpDrawable *drawable;
gdouble coeff_0_0;
gdouble coeff_0_1;
gdouble coeff_0_2;
gdouble coeff_1_0;
gdouble coeff_1_1;
gdouble coeff_1_2;
gdouble coeff_2_0;
gdouble coeff_2_1;
gdouble coeff_2_2;
gint32 transform_direction;
gint32 interpolation;
gboolean supersample;
gint32 recursion_level;
gboolean clip_result;
drawable = (GimpDrawable *) gimp_item_get_by_ID (gimp, args[0].value.pdb_int);
if (! (GIMP_IS_DRAWABLE (drawable) && ! gimp_item_is_removed (GIMP_ITEM (drawable))))
success = FALSE;
coeff_0_0 = args[1].value.pdb_float;
coeff_0_1 = args[2].value.pdb_float;
coeff_0_2 = args[3].value.pdb_float;
coeff_1_0 = args[4].value.pdb_float;
coeff_1_1 = args[5].value.pdb_float;
coeff_1_2 = args[6].value.pdb_float;
coeff_2_0 = args[7].value.pdb_float;
coeff_2_1 = args[8].value.pdb_float;
coeff_2_2 = args[9].value.pdb_float;
transform_direction = args[10].value.pdb_int;
if (transform_direction < GIMP_TRANSFORM_FORWARD || transform_direction > GIMP_TRANSFORM_BACKWARD)
success = FALSE;
interpolation = args[11].value.pdb_int;
if (interpolation < GIMP_INTERPOLATION_NONE || interpolation > GIMP_INTERPOLATION_CUBIC)
success = FALSE;
supersample = args[12].value.pdb_int ? TRUE : FALSE;
recursion_level = args[13].value.pdb_int;
if (recursion_level <= 0)
success = FALSE;
clip_result = args[14].value.pdb_int ? TRUE : FALSE;
if (success)
{
gint x, y, width, height;
success = gimp_item_is_attached (GIMP_ITEM (drawable));
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
GimpMatrix3 matrix;
/* Assemble the transformation matrix */
matrix.coeff[0][0] = coeff_0_0;
matrix.coeff[0][1] = coeff_0_1;
matrix.coeff[0][2] = coeff_0_2;
matrix.coeff[1][0] = coeff_1_0;
matrix.coeff[1][1] = coeff_1_1;
matrix.coeff[1][2] = coeff_1_2;
matrix.coeff[2][0] = coeff_2_0;
matrix.coeff[2][1] = coeff_2_1;
matrix.coeff[2][2] = coeff_2_2;
if (progress)
gimp_progress_start (progress, _("2D Transform..."), FALSE);
/* Transform the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix, transform_direction,
interpolation, supersample,
recursion_level,
clip_result, progress);
if (progress)
gimp_progress_end (progress);
}
}
return_args = procedural_db_return_args (&drawable_transform_matrix_proc, success);
if (success)
return_args[1].value.pdb_int = gimp_item_get_ID (GIMP_ITEM (drawable));
return return_args;
}
static ProcArg drawable_transform_matrix_inargs[] =
{
{
GIMP_PDB_DRAWABLE,
"drawable",
"The affected drawable"
},
{
GIMP_PDB_FLOAT,
"coeff_0_0",
"coefficient (0,0) of the transformation matrix"
},
{
GIMP_PDB_FLOAT,
"coeff_0_1",
"coefficient (0,1) of the transformation matrix"
},
{
GIMP_PDB_FLOAT,
"coeff_0_2",
"coefficient (0,2) of the transformation matrix"
},
{
GIMP_PDB_FLOAT,
"coeff_1_0",
"coefficient (1,0) of the transformation matrix"
},
{
GIMP_PDB_FLOAT,
"coeff_1_1",
"coefficient (1,1) of the transformation matrix"
},
{
GIMP_PDB_FLOAT,
"coeff_1_2",
"coefficient (1,2) of the transformation matrix"
},
{
GIMP_PDB_FLOAT,
"coeff_2_0",
"coefficient (2,0) of the transformation matrix"
},
{
GIMP_PDB_FLOAT,
"coeff_2_1",
"coefficient (2,1) of the transformation matrix"
},
{
GIMP_PDB_FLOAT,
"coeff_2_2",
"coefficient (2,2) of the transformation matrix"
},
{
GIMP_PDB_INT32,
"transform_direction",
"Direction of Transformation: { GIMP_TRANSFORM_FORWARD (0), GIMP_TRANSFORM_BACKWARD (1) }"
},
{
GIMP_PDB_INT32,
"interpolation",
"Type of interpolation: { GIMP_INTERPOLATION_NONE (0), GIMP_INTERPOLATION_LINEAR (1), GIMP_INTERPOLATION_CUBIC (2) }"
},
{
GIMP_PDB_INT32,
"supersample",
"Whether to perform supersample"
},
{
GIMP_PDB_INT32,
"recursion_level",
"Level of recursion (3 is a nice default)"
},
{
GIMP_PDB_INT32,
"clip_result",
"Whether to clip results"
}
};
static ProcArg drawable_transform_matrix_outargs[] =
{
{
GIMP_PDB_DRAWABLE,
"drawable",
"The transformed drawable"
}
};
static ProcRecord drawable_transform_matrix_proc =
{
"gimp_drawable_transform_matrix",
"Transform the specified drawable in 2d, with extra parameters.",
"This procedure 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 transformation is done by assembling a 3x3 matrix from the coefficients passed. 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.",
"João S. O. Bueno Calligaris",
"João S. O. Bueno Calligaris",
"2004",
NULL,
GIMP_INTERNAL,
15,
drawable_transform_matrix_inargs,
1,
drawable_transform_matrix_outargs,
{ { drawable_transform_matrix_invoker } }
};

View File

@ -74,7 +74,7 @@ void register_transform_tools_procs (Gimp *gimp);
void register_undo_procs (Gimp *gimp);
void register_unit_procs (Gimp *gimp);
/* 420 procedures registered total */
/* 421 procedures registered total */
void
internal_procs_init (Gimp *gimp,
@ -101,67 +101,67 @@ internal_procs_init (Gimp *gimp,
(* status_callback) (NULL, _("Context"), 0.095);
register_context_procs (gimp);
(* status_callback) (NULL, _("Convert"), 0.148);
(* status_callback) (NULL, _("Convert"), 0.147);
register_convert_procs (gimp);
(* status_callback) (NULL, _("Display procedures"), 0.155);
(* status_callback) (NULL, _("Display procedures"), 0.154);
register_display_procs (gimp);
(* status_callback) (NULL, _("Drawable procedures"), 0.164);
register_drawable_procs (gimp);
(* status_callback) (NULL, _("Transformation procedures"), 0.243);
(* status_callback) (NULL, _("Transformation procedures"), 0.242);
register_drawable_transform_procs (gimp);
(* status_callback) (NULL, _("Edit procedures"), 0.26);
(* status_callback) (NULL, _("Edit procedures"), 0.261);
register_edit_procs (gimp);
(* status_callback) (NULL, _("File Operations"), 0.279);
(* status_callback) (NULL, _("File Operations"), 0.28);
register_fileops_procs (gimp);
(* status_callback) (NULL, _("Floating selections"), 0.3);
(* status_callback) (NULL, _("Floating selections"), 0.302);
register_floating_sel_procs (gimp);
(* status_callback) (NULL, _("Font UI"), 0.314);
(* status_callback) (NULL, _("Font UI"), 0.316);
register_font_select_procs (gimp);
(* status_callback) (NULL, _("Fonts"), 0.321);
(* status_callback) (NULL, _("Fonts"), 0.323);
register_fonts_procs (gimp);
(* status_callback) (NULL, _("Gimprc procedures"), 0.326);
(* status_callback) (NULL, _("Gimprc procedures"), 0.328);
register_gimprc_procs (gimp);
(* status_callback) (NULL, _("Gradient"), 0.34);
(* status_callback) (NULL, _("Gradient"), 0.342);
register_gradient_procs (gimp);
(* status_callback) (NULL, _("Gradient UI"), 0.41);
(* status_callback) (NULL, _("Gradient UI"), 0.411);
register_gradient_select_procs (gimp);
(* status_callback) (NULL, _("Gradients"), 0.417);
(* status_callback) (NULL, _("Gradients"), 0.418);
register_gradients_procs (gimp);
(* status_callback) (NULL, _("Guide procedures"), 0.429);
(* status_callback) (NULL, _("Guide procedures"), 0.43);
register_guides_procs (gimp);
(* status_callback) (NULL, _("Help procedures"), 0.443);
(* status_callback) (NULL, _("Help procedures"), 0.444);
register_help_procs (gimp);
(* status_callback) (NULL, _("Image"), 0.445);
(* status_callback) (NULL, _("Image"), 0.447);
register_image_procs (gimp);
(* status_callback) (NULL, _("Layer"), 0.593);
(* status_callback) (NULL, _("Layer"), 0.594);
register_layer_procs (gimp);
(* status_callback) (NULL, _("Message procedures"), 0.655);
(* status_callback) (NULL, _("Message procedures"), 0.656);
register_message_procs (gimp);
(* status_callback) (NULL, _("Miscellaneous"), 0.662);
(* status_callback) (NULL, _("Miscellaneous"), 0.663);
register_misc_procs (gimp);
(* status_callback) (NULL, _("Paint Tool procedures"), 0.667);
register_paint_tools_procs (gimp);
(* status_callback) (NULL, _("Palette"), 0.702);
(* status_callback) (NULL, _("Palette"), 0.703);
register_palette_procs (gimp);
(* status_callback) (NULL, _("Palette UI"), 0.729);
@ -170,7 +170,7 @@ internal_procs_init (Gimp *gimp,
(* status_callback) (NULL, _("Palettes"), 0.736);
register_palettes_procs (gimp);
(* status_callback) (NULL, _("Parasite procedures"), 0.745);
(* status_callback) (NULL, _("Parasite procedures"), 0.746);
register_parasite_procs (gimp);
(* status_callback) (NULL, _("Paths"), 0.774);
@ -179,10 +179,10 @@ internal_procs_init (Gimp *gimp,
(* status_callback) (NULL, _("Pattern"), 0.81);
register_pattern_procs (gimp);
(* status_callback) (NULL, _("Pattern UI"), 0.814);
(* status_callback) (NULL, _("Pattern UI"), 0.815);
register_pattern_select_procs (gimp);
(* status_callback) (NULL, _("Patterns"), 0.821);
(* status_callback) (NULL, _("Patterns"), 0.822);
register_patterns_procs (gimp);
(* status_callback) (NULL, _("Plug-in"), 0.831);
@ -191,7 +191,7 @@ internal_procs_init (Gimp *gimp,
(* status_callback) (NULL, _("Procedural database"), 0.843);
register_procedural_db_procs (gimp);
(* status_callback) (NULL, _("Progress"), 0.864);
(* status_callback) (NULL, _("Progress"), 0.865);
register_progress_procs (gimp);
(* status_callback) (NULL, _("Image mask"), 0.876);
@ -203,7 +203,7 @@ internal_procs_init (Gimp *gimp,
(* status_callback) (NULL, _("Text procedures"), 0.931);
register_text_tool_procs (gimp);
(* status_callback) (NULL, _("Transform Tool procedures"), 0.94);
(* status_callback) (NULL, _("Transform Tool procedures"), 0.941);
register_transform_tools_procs (gimp);
(* status_callback) (NULL, _("Undo"), 0.955);

View File

@ -76,11 +76,16 @@ flip_invoker (Gimp *gimp,
if (success)
{
gint x, y, width, height;
success = gimp_item_is_attached (GIMP_ITEM (drawable));
if (success)
success = gimp_drawable_transform_flip (drawable, context,
flip_type, TRUE, 0.0, FALSE);
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
success = gimp_drawable_transform_flip (drawable, context,
flip_type, TRUE, 0.0, FALSE);
}
}
return_args = procedural_db_return_args (&flip_proc, success);
@ -167,43 +172,39 @@ perspective_invoker (Gimp *gimp,
if (success)
{
gint x, y, width, height;
success = gimp_item_is_attached (GIMP_ITEM (drawable));
if (success)
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
gint x, y, width, height;
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type = GIMP_INTERPOLATION_NONE;
if (gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type;
/* Assemble the transformation matrix */
gimp_transform_matrix_perspective (x, y, width, height,
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);
/* Assemble the transformation matrix */
gimp_transform_matrix_perspective (x, y, x + width, y + height,
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;
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
else
interpolation_type = GIMP_INTERPOLATION_NONE;
if (progress)
gimp_progress_start (progress, _("Perspective..."), FALSE);
if (progress)
gimp_progress_start (progress, _("Perspective..."), FALSE);
/* Perspective the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
GIMP_TRANSFORM_FORWARD,
interpolation_type, TRUE, 3,
FALSE, progress);
/* Perspective the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
GIMP_TRANSFORM_FORWARD,
interpolation_type, TRUE, 3,
FALSE, progress);
if (progress)
gimp_progress_end (progress);
}
if (progress)
gimp_progress_end (progress);
}
}
@ -318,39 +319,35 @@ rotate_invoker (Gimp *gimp,
if (success)
{
gint x, y, width, height;
success = gimp_item_is_attached (GIMP_ITEM (drawable));
if (success)
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
gint x, y, width, height;
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type = GIMP_INTERPOLATION_NONE;
if (gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type;
/* Assemble the transformation matrix */
gimp_transform_matrix_rotate (x, y, width, height,
angle, &matrix);
/* Assemble the transformation matrix */
gimp_transform_matrix_rotate (x, y, x + width, y + height,
angle, &matrix);
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
else
interpolation_type = GIMP_INTERPOLATION_NONE;
if (progress)
gimp_progress_start (progress, _("Rotating..."), FALSE);
if (progress)
gimp_progress_start (progress, _("Rotating..."), FALSE);
/* Rotate the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
GIMP_TRANSFORM_FORWARD,
interpolation_type, FALSE, 3,
FALSE, progress);
/* Rotate the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
GIMP_TRANSFORM_FORWARD,
interpolation_type, FALSE, 3,
FALSE, progress);
if (progress)
gimp_progress_end (progress);
}
if (progress)
gimp_progress_end (progress);
}
}
@ -435,43 +432,41 @@ scale_invoker (Gimp *gimp,
if (success)
{
gint x, y, width, height;
success = (gimp_item_is_attached (GIMP_ITEM (drawable)) &&
trans_info[X0] < trans_info[X1] &&
trans_info[Y0] < trans_info[X1]);
if (success)
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
gint x, y, width, height;
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type = GIMP_INTERPOLATION_NONE;
if (gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type;
/* Assemble the transformation matrix */
gimp_transform_matrix_scale (x, y, width, height,
trans_info[X0],
trans_info[Y0],
trans_info[X1] - trans_info[X0],
trans_info[Y1] - trans_info[Y0],
&matrix);
/* Assemble the transformation matrix */
gimp_transform_matrix_scale (x, y, x + width, y + height,
trans_info[X0], trans_info[Y0],
trans_info[X1], trans_info[Y1],
&matrix);
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
else
interpolation_type = GIMP_INTERPOLATION_NONE;
if (progress)
gimp_progress_start (progress, _("Scaling..."), FALSE);
if (progress)
gimp_progress_start (progress, _("Scaling..."), FALSE);
/* Scale the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
GIMP_TRANSFORM_FORWARD,
interpolation_type, TRUE, 3,
FALSE, progress);
/* Scale the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
GIMP_TRANSFORM_FORWARD,
interpolation_type, TRUE, 3,
FALSE, progress);
if (progress)
gimp_progress_end (progress);
}
if (progress)
gimp_progress_end (progress);
}
}
@ -570,40 +565,36 @@ shear_invoker (Gimp *gimp,
if (success)
{
gint x, y, width, height;
success = gimp_item_is_attached (GIMP_ITEM (drawable));
if (success)
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
gint x, y, width, height;
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type = GIMP_INTERPOLATION_NONE;
if (gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type;
/* Assemble the transformation matrix */
gimp_transform_matrix_shear (x, y, width, height,
shear_type, magnitude,
&matrix);
/* Assemble the transformation matrix */
gimp_transform_matrix_shear (x, y, x + width, y + height,
shear_type, magnitude,
&matrix);
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
else
interpolation_type = GIMP_INTERPOLATION_NONE;
if (progress)
gimp_progress_start (progress, _("Shearing..."), FALSE);
if (progress)
gimp_progress_start (progress, _("Shearing..."), FALSE);
/* Shear the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
GIMP_TRANSFORM_FORWARD,
interpolation_type, FALSE, 3,
FALSE, progress);
/* Shear the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
GIMP_TRANSFORM_FORWARD,
interpolation_type, FALSE, 3,
FALSE, progress);
if (progress)
gimp_progress_end (progress);
}
if (progress)
gimp_progress_end (progress);
}
}
@ -705,12 +696,15 @@ transform_2d_invoker (Gimp *gimp,
if (success)
{
gint x, y, width, height;
success = gimp_item_is_attached (GIMP_ITEM (drawable));
if (success)
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type;
GimpInterpolationType interpolation_type = GIMP_INTERPOLATION_NONE;
/* Assemble the transformation matrix */
gimp_matrix3_identity (&matrix);
@ -721,8 +715,6 @@ transform_2d_invoker (Gimp *gimp,
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
else
interpolation_type = GIMP_INTERPOLATION_NONE;
if (progress)
gimp_progress_start (progress, _("2D Transform..."), FALSE);

View File

@ -239,8 +239,8 @@ gimp_perspective_tool_recalc (GimpTransformTool *tr_tool,
{
gimp_transform_matrix_perspective (tr_tool->x1,
tr_tool->y1,
tr_tool->x2,
tr_tool->y2,
tr_tool->x2 - tr_tool->x1,
tr_tool->y2 - tr_tool->y1,
tr_tool->trans_info[X0],
tr_tool->trans_info[Y0],
tr_tool->trans_info[X1],

View File

@ -477,12 +477,12 @@ gimp_scale_tool_recalc (GimpTransformTool *tr_tool,
{
gimp_transform_matrix_scale (tr_tool->x1,
tr_tool->y1,
tr_tool->x2,
tr_tool->y2,
tr_tool->x2 - tr_tool->x1,
tr_tool->y2 - tr_tool->y1,
tr_tool->trans_info[X0],
tr_tool->trans_info[Y0],
tr_tool->trans_info[X1],
tr_tool->trans_info[Y1],
tr_tool->trans_info[X1] - tr_tool->trans_info[X0],
tr_tool->trans_info[Y1] - tr_tool->trans_info[Y0],
&tr_tool->transform);
}

View File

@ -294,8 +294,8 @@ gimp_shear_tool_recalc (GimpTransformTool *tr_tool,
gimp_transform_matrix_shear (tr_tool->x1,
tr_tool->y1,
tr_tool->x2,
tr_tool->y2,
tr_tool->x2 - tr_tool->x1,
tr_tool->y2 - tr_tool->y1,
tr_tool->trans_info[HORZ_OR_VERT],
amount,
&tr_tool->transform);

View File

@ -39,9 +39,9 @@
*
* Flip the specified drawable either vertically or horizontally.
*
* 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
* This procedure 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 flipped. If center is set to true, the flip
* is around the image center. Otherwise, the coordinate of the axis
* needs to be specified. The return value is the ID of the flipped
@ -92,10 +92,10 @@ gimp_drawable_transform_flip (gint32 drawable_ID,
/**
* gimp_drawable_transform_flip_free:
* @drawable_ID: The affected drawable.
* @x1: horz. coord. of one end of axis.
* @y1: vert. coord. of one end of axis.
* @x2: horz. coord. of other end of axis.
* @y2: vert. coord. of other end of axis.
* @x0: horz. coord. of one end of axis.
* @y0: vert. coord. of one end of axis.
* @x1: horz. coord. of other end of axis.
* @y1: vert. coord. of other end of axis.
* @transform_direction: Direction of Transformation.
* @interpolation: Type of interpolation.
* @supersample: Whether to perform supersample.
@ -104,9 +104,9 @@ gimp_drawable_transform_flip (gint32 drawable_ID,
*
* Flip the specified drawable around a given line.
*
* 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
* This procedure 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 flipped. The axis to flip around is
* specified by specifying two points from that line. The return value
* is the ID of the flipped drawable. If there was no selection, this
@ -121,10 +121,10 @@ gimp_drawable_transform_flip (gint32 drawable_ID,
*/
gint32
gimp_drawable_transform_flip_free (gint32 drawable_ID,
gdouble x0,
gdouble y0,
gdouble x1,
gdouble y1,
gdouble x2,
gdouble y2,
GimpTransformDirection transform_direction,
GimpInterpolationType interpolation,
gboolean supersample,
@ -138,10 +138,10 @@ gimp_drawable_transform_flip_free (gint32 drawable_ID,
return_vals = gimp_run_procedure ("gimp_drawable_transform_flip_free",
&nreturn_vals,
GIMP_PDB_DRAWABLE, drawable_ID,
GIMP_PDB_FLOAT, x0,
GIMP_PDB_FLOAT, y0,
GIMP_PDB_FLOAT, x1,
GIMP_PDB_FLOAT, y1,
GIMP_PDB_FLOAT, x2,
GIMP_PDB_FLOAT, y2,
GIMP_PDB_INT32, transform_direction,
GIMP_PDB_INT32, interpolation,
GIMP_PDB_INT32, supersample,
@ -177,7 +177,7 @@ gimp_drawable_transform_flip_free (gint32 drawable_ID,
* Perform a possibly non-affine transformation on the specified
* drawable, with extra parameters.
*
* This tool performs a possibly non-affine transformation on the
* This procedure 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,
@ -247,8 +247,8 @@ gimp_drawable_transform_perspective (gint32 drawable_ID,
* gimp_drawable_transform_rotate:
* @drawable_ID: The affected drawable.
* @angle: The angle of rotation (radians).
* @cx: The hor. coordinate of the center of rotation.
* @cy: The vert. coordinate of the center of rotation.
* @center_x: The hor. coordinate of the center of rotation.
* @center_y: The vert. coordinate of the center of rotation.
* @transform_direction: Direction of Transformation.
* @interpolation: Type of interpolation.
* @supersample: Whether to perform supersample.
@ -258,9 +258,9 @@ gimp_drawable_transform_perspective (gint32 drawable_ID,
* Rotate the specified drawable about given coordinates through the
* specified angle.
*
* 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
* This function 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 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,
@ -273,8 +273,8 @@ gimp_drawable_transform_perspective (gint32 drawable_ID,
gint32
gimp_drawable_transform_rotate (gint32 drawable_ID,
gdouble angle,
gint cx,
gint cy,
gint center_x,
gint center_y,
GimpTransformDirection transform_direction,
GimpInterpolationType interpolation,
gboolean supersample,
@ -289,8 +289,8 @@ gimp_drawable_transform_rotate (gint32 drawable_ID,
&nreturn_vals,
GIMP_PDB_DRAWABLE, drawable_ID,
GIMP_PDB_FLOAT, angle,
GIMP_PDB_INT32, cx,
GIMP_PDB_INT32, cy,
GIMP_PDB_INT32, center_x,
GIMP_PDB_INT32, center_y,
GIMP_PDB_INT32, transform_direction,
GIMP_PDB_INT32, interpolation,
GIMP_PDB_INT32, supersample,
@ -321,9 +321,9 @@ gimp_drawable_transform_rotate (gint32 drawable_ID,
*
* Scale the specified drawable with extra parameters
*
* 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
* This procedure 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 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,
@ -385,9 +385,9 @@ gimp_drawable_transform_scale (gint32 drawable_ID,
* Shear the specified drawable about its center by the specified
* magnitude, with extra parameters.
*
* 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
* This procedure 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 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,
@ -452,14 +452,14 @@ gimp_drawable_transform_shear (gint32 drawable_ID,
*
* Transform the specified drawable in 2d, with extra parameters.
*
* 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 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
* This procedure 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 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.
*
@ -510,3 +510,84 @@ gimp_drawable_transform_2d (gint32 drawable_ID,
return ret_drawable_ID;
}
/**
* gimp_drawable_transform_matrix:
* @drawable_ID: The affected drawable.
* @coeff_0_0: coefficient (0,0) of the transformation matrix.
* @coeff_0_1: coefficient (0,1) of the transformation matrix.
* @coeff_0_2: coefficient (0,2) of the transformation matrix.
* @coeff_1_0: coefficient (1,0) of the transformation matrix.
* @coeff_1_1: coefficient (1,1) of the transformation matrix.
* @coeff_1_2: coefficient (1,2) of the transformation matrix.
* @coeff_2_0: coefficient (2,0) of the transformation matrix.
* @coeff_2_1: coefficient (2,1) of the transformation matrix.
* @coeff_2_2: coefficient (2,2) of the transformation matrix.
* @transform_direction: Direction of Transformation.
* @interpolation: Type of interpolation.
* @supersample: Whether to perform supersample.
* @recursion_level: Level of recursion (3 is a nice default).
* @clip_result: Whether to clip results.
*
* Transform the specified drawable in 2d, with extra parameters.
*
* This procedure 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 transformation is
* done by assembling a 3x3 matrix from the coefficients passed. 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.
*
* Returns: The transformed drawable.
*
* Since: GIMP 2.2
*/
gint32
gimp_drawable_transform_matrix (gint32 drawable_ID,
gdouble coeff_0_0,
gdouble coeff_0_1,
gdouble coeff_0_2,
gdouble coeff_1_0,
gdouble coeff_1_1,
gdouble coeff_1_2,
gdouble coeff_2_0,
gdouble coeff_2_1,
gdouble coeff_2_2,
GimpTransformDirection transform_direction,
GimpInterpolationType interpolation,
gboolean supersample,
gint recursion_level,
gboolean clip_result)
{
GimpParam *return_vals;
gint nreturn_vals;
gint32 ret_drawable_ID = -1;
return_vals = gimp_run_procedure ("gimp_drawable_transform_matrix",
&nreturn_vals,
GIMP_PDB_DRAWABLE, drawable_ID,
GIMP_PDB_FLOAT, coeff_0_0,
GIMP_PDB_FLOAT, coeff_0_1,
GIMP_PDB_FLOAT, coeff_0_2,
GIMP_PDB_FLOAT, coeff_1_0,
GIMP_PDB_FLOAT, coeff_1_1,
GIMP_PDB_FLOAT, coeff_1_2,
GIMP_PDB_FLOAT, coeff_2_0,
GIMP_PDB_FLOAT, coeff_2_1,
GIMP_PDB_FLOAT, coeff_2_2,
GIMP_PDB_INT32, transform_direction,
GIMP_PDB_INT32, interpolation,
GIMP_PDB_INT32, supersample,
GIMP_PDB_INT32, recursion_level,
GIMP_PDB_INT32, clip_result,
GIMP_PDB_END);
if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
ret_drawable_ID = return_vals[1].data.d_drawable;
gimp_destroy_params (return_vals, nreturn_vals);
return ret_drawable_ID;
}

View File

@ -39,10 +39,10 @@ gint32 gimp_drawable_transform_flip (gint32 drawable_ID,
gint recursion_level,
gboolean clip_result);
gint32 gimp_drawable_transform_flip_free (gint32 drawable_ID,
gdouble x0,
gdouble y0,
gdouble x1,
gdouble y1,
gdouble x2,
gdouble y2,
GimpTransformDirection transform_direction,
GimpInterpolationType interpolation,
gboolean supersample,
@ -64,8 +64,8 @@ gint32 gimp_drawable_transform_perspective (gint32 drawable_ID,
gboolean clip_result);
gint32 gimp_drawable_transform_rotate (gint32 drawable_ID,
gdouble angle,
gint cx,
gint cy,
gint center_x,
gint center_y,
GimpTransformDirection transform_direction,
GimpInterpolationType interpolation,
gboolean supersample,
@ -102,6 +102,21 @@ gint32 gimp_drawable_transform_2d (gint32 drawable_ID,
gboolean supersample,
gint recursion_level,
gboolean clip_result);
gint32 gimp_drawable_transform_matrix (gint32 drawable_ID,
gdouble coeff_0_0,
gdouble coeff_0_1,
gdouble coeff_0_2,
gdouble coeff_1_0,
gdouble coeff_1_1,
gdouble coeff_1_2,
gdouble coeff_2_0,
gdouble coeff_2_1,
gdouble coeff_2_2,
GimpTransformDirection transform_direction,
GimpInterpolationType interpolation,
gboolean supersample,
gint recursion_level,
gboolean clip_result);
G_END_DECLS

View File

@ -78,11 +78,12 @@ Flip the specified drawable 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 flipped.
If center is set to true, the flip is around the image center. Otherwise,
the coordinate of the axis needs to be specified.
This procedure 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 flipped. If center is set to true, the flip is around
the image center. Otherwise, the coordinate of the axis needs to be
specified.
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.
@ -109,14 +110,19 @@ HELP
%invoke = (
code => <<'CODE'
{
gint x, y, width, height;
success = gimp_item_is_attached (GIMP_ITEM (drawable));
if (success)
success = gimp_drawable_transform_flip (drawable,
context,
transform_direction,
center, axis,
clip_result);
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
success = gimp_drawable_transform_flip (drawable,
context,
transform_direction,
center, axis,
clip_result);
}
}
CODE
);
@ -129,10 +135,11 @@ Flip the specified drawable around a given line.
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 flipped. The
axis to flip around is specified by specifying two points from that line.
This procedure 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 flipped. The axis to flip around is specified by
specifying two points from that line.
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.
@ -144,13 +151,13 @@ HELP
@inargs = (
&drawable_arg,
{ name => 'x1', type => 'float',
{ name => 'x0', type => 'float',
desc => 'horz. coord. of one end of axis' },
{ name => 'y1', type => 'float',
{ name => 'y0', type => 'float',
desc => 'vert. coord. of one end of axis' },
{ name => 'x2', type => 'float',
{ name => 'x1', type => 'float',
desc => 'horz. coord. of other end of axis' },
{ name => 'y2', type => 'float',
{ name => 'y1', type => 'float',
desc => 'vert. coord. of other end of axis' },
&transform_options_args,
@ -162,44 +169,34 @@ HELP
%invoke = (
code => <<'CODE'
{
gint x, y, width, height;
success = gimp_item_is_attached (GIMP_ITEM (drawable));
if (success)
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
gint x, y, width, height;
GimpMatrix3 matrix;
if (gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
gdouble angle;
gdouble dx, dy;
GimpMatrix3 matrix;
/* Assemble the transformation matrix */
gimp_transform_matrix_flip_free (x, y, width, height,
x0, y0, x1, y1,
&matrix);
angle = atan2 ((y2 - y1), (x2 - x1));
dx = x - x1;
dy = (x1 + ( (gdouble) (y2 - y1) / (x2 - x1) ) * x ) - y1;
if (progress)
gimp_progress_start (progress, _("Flip..."), FALSE);
gimp_matrix3_identity (&matrix);
gimp_matrix3_translate (&matrix, dx, dy);
gimp_matrix3_rotate (&matrix, -angle);
gimp_matrix3_scale (&matrix, 1.0, -1.0);
gimp_matrix3_rotate (&matrix, angle);
gimp_matrix3_translate (&matrix, -dx, -dy);
if (progress)
gimp_progress_start (progress, _("Flip..."), FALSE);
/* Transform the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
transform_direction,
interpolation,
supersample,
recursion_level,
clip_result,
progress);
if (progress)
gimp_progress_end (progress);
}
/* Transform the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
transform_direction,
interpolation,
supersample,
recursion_level,
clip_result,
progress);
if (progress)
gimp_progress_end (progress);
}
}
CODE
@ -213,19 +210,21 @@ Perform a possibly non-affine transformation on the specified drawable, with ext
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 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
This procedure 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 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.
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
&pdb_misc;
@ -256,39 +255,37 @@ HELP
vars => [ 'gdouble trans_info[8]' ],
code => <<'CODE'
{
gint x, y, width, height;
success = gimp_item_is_attached (GIMP_ITEM (drawable));
if (success)
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
gint x, y, width, height;
GimpMatrix3 matrix;
if (gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
GimpMatrix3 matrix;
/* Assemble the transformation matrix */
gimp_transform_matrix_perspective (x, y, width, height,
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);
/* Assemble the transformation matrix */
gimp_transform_matrix_perspective (x, y, x + width, y + height,
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 (progress)
gimp_progress_start (progress, _("Perspective..."), FALSE);
if (progress)
gimp_progress_start (progress, _("Perspective..."), FALSE);
/* Perspective the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
transform_direction,
interpolation, supersample,
recursion_level,
clip_result,
progress);
/* Perspective the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
transform_direction,
interpolation, supersample,
recursion_level,
clip_result,
progress);
if (progress)
gimp_progress_end (progress);
}
if (progress)
gimp_progress_end (progress);
}
}
CODE
@ -301,12 +298,13 @@ Rotate the specified drawable about given coordinates through the specified angl
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 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.
This function 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 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
&pdb_misc;
@ -315,9 +313,9 @@ HELP
&drawable_arg,
{ name => 'angle', type => 'float',
desc => 'The angle of rotation (radians)' },
{ name => 'cx', type => 'int32',
{ name => 'center_x', type => 'int32',
desc => 'The hor. coordinate of the center of rotation' },
{ name => 'cy', type => 'int32',
{ name => 'center_y', type => 'int32',
desc => 'The vert. coordinate of the center of rotation' },
&transform_options_args,
&clip_result_arg
@ -328,14 +326,18 @@ HELP
%invoke = (
code => <<'CODE'
{
gint x, y, width, height;
success = gimp_item_is_attached (GIMP_ITEM (drawable));
if (success)
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
GimpMatrix3 matrix;
GimpMatrix3 matrix;
/* Assemble the transformation matrix */
gimp_transform_matrix_rotate_center (cx, cy, angle, &matrix);
gimp_transform_matrix_rotate_center (center_x, center_y, angle,
&matrix);
if (progress)
gimp_progress_start (progress, _("Rotating..."), FALSE);
@ -359,12 +361,13 @@ sub drawable_transform_scale {
$blurb = 'Scale the specified drawable with extra parameters';
$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 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.
This procedure 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 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
&pdb_misc;
@ -396,38 +399,38 @@ HELP
vars => [ 'gdouble trans_info[4]' ],
code => <<'CODE'
{
gint x, y, width, height;
success = (gimp_item_is_attached (GIMP_ITEM (drawable)) &&
trans_info[X0] < trans_info[X1] &&
trans_info[Y0] < trans_info[X1]);
if (success)
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
gint x, y, width, height;
GimpMatrix3 matrix;
if (gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
GimpMatrix3 matrix;
/* Assemble the transformation matrix */
gimp_transform_matrix_scale (x, y, width, height,
trans_info[X0],
trans_info[Y0],
trans_info[X1] - trans_info[X0],
trans_info[Y1] - trans_info[Y0],
&matrix);
/* Assemble the transformation matrix */
gimp_transform_matrix_scale (x, y, x + width, y + height,
trans_info[X0], trans_info[Y0],
trans_info[X1], trans_info[Y1],
&matrix);
if (progress)
gimp_progress_start (progress, _("Scaling..."), FALSE);
if (progress)
gimp_progress_start (progress, _("Scaling..."), FALSE);
/* Scale the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
transform_direction,
interpolation, supersample,
recursion_level,
clip_result, progress);
/* Scale the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
transform_direction,
interpolation, supersample,
recursion_level,
clip_result, progress);
if (progress)
gimp_progress_end (progress);
}
if (progress)
gimp_progress_end (progress);
}
}
CODE
@ -440,15 +443,16 @@ Shear the specified drawable about its center by the specified magnitude, with e
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 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.
This procedure 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 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
&pdb_misc;
@ -468,35 +472,33 @@ HELP
%invoke = (
code => <<'CODE'
{
gint x, y, width, height;
success = gimp_item_is_attached (GIMP_ITEM (drawable));
if (success)
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
gint x, y, width, height;
if (gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
GimpMatrix3 matrix;
GimpMatrix3 matrix;
/* Assemble the transformation matrix */
gimp_transform_matrix_shear (x, y, x + width, y + height,
shear_type, magnitude,
&matrix);
/* Assemble the transformation matrix */
gimp_transform_matrix_shear (x, y, width, height,
shear_type, magnitude,
&matrix);
if (progress)
gimp_progress_start (progress, _("Shearing..."), FALSE);
if (progress)
gimp_progress_start (progress, _("Shearing..."), FALSE);
/* Shear the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
transform_direction,
interpolation, supersample,
recursion_level,
clip_result, progress);
/* Shear the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
transform_direction,
interpolation, supersample,
recursion_level,
clip_result, progress);
if (progress)
gimp_progress_end (progress);
}
if (progress)
gimp_progress_end (progress);
}
}
CODE
@ -510,15 +512,17 @@ Transform the specified drawable in 2d, with extra parameters.
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 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.
This procedure 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 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
&pdb_misc;
@ -548,11 +552,14 @@ HELP
%invoke = (
code => <<'CODE'
{
gint x, y, width, height;
success = gimp_item_is_attached (GIMP_ITEM (drawable));
if (success)
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
GimpMatrix3 matrix;
GimpMatrix3 matrix;
/* Assemble the transformation matrix */
gimp_matrix3_identity (&matrix);
@ -579,6 +586,91 @@ CODE
);
}
sub drawable_transform_matrix {
$blurb = <<'BLURB';
Transform the specified drawable in 2d, with extra parameters.
BLURB
$help = <<'HELP';
This procedure 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 transformation is done by
assembling a 3x3 matrix from the coefficients passed. 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
&pdb_misc;
@inargs = (
&drawable_arg,
{ name => 'coeff_0_0', type => 'float',
desc => 'coefficient (0,0) of the transformation matrix' },
{ name => 'coeff_0_1', type => 'float',
desc => 'coefficient (0,1) of the transformation matrix' },
{ name => 'coeff_0_2', type => 'float',
desc => 'coefficient (0,2) of the transformation matrix' },
{ name => 'coeff_1_0', type => 'float',
desc => 'coefficient (1,0) of the transformation matrix' },
{ name => 'coeff_1_1', type => 'float',
desc => 'coefficient (1,1) of the transformation matrix' },
{ name => 'coeff_1_2', type => 'float',
desc => 'coefficient (1,2) of the transformation matrix' },
{ name => 'coeff_2_0', type => 'float',
desc => 'coefficient (2,0) of the transformation matrix' },
{ name => 'coeff_2_1', type => 'float',
desc => 'coefficient (2,1) of the transformation matrix' },
{ name => 'coeff_2_2', type => 'float',
desc => 'coefficient (2,2) of the transformation matrix' },
&transform_options_args,
&clip_result_arg
);
@outargs = ( &drawable_out_arg('transformed') );
%invoke = (
code => <<'CODE'
{
gint x, y, width, height;
success = gimp_item_is_attached (GIMP_ITEM (drawable));
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
GimpMatrix3 matrix;
/* Assemble the transformation matrix */
matrix.coeff[0][0] = coeff_0_0;
matrix.coeff[0][1] = coeff_0_1;
matrix.coeff[0][2] = coeff_0_2;
matrix.coeff[1][0] = coeff_1_0;
matrix.coeff[1][1] = coeff_1_1;
matrix.coeff[1][2] = coeff_1_2;
matrix.coeff[2][0] = coeff_2_0;
matrix.coeff[2][1] = coeff_2_1;
matrix.coeff[2][2] = coeff_2_2;
if (progress)
gimp_progress_start (progress, _("2D Transform..."), FALSE);
/* Transform the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix, transform_direction,
interpolation, supersample,
recursion_level,
clip_result, progress);
if (progress)
gimp_progress_end (progress);
}
}
CODE
);
}
@headers = qw("libgimpmath/gimpmath.h" "config/gimpcoreconfig.h"
"core/gimp.h" "core/gimp-transform-utils.h" "core/gimpimage.h"
"core/gimpdrawable.h" "core/gimpdrawable-transform.h"
@ -588,7 +680,8 @@ CODE
@procs = qw(drawable_transform_flip drawable_transform_flip_free
drawable_transform_perspective
drawable_transform_rotate drawable_transform_scale
drawable_transform_shear drawable_transform_2d);
drawable_transform_shear drawable_transform_2d
drawable_transform_matrix);
%exports = (app => [@procs], lib => [@procs]);

View File

@ -68,11 +68,16 @@ HELP
%invoke = (
code => <<'CODE'
{
gint x, y, width, height;
success = gimp_item_is_attached (GIMP_ITEM (drawable));
if (success)
success = gimp_drawable_transform_flip (drawable, context,
flip_type, TRUE, 0.0, FALSE);
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
success = gimp_drawable_transform_flip (drawable, context,
flip_type, TRUE, 0.0, FALSE);
}
}
CODE
);
@ -127,43 +132,39 @@ HELP
vars => [ 'gdouble trans_info[8]' ],
code => <<'CODE'
{
gint x, y, width, height;
success = gimp_item_is_attached (GIMP_ITEM (drawable));
if (success)
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
gint x, y, width, height;
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type = GIMP_INTERPOLATION_NONE;
if (gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type;
/* Assemble the transformation matrix */
gimp_transform_matrix_perspective (x, y, width, height,
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);
/* Assemble the transformation matrix */
gimp_transform_matrix_perspective (x, y, x + width, y + height,
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;
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
else
interpolation_type = GIMP_INTERPOLATION_NONE;
if (progress)
gimp_progress_start (progress, _("Perspective..."), FALSE);
if (progress)
gimp_progress_start (progress, _("Perspective..."), FALSE);
/* Perspective the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
GIMP_TRANSFORM_FORWARD,
interpolation_type, TRUE, 3,
FALSE, progress);
/* Perspective the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
GIMP_TRANSFORM_FORWARD,
interpolation_type, TRUE, 3,
FALSE, progress);
if (progress)
gimp_progress_end (progress);
}
if (progress)
gimp_progress_end (progress);
}
}
CODE
@ -201,39 +202,35 @@ HELP
%invoke = (
code => <<'CODE'
{
gint x, y, width, height;
success = gimp_item_is_attached (GIMP_ITEM (drawable));
if (success)
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
gint x, y, width, height;
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type = GIMP_INTERPOLATION_NONE;
if (gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type;
/* Assemble the transformation matrix */
gimp_transform_matrix_rotate (x, y, width, height,
angle, &matrix);
/* Assemble the transformation matrix */
gimp_transform_matrix_rotate (x, y, x + width, y + height,
angle, &matrix);
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
else
interpolation_type = GIMP_INTERPOLATION_NONE;
if (progress)
gimp_progress_start (progress, _("Rotating..."), FALSE);
if (progress)
gimp_progress_start (progress, _("Rotating..."), FALSE);
/* Rotate the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
GIMP_TRANSFORM_FORWARD,
interpolation_type, FALSE, 3,
FALSE, progress);
/* Rotate the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
GIMP_TRANSFORM_FORWARD,
interpolation_type, FALSE, 3,
FALSE, progress);
if (progress)
gimp_progress_end (progress);
}
if (progress)
gimp_progress_end (progress);
}
}
CODE
@ -280,43 +277,41 @@ HELP
vars => [ 'gdouble trans_info[4]' ],
code => <<'CODE'
{
gint x, y, width, height;
success = (gimp_item_is_attached (GIMP_ITEM (drawable)) &&
trans_info[X0] < trans_info[X1] &&
trans_info[Y0] < trans_info[X1]);
if (success)
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
gint x, y, width, height;
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type = GIMP_INTERPOLATION_NONE;
if (gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type;
/* Assemble the transformation matrix */
gimp_transform_matrix_scale (x, y, width, height,
trans_info[X0],
trans_info[Y0],
trans_info[X1] - trans_info[X0],
trans_info[Y1] - trans_info[Y0],
&matrix);
/* Assemble the transformation matrix */
gimp_transform_matrix_scale (x, y, x + width, y + height,
trans_info[X0], trans_info[Y0],
trans_info[X1], trans_info[Y1],
&matrix);
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
else
interpolation_type = GIMP_INTERPOLATION_NONE;
if (progress)
gimp_progress_start (progress, _("Scaling..."), FALSE);
if (progress)
gimp_progress_start (progress, _("Scaling..."), FALSE);
/* Scale the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
GIMP_TRANSFORM_FORWARD,
interpolation_type, TRUE, 3,
FALSE, progress);
/* Scale the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
GIMP_TRANSFORM_FORWARD,
interpolation_type, TRUE, 3,
FALSE, progress);
if (progress)
gimp_progress_end (progress);
}
if (progress)
gimp_progress_end (progress);
}
}
CODE
@ -359,40 +354,36 @@ HELP
%invoke = (
code => <<'CODE'
{
gint x, y, width, height;
success = gimp_item_is_attached (GIMP_ITEM (drawable));
if (success)
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
gint x, y, width, height;
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type = GIMP_INTERPOLATION_NONE;
if (gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type;
/* Assemble the transformation matrix */
gimp_transform_matrix_shear (x, y, width, height,
shear_type, magnitude,
&matrix);
/* Assemble the transformation matrix */
gimp_transform_matrix_shear (x, y, x + width, y + height,
shear_type, magnitude,
&matrix);
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
else
interpolation_type = GIMP_INTERPOLATION_NONE;
if (progress)
gimp_progress_start (progress, _("Shearing..."), FALSE);
if (progress)
gimp_progress_start (progress, _("Shearing..."), FALSE);
/* Shear the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
GIMP_TRANSFORM_FORWARD,
interpolation_type, FALSE, 3,
FALSE, progress);
/* Shear the selection */
success = gimp_drawable_transform_affine (drawable, context,
&matrix,
GIMP_TRANSFORM_FORWARD,
interpolation_type, FALSE, 3,
FALSE, progress);
if (progress)
gimp_progress_end (progress);
}
if (progress)
gimp_progress_end (progress);
}
}
CODE
@ -445,12 +436,15 @@ HELP
%invoke = (
code => <<'CODE'
{
gint x, y, width, height;
success = gimp_item_is_attached (GIMP_ITEM (drawable));
if (success)
if (success &&
gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
{
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type;
GimpInterpolationType interpolation_type = GIMP_INTERPOLATION_NONE;
/* Assemble the transformation matrix */
gimp_matrix3_identity (&matrix);
@ -461,8 +455,6 @@ HELP
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
else
interpolation_type = GIMP_INTERPOLATION_NONE;
if (progress)
gimp_progress_start (progress, _("2D Transform..."), FALSE);