Rotation command in PDB

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The current gimp_rotate procedure does not allow for rotation around an
arbitrary point even though its code is quite capable of it.  It just selects
the center of the image and uses that as the rotation origin.  I added a
gimp_rotate_around_point procedure and use it in all the scripts I'm
writing.  With the new procedure, you only need to select the region you wish
to rotate (just like the interactive rotate tool in the toolbox).  Below I've
included the source code additions I made to tools_cmds.c (I don't know how to
use diff and patch yet).  All I really did was copy the original rotate_invoker
and add X and Y center point parameters to it.  Obviously, the two procedures
could be written to reuse the same invoker code.


-Michael




/*
--Added declaration
*/

static ProcRecord rotate_around_point_proc;




/*
--Added register function call
*/

void
register_tools_procs (void)
{
  ...
  
  procedural_db_register (&rotate_around_point_proc);
  
  ...
}




/*
--Added new invoker
--It just gets its center point from the arguments and sets
--the return arguments to reference the correct PDB proc
*/

static Argument *
rotate_around_point_invoker (Argument *args)
{
  gboolean success = TRUE;
  Argument *return_args;
  GimpDrawable *drawable;
  gboolean interpolation;
  gdouble angle;
  GimpImage *gimage;
  TileManager *float_tiles, *new_tiles;
  gboolean new_layer;
  double cx, cy;
  GimpMatrix3 matrix;

  drawable = gimp_drawable_get_ID (args[0].value.pdb_int);
  if (drawable == NULL)
    success = FALSE;

  interpolation = args[1].value.pdb_int ? TRUE : FALSE;

  angle = args[2].value.pdb_float;

  if (success)
    {
      gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
    
      /* Start a transform undo group */
      undo_push_group_start (gimage, TRANSFORM_CORE_UNDO);
    
      /* Cut/Copy from the specified drawable */
      float_tiles = transform_core_cut (gimage, drawable, &new_layer);

	  /* get the center from the arguments passed in */
	  cx = args[3].value.pdb_int;
	  cy = args[4].value.pdb_int;

#if 0
      cx = float_tiles->x + float_tiles->width / 2.0;
      cy = float_tiles->y + float_tiles->height / 2.0;
#endif

      /* Assemble the transformation matrix */
      gimp_matrix3_identity  (matrix);
      gimp_matrix3_translate (matrix, -cx, -cy);
      gimp_matrix3_rotate    (matrix, angle);
      gimp_matrix3_translate (matrix, +cx, +cy);
    
      /* Rotate the buffer */
      new_tiles = rotate_tool_rotate (gimage, drawable, NULL, angle,
				      float_tiles, interpolation, matrix);
    
      /* Free the cut/copied buffer */
      tile_manager_destroy (float_tiles);
    
      if (new_tiles)
	success = transform_core_paste (gimage, drawable, new_tiles, new_layer);
      else
	success = FALSE;
    
      /* Push the undo group end */
      undo_push_group_end (gimage);
    }

  return_args = procedural_db_return_args (&rotate_around_point_proc, success);

  if (success)
    return_args[1].value.pdb_int = drawable_ID (GIMP_DRAWABLE (drawable));

  return return_args;
}




/*
--It gets its own input arguments
--Note: I reused the output argments since they are identical.
*/

static ProcArg rotate_around_point_inargs[] =
{
  {
    PDB_DRAWABLE,
    "drawable",
    "The affected drawable"
  },
  {
    PDB_INT32,
    "interpolation",
    "Whether to use interpolation"
  },
  {
    PDB_FLOAT,
    "angle",
    "The angle of rotation (radians)"
  },
  {
    PDB_INT32,
    "x",
    "the x coordinate of the point"
  },
  {
    PDB_INT32,
    "y",
    "the y coordinate of the point"
  }
};




/*
--Added the procedure info
*/

static ProcRecord rotate_around_point_proc =
{
  "gimp_rotate_around_point",
  "Rotate the specified drawable about a point 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 interpolation parameter can be set to TRUE to indicate that either linear or cubic interpolation should be used to smooth the resulting rotated drawable. The return value is the ID of the rotated drawable. If there was no selection, this will be equal to the drawable ID supplied as input. Otherwise, this will be the newly created and rotated drawable.",
  "Spencer Kimball & Peter Mattis",
  "Spencer Kimball & Peter Mattis",
  "1995-1996",
  PDB_INTERNAL,
  5,
  rotate_around_point_inargs,
  1,
  rotate_outargs,
  { { rotate_around_point_invoker } }
};



[Index of Archives]     [Video For Linux]     [Photo]     [Yosemite News]     [gtk]     [GIMP for Windows]     [KDE]     [GEGL]     [Gimp's Home]     [Gimp on GUI]     [Gimp on Windows]     [Steve's Art]

  Powered by Linux