From 57044c2f46c04791a8fde428dfd2396f8444b8ee Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Mon, 19 Nov 2001 18:23:43 +0000 Subject: [PATCH] forgot to commit last time. 2001-11-19 Michael Natterer * app/display/gimpdisplay-foreach.c: forgot to commit last time. Transform stuff cleanup: * app/core/Makefile.am * app/core/core-types.h * app/core/gimpdrawable-transform.[ch]: new files implementing the actual transform functions cut from tools/gimptransformtool.*. * app/core/gimpdrawable-transform-utils.[ch]: new files implementing transform matrix assembly utility functions. * app/tools/gimptransformtool.[ch]: removed the stuff here. cleanup. * app/tools/transform_options.[ch]: removed all stuff which does not belong here, e.g. the transform_tool_* functions and the global "transform_options" variable. Works like all other tool options now. * app/tools/gimpfliptool.[ch] * app/tools/gimpperspectivetool.[ch] * app/tools/gimprotatetool.[ch] * app/tools/gimpscaletool.[ch] * app/tools/gimpsheartool.[ch]: massive code removal because we can use core/gimpdrawable-fransform* functions now. cleanup. * tools/pdbgen/Makefile.am * tools/pdbgen/groups.pl: added new PDB group "transform_tools". * tools/pdbgen/pdb/tools.pdb: removed the transform stuff here... * tools/pdbgen/pdb/transform_tools.pdb: and added *much* simplified versions which use the new core/gimpdrawable-transform* utilities. * app/pdb/Makefile.am * app/pdb/transform_tools_cmds.c: new file. * app/pdb/internal_procs.c * app/pdb/tools_cmds.c: regenerated. * libgimp/Makefile.am * libgimp/gimp_pdb.h * libgimp/gimptransformtools_pdb.[ch]: new files. * libgimp/gimptools_pdb.[ch]: regenerated. --- ChangeLog | 49 + app/core/Makefile.am | 4 + app/core/core-types.h | 6 + app/core/gimp-transform-region.c | 1343 ++++------------------- app/core/gimp-transform-utils.c | 193 ++++ app/core/gimp-transform-utils.h | 60 + app/core/gimpdrawable-transform-utils.c | 193 ++++ app/core/gimpdrawable-transform-utils.h | 60 + app/core/gimpdrawable-transform.c | 1343 ++++------------------- app/core/gimpdrawable-transform.h | 64 ++ app/display/gimpdisplay-foreach.c | 4 +- app/tools/gimpfliptool.c | 141 +-- app/tools/gimpfliptool.h | 10 +- app/tools/gimpperspectivetool.c | 239 +--- app/tools/gimpperspectivetool.h | 14 +- app/tools/gimprotatetool.c | 240 ++-- app/tools/gimprotatetool.h | 12 +- app/tools/gimpscaletool.c | 374 +++---- app/tools/gimpscaletool.h | 12 +- app/tools/gimpsheartool.c | 222 ++-- app/tools/gimpsheartool.h | 12 +- app/tools/gimptransformoptions.c | 293 +++-- app/tools/gimptransformoptions.h | 47 +- app/tools/gimptransformtool.c | 1269 ++++++--------------- app/tools/gimptransformtool.h | 61 +- app/tools/transform_options.c | 293 +++-- app/tools/transform_options.h | 47 +- libgimp/Makefile.am | 2 + libgimp/gimp_pdb.h | 1 + libgimp/gimptools_pdb.c | 334 ------ libgimp/gimptools_pdb.h | 34 - libgimp/gimptransformtools_pdb.c | 358 ++++++ libgimp/gimptransformtools_pdb.h | 74 ++ tools/pdbgen/Makefile.am | 1 + tools/pdbgen/groups.pl | 1 + tools/pdbgen/pdb/misc_tools.pdb | 515 +-------- tools/pdbgen/pdb/paint_tools.pdb | 515 +-------- tools/pdbgen/pdb/tools.pdb | 515 +-------- tools/pdbgen/pdb/transform_tools.pdb | 1033 ++--------------- 39 files changed, 2647 insertions(+), 7341 deletions(-) create mode 100644 app/core/gimp-transform-utils.c create mode 100644 app/core/gimp-transform-utils.h create mode 100644 app/core/gimpdrawable-transform-utils.c create mode 100644 app/core/gimpdrawable-transform-utils.h create mode 100644 app/core/gimpdrawable-transform.h create mode 100644 libgimp/gimptransformtools_pdb.c create mode 100644 libgimp/gimptransformtools_pdb.h diff --git a/ChangeLog b/ChangeLog index f5b81abf73..95672b0574 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,52 @@ +2001-11-19 Michael Natterer + + * app/display/gimpdisplay-foreach.c: forgot to commit last time. + + Transform stuff cleanup: + + * app/core/Makefile.am + * app/core/core-types.h + * app/core/gimpdrawable-transform.[ch]: new files implementing + the actual transform functions cut from tools/gimptransformtool.*. + + * app/core/gimpdrawable-transform-utils.[ch]: new files implementing + transform matrix assembly utility functions. + + * app/tools/gimptransformtool.[ch]: removed the stuff here. cleanup. + + * app/tools/transform_options.[ch]: removed all stuff which does + not belong here, e.g. the transform_tool_* functions and the + global "transform_options" variable. Works like all other tool + options now. + + * app/tools/gimpfliptool.[ch] + * app/tools/gimpperspectivetool.[ch] + * app/tools/gimprotatetool.[ch] + * app/tools/gimpscaletool.[ch] + * app/tools/gimpsheartool.[ch]: massive code removal because + we can use core/gimpdrawable-fransform* functions now. cleanup. + + * tools/pdbgen/Makefile.am + * tools/pdbgen/groups.pl: added new PDB group "transform_tools". + + * tools/pdbgen/pdb/tools.pdb: removed the transform stuff here... + + * tools/pdbgen/pdb/transform_tools.pdb: and added *much* + simplified versions which use the new core/gimpdrawable-transform* + utilities. + + * app/pdb/Makefile.am + * app/pdb/transform_tools_cmds.c: new file. + + * app/pdb/internal_procs.c + * app/pdb/tools_cmds.c: regenerated. + + * libgimp/Makefile.am + * libgimp/gimp_pdb.h + * libgimp/gimptransformtools_pdb.[ch]: new files. + + * libgimp/gimptools_pdb.[ch]: regenerated. + 2001-11-19 Daniel Egger * app/paint-funcs/paint-funcs.c diff --git a/app/core/Makefile.am b/app/core/Makefile.am index 32f3edcd60..31841175d0 100644 --- a/app/core/Makefile.am +++ b/app/core/Makefile.am @@ -64,6 +64,10 @@ libappcore_a_sources = @STRIP_BEGIN@ \ gimpdrawable-offset.h \ gimpdrawable-preview.c \ gimpdrawable-preview.h \ + gimpdrawable-transform.c \ + gimpdrawable-transform.h \ + gimpdrawable-transform-utils.c \ + gimpdrawable-transform-utils.h \ gimpedit.c \ gimpedit.h \ gimpgradient.c \ diff --git a/app/core/core-types.h b/app/core/core-types.h index 678303b72c..9278a9f4bd 100644 --- a/app/core/core-types.h +++ b/app/core/core-types.h @@ -193,6 +193,12 @@ typedef enum REPEAT_TRIANGULAR } RepeatMode; +typedef enum /*< skip >*/ +{ + GIMP_TRANSFORM_FORWARD, + GIMP_TRANSFORM_BACKWARD +} GimpTransformDirection; + /* base objects */ diff --git a/app/core/gimp-transform-region.c b/app/core/gimp-transform-region.c index a775e89581..90c757063c 100644 --- a/app/core/gimp-transform-region.c +++ b/app/core/gimp-transform-region.c @@ -18,15 +18,11 @@ #include "config.h" -#include - -#include +#include #include "libgimpmath/gimpmath.h" -#include "libgimpwidgets/gimpwidgets.h" -#include "tools-types.h" -#include "gui/gui-types.h" +#include "core-types.h" #include "base/base-config.h" #include "base/pixel-region.h" @@ -36,57 +32,30 @@ #include "paint-funcs/paint-funcs.h" -#include "core/gimp.h" -#include "core/gimpchannel.h" -#include "core/gimpcontext.h" -#include "core/gimpdrawable.h" -#include "core/gimpimage.h" -#include "core/gimpimage-mask.h" -#include "core/gimplayer.h" -#include "core/gimpmarshal.h" -#include "core/gimptoolinfo.h" +#include "gimp.h" +#include "gimpchannel.h" +#include "gimpcontext.h" +#include "gimpdrawable.h" +#include "gimpdrawable-transform.h" +#include "gimpimage.h" +#include "gimpimage-mask.h" +#include "gimplayer.h" -#include "gui/info-dialog.h" - -#include "display/gimpdisplay.h" -#include "display/gimpdisplay-foreach.h" -#include "display/gimpdisplayshell.h" - -#include "tool_manager.h" -#include "tool_options.h" -#include "transform_options.h" -#include "gimptransformtool.h" -#include "gimpperspectivetool.h" -#include "gimprotatetool.h" -#include "gimpscaletool.h" -#include "gimpsheartool.h" -#include "gimpfliptool.h" - -#include "app_procs.h" #include "floating_sel.h" #include "undo.h" -#include "path_transform.h" #include "libgimp/gimpintl.h" -enum -{ - TRANSFORM, - LAST_SIGNAL -}; - -#define HANDLE 10 - #define BILINEAR(jk,j1k,jk1,j1k1,dx,dy) \ ((1-dy) * (jk + dx * (j1k - jk)) + \ dy * (jk1 + dx * (j1k1 - jk1))) /* access interleaved pixels */ #define CUBIC_ROW(dx, row, step) \ - gimp_transform_tool_cubic(dx, (row)[0], (row)[step], (row)[step+step], (row)[step+step+step]) + gimp_drawable_transform_cubic(dx, (row)[0], (row)[step], (row)[step+step], (row)[step+step+step]) #define CUBIC_SCALED_ROW(dx, row, step, i) \ - gimp_transform_tool_cubic(dx, (row)[0] * (row)[i], \ + gimp_drawable_transform_cubic(dx, (row)[0] * (row)[i], \ (row)[step] * (row)[step + i], \ (row)[step+step]* (row)[step+step + i], \ (row)[step+step+step] * (row)[step+step+step + i]) @@ -96,1059 +65,28 @@ enum src[i] = tile_data_pointer (tile[i], (x) % TILE_WIDTH, (y) % TILE_HEIGHT); -/* forward function declarations */ -static void gimp_transform_tool_bounds (GimpTransformTool *tool, - GimpDisplay *gdisp); -static void gimp_transform_tool_recalc (GimpTransformTool *tool, - GimpDisplay *gdisp); -static void gimp_transform_tool_doit (GimpTransformTool *tool, - GimpDisplay *gdisp); -static gdouble gimp_transform_tool_cubic (gdouble dx, - gint jm1, - gint j, - gint jp1, - gint jp2); -static void gimp_transform_tool_setup_grid (GimpTransformTool *tool); -static void gimp_transform_tool_grid_recalc (GimpTransformTool *gimp_transform_tool); -static void gimp_transform_tool_init (GimpTransformTool *tool); -static void gimp_transform_tool_class_init (GimpTransformToolClass *tool); +/* forward function prototypes */ -static void gimp_transform_tool_finalize (GObject *object); - -static void gimp_transform_tool_button_press (GimpTool *tool, - GimpCoords *coords, - guint32 time, - GdkModifierType state, - GimpDisplay *gdisp); - -static void gimp_transform_tool_button_release (GimpTool *tool, - GimpCoords *coords, - guint32 time, - GdkModifierType state, - GimpDisplay *gdisp); - -static void gimp_transform_tool_motion (GimpTool *tool, - GimpCoords *coords, - guint32 time, - GdkModifierType state, - GimpDisplay *gdisp); - -static void gimp_transform_tool_cursor_update (GimpTool *tool, - GimpCoords *coords, - GdkModifierType state, - GimpDisplay *gdisp); - -static void gimp_transform_tool_control (GimpTool *tool, - ToolAction action, - GimpDisplay *gdisp); - -static void gimp_transform_tool_draw (GimpDrawTool *draw_tool); +static gdouble gimp_drawable_transform_cubic (gdouble dx, + gint jm1, + gint j, + gint jp1, + gint jp2); -/* variables */ -static TranInfo old_trans_info; -InfoDialog *transform_info = NULL; -static gboolean transform_info_inited = FALSE; - -static GimpDrawToolClass *parent_class = NULL; - -static guint gimp_transform_tool_signals[LAST_SIGNAL] = { 0 }; - - -GType -gimp_transform_tool_get_type (void) -{ - static GType tool_type = 0; - - if (! tool_type) - { - static const GTypeInfo tool_info = - { - sizeof (GimpTransformToolClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) gimp_transform_tool_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (GimpTransformTool), - 0, /* n_preallocs */ - (GInstanceInitFunc) gimp_transform_tool_init, - }; - - tool_type = g_type_register_static (GIMP_TYPE_DRAW_TOOL, - "GimpTransformTool", - &tool_info, 0); - } - - return tool_type; -} - -static void -gimp_transform_tool_class_init (GimpTransformToolClass *klass) -{ - GObjectClass *object_class; - GimpToolClass *tool_class; - GimpDrawToolClass *draw_class; - - object_class = G_OBJECT_CLASS (klass); - tool_class = GIMP_TOOL_CLASS (klass); - draw_class = GIMP_DRAW_TOOL_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - gimp_transform_tool_signals[TRANSFORM] = - g_signal_new ("transform", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GimpTransformToolClass, transform), - NULL, NULL, - gimp_cclosure_marshal_POINTER__POINTER_INT, - G_TYPE_POINTER, 2, - G_TYPE_POINTER, - G_TYPE_INT); - - object_class->finalize = gimp_transform_tool_finalize; - - tool_class->control = gimp_transform_tool_control; - tool_class->button_press = gimp_transform_tool_button_press; - tool_class->button_release = gimp_transform_tool_button_release; - tool_class->motion = gimp_transform_tool_motion; - tool_class->cursor_update = gimp_transform_tool_cursor_update; - - draw_class->draw = gimp_transform_tool_draw; -} - -static void -gimp_transform_tool_init (GimpTransformTool *tr_tool) -{ - GimpTool *tool = GIMP_TOOL (tr_tool); - gint i; - - tr_tool->function = TRANSFORM_CREATING; - tr_tool->original = NULL; - - for (i = 0; i < TRAN_INFO_SIZE; i++) - tr_tool->trans_info[i] = 0; - - tr_tool->grid_coords = tr_tool->tgrid_coords = NULL; - - /* FIXME */ - tr_tool->interactive = TRUE; - - tool->scroll_lock = TRUE; /* Disallow scrolling */ - tool->preserve = FALSE; /* Don't preserve on drawable change */ - -} +/* public functions */ TileManager * -gimp_transform_tool_transform (GimpTransformTool *tool, - GimpDisplay *gdisp, - TransformState state) -{ - TileManager *retval; - - g_return_val_if_fail (tool, NULL); - g_return_val_if_fail (GIMP_IS_TRANSFORM_TOOL (tool), NULL); - - g_signal_emit (G_OBJECT (tool), gimp_transform_tool_signals[TRANSFORM], 0, - gdisp, state, &retval); - - return retval; -} - -static void -transform_ok_callback (GtkWidget *widget, - gpointer data) -{ - GimpTool *tool; - - tool = GIMP_TOOL(data); - gimp_transform_tool_doit (GIMP_TRANSFORM_TOOL(tool), tool->gdisp); -} - -static void -transform_reset_callback (GtkWidget *widget, - gpointer data) -{ - GimpTransformTool *tool; - GimpDrawTool *dr_tool; - gint i; - - tool = GIMP_TRANSFORM_TOOL (data); - dr_tool = GIMP_DRAW_TOOL (data); - - /* stop the current tool drawing process */ - gimp_draw_tool_pause (dr_tool); - - /* Restore the previous transformation info */ - for (i = 0; i < TRAN_INFO_SIZE; i++) - tool->trans_info [i] = old_trans_info [i]; - - /* recalculate the tool's transformation matrix */ - gimp_transform_tool_recalc (tool, GIMP_TOOL(tool)->gdisp); - - /* resume drawing the current tool */ - gimp_draw_tool_resume (dr_tool); -} - -static void -gimp_transform_tool_finalize (GObject *object) -{ - GimpTransformTool *tr_tool; - - tr_tool = GIMP_TRANSFORM_TOOL (object); - - if (tr_tool->original) - { - tile_manager_destroy (tr_tool->original); - tr_tool->original = NULL; - } - - if (transform_info) - { - info_dialog_free (transform_info); - transform_info = NULL; - transform_info_inited = FALSE; - } - - if (tr_tool->grid_coords) - { - g_free (tr_tool->grid_coords); - tr_tool->grid_coords = NULL; - } - - if (tr_tool->tgrid_coords) - { - g_free (tr_tool->tgrid_coords); - tr_tool->tgrid_coords = NULL; - } - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -gimp_transform_tool_control (GimpTool *tool, - ToolAction action, - GimpDisplay *gdisp) -{ - GimpDrawTool *dr_tool; - GimpTransformTool *tr_tool; - - dr_tool = GIMP_DRAW_TOOL (tool); - tr_tool = GIMP_TRANSFORM_TOOL (tool); - - switch (action) - { - case PAUSE: - break; - - case RESUME: - gimp_transform_tool_recalc (tr_tool, gdisp); - break; - - case HALT: - gimp_transform_tool_reset (tr_tool, gdisp); - break; - - default: - break; - } - - if (GIMP_TOOL_CLASS (parent_class)->control) - GIMP_TOOL_CLASS (parent_class)->control (tool, action, gdisp); -} - -static void -gimp_transform_tool_button_press (GimpTool *tool, - GimpCoords *coords, - guint32 time, - GdkModifierType state, - GimpDisplay *gdisp) -{ - GimpTransformTool *gt_tool; - GimpDrawTool *draw_tool; - GimpDisplayShell *shell; - GimpDrawable *drawable; - gdouble dist; - gdouble closest_dist; - gint i; - gint off_x, off_y; - - gt_tool = GIMP_TRANSFORM_TOOL (tool); - draw_tool = GIMP_DRAW_TOOL (tool); - - shell = GIMP_DISPLAY_SHELL (gdisp->shell); - - drawable = gimp_image_active_drawable (gdisp->gimage); - - if (gt_tool->function == TRANSFORM_CREATING && tool->state == ACTIVE) - { - /* Save the current transformation info */ - for (i = 0; i < TRAN_INFO_SIZE; i++) - old_trans_info [i] = gt_tool->trans_info [i]; - } - - /* if we have already displayed the bounding box and handles, - * check to make sure that the display which currently owns the - * tool is the one which just received the button pressed event - */ - if ((gdisp == tool->gdisp) && gt_tool->interactive) - { - /* start drawing the bounding box and handles... */ - gimp_draw_tool_start (GIMP_DRAW_TOOL (tool), shell->canvas->window); - - closest_dist = gimp_draw_tool_calc_distance (draw_tool, gdisp, - coords->x, coords->y, - gt_tool->tx1, gt_tool->ty1); - gt_tool->function = TRANSFORM_HANDLE_1; - - dist = gimp_draw_tool_calc_distance (draw_tool, gdisp, - coords->x, coords->y, - gt_tool->tx2, gt_tool->ty2); - if (dist < closest_dist) - { - closest_dist = dist; - gt_tool->function = TRANSFORM_HANDLE_2; - } - - dist = gimp_draw_tool_calc_distance (draw_tool, gdisp, - coords->x, coords->y, - gt_tool->tx3, gt_tool->ty3); - if (dist < closest_dist) - { - closest_dist = dist; - gt_tool->function = TRANSFORM_HANDLE_3; - } - - dist = gimp_draw_tool_calc_distance (draw_tool, gdisp, - coords->x, coords->y, - gt_tool->tx4, gt_tool->ty4); - if (dist < closest_dist) - { - closest_dist = dist; - gt_tool->function = TRANSFORM_HANDLE_4; - } - - if (gimp_draw_tool_on_handle (draw_tool, gdisp, - coords->x, coords->y, - GIMP_HANDLE_CIRCLE, - gt_tool->tcx, gt_tool->tcy, - HANDLE, HANDLE, - GIMP_HANDLE_CIRCLE, - FALSE)) - { - gt_tool->function = TRANSFORM_HANDLE_CENTER; - } - - /* Save the current pointer position */ - gt_tool->lastx = gt_tool->startx = coords->x; - gt_tool->lasty = gt_tool->starty = coords->y; - - gdk_pointer_grab (shell->canvas->window, FALSE, - GDK_POINTER_MOTION_HINT_MASK | - GDK_BUTTON1_MOTION_MASK | - GDK_BUTTON_RELEASE_MASK, - NULL, NULL, time); - - tool->state = ACTIVE; - return; - } - - /* Initialisation stuff: if the cursor is clicked inside the current - * selection, show the bounding box and handles... - */ - gimp_drawable_offsets (drawable, &off_x, &off_y); - - if (coords->x >= off_x && - coords->y >= off_y && - coords->x < (off_x + gimp_drawable_width (drawable)) && - coords->y < (off_y + gimp_drawable_height (drawable))) - { - if (gimage_mask_is_empty (gdisp->gimage) || - gimage_mask_value (gdisp->gimage, coords->x, coords->y)) - { - if (GIMP_IS_LAYER (drawable) && - gimp_layer_get_mask (GIMP_LAYER (drawable))) - { - g_message (_("Transformations do not work on\n" - "layers that contain layer masks.")); - tool->state = INACTIVE; - return; - } - - /* If the tool is already active, clear the current state - * and reset - */ - if (tool->state == ACTIVE) - gimp_transform_tool_reset (gt_tool, gdisp); - - /* Set the pointer to the active display */ - tool->gdisp = gdisp; - tool->drawable = drawable; - tool->state = ACTIVE; - - /* Grab the pointer if we're in non-interactive mode */ - if (! gt_tool->interactive) - gdk_pointer_grab (shell->canvas->window, FALSE, - GDK_POINTER_MOTION_HINT_MASK | - GDK_BUTTON1_MOTION_MASK | - GDK_BUTTON_RELEASE_MASK, - NULL, NULL, time); - - /* Find the transform bounds for some tools (like scale, - * perspective) that actually need the bounds for - * initializing - */ - gimp_transform_tool_bounds (gt_tool, gdisp); - - /* Initialize the transform tool */ - gimp_transform_tool_transform (gt_tool, gdisp, TRANSFORM_INIT); - - if (transform_info && !transform_info_inited) - { - GType tool_type; - - tool_type = - gimp_context_get_tool (gimp_get_user_context (gdisp->gimage->gimp))->tool_type; - - gimp_dialog_create_action_area - (GIMP_DIALOG (transform_info->shell), - - /* FIXME: this does not belong here */ - (tool_type == GIMP_TYPE_ROTATE_TOOL) ? _("Rotate") : - (tool_type == GIMP_TYPE_SCALE_TOOL) ? _("Scale") : - (tool_type == GIMP_TYPE_SHEAR_TOOL) ? _("Shear") : - (tool_type == GIMP_TYPE_PERSPECTIVE_TOOL) ? _("Transform") : - "EEK", - transform_ok_callback, - tool, NULL, NULL, TRUE, FALSE, - - _("Reset"), transform_reset_callback, - tool, NULL, NULL, FALSE, FALSE, - - NULL); - - transform_info_inited = TRUE; - } - - /* Recalculate the transform tool */ - gimp_transform_tool_recalc (gt_tool, gdisp); - - /* recall this function to find which handle we're dragging */ - if (gt_tool->interactive) - gimp_transform_tool_button_press (tool, coords, time, state, gdisp); - } - } -} - -static void -gimp_transform_tool_button_release (GimpTool *tool, - GimpCoords *coords, - guint32 time, - GdkModifierType state, - GimpDisplay *gdisp) -{ - GimpTransformTool *gt_tool; - gint i; - - gt_tool = GIMP_TRANSFORM_TOOL (tool); - - /* if we are creating, there is nothing to be done...exit */ - if (gt_tool->function == TRANSFORM_CREATING && gt_tool->interactive) - return; - - /* release of the pointer grab */ - gdk_pointer_ungrab (time); - gdk_flush (); - - /* if the 3rd button isn't pressed, transform the selected mask */ - if (! (state & GDK_BUTTON3_MASK)) - { - /* Shift-clicking is another way to approve the transform */ - if ((state & GDK_SHIFT_MASK) || GIMP_IS_FLIP_TOOL (tool)) - { - gimp_transform_tool_doit (gt_tool, gdisp); - } - else - { - /* Only update the paths preview */ - path_transform_current_path (gdisp->gimage, - gt_tool->transform, TRUE); - } - } - else - { - /* stop the current tool drawing process */ - gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool)); - - /* Restore the previous transformation info */ - for (i = 0; i < TRAN_INFO_SIZE; i++) - gt_tool->trans_info [i] = old_trans_info [i]; - - /* recalculate the tool's transformation matrix */ - gimp_transform_tool_recalc (gt_tool, gdisp); - - /* resume drawing the current tool */ - gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool)); - - /* Update the paths preview */ - path_transform_current_path (gdisp->gimage, - gt_tool->transform, TRUE); - } - - /* if this tool is non-interactive, make it inactive after use */ - if (! gt_tool->interactive) - tool->state = INACTIVE; -} - -static void -gimp_transform_tool_doit (GimpTransformTool *gt_tool, - GimpDisplay *gdisp) -{ - GimpDisplayShell *shell; - GimpTool *tool; - TileManager *new_tiles; - TransformUndo *tu; - PathUndo *pundo; - gboolean new_layer; - gint i; - - gimp_set_busy (gdisp->gimage->gimp); - - tool = GIMP_TOOL (gt_tool); - - shell = GIMP_DISPLAY_SHELL (gdisp->shell); - - /* undraw the tool before we muck around with the transform matrix */ - gimp_draw_tool_pause (GIMP_DRAW_TOOL (gt_tool)); - - /* We're going to dirty this image, but we want to keep the tool - * around - */ - tool->preserve = TRUE; - - /* Start a transform undo group */ - undo_push_group_start (gdisp->gimage, TRANSFORM_CORE_UNDO); - - /* With the old UI, if original is NULL, then this is the - * first transformation. In the new UI, it is always so, right? - */ - g_assert (gt_tool->original == NULL); - - /* If we're in interactive mode, we need to copy the current - * selection to the transform tool's private selection pointer, so - * that the original source can be repeatedly modified. - */ - tool->drawable = gimp_image_active_drawable (gdisp->gimage); - - gt_tool->original = gimp_transform_tool_cut (gdisp->gimage, - tool->drawable, - &new_layer); - - pundo = path_transform_start_undo (gdisp->gimage); - - /* Send the request for the transformation to the tool... - */ - new_tiles = gimp_transform_tool_transform (gt_tool, gdisp, - TRANSFORM_FINISH); - - gimp_transform_tool_transform (gt_tool, gdisp, TRANSFORM_INIT); - - gimp_transform_tool_recalc (gt_tool, gdisp); - - if (new_tiles) - { - /* paste the new transformed image to the gimage...also implement - * undo... - */ - /* FIXME: we should check if the drawable is still valid */ - gimp_transform_tool_paste (gdisp->gimage, tool->drawable, - new_tiles, new_layer); - - /* create and initialize the transform_undo structure */ - tu = g_new0 (TransformUndo, 1); - tu->tool_ID = tool->ID; - tu->tool_type = G_TYPE_FROM_INSTANCE (tool); - - for (i = 0; i < TRAN_INFO_SIZE; i++) - tu->trans_info[i] = old_trans_info[i]; - - tu->original = NULL; - tu->path_undo = pundo; - - /* Make a note of the new current drawable (since we may have - * a floating selection, etc now. - */ - tool->drawable = gimp_image_active_drawable (gdisp->gimage); - - undo_push_transform (gdisp->gimage, tu); - } - - /* push the undo group end */ - undo_push_group_end (gdisp->gimage); - - /* We're done dirtying the image, and would like to be restarted - * if the image gets dirty while the tool exists - */ - tool->preserve = FALSE; - -#ifdef __GNUC__ -#warning FIXME: investigate why display update was done here -#endif -#if 0 - /* Flush the gdisplays */ - if (gdisp->disp_xoffset || gdisp->disp_yoffset) - { - gint x, y; - - x = shell->disp_width; - y = shell->disp_height; - - if (gdisp->disp_yoffset) - { - gimp_display_shell_add_expose_area (shell, - 0, 0, - gdisp->disp_width, - gdisp->disp_yoffset); - gimp_display_shell_add_expose_area (shell, - 0, gdisp->disp_yoffset + y, - gdisp->disp_width, gdisp->disp_height); - } - - if (gdisp->disp_xoffset) - { - gimp_display_shell_add_expose_area (shell, - 0, 0, - gdisp->disp_xoffset, gdisp->disp_height); - gimp_display_shell_add_expose_area (shell, - gdisp->disp_xoffset + x, 0, - gdisp->disp_width, gdisp->disp_height); - } - } -#endif - - gimp_unset_busy (gdisp->gimage->gimp); - - gdisplays_flush (); - - gimp_transform_tool_reset (gt_tool, gdisp); - - /* if this tool is non-interactive, make it inactive after use */ - if (!gt_tool->interactive) - tool->state = INACTIVE; -} - -static void -gimp_transform_tool_motion (GimpTool *tool, - GimpCoords *coords, - guint32 time, - GdkModifierType state, - GimpDisplay *gdisp) -{ - GimpTransformTool *tr_tool; - - tr_tool = GIMP_TRANSFORM_TOOL (tool); - - /* if we are creating or this tool is non-interactive, there is - * nothing to be done so exit. - */ - if (tr_tool->function == TRANSFORM_CREATING || ! tr_tool->interactive) - return; - - gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool)); - - tr_tool->curx = coords->x; - tr_tool->cury = coords->y; - tr_tool->state = state; - - /* recalculate the tool's transformation matrix */ - gimp_transform_tool_transform (tr_tool, gdisp, TRANSFORM_MOTION); - - tr_tool->lastx = tr_tool->curx; - tr_tool->lasty = tr_tool->cury; - - gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool)); -} - -static void -gimp_transform_tool_cursor_update (GimpTool *tool, - GimpCoords *coords, - GdkModifierType state, - GimpDisplay *gdisp) -{ - GimpTransformTool *tr_tool; - GimpDrawable *drawable; - GdkCursorType ctype = GDK_TOP_LEFT_ARROW; - - tr_tool = GIMP_TRANSFORM_TOOL (tool); - - if ((drawable = gimp_image_active_drawable (gdisp->gimage))) - { - gint off_x, off_y; - - gimp_drawable_offsets (drawable, &off_x, &off_y); - - if (GIMP_IS_LAYER (drawable) && - gimp_layer_get_mask (GIMP_LAYER (drawable))) - { - ctype = GIMP_BAD_CURSOR; - } - else if (coords->x >= off_x && - coords->y >= off_y && - coords->x < (off_x + drawable->width) && - coords->y < (off_y + drawable->height)) - { - if (gimage_mask_is_empty (gdisp->gimage) || - gimage_mask_value (gdisp->gimage, coords->x, coords->y)) - { - ctype = GIMP_MOUSE_CURSOR; - } - } - } - - gimp_display_shell_install_tool_cursor (GIMP_DISPLAY_SHELL (gdisp->shell), - ctype, - tool->tool_cursor, - GIMP_CURSOR_MODIFIER_NONE); -} - -static void -gimp_transform_tool_draw (GimpDrawTool *draw_tool) -{ - GimpTransformTool *tr_tool; - gint i, k, gci; - - tr_tool = GIMP_TRANSFORM_TOOL (draw_tool); - - /* draw the bounding box */ - gimp_draw_tool_draw_line (draw_tool, - tr_tool->tx1, tr_tool->ty1, - tr_tool->tx2, tr_tool->ty2, - FALSE); - gimp_draw_tool_draw_line (draw_tool, - tr_tool->tx2, tr_tool->ty2, - tr_tool->tx4, tr_tool->ty4, - FALSE); - gimp_draw_tool_draw_line (draw_tool, - tr_tool->tx3, tr_tool->ty3, - tr_tool->tx4, tr_tool->ty4, - FALSE); - gimp_draw_tool_draw_line (draw_tool, - tr_tool->tx3, tr_tool->ty3, - tr_tool->tx1, tr_tool->ty1, - FALSE); - - /* Draw the grid */ - - if ((tr_tool->grid_coords != NULL) && - (tr_tool->tgrid_coords != NULL) /* FIXME!!! this doesn't belong here && - ((tool->type != PERSPECTIVE) || - ((tr_tool->transform[0][0] >=0.0) && - (tr_tool->transform[1][1] >=0.0)) */ ) - { - gci = 0; - k = tr_tool->ngx + tr_tool->ngy; - - for (i = 0; i < k; i++) - { - gimp_draw_tool_draw_line (draw_tool, - tr_tool->tgrid_coords[gci], - tr_tool->tgrid_coords[gci + 1], - tr_tool->tgrid_coords[gci + 2], - tr_tool->tgrid_coords[gci + 3], - FALSE); - gci += 4; - } - } - - /* draw the tool handles */ - gimp_draw_tool_draw_handle (draw_tool, - GIMP_HANDLE_SQUARE, - tr_tool->tx1, tr_tool->ty1, - HANDLE, HANDLE, - GTK_ANCHOR_CENTER, - FALSE); - gimp_draw_tool_draw_handle (draw_tool, - GIMP_HANDLE_SQUARE, - tr_tool->tx2, tr_tool->ty2, - HANDLE, HANDLE, - GTK_ANCHOR_CENTER, - FALSE); - gimp_draw_tool_draw_handle (draw_tool, - GIMP_HANDLE_SQUARE, - tr_tool->tx3, tr_tool->ty3, - HANDLE, HANDLE, - GTK_ANCHOR_CENTER, - FALSE); - gimp_draw_tool_draw_handle (draw_tool, - GIMP_HANDLE_SQUARE, - tr_tool->tx4, tr_tool->ty4, - HANDLE, HANDLE, - GTK_ANCHOR_CENTER, - FALSE); - - /* draw the center */ - gimp_draw_tool_draw_handle (draw_tool, - GIMP_HANDLE_FILLED_CIRCLE, - tr_tool->tcx, tr_tool->tcy, - HANDLE, HANDLE, - GTK_ANCHOR_CENTER, - FALSE); - - if (gimp_transform_tool_showpath ()) - { - GimpMatrix3 tmp_matrix; - - if (gimp_transform_tool_direction () == TRANSFORM_CORRECTIVE) - { - gimp_matrix3_invert (tr_tool->transform, tmp_matrix); - } - else - { - gimp_matrix3_duplicate (tr_tool->transform, tmp_matrix); - } - - path_transform_draw_current (GIMP_TOOL (draw_tool)->gdisp, - draw_tool, tmp_matrix); - } -} - -void -gimp_transform_tool_transform_bounding_box (GimpTransformTool *tr_tool) -{ - GimpTool *tool; - gint i, k; - gint gci; - - tool = GIMP_TOOL (tr_tool); - - gimp_matrix3_transform_point (tr_tool->transform, - tr_tool->x1, tr_tool->y1, - &tr_tool->tx1, &tr_tool->ty1); - gimp_matrix3_transform_point (tr_tool->transform, - tr_tool->x2, tr_tool->y1, - &tr_tool->tx2, &tr_tool->ty2); - gimp_matrix3_transform_point (tr_tool->transform, - tr_tool->x1, tr_tool->y2, - &tr_tool->tx3, &tr_tool->ty3); - gimp_matrix3_transform_point (tr_tool->transform, - tr_tool->x2, tr_tool->y2, - &tr_tool->tx4, &tr_tool->ty4); - - gimp_matrix3_transform_point (tr_tool->transform, - tr_tool->cx, tr_tool->cy, - &tr_tool->tcx, &tr_tool->tcy); - - if (tr_tool->grid_coords != NULL && - tr_tool->tgrid_coords != NULL) - { - gci = 0; - k = (tr_tool->ngx + tr_tool->ngy) * 2; - - for (i = 0; i < k; i++) - { - gimp_matrix3_transform_point (tr_tool->transform, - tr_tool->grid_coords[gci], - tr_tool->grid_coords[gci+1], - &(tr_tool->tgrid_coords[gci]), - &(tr_tool->tgrid_coords[gci+1])); - gci += 2; - } - } -} - -void -gimp_transform_tool_reset (GimpTransformTool *tr_tool, - GimpDisplay *gdisp) -{ - GimpTool *tool; - - tool = GIMP_TOOL (tr_tool); - - if (tr_tool->original) - { - tile_manager_destroy (tr_tool->original); - tr_tool->original = NULL; - } - - /* inactivate the tool */ - tr_tool->function = TRANSFORM_CREATING; - gimp_draw_tool_stop (GIMP_DRAW_TOOL (tr_tool)); - info_dialog_popdown (transform_info); - - tool->state = INACTIVE; - tool->gdisp = NULL; - tool->drawable = NULL; -} - -static void -gimp_transform_tool_bounds (GimpTransformTool *tr_tool, - GimpDisplay *gdisp) -{ - TileManager *tiles; - GimpDrawable *drawable; - gint offset_x, offset_y; - - tiles = tr_tool->original; - drawable = gimp_image_active_drawable (gdisp->gimage); - - /* find the boundaries */ - if (tiles) - { - tile_manager_get_offsets (tiles, - &tr_tool->x1, &tr_tool->y1); - - tr_tool->x2 = tr_tool->x1 + tile_manager_width (tiles); - tr_tool->y2 = tr_tool->y1 + tile_manager_height (tiles); - } - else - { - gimp_drawable_offsets (drawable, &offset_x, &offset_y); - gimp_drawable_mask_bounds (drawable, - &tr_tool->x1, &tr_tool->y1, - &tr_tool->x2, &tr_tool->y2); - tr_tool->x1 += offset_x; - tr_tool->y1 += offset_y; - tr_tool->x2 += offset_x; - tr_tool->y2 += offset_y; - } - - tr_tool->cx = (tr_tool->x1 + tr_tool->x2) / 2; - tr_tool->cy = (tr_tool->y1 + tr_tool->y2) / 2; - - /* changing the bounds invalidates any grid we may have */ - gimp_transform_tool_grid_recalc (tr_tool); -} - -void -gimp_transform_tool_grid_density_changed (void) -{ - GimpTransformTool *tr_tool; - GimpDrawTool *dr_tool; - - /* EEEK!!! */ - tr_tool = GIMP_TRANSFORM_TOOL (tool_manager_get_active (the_gimp)); - - dr_tool = GIMP_DRAW_TOOL (tr_tool); - - if (tr_tool->function == TRANSFORM_CREATING) - return; - - gimp_draw_tool_pause (dr_tool); - - gimp_transform_tool_grid_recalc (tr_tool); - gimp_transform_tool_transform_bounding_box (tr_tool); - - gimp_draw_tool_resume (dr_tool); -} - -void -gimp_transform_tool_showpath_changed (gint type /* a truly undescriptive name */) -{ - GimpTransformTool *tr_tool; - - /* EEEEEEEK!!! */ - tr_tool = GIMP_TRANSFORM_TOOL (tool_manager_get_active (the_gimp)); - - if (tr_tool->function == TRANSFORM_CREATING) - return; - - if (type) - gimp_draw_tool_pause (GIMP_DRAW_TOOL (tr_tool)); - else - gimp_draw_tool_resume (GIMP_DRAW_TOOL (tr_tool)); -} - -static void -gimp_transform_tool_grid_recalc (GimpTransformTool *tr_tool) -{ - if (tr_tool->grid_coords != NULL) - { - g_free (tr_tool->grid_coords); - tr_tool->grid_coords = NULL; - } - - if (tr_tool->tgrid_coords != NULL) - { - g_free (tr_tool->tgrid_coords); - tr_tool->tgrid_coords = NULL; - } - - if (gimp_transform_tool_show_grid ()) - gimp_transform_tool_setup_grid (tr_tool); -} - -static void -gimp_transform_tool_setup_grid (GimpTransformTool *tr_tool) -{ - GimpTool *tool; - gint i, gci; - gdouble *coords; - - tool = GIMP_TOOL (tr_tool); - - /* We use the gimp_transform_tool_grid_size function only here, even - * if the user changes the grid size in the middle of an - * operation, nothing happens. - */ - tr_tool->ngx = (tr_tool->x2 - tr_tool->x1) / gimp_transform_tool_grid_size (); - if (tr_tool->ngx > 0) - tr_tool->ngx--; - - tr_tool->ngy = (tr_tool->y2 - tr_tool->y1) / gimp_transform_tool_grid_size (); - if (tr_tool->ngy > 0) - tr_tool->ngy--; - - tr_tool->grid_coords = coords = - g_new (gdouble, (tr_tool->ngx + tr_tool->ngy) * 4); - - tr_tool->tgrid_coords = - g_new (gdouble, (tr_tool->ngx + tr_tool->ngy) * 4); - - gci = 0; - - for (i = 1; i <= tr_tool->ngx; i++) - { - coords[gci] = tr_tool->x1 + - ((gdouble) i) / (tr_tool->ngx + 1) * - (tr_tool->x2 - tr_tool->x1); - coords[gci+1] = tr_tool->y1; - coords[gci+2] = coords[gci]; - coords[gci+3] = tr_tool->y2; - gci += 4; - } - - for (i = 1; i <= tr_tool->ngy; i++) - { - coords[gci] = tr_tool->x1; - coords[gci+1] = tr_tool->y1 + - ((gdouble) i) / (tr_tool->ngy + 1) * - (tr_tool->y2 - tr_tool->y1); - coords[gci+2] = tr_tool->x2; - coords[gci+3] = coords[gci+1]; - gci += 4; - } -} - -static void -gimp_transform_tool_recalc (GimpTransformTool *tr_tool, - GimpDisplay *gdisp) -{ - gimp_transform_tool_bounds (tr_tool, gdisp); - - gimp_transform_tool_transform (tr_tool, gdisp, TRANSFORM_RECALC); -} - -/* Actually carry out a transformation */ -TileManager * -gimp_transform_tool_do (GimpImage *gimage, - GimpDrawable *drawable, - TileManager *float_tiles, - gboolean interpolation, - GimpMatrix3 matrix, - GimpProgressFunc progress_callback, - gpointer progress_data) +gimp_drawable_transform_tiles_affine (GimpDrawable *drawable, + TileManager *float_tiles, + gboolean interpolation, + gboolean clip_result, + GimpMatrix3 matrix, + GimpTransformDirection direction, + GimpProgressFunc progress_callback, + gpointer progress_data) { + GimpImage *gimage; PixelRegion destPR; TileManager *tiles; GimpMatrix3 m; @@ -1175,6 +113,13 @@ gimp_transform_tool_do (GimpImage *gimage, PixelSurround surround; + g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL); + g_return_val_if_fail (float_tiles != NULL, NULL); + + gimage = gimp_drawable_gimage (drawable); + + g_return_val_if_fail (GIMP_IS_IMAGE (gimage), NULL); + alpha = 0; /* turn interpolation off for simple transformations (e.g. rot90) */ @@ -1217,10 +162,11 @@ gimp_transform_tool_do (GimpImage *gimage, alpha = 0; } - if (gimp_transform_tool_direction () == TRANSFORM_CORRECTIVE) + if (direction == GIMP_TRANSFORM_BACKWARD) { /* keep the original matrix here, so we dont need to recalculate - the inverse later */ + * the inverse later + */ gimp_matrix3_duplicate (matrix, m); gimp_matrix3_invert (matrix, im); matrix = im; @@ -1231,15 +177,19 @@ gimp_transform_tool_do (GimpImage *gimage, gimp_matrix3_invert (matrix, m); } +#ifdef __GNUC__ +#warning FIXME: path_transform_current_path +#endif +#if 0 path_transform_current_path (gimage, matrix, FALSE); +#endif tile_manager_get_offsets (float_tiles, &x1, &y1); x2 = x1 + tile_manager_width (float_tiles); y2 = y1 + tile_manager_height (float_tiles); /* Find the bounding coordinates */ - if (alpha == 0 || (tool_manager_get_active (gimage->gimp) && - gimp_transform_tool_clip ())) + if (alpha == 0 || clip_result) { tx1 = x1; ty1 = y1; @@ -1376,7 +326,7 @@ gimp_transform_tool_do (GimpImage *gimage, /* calculate alpha of result */ start = &data[alpha]; - a_val = gimp_transform_tool_cubic + a_val = gimp_drawable_transform_cubic (dy, CUBIC_ROW (dx, start, bytes), CUBIC_ROW (dx, start + row, bytes), @@ -1409,7 +359,7 @@ gimp_transform_tool_do (GimpImage *gimage, start = &data[alpha]; newval = RINT (a_recip * - gimp_transform_tool_cubic + gimp_drawable_transform_cubic (dy, CUBIC_SCALED_ROW (dx, start, bytes, i), CUBIC_SCALED_ROW (dx, start + row, bytes, i), @@ -1574,20 +524,183 @@ gimp_transform_tool_do (GimpImage *gimage, } TileManager * -gimp_transform_tool_cut (GimpImage *gimage, - GimpDrawable *drawable, - gboolean *new_layer) +gimp_drawable_transform_tiles_flip (GimpDrawable *drawable, + TileManager *orig, + InternalOrientationType flip_type) { + TileManager *new; + PixelRegion srcPR, destPR; + gint orig_width; + gint orig_height; + gint orig_bpp; + gint orig_x, orig_y; + gint i; + + g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL); + g_return_val_if_fail (orig != NULL, NULL); + + orig_width = tile_manager_width (orig); + orig_height = tile_manager_height (orig); + orig_bpp = tile_manager_bpp (orig); + tile_manager_get_offsets (orig, &orig_x, &orig_y); + + new = tile_manager_new (orig_width, orig_height, orig_bpp); + tile_manager_set_offsets (new, orig_x, orig_y); + + if (flip_type == ORIENTATION_HORIZONTAL) + { + for (i = 0; i < orig_width; i++) + { + pixel_region_init (&srcPR, orig, i, 0, 1, orig_height, FALSE); + pixel_region_init (&destPR, new, + (orig_width - i - 1), 0, 1, orig_height, TRUE); + copy_region (&srcPR, &destPR); + } + } + else + { + for (i = 0; i < orig_height; i++) + { + pixel_region_init (&srcPR, orig, 0, i, orig_width, 1, FALSE); + pixel_region_init (&destPR, new, + 0, (orig_height - i - 1), orig_width, 1, TRUE); + copy_region (&srcPR, &destPR); + } + } + +#ifdef __GNUC__ +#warning FIXME: path_transform_flip_horz/vert +#endif +#if 0 + /* flip locked paths */ + /* Note that the undo structures etc are setup before we enter this + * function. + */ + if (flip_type == ORIENTATION_HORIZONTAL) + path_transform_flip_horz (gimage); + else + path_transform_flip_vert (gimage); +#endif + + return new; +} + +gboolean +gimp_drawable_transform_affine (GimpDrawable *drawable, + gboolean interpolation, + gboolean clip_result, + GimpMatrix3 matrix, + GimpTransformDirection direction) +{ + GimpImage *gimage; + TileManager *float_tiles; + gboolean new_layer; + gboolean success = FALSE; + + g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), FALSE); + + gimage = gimp_drawable_gimage (drawable); + + g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE); + + /* Start a transform undo group */ + undo_push_group_start (gimage, TRANSFORM_CORE_UNDO); + + /* Cut/Copy from the specified drawable */ + float_tiles = gimp_drawable_transform_cut (drawable, &new_layer); + + if (float_tiles) + { + TileManager *new_tiles; + + /* transform the buffer */ + new_tiles = gimp_drawable_transform_tiles_affine (drawable, + float_tiles, + interpolation, + FALSE, + matrix, + GIMP_TRANSFORM_FORWARD, + NULL, NULL); + + /* Free the cut/copied buffer */ + tile_manager_destroy (float_tiles); + + if (new_tiles) + success = gimp_drawable_transform_paste (drawable, new_tiles, new_layer); + } + + /* push the undo group end */ + undo_push_group_end (gimage); + + return success; +} + +gboolean +gimp_drawable_transform_flip (GimpDrawable *drawable, + InternalOrientationType flip_type) +{ + GimpImage *gimage; + TileManager *float_tiles; + gboolean new_layer; + gboolean success = FALSE; + + g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), FALSE); + + gimage = gimp_drawable_gimage (drawable); + + g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE); + + /* Start a transform undo group */ + undo_push_group_start (gimage, TRANSFORM_CORE_UNDO); + + /* Cut/Copy from the specified drawable */ + float_tiles = gimp_drawable_transform_cut (drawable, &new_layer); + + if (float_tiles) + { + TileManager *new_tiles; + + /* transform the buffer */ + new_tiles = gimp_drawable_transform_tiles_flip (drawable, + float_tiles, + flip_type); + + /* Free the cut/copied buffer */ + tile_manager_destroy (float_tiles); + + if (new_tiles) + success = gimp_drawable_transform_paste (drawable, new_tiles, new_layer); + } + + /* push the undo group end */ + undo_push_group_end (gimage); + + return success; +} + +TileManager * +gimp_drawable_transform_cut (GimpDrawable *drawable, + gboolean *new_layer) +{ + GimpImage *gimage; TileManager *tiles; + g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL); + g_return_val_if_fail (new_layer != NULL, NULL); + + gimage = gimp_drawable_gimage (drawable); + + g_return_val_if_fail (GIMP_IS_IMAGE (gimage), NULL); + /* extract the selected mask if there is a selection */ if (! gimage_mask_is_empty (gimage)) { /* set the keep_indexed flag to FALSE here, since we use - gimp_layer_new_from_tiles() later which assumes that the tiles - are either RGB or GRAY. Eeek!!! (Sven) + * gimp_layer_new_from_tiles() later which assumes that the tiles + * are either RGB or GRAY. Eeek!!! (Sven) */ tiles = gimage_mask_extract (gimage, drawable, TRUE, FALSE, TRUE); + *new_layer = TRUE; } /* otherwise, just copy the layer */ @@ -1597,24 +710,30 @@ gimp_transform_tool_cut (GimpImage *gimage, tiles = gimage_mask_extract (gimage, drawable, FALSE, TRUE, TRUE); else tiles = gimage_mask_extract (gimage, drawable, FALSE, TRUE, FALSE); + *new_layer = FALSE; } return tiles; } - -/* Paste a transform to the gdisplay */ gboolean -gimp_transform_tool_paste (GimpImage *gimage, - GimpDrawable *drawable, - TileManager *tiles, - gboolean new_layer) +gimp_drawable_transform_paste (GimpDrawable *drawable, + TileManager *tiles, + gboolean new_layer) { + GimpImage *gimage; GimpLayer *layer = NULL; GimpChannel *channel = NULL; GimpLayer *floating_layer; + g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), FALSE); + g_return_val_if_fail (tiles != NULL, FALSE); + + gimage = gimp_drawable_gimage (drawable); + + g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE); + if (new_layer) { layer = @@ -1706,11 +825,11 @@ gimp_transform_tool_paste (GimpImage *gimage, /* Note: cubic function no longer clips result */ static gdouble -gimp_transform_tool_cubic (gdouble dx, - gint jm1, - gint j, - gint jp1, - gint jp2) +gimp_drawable_transform_cubic (gdouble dx, + gint jm1, + gint j, + gint jp1, + gint jp2) { gdouble result; diff --git a/app/core/gimp-transform-utils.c b/app/core/gimp-transform-utils.c new file mode 100644 index 0000000000..99d3cab543 --- /dev/null +++ b/app/core/gimp-transform-utils.c @@ -0,0 +1,193 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995-2001 Spencer Kimball, Peter Mattis, and others + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include "libgimpmath/gimpmath.h" + +#include "core-types.h" + +#include "gimpdrawable-transform-utils.h" + + +void +gimp_drawable_transform_matrix_rotate (gint x1, + gint y1, + gint x2, + gint y2, + gdouble angle, + GimpMatrix3 result) +{ + gdouble cx; + gdouble cy; + + cx = (gdouble) (x1 + x2) / 2.0; + cy = (gdouble) (y1 + y2) / 2.0; + + gimp_matrix3_identity (result); + gimp_matrix3_translate (result, -cx, -cy); + gimp_matrix3_rotate (result, angle); + gimp_matrix3_translate (result, +cx, +cy); +} + +void +gimp_drawable_transform_matrix_scale (gint x1, + gint y1, + gint x2, + gint y2, + gdouble tx1, + gdouble ty1, + gdouble tx2, + gdouble ty2, + GimpMatrix3 result) +{ + gdouble scalex; + gdouble scaley; + + scalex = scaley = 1.0; + + if ((x2 - x1) > 0) + scalex = (tx2 - tx1) / (gdouble) (x2 - x1); + + if ((y2 - y1) > 0) + scaley = (ty2 - ty1) / (gdouble) (y2 - y1); + + gimp_matrix3_identity (result); + gimp_matrix3_translate (result, -x1, -y1); + gimp_matrix3_scale (result, scalex, scaley); + gimp_matrix3_translate (result, tx1, ty1); +} + +void +gimp_drawable_transform_matrix_shear (gint x1, + gint y1, + gint x2, + gint y2, + InternalOrientationType orientation, + gdouble amount, + GimpMatrix3 result) +{ + gint width; + gint height; + gdouble cx; + gdouble cy; + + width = x2 - x1; + height = y2 - y1; + + if (width == 0) + width = 1; + if (height == 0) + height = 1; + + cx = (gdouble) (x1 + x2) / 2.0; + cy = (gdouble) (y1 + y2) / 2.0; + + gimp_matrix3_identity (result); + gimp_matrix3_translate (result, -cx, -cy); + + if (orientation == ORIENTATION_HORIZONTAL) + gimp_matrix3_xshear (result, amount / height); + else + gimp_matrix3_yshear (result, amount / width); + + gimp_matrix3_translate (result, +cx, +cy); +} + +void +gimp_drawable_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, + GimpMatrix3 result) +{ + GimpMatrix3 matrix; + gdouble scalex; + gdouble scaley; + + scalex = scaley = 1.0; + + if ((x2 - x1) > 0) + scalex = 1.0 / (gdouble) (x2 - x1); + + if ((y2 - y1) > 0) + scaley = 1.0 / (gdouble) (y2 - y1); + + /* Determine the perspective transform that maps from + * the unit cube to the transformed coordinates + */ + { + gdouble dx1, dx2, dx3, dy1, dy2, dy3; + gdouble det1, det2; + + dx1 = tx2 - tx4; + dx2 = tx3 - tx4; + dx3 = tx1 - tx2 + tx4 - tx3; + + dy1 = ty2 - ty3; + dy2 = ty3 - ty4; + dy3 = ty1 - ty2 + ty4 - ty3; + + /* Is the mapping affine? */ + if ((dx3 == 0.0) && (dy3 == 0.0)) + { + matrix[0][0] = tx2 - tx1; + matrix[0][1] = tx4 - tx2; + matrix[0][2] = tx1; + matrix[1][0] = ty2 - ty1; + matrix[1][1] = ty4 - ty2; + matrix[1][2] = ty1; + matrix[2][0] = 0.0; + matrix[2][1] = 0.0; + } + else + { + det1 = dx3 * dy2 - dy3 * dx2; + det2 = dx1 * dy2 - dy1 * dx2; + matrix[2][0] = det1 / det2; + det1 = dx1 * dy3 - dy1 * dx3; + det2 = dx1 * dy2 - dy1 * dx2; + matrix[2][1] = det1 / det2; + + matrix[0][0] = tx2 - tx1 + matrix[2][0] * tx2; + matrix[0][1] = tx3 - tx1 + matrix[2][1] * tx3; + matrix[0][2] = tx1; + + matrix[1][0] = ty2 - ty1 + matrix[2][0] * ty2; + matrix[1][1] = ty3 - ty1 + matrix[2][1] * ty3; + matrix[1][2] = ty1; + } + + matrix[2][2] = 1.0; + } + + gimp_matrix3_identity (result); + gimp_matrix3_translate (result, -x1, -y1); + gimp_matrix3_scale (result, scalex, scaley); + gimp_matrix3_mult (matrix, result); +} diff --git a/app/core/gimp-transform-utils.h b/app/core/gimp-transform-utils.h new file mode 100644 index 0000000000..c7163fdb8b --- /dev/null +++ b/app/core/gimp-transform-utils.h @@ -0,0 +1,60 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995-2001 Spencer Kimball, Peter Mattis, and others + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GIMP_DRAWABLE_TRANSFORM_UTILS_H__ +#define __GIMP_DRAWABLE_TRANSFORM_UTILS_H__ + + +void gimp_drawable_transform_matrix_rotate (gint x1, + gint y1, + gint x2, + gint y2, + gdouble angle, + GimpMatrix3 result); +void gimp_drawable_transform_matrix_scale (gint x1, + gint y1, + gint x2, + gint y2, + gdouble tx1, + gdouble ty1, + gdouble tx2, + gdouble ty2, + GimpMatrix3 result); +void gimp_drawable_transform_matrix_shear (gint x1, + gint y1, + gint x2, + gint y2, + InternalOrientationType orientation, + gdouble amount, + GimpMatrix3 result); +void gimp_drawable_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); + + +#endif /* __GIMP_DRAWABLE_TRANSFORM_SHEAR_H__ */ diff --git a/app/core/gimpdrawable-transform-utils.c b/app/core/gimpdrawable-transform-utils.c new file mode 100644 index 0000000000..99d3cab543 --- /dev/null +++ b/app/core/gimpdrawable-transform-utils.c @@ -0,0 +1,193 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995-2001 Spencer Kimball, Peter Mattis, and others + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include "libgimpmath/gimpmath.h" + +#include "core-types.h" + +#include "gimpdrawable-transform-utils.h" + + +void +gimp_drawable_transform_matrix_rotate (gint x1, + gint y1, + gint x2, + gint y2, + gdouble angle, + GimpMatrix3 result) +{ + gdouble cx; + gdouble cy; + + cx = (gdouble) (x1 + x2) / 2.0; + cy = (gdouble) (y1 + y2) / 2.0; + + gimp_matrix3_identity (result); + gimp_matrix3_translate (result, -cx, -cy); + gimp_matrix3_rotate (result, angle); + gimp_matrix3_translate (result, +cx, +cy); +} + +void +gimp_drawable_transform_matrix_scale (gint x1, + gint y1, + gint x2, + gint y2, + gdouble tx1, + gdouble ty1, + gdouble tx2, + gdouble ty2, + GimpMatrix3 result) +{ + gdouble scalex; + gdouble scaley; + + scalex = scaley = 1.0; + + if ((x2 - x1) > 0) + scalex = (tx2 - tx1) / (gdouble) (x2 - x1); + + if ((y2 - y1) > 0) + scaley = (ty2 - ty1) / (gdouble) (y2 - y1); + + gimp_matrix3_identity (result); + gimp_matrix3_translate (result, -x1, -y1); + gimp_matrix3_scale (result, scalex, scaley); + gimp_matrix3_translate (result, tx1, ty1); +} + +void +gimp_drawable_transform_matrix_shear (gint x1, + gint y1, + gint x2, + gint y2, + InternalOrientationType orientation, + gdouble amount, + GimpMatrix3 result) +{ + gint width; + gint height; + gdouble cx; + gdouble cy; + + width = x2 - x1; + height = y2 - y1; + + if (width == 0) + width = 1; + if (height == 0) + height = 1; + + cx = (gdouble) (x1 + x2) / 2.0; + cy = (gdouble) (y1 + y2) / 2.0; + + gimp_matrix3_identity (result); + gimp_matrix3_translate (result, -cx, -cy); + + if (orientation == ORIENTATION_HORIZONTAL) + gimp_matrix3_xshear (result, amount / height); + else + gimp_matrix3_yshear (result, amount / width); + + gimp_matrix3_translate (result, +cx, +cy); +} + +void +gimp_drawable_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, + GimpMatrix3 result) +{ + GimpMatrix3 matrix; + gdouble scalex; + gdouble scaley; + + scalex = scaley = 1.0; + + if ((x2 - x1) > 0) + scalex = 1.0 / (gdouble) (x2 - x1); + + if ((y2 - y1) > 0) + scaley = 1.0 / (gdouble) (y2 - y1); + + /* Determine the perspective transform that maps from + * the unit cube to the transformed coordinates + */ + { + gdouble dx1, dx2, dx3, dy1, dy2, dy3; + gdouble det1, det2; + + dx1 = tx2 - tx4; + dx2 = tx3 - tx4; + dx3 = tx1 - tx2 + tx4 - tx3; + + dy1 = ty2 - ty3; + dy2 = ty3 - ty4; + dy3 = ty1 - ty2 + ty4 - ty3; + + /* Is the mapping affine? */ + if ((dx3 == 0.0) && (dy3 == 0.0)) + { + matrix[0][0] = tx2 - tx1; + matrix[0][1] = tx4 - tx2; + matrix[0][2] = tx1; + matrix[1][0] = ty2 - ty1; + matrix[1][1] = ty4 - ty2; + matrix[1][2] = ty1; + matrix[2][0] = 0.0; + matrix[2][1] = 0.0; + } + else + { + det1 = dx3 * dy2 - dy3 * dx2; + det2 = dx1 * dy2 - dy1 * dx2; + matrix[2][0] = det1 / det2; + det1 = dx1 * dy3 - dy1 * dx3; + det2 = dx1 * dy2 - dy1 * dx2; + matrix[2][1] = det1 / det2; + + matrix[0][0] = tx2 - tx1 + matrix[2][0] * tx2; + matrix[0][1] = tx3 - tx1 + matrix[2][1] * tx3; + matrix[0][2] = tx1; + + matrix[1][0] = ty2 - ty1 + matrix[2][0] * ty2; + matrix[1][1] = ty3 - ty1 + matrix[2][1] * ty3; + matrix[1][2] = ty1; + } + + matrix[2][2] = 1.0; + } + + gimp_matrix3_identity (result); + gimp_matrix3_translate (result, -x1, -y1); + gimp_matrix3_scale (result, scalex, scaley); + gimp_matrix3_mult (matrix, result); +} diff --git a/app/core/gimpdrawable-transform-utils.h b/app/core/gimpdrawable-transform-utils.h new file mode 100644 index 0000000000..c7163fdb8b --- /dev/null +++ b/app/core/gimpdrawable-transform-utils.h @@ -0,0 +1,60 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995-2001 Spencer Kimball, Peter Mattis, and others + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GIMP_DRAWABLE_TRANSFORM_UTILS_H__ +#define __GIMP_DRAWABLE_TRANSFORM_UTILS_H__ + + +void gimp_drawable_transform_matrix_rotate (gint x1, + gint y1, + gint x2, + gint y2, + gdouble angle, + GimpMatrix3 result); +void gimp_drawable_transform_matrix_scale (gint x1, + gint y1, + gint x2, + gint y2, + gdouble tx1, + gdouble ty1, + gdouble tx2, + gdouble ty2, + GimpMatrix3 result); +void gimp_drawable_transform_matrix_shear (gint x1, + gint y1, + gint x2, + gint y2, + InternalOrientationType orientation, + gdouble amount, + GimpMatrix3 result); +void gimp_drawable_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); + + +#endif /* __GIMP_DRAWABLE_TRANSFORM_SHEAR_H__ */ diff --git a/app/core/gimpdrawable-transform.c b/app/core/gimpdrawable-transform.c index a775e89581..90c757063c 100644 --- a/app/core/gimpdrawable-transform.c +++ b/app/core/gimpdrawable-transform.c @@ -18,15 +18,11 @@ #include "config.h" -#include - -#include +#include #include "libgimpmath/gimpmath.h" -#include "libgimpwidgets/gimpwidgets.h" -#include "tools-types.h" -#include "gui/gui-types.h" +#include "core-types.h" #include "base/base-config.h" #include "base/pixel-region.h" @@ -36,57 +32,30 @@ #include "paint-funcs/paint-funcs.h" -#include "core/gimp.h" -#include "core/gimpchannel.h" -#include "core/gimpcontext.h" -#include "core/gimpdrawable.h" -#include "core/gimpimage.h" -#include "core/gimpimage-mask.h" -#include "core/gimplayer.h" -#include "core/gimpmarshal.h" -#include "core/gimptoolinfo.h" +#include "gimp.h" +#include "gimpchannel.h" +#include "gimpcontext.h" +#include "gimpdrawable.h" +#include "gimpdrawable-transform.h" +#include "gimpimage.h" +#include "gimpimage-mask.h" +#include "gimplayer.h" -#include "gui/info-dialog.h" - -#include "display/gimpdisplay.h" -#include "display/gimpdisplay-foreach.h" -#include "display/gimpdisplayshell.h" - -#include "tool_manager.h" -#include "tool_options.h" -#include "transform_options.h" -#include "gimptransformtool.h" -#include "gimpperspectivetool.h" -#include "gimprotatetool.h" -#include "gimpscaletool.h" -#include "gimpsheartool.h" -#include "gimpfliptool.h" - -#include "app_procs.h" #include "floating_sel.h" #include "undo.h" -#include "path_transform.h" #include "libgimp/gimpintl.h" -enum -{ - TRANSFORM, - LAST_SIGNAL -}; - -#define HANDLE 10 - #define BILINEAR(jk,j1k,jk1,j1k1,dx,dy) \ ((1-dy) * (jk + dx * (j1k - jk)) + \ dy * (jk1 + dx * (j1k1 - jk1))) /* access interleaved pixels */ #define CUBIC_ROW(dx, row, step) \ - gimp_transform_tool_cubic(dx, (row)[0], (row)[step], (row)[step+step], (row)[step+step+step]) + gimp_drawable_transform_cubic(dx, (row)[0], (row)[step], (row)[step+step], (row)[step+step+step]) #define CUBIC_SCALED_ROW(dx, row, step, i) \ - gimp_transform_tool_cubic(dx, (row)[0] * (row)[i], \ + gimp_drawable_transform_cubic(dx, (row)[0] * (row)[i], \ (row)[step] * (row)[step + i], \ (row)[step+step]* (row)[step+step + i], \ (row)[step+step+step] * (row)[step+step+step + i]) @@ -96,1059 +65,28 @@ enum src[i] = tile_data_pointer (tile[i], (x) % TILE_WIDTH, (y) % TILE_HEIGHT); -/* forward function declarations */ -static void gimp_transform_tool_bounds (GimpTransformTool *tool, - GimpDisplay *gdisp); -static void gimp_transform_tool_recalc (GimpTransformTool *tool, - GimpDisplay *gdisp); -static void gimp_transform_tool_doit (GimpTransformTool *tool, - GimpDisplay *gdisp); -static gdouble gimp_transform_tool_cubic (gdouble dx, - gint jm1, - gint j, - gint jp1, - gint jp2); -static void gimp_transform_tool_setup_grid (GimpTransformTool *tool); -static void gimp_transform_tool_grid_recalc (GimpTransformTool *gimp_transform_tool); -static void gimp_transform_tool_init (GimpTransformTool *tool); -static void gimp_transform_tool_class_init (GimpTransformToolClass *tool); +/* forward function prototypes */ -static void gimp_transform_tool_finalize (GObject *object); - -static void gimp_transform_tool_button_press (GimpTool *tool, - GimpCoords *coords, - guint32 time, - GdkModifierType state, - GimpDisplay *gdisp); - -static void gimp_transform_tool_button_release (GimpTool *tool, - GimpCoords *coords, - guint32 time, - GdkModifierType state, - GimpDisplay *gdisp); - -static void gimp_transform_tool_motion (GimpTool *tool, - GimpCoords *coords, - guint32 time, - GdkModifierType state, - GimpDisplay *gdisp); - -static void gimp_transform_tool_cursor_update (GimpTool *tool, - GimpCoords *coords, - GdkModifierType state, - GimpDisplay *gdisp); - -static void gimp_transform_tool_control (GimpTool *tool, - ToolAction action, - GimpDisplay *gdisp); - -static void gimp_transform_tool_draw (GimpDrawTool *draw_tool); +static gdouble gimp_drawable_transform_cubic (gdouble dx, + gint jm1, + gint j, + gint jp1, + gint jp2); -/* variables */ -static TranInfo old_trans_info; -InfoDialog *transform_info = NULL; -static gboolean transform_info_inited = FALSE; - -static GimpDrawToolClass *parent_class = NULL; - -static guint gimp_transform_tool_signals[LAST_SIGNAL] = { 0 }; - - -GType -gimp_transform_tool_get_type (void) -{ - static GType tool_type = 0; - - if (! tool_type) - { - static const GTypeInfo tool_info = - { - sizeof (GimpTransformToolClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) gimp_transform_tool_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (GimpTransformTool), - 0, /* n_preallocs */ - (GInstanceInitFunc) gimp_transform_tool_init, - }; - - tool_type = g_type_register_static (GIMP_TYPE_DRAW_TOOL, - "GimpTransformTool", - &tool_info, 0); - } - - return tool_type; -} - -static void -gimp_transform_tool_class_init (GimpTransformToolClass *klass) -{ - GObjectClass *object_class; - GimpToolClass *tool_class; - GimpDrawToolClass *draw_class; - - object_class = G_OBJECT_CLASS (klass); - tool_class = GIMP_TOOL_CLASS (klass); - draw_class = GIMP_DRAW_TOOL_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - gimp_transform_tool_signals[TRANSFORM] = - g_signal_new ("transform", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GimpTransformToolClass, transform), - NULL, NULL, - gimp_cclosure_marshal_POINTER__POINTER_INT, - G_TYPE_POINTER, 2, - G_TYPE_POINTER, - G_TYPE_INT); - - object_class->finalize = gimp_transform_tool_finalize; - - tool_class->control = gimp_transform_tool_control; - tool_class->button_press = gimp_transform_tool_button_press; - tool_class->button_release = gimp_transform_tool_button_release; - tool_class->motion = gimp_transform_tool_motion; - tool_class->cursor_update = gimp_transform_tool_cursor_update; - - draw_class->draw = gimp_transform_tool_draw; -} - -static void -gimp_transform_tool_init (GimpTransformTool *tr_tool) -{ - GimpTool *tool = GIMP_TOOL (tr_tool); - gint i; - - tr_tool->function = TRANSFORM_CREATING; - tr_tool->original = NULL; - - for (i = 0; i < TRAN_INFO_SIZE; i++) - tr_tool->trans_info[i] = 0; - - tr_tool->grid_coords = tr_tool->tgrid_coords = NULL; - - /* FIXME */ - tr_tool->interactive = TRUE; - - tool->scroll_lock = TRUE; /* Disallow scrolling */ - tool->preserve = FALSE; /* Don't preserve on drawable change */ - -} +/* public functions */ TileManager * -gimp_transform_tool_transform (GimpTransformTool *tool, - GimpDisplay *gdisp, - TransformState state) -{ - TileManager *retval; - - g_return_val_if_fail (tool, NULL); - g_return_val_if_fail (GIMP_IS_TRANSFORM_TOOL (tool), NULL); - - g_signal_emit (G_OBJECT (tool), gimp_transform_tool_signals[TRANSFORM], 0, - gdisp, state, &retval); - - return retval; -} - -static void -transform_ok_callback (GtkWidget *widget, - gpointer data) -{ - GimpTool *tool; - - tool = GIMP_TOOL(data); - gimp_transform_tool_doit (GIMP_TRANSFORM_TOOL(tool), tool->gdisp); -} - -static void -transform_reset_callback (GtkWidget *widget, - gpointer data) -{ - GimpTransformTool *tool; - GimpDrawTool *dr_tool; - gint i; - - tool = GIMP_TRANSFORM_TOOL (data); - dr_tool = GIMP_DRAW_TOOL (data); - - /* stop the current tool drawing process */ - gimp_draw_tool_pause (dr_tool); - - /* Restore the previous transformation info */ - for (i = 0; i < TRAN_INFO_SIZE; i++) - tool->trans_info [i] = old_trans_info [i]; - - /* recalculate the tool's transformation matrix */ - gimp_transform_tool_recalc (tool, GIMP_TOOL(tool)->gdisp); - - /* resume drawing the current tool */ - gimp_draw_tool_resume (dr_tool); -} - -static void -gimp_transform_tool_finalize (GObject *object) -{ - GimpTransformTool *tr_tool; - - tr_tool = GIMP_TRANSFORM_TOOL (object); - - if (tr_tool->original) - { - tile_manager_destroy (tr_tool->original); - tr_tool->original = NULL; - } - - if (transform_info) - { - info_dialog_free (transform_info); - transform_info = NULL; - transform_info_inited = FALSE; - } - - if (tr_tool->grid_coords) - { - g_free (tr_tool->grid_coords); - tr_tool->grid_coords = NULL; - } - - if (tr_tool->tgrid_coords) - { - g_free (tr_tool->tgrid_coords); - tr_tool->tgrid_coords = NULL; - } - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -gimp_transform_tool_control (GimpTool *tool, - ToolAction action, - GimpDisplay *gdisp) -{ - GimpDrawTool *dr_tool; - GimpTransformTool *tr_tool; - - dr_tool = GIMP_DRAW_TOOL (tool); - tr_tool = GIMP_TRANSFORM_TOOL (tool); - - switch (action) - { - case PAUSE: - break; - - case RESUME: - gimp_transform_tool_recalc (tr_tool, gdisp); - break; - - case HALT: - gimp_transform_tool_reset (tr_tool, gdisp); - break; - - default: - break; - } - - if (GIMP_TOOL_CLASS (parent_class)->control) - GIMP_TOOL_CLASS (parent_class)->control (tool, action, gdisp); -} - -static void -gimp_transform_tool_button_press (GimpTool *tool, - GimpCoords *coords, - guint32 time, - GdkModifierType state, - GimpDisplay *gdisp) -{ - GimpTransformTool *gt_tool; - GimpDrawTool *draw_tool; - GimpDisplayShell *shell; - GimpDrawable *drawable; - gdouble dist; - gdouble closest_dist; - gint i; - gint off_x, off_y; - - gt_tool = GIMP_TRANSFORM_TOOL (tool); - draw_tool = GIMP_DRAW_TOOL (tool); - - shell = GIMP_DISPLAY_SHELL (gdisp->shell); - - drawable = gimp_image_active_drawable (gdisp->gimage); - - if (gt_tool->function == TRANSFORM_CREATING && tool->state == ACTIVE) - { - /* Save the current transformation info */ - for (i = 0; i < TRAN_INFO_SIZE; i++) - old_trans_info [i] = gt_tool->trans_info [i]; - } - - /* if we have already displayed the bounding box and handles, - * check to make sure that the display which currently owns the - * tool is the one which just received the button pressed event - */ - if ((gdisp == tool->gdisp) && gt_tool->interactive) - { - /* start drawing the bounding box and handles... */ - gimp_draw_tool_start (GIMP_DRAW_TOOL (tool), shell->canvas->window); - - closest_dist = gimp_draw_tool_calc_distance (draw_tool, gdisp, - coords->x, coords->y, - gt_tool->tx1, gt_tool->ty1); - gt_tool->function = TRANSFORM_HANDLE_1; - - dist = gimp_draw_tool_calc_distance (draw_tool, gdisp, - coords->x, coords->y, - gt_tool->tx2, gt_tool->ty2); - if (dist < closest_dist) - { - closest_dist = dist; - gt_tool->function = TRANSFORM_HANDLE_2; - } - - dist = gimp_draw_tool_calc_distance (draw_tool, gdisp, - coords->x, coords->y, - gt_tool->tx3, gt_tool->ty3); - if (dist < closest_dist) - { - closest_dist = dist; - gt_tool->function = TRANSFORM_HANDLE_3; - } - - dist = gimp_draw_tool_calc_distance (draw_tool, gdisp, - coords->x, coords->y, - gt_tool->tx4, gt_tool->ty4); - if (dist < closest_dist) - { - closest_dist = dist; - gt_tool->function = TRANSFORM_HANDLE_4; - } - - if (gimp_draw_tool_on_handle (draw_tool, gdisp, - coords->x, coords->y, - GIMP_HANDLE_CIRCLE, - gt_tool->tcx, gt_tool->tcy, - HANDLE, HANDLE, - GIMP_HANDLE_CIRCLE, - FALSE)) - { - gt_tool->function = TRANSFORM_HANDLE_CENTER; - } - - /* Save the current pointer position */ - gt_tool->lastx = gt_tool->startx = coords->x; - gt_tool->lasty = gt_tool->starty = coords->y; - - gdk_pointer_grab (shell->canvas->window, FALSE, - GDK_POINTER_MOTION_HINT_MASK | - GDK_BUTTON1_MOTION_MASK | - GDK_BUTTON_RELEASE_MASK, - NULL, NULL, time); - - tool->state = ACTIVE; - return; - } - - /* Initialisation stuff: if the cursor is clicked inside the current - * selection, show the bounding box and handles... - */ - gimp_drawable_offsets (drawable, &off_x, &off_y); - - if (coords->x >= off_x && - coords->y >= off_y && - coords->x < (off_x + gimp_drawable_width (drawable)) && - coords->y < (off_y + gimp_drawable_height (drawable))) - { - if (gimage_mask_is_empty (gdisp->gimage) || - gimage_mask_value (gdisp->gimage, coords->x, coords->y)) - { - if (GIMP_IS_LAYER (drawable) && - gimp_layer_get_mask (GIMP_LAYER (drawable))) - { - g_message (_("Transformations do not work on\n" - "layers that contain layer masks.")); - tool->state = INACTIVE; - return; - } - - /* If the tool is already active, clear the current state - * and reset - */ - if (tool->state == ACTIVE) - gimp_transform_tool_reset (gt_tool, gdisp); - - /* Set the pointer to the active display */ - tool->gdisp = gdisp; - tool->drawable = drawable; - tool->state = ACTIVE; - - /* Grab the pointer if we're in non-interactive mode */ - if (! gt_tool->interactive) - gdk_pointer_grab (shell->canvas->window, FALSE, - GDK_POINTER_MOTION_HINT_MASK | - GDK_BUTTON1_MOTION_MASK | - GDK_BUTTON_RELEASE_MASK, - NULL, NULL, time); - - /* Find the transform bounds for some tools (like scale, - * perspective) that actually need the bounds for - * initializing - */ - gimp_transform_tool_bounds (gt_tool, gdisp); - - /* Initialize the transform tool */ - gimp_transform_tool_transform (gt_tool, gdisp, TRANSFORM_INIT); - - if (transform_info && !transform_info_inited) - { - GType tool_type; - - tool_type = - gimp_context_get_tool (gimp_get_user_context (gdisp->gimage->gimp))->tool_type; - - gimp_dialog_create_action_area - (GIMP_DIALOG (transform_info->shell), - - /* FIXME: this does not belong here */ - (tool_type == GIMP_TYPE_ROTATE_TOOL) ? _("Rotate") : - (tool_type == GIMP_TYPE_SCALE_TOOL) ? _("Scale") : - (tool_type == GIMP_TYPE_SHEAR_TOOL) ? _("Shear") : - (tool_type == GIMP_TYPE_PERSPECTIVE_TOOL) ? _("Transform") : - "EEK", - transform_ok_callback, - tool, NULL, NULL, TRUE, FALSE, - - _("Reset"), transform_reset_callback, - tool, NULL, NULL, FALSE, FALSE, - - NULL); - - transform_info_inited = TRUE; - } - - /* Recalculate the transform tool */ - gimp_transform_tool_recalc (gt_tool, gdisp); - - /* recall this function to find which handle we're dragging */ - if (gt_tool->interactive) - gimp_transform_tool_button_press (tool, coords, time, state, gdisp); - } - } -} - -static void -gimp_transform_tool_button_release (GimpTool *tool, - GimpCoords *coords, - guint32 time, - GdkModifierType state, - GimpDisplay *gdisp) -{ - GimpTransformTool *gt_tool; - gint i; - - gt_tool = GIMP_TRANSFORM_TOOL (tool); - - /* if we are creating, there is nothing to be done...exit */ - if (gt_tool->function == TRANSFORM_CREATING && gt_tool->interactive) - return; - - /* release of the pointer grab */ - gdk_pointer_ungrab (time); - gdk_flush (); - - /* if the 3rd button isn't pressed, transform the selected mask */ - if (! (state & GDK_BUTTON3_MASK)) - { - /* Shift-clicking is another way to approve the transform */ - if ((state & GDK_SHIFT_MASK) || GIMP_IS_FLIP_TOOL (tool)) - { - gimp_transform_tool_doit (gt_tool, gdisp); - } - else - { - /* Only update the paths preview */ - path_transform_current_path (gdisp->gimage, - gt_tool->transform, TRUE); - } - } - else - { - /* stop the current tool drawing process */ - gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool)); - - /* Restore the previous transformation info */ - for (i = 0; i < TRAN_INFO_SIZE; i++) - gt_tool->trans_info [i] = old_trans_info [i]; - - /* recalculate the tool's transformation matrix */ - gimp_transform_tool_recalc (gt_tool, gdisp); - - /* resume drawing the current tool */ - gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool)); - - /* Update the paths preview */ - path_transform_current_path (gdisp->gimage, - gt_tool->transform, TRUE); - } - - /* if this tool is non-interactive, make it inactive after use */ - if (! gt_tool->interactive) - tool->state = INACTIVE; -} - -static void -gimp_transform_tool_doit (GimpTransformTool *gt_tool, - GimpDisplay *gdisp) -{ - GimpDisplayShell *shell; - GimpTool *tool; - TileManager *new_tiles; - TransformUndo *tu; - PathUndo *pundo; - gboolean new_layer; - gint i; - - gimp_set_busy (gdisp->gimage->gimp); - - tool = GIMP_TOOL (gt_tool); - - shell = GIMP_DISPLAY_SHELL (gdisp->shell); - - /* undraw the tool before we muck around with the transform matrix */ - gimp_draw_tool_pause (GIMP_DRAW_TOOL (gt_tool)); - - /* We're going to dirty this image, but we want to keep the tool - * around - */ - tool->preserve = TRUE; - - /* Start a transform undo group */ - undo_push_group_start (gdisp->gimage, TRANSFORM_CORE_UNDO); - - /* With the old UI, if original is NULL, then this is the - * first transformation. In the new UI, it is always so, right? - */ - g_assert (gt_tool->original == NULL); - - /* If we're in interactive mode, we need to copy the current - * selection to the transform tool's private selection pointer, so - * that the original source can be repeatedly modified. - */ - tool->drawable = gimp_image_active_drawable (gdisp->gimage); - - gt_tool->original = gimp_transform_tool_cut (gdisp->gimage, - tool->drawable, - &new_layer); - - pundo = path_transform_start_undo (gdisp->gimage); - - /* Send the request for the transformation to the tool... - */ - new_tiles = gimp_transform_tool_transform (gt_tool, gdisp, - TRANSFORM_FINISH); - - gimp_transform_tool_transform (gt_tool, gdisp, TRANSFORM_INIT); - - gimp_transform_tool_recalc (gt_tool, gdisp); - - if (new_tiles) - { - /* paste the new transformed image to the gimage...also implement - * undo... - */ - /* FIXME: we should check if the drawable is still valid */ - gimp_transform_tool_paste (gdisp->gimage, tool->drawable, - new_tiles, new_layer); - - /* create and initialize the transform_undo structure */ - tu = g_new0 (TransformUndo, 1); - tu->tool_ID = tool->ID; - tu->tool_type = G_TYPE_FROM_INSTANCE (tool); - - for (i = 0; i < TRAN_INFO_SIZE; i++) - tu->trans_info[i] = old_trans_info[i]; - - tu->original = NULL; - tu->path_undo = pundo; - - /* Make a note of the new current drawable (since we may have - * a floating selection, etc now. - */ - tool->drawable = gimp_image_active_drawable (gdisp->gimage); - - undo_push_transform (gdisp->gimage, tu); - } - - /* push the undo group end */ - undo_push_group_end (gdisp->gimage); - - /* We're done dirtying the image, and would like to be restarted - * if the image gets dirty while the tool exists - */ - tool->preserve = FALSE; - -#ifdef __GNUC__ -#warning FIXME: investigate why display update was done here -#endif -#if 0 - /* Flush the gdisplays */ - if (gdisp->disp_xoffset || gdisp->disp_yoffset) - { - gint x, y; - - x = shell->disp_width; - y = shell->disp_height; - - if (gdisp->disp_yoffset) - { - gimp_display_shell_add_expose_area (shell, - 0, 0, - gdisp->disp_width, - gdisp->disp_yoffset); - gimp_display_shell_add_expose_area (shell, - 0, gdisp->disp_yoffset + y, - gdisp->disp_width, gdisp->disp_height); - } - - if (gdisp->disp_xoffset) - { - gimp_display_shell_add_expose_area (shell, - 0, 0, - gdisp->disp_xoffset, gdisp->disp_height); - gimp_display_shell_add_expose_area (shell, - gdisp->disp_xoffset + x, 0, - gdisp->disp_width, gdisp->disp_height); - } - } -#endif - - gimp_unset_busy (gdisp->gimage->gimp); - - gdisplays_flush (); - - gimp_transform_tool_reset (gt_tool, gdisp); - - /* if this tool is non-interactive, make it inactive after use */ - if (!gt_tool->interactive) - tool->state = INACTIVE; -} - -static void -gimp_transform_tool_motion (GimpTool *tool, - GimpCoords *coords, - guint32 time, - GdkModifierType state, - GimpDisplay *gdisp) -{ - GimpTransformTool *tr_tool; - - tr_tool = GIMP_TRANSFORM_TOOL (tool); - - /* if we are creating or this tool is non-interactive, there is - * nothing to be done so exit. - */ - if (tr_tool->function == TRANSFORM_CREATING || ! tr_tool->interactive) - return; - - gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool)); - - tr_tool->curx = coords->x; - tr_tool->cury = coords->y; - tr_tool->state = state; - - /* recalculate the tool's transformation matrix */ - gimp_transform_tool_transform (tr_tool, gdisp, TRANSFORM_MOTION); - - tr_tool->lastx = tr_tool->curx; - tr_tool->lasty = tr_tool->cury; - - gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool)); -} - -static void -gimp_transform_tool_cursor_update (GimpTool *tool, - GimpCoords *coords, - GdkModifierType state, - GimpDisplay *gdisp) -{ - GimpTransformTool *tr_tool; - GimpDrawable *drawable; - GdkCursorType ctype = GDK_TOP_LEFT_ARROW; - - tr_tool = GIMP_TRANSFORM_TOOL (tool); - - if ((drawable = gimp_image_active_drawable (gdisp->gimage))) - { - gint off_x, off_y; - - gimp_drawable_offsets (drawable, &off_x, &off_y); - - if (GIMP_IS_LAYER (drawable) && - gimp_layer_get_mask (GIMP_LAYER (drawable))) - { - ctype = GIMP_BAD_CURSOR; - } - else if (coords->x >= off_x && - coords->y >= off_y && - coords->x < (off_x + drawable->width) && - coords->y < (off_y + drawable->height)) - { - if (gimage_mask_is_empty (gdisp->gimage) || - gimage_mask_value (gdisp->gimage, coords->x, coords->y)) - { - ctype = GIMP_MOUSE_CURSOR; - } - } - } - - gimp_display_shell_install_tool_cursor (GIMP_DISPLAY_SHELL (gdisp->shell), - ctype, - tool->tool_cursor, - GIMP_CURSOR_MODIFIER_NONE); -} - -static void -gimp_transform_tool_draw (GimpDrawTool *draw_tool) -{ - GimpTransformTool *tr_tool; - gint i, k, gci; - - tr_tool = GIMP_TRANSFORM_TOOL (draw_tool); - - /* draw the bounding box */ - gimp_draw_tool_draw_line (draw_tool, - tr_tool->tx1, tr_tool->ty1, - tr_tool->tx2, tr_tool->ty2, - FALSE); - gimp_draw_tool_draw_line (draw_tool, - tr_tool->tx2, tr_tool->ty2, - tr_tool->tx4, tr_tool->ty4, - FALSE); - gimp_draw_tool_draw_line (draw_tool, - tr_tool->tx3, tr_tool->ty3, - tr_tool->tx4, tr_tool->ty4, - FALSE); - gimp_draw_tool_draw_line (draw_tool, - tr_tool->tx3, tr_tool->ty3, - tr_tool->tx1, tr_tool->ty1, - FALSE); - - /* Draw the grid */ - - if ((tr_tool->grid_coords != NULL) && - (tr_tool->tgrid_coords != NULL) /* FIXME!!! this doesn't belong here && - ((tool->type != PERSPECTIVE) || - ((tr_tool->transform[0][0] >=0.0) && - (tr_tool->transform[1][1] >=0.0)) */ ) - { - gci = 0; - k = tr_tool->ngx + tr_tool->ngy; - - for (i = 0; i < k; i++) - { - gimp_draw_tool_draw_line (draw_tool, - tr_tool->tgrid_coords[gci], - tr_tool->tgrid_coords[gci + 1], - tr_tool->tgrid_coords[gci + 2], - tr_tool->tgrid_coords[gci + 3], - FALSE); - gci += 4; - } - } - - /* draw the tool handles */ - gimp_draw_tool_draw_handle (draw_tool, - GIMP_HANDLE_SQUARE, - tr_tool->tx1, tr_tool->ty1, - HANDLE, HANDLE, - GTK_ANCHOR_CENTER, - FALSE); - gimp_draw_tool_draw_handle (draw_tool, - GIMP_HANDLE_SQUARE, - tr_tool->tx2, tr_tool->ty2, - HANDLE, HANDLE, - GTK_ANCHOR_CENTER, - FALSE); - gimp_draw_tool_draw_handle (draw_tool, - GIMP_HANDLE_SQUARE, - tr_tool->tx3, tr_tool->ty3, - HANDLE, HANDLE, - GTK_ANCHOR_CENTER, - FALSE); - gimp_draw_tool_draw_handle (draw_tool, - GIMP_HANDLE_SQUARE, - tr_tool->tx4, tr_tool->ty4, - HANDLE, HANDLE, - GTK_ANCHOR_CENTER, - FALSE); - - /* draw the center */ - gimp_draw_tool_draw_handle (draw_tool, - GIMP_HANDLE_FILLED_CIRCLE, - tr_tool->tcx, tr_tool->tcy, - HANDLE, HANDLE, - GTK_ANCHOR_CENTER, - FALSE); - - if (gimp_transform_tool_showpath ()) - { - GimpMatrix3 tmp_matrix; - - if (gimp_transform_tool_direction () == TRANSFORM_CORRECTIVE) - { - gimp_matrix3_invert (tr_tool->transform, tmp_matrix); - } - else - { - gimp_matrix3_duplicate (tr_tool->transform, tmp_matrix); - } - - path_transform_draw_current (GIMP_TOOL (draw_tool)->gdisp, - draw_tool, tmp_matrix); - } -} - -void -gimp_transform_tool_transform_bounding_box (GimpTransformTool *tr_tool) -{ - GimpTool *tool; - gint i, k; - gint gci; - - tool = GIMP_TOOL (tr_tool); - - gimp_matrix3_transform_point (tr_tool->transform, - tr_tool->x1, tr_tool->y1, - &tr_tool->tx1, &tr_tool->ty1); - gimp_matrix3_transform_point (tr_tool->transform, - tr_tool->x2, tr_tool->y1, - &tr_tool->tx2, &tr_tool->ty2); - gimp_matrix3_transform_point (tr_tool->transform, - tr_tool->x1, tr_tool->y2, - &tr_tool->tx3, &tr_tool->ty3); - gimp_matrix3_transform_point (tr_tool->transform, - tr_tool->x2, tr_tool->y2, - &tr_tool->tx4, &tr_tool->ty4); - - gimp_matrix3_transform_point (tr_tool->transform, - tr_tool->cx, tr_tool->cy, - &tr_tool->tcx, &tr_tool->tcy); - - if (tr_tool->grid_coords != NULL && - tr_tool->tgrid_coords != NULL) - { - gci = 0; - k = (tr_tool->ngx + tr_tool->ngy) * 2; - - for (i = 0; i < k; i++) - { - gimp_matrix3_transform_point (tr_tool->transform, - tr_tool->grid_coords[gci], - tr_tool->grid_coords[gci+1], - &(tr_tool->tgrid_coords[gci]), - &(tr_tool->tgrid_coords[gci+1])); - gci += 2; - } - } -} - -void -gimp_transform_tool_reset (GimpTransformTool *tr_tool, - GimpDisplay *gdisp) -{ - GimpTool *tool; - - tool = GIMP_TOOL (tr_tool); - - if (tr_tool->original) - { - tile_manager_destroy (tr_tool->original); - tr_tool->original = NULL; - } - - /* inactivate the tool */ - tr_tool->function = TRANSFORM_CREATING; - gimp_draw_tool_stop (GIMP_DRAW_TOOL (tr_tool)); - info_dialog_popdown (transform_info); - - tool->state = INACTIVE; - tool->gdisp = NULL; - tool->drawable = NULL; -} - -static void -gimp_transform_tool_bounds (GimpTransformTool *tr_tool, - GimpDisplay *gdisp) -{ - TileManager *tiles; - GimpDrawable *drawable; - gint offset_x, offset_y; - - tiles = tr_tool->original; - drawable = gimp_image_active_drawable (gdisp->gimage); - - /* find the boundaries */ - if (tiles) - { - tile_manager_get_offsets (tiles, - &tr_tool->x1, &tr_tool->y1); - - tr_tool->x2 = tr_tool->x1 + tile_manager_width (tiles); - tr_tool->y2 = tr_tool->y1 + tile_manager_height (tiles); - } - else - { - gimp_drawable_offsets (drawable, &offset_x, &offset_y); - gimp_drawable_mask_bounds (drawable, - &tr_tool->x1, &tr_tool->y1, - &tr_tool->x2, &tr_tool->y2); - tr_tool->x1 += offset_x; - tr_tool->y1 += offset_y; - tr_tool->x2 += offset_x; - tr_tool->y2 += offset_y; - } - - tr_tool->cx = (tr_tool->x1 + tr_tool->x2) / 2; - tr_tool->cy = (tr_tool->y1 + tr_tool->y2) / 2; - - /* changing the bounds invalidates any grid we may have */ - gimp_transform_tool_grid_recalc (tr_tool); -} - -void -gimp_transform_tool_grid_density_changed (void) -{ - GimpTransformTool *tr_tool; - GimpDrawTool *dr_tool; - - /* EEEK!!! */ - tr_tool = GIMP_TRANSFORM_TOOL (tool_manager_get_active (the_gimp)); - - dr_tool = GIMP_DRAW_TOOL (tr_tool); - - if (tr_tool->function == TRANSFORM_CREATING) - return; - - gimp_draw_tool_pause (dr_tool); - - gimp_transform_tool_grid_recalc (tr_tool); - gimp_transform_tool_transform_bounding_box (tr_tool); - - gimp_draw_tool_resume (dr_tool); -} - -void -gimp_transform_tool_showpath_changed (gint type /* a truly undescriptive name */) -{ - GimpTransformTool *tr_tool; - - /* EEEEEEEK!!! */ - tr_tool = GIMP_TRANSFORM_TOOL (tool_manager_get_active (the_gimp)); - - if (tr_tool->function == TRANSFORM_CREATING) - return; - - if (type) - gimp_draw_tool_pause (GIMP_DRAW_TOOL (tr_tool)); - else - gimp_draw_tool_resume (GIMP_DRAW_TOOL (tr_tool)); -} - -static void -gimp_transform_tool_grid_recalc (GimpTransformTool *tr_tool) -{ - if (tr_tool->grid_coords != NULL) - { - g_free (tr_tool->grid_coords); - tr_tool->grid_coords = NULL; - } - - if (tr_tool->tgrid_coords != NULL) - { - g_free (tr_tool->tgrid_coords); - tr_tool->tgrid_coords = NULL; - } - - if (gimp_transform_tool_show_grid ()) - gimp_transform_tool_setup_grid (tr_tool); -} - -static void -gimp_transform_tool_setup_grid (GimpTransformTool *tr_tool) -{ - GimpTool *tool; - gint i, gci; - gdouble *coords; - - tool = GIMP_TOOL (tr_tool); - - /* We use the gimp_transform_tool_grid_size function only here, even - * if the user changes the grid size in the middle of an - * operation, nothing happens. - */ - tr_tool->ngx = (tr_tool->x2 - tr_tool->x1) / gimp_transform_tool_grid_size (); - if (tr_tool->ngx > 0) - tr_tool->ngx--; - - tr_tool->ngy = (tr_tool->y2 - tr_tool->y1) / gimp_transform_tool_grid_size (); - if (tr_tool->ngy > 0) - tr_tool->ngy--; - - tr_tool->grid_coords = coords = - g_new (gdouble, (tr_tool->ngx + tr_tool->ngy) * 4); - - tr_tool->tgrid_coords = - g_new (gdouble, (tr_tool->ngx + tr_tool->ngy) * 4); - - gci = 0; - - for (i = 1; i <= tr_tool->ngx; i++) - { - coords[gci] = tr_tool->x1 + - ((gdouble) i) / (tr_tool->ngx + 1) * - (tr_tool->x2 - tr_tool->x1); - coords[gci+1] = tr_tool->y1; - coords[gci+2] = coords[gci]; - coords[gci+3] = tr_tool->y2; - gci += 4; - } - - for (i = 1; i <= tr_tool->ngy; i++) - { - coords[gci] = tr_tool->x1; - coords[gci+1] = tr_tool->y1 + - ((gdouble) i) / (tr_tool->ngy + 1) * - (tr_tool->y2 - tr_tool->y1); - coords[gci+2] = tr_tool->x2; - coords[gci+3] = coords[gci+1]; - gci += 4; - } -} - -static void -gimp_transform_tool_recalc (GimpTransformTool *tr_tool, - GimpDisplay *gdisp) -{ - gimp_transform_tool_bounds (tr_tool, gdisp); - - gimp_transform_tool_transform (tr_tool, gdisp, TRANSFORM_RECALC); -} - -/* Actually carry out a transformation */ -TileManager * -gimp_transform_tool_do (GimpImage *gimage, - GimpDrawable *drawable, - TileManager *float_tiles, - gboolean interpolation, - GimpMatrix3 matrix, - GimpProgressFunc progress_callback, - gpointer progress_data) +gimp_drawable_transform_tiles_affine (GimpDrawable *drawable, + TileManager *float_tiles, + gboolean interpolation, + gboolean clip_result, + GimpMatrix3 matrix, + GimpTransformDirection direction, + GimpProgressFunc progress_callback, + gpointer progress_data) { + GimpImage *gimage; PixelRegion destPR; TileManager *tiles; GimpMatrix3 m; @@ -1175,6 +113,13 @@ gimp_transform_tool_do (GimpImage *gimage, PixelSurround surround; + g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL); + g_return_val_if_fail (float_tiles != NULL, NULL); + + gimage = gimp_drawable_gimage (drawable); + + g_return_val_if_fail (GIMP_IS_IMAGE (gimage), NULL); + alpha = 0; /* turn interpolation off for simple transformations (e.g. rot90) */ @@ -1217,10 +162,11 @@ gimp_transform_tool_do (GimpImage *gimage, alpha = 0; } - if (gimp_transform_tool_direction () == TRANSFORM_CORRECTIVE) + if (direction == GIMP_TRANSFORM_BACKWARD) { /* keep the original matrix here, so we dont need to recalculate - the inverse later */ + * the inverse later + */ gimp_matrix3_duplicate (matrix, m); gimp_matrix3_invert (matrix, im); matrix = im; @@ -1231,15 +177,19 @@ gimp_transform_tool_do (GimpImage *gimage, gimp_matrix3_invert (matrix, m); } +#ifdef __GNUC__ +#warning FIXME: path_transform_current_path +#endif +#if 0 path_transform_current_path (gimage, matrix, FALSE); +#endif tile_manager_get_offsets (float_tiles, &x1, &y1); x2 = x1 + tile_manager_width (float_tiles); y2 = y1 + tile_manager_height (float_tiles); /* Find the bounding coordinates */ - if (alpha == 0 || (tool_manager_get_active (gimage->gimp) && - gimp_transform_tool_clip ())) + if (alpha == 0 || clip_result) { tx1 = x1; ty1 = y1; @@ -1376,7 +326,7 @@ gimp_transform_tool_do (GimpImage *gimage, /* calculate alpha of result */ start = &data[alpha]; - a_val = gimp_transform_tool_cubic + a_val = gimp_drawable_transform_cubic (dy, CUBIC_ROW (dx, start, bytes), CUBIC_ROW (dx, start + row, bytes), @@ -1409,7 +359,7 @@ gimp_transform_tool_do (GimpImage *gimage, start = &data[alpha]; newval = RINT (a_recip * - gimp_transform_tool_cubic + gimp_drawable_transform_cubic (dy, CUBIC_SCALED_ROW (dx, start, bytes, i), CUBIC_SCALED_ROW (dx, start + row, bytes, i), @@ -1574,20 +524,183 @@ gimp_transform_tool_do (GimpImage *gimage, } TileManager * -gimp_transform_tool_cut (GimpImage *gimage, - GimpDrawable *drawable, - gboolean *new_layer) +gimp_drawable_transform_tiles_flip (GimpDrawable *drawable, + TileManager *orig, + InternalOrientationType flip_type) { + TileManager *new; + PixelRegion srcPR, destPR; + gint orig_width; + gint orig_height; + gint orig_bpp; + gint orig_x, orig_y; + gint i; + + g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL); + g_return_val_if_fail (orig != NULL, NULL); + + orig_width = tile_manager_width (orig); + orig_height = tile_manager_height (orig); + orig_bpp = tile_manager_bpp (orig); + tile_manager_get_offsets (orig, &orig_x, &orig_y); + + new = tile_manager_new (orig_width, orig_height, orig_bpp); + tile_manager_set_offsets (new, orig_x, orig_y); + + if (flip_type == ORIENTATION_HORIZONTAL) + { + for (i = 0; i < orig_width; i++) + { + pixel_region_init (&srcPR, orig, i, 0, 1, orig_height, FALSE); + pixel_region_init (&destPR, new, + (orig_width - i - 1), 0, 1, orig_height, TRUE); + copy_region (&srcPR, &destPR); + } + } + else + { + for (i = 0; i < orig_height; i++) + { + pixel_region_init (&srcPR, orig, 0, i, orig_width, 1, FALSE); + pixel_region_init (&destPR, new, + 0, (orig_height - i - 1), orig_width, 1, TRUE); + copy_region (&srcPR, &destPR); + } + } + +#ifdef __GNUC__ +#warning FIXME: path_transform_flip_horz/vert +#endif +#if 0 + /* flip locked paths */ + /* Note that the undo structures etc are setup before we enter this + * function. + */ + if (flip_type == ORIENTATION_HORIZONTAL) + path_transform_flip_horz (gimage); + else + path_transform_flip_vert (gimage); +#endif + + return new; +} + +gboolean +gimp_drawable_transform_affine (GimpDrawable *drawable, + gboolean interpolation, + gboolean clip_result, + GimpMatrix3 matrix, + GimpTransformDirection direction) +{ + GimpImage *gimage; + TileManager *float_tiles; + gboolean new_layer; + gboolean success = FALSE; + + g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), FALSE); + + gimage = gimp_drawable_gimage (drawable); + + g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE); + + /* Start a transform undo group */ + undo_push_group_start (gimage, TRANSFORM_CORE_UNDO); + + /* Cut/Copy from the specified drawable */ + float_tiles = gimp_drawable_transform_cut (drawable, &new_layer); + + if (float_tiles) + { + TileManager *new_tiles; + + /* transform the buffer */ + new_tiles = gimp_drawable_transform_tiles_affine (drawable, + float_tiles, + interpolation, + FALSE, + matrix, + GIMP_TRANSFORM_FORWARD, + NULL, NULL); + + /* Free the cut/copied buffer */ + tile_manager_destroy (float_tiles); + + if (new_tiles) + success = gimp_drawable_transform_paste (drawable, new_tiles, new_layer); + } + + /* push the undo group end */ + undo_push_group_end (gimage); + + return success; +} + +gboolean +gimp_drawable_transform_flip (GimpDrawable *drawable, + InternalOrientationType flip_type) +{ + GimpImage *gimage; + TileManager *float_tiles; + gboolean new_layer; + gboolean success = FALSE; + + g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), FALSE); + + gimage = gimp_drawable_gimage (drawable); + + g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE); + + /* Start a transform undo group */ + undo_push_group_start (gimage, TRANSFORM_CORE_UNDO); + + /* Cut/Copy from the specified drawable */ + float_tiles = gimp_drawable_transform_cut (drawable, &new_layer); + + if (float_tiles) + { + TileManager *new_tiles; + + /* transform the buffer */ + new_tiles = gimp_drawable_transform_tiles_flip (drawable, + float_tiles, + flip_type); + + /* Free the cut/copied buffer */ + tile_manager_destroy (float_tiles); + + if (new_tiles) + success = gimp_drawable_transform_paste (drawable, new_tiles, new_layer); + } + + /* push the undo group end */ + undo_push_group_end (gimage); + + return success; +} + +TileManager * +gimp_drawable_transform_cut (GimpDrawable *drawable, + gboolean *new_layer) +{ + GimpImage *gimage; TileManager *tiles; + g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL); + g_return_val_if_fail (new_layer != NULL, NULL); + + gimage = gimp_drawable_gimage (drawable); + + g_return_val_if_fail (GIMP_IS_IMAGE (gimage), NULL); + /* extract the selected mask if there is a selection */ if (! gimage_mask_is_empty (gimage)) { /* set the keep_indexed flag to FALSE here, since we use - gimp_layer_new_from_tiles() later which assumes that the tiles - are either RGB or GRAY. Eeek!!! (Sven) + * gimp_layer_new_from_tiles() later which assumes that the tiles + * are either RGB or GRAY. Eeek!!! (Sven) */ tiles = gimage_mask_extract (gimage, drawable, TRUE, FALSE, TRUE); + *new_layer = TRUE; } /* otherwise, just copy the layer */ @@ -1597,24 +710,30 @@ gimp_transform_tool_cut (GimpImage *gimage, tiles = gimage_mask_extract (gimage, drawable, FALSE, TRUE, TRUE); else tiles = gimage_mask_extract (gimage, drawable, FALSE, TRUE, FALSE); + *new_layer = FALSE; } return tiles; } - -/* Paste a transform to the gdisplay */ gboolean -gimp_transform_tool_paste (GimpImage *gimage, - GimpDrawable *drawable, - TileManager *tiles, - gboolean new_layer) +gimp_drawable_transform_paste (GimpDrawable *drawable, + TileManager *tiles, + gboolean new_layer) { + GimpImage *gimage; GimpLayer *layer = NULL; GimpChannel *channel = NULL; GimpLayer *floating_layer; + g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), FALSE); + g_return_val_if_fail (tiles != NULL, FALSE); + + gimage = gimp_drawable_gimage (drawable); + + g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE); + if (new_layer) { layer = @@ -1706,11 +825,11 @@ gimp_transform_tool_paste (GimpImage *gimage, /* Note: cubic function no longer clips result */ static gdouble -gimp_transform_tool_cubic (gdouble dx, - gint jm1, - gint j, - gint jp1, - gint jp2) +gimp_drawable_transform_cubic (gdouble dx, + gint jm1, + gint j, + gint jp1, + gint jp2) { gdouble result; diff --git a/app/core/gimpdrawable-transform.h b/app/core/gimpdrawable-transform.h new file mode 100644 index 0000000000..3db0f9f91a --- /dev/null +++ b/app/core/gimpdrawable-transform.h @@ -0,0 +1,64 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995-2001 Spencer Kimball, Peter Mattis, and others + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GIMP_DRAWABLE_TRANSFORM_H__ +#define __GIMP_DRAWABLE_TRANSFORM_H__ + + +typedef enum +{ + X0, + Y0, + X1, + Y1, + X2, + Y2, + X3, + Y3 +} GimpTransformBoundingBox; + + +TileManager * gimp_drawable_transform_tiles_affine (GimpDrawable *drawable, + TileManager *float_tiles, + gboolean interpolation, + gboolean clip_result, + GimpMatrix3 matrix, + GimpTransformDirection direction, + GimpProgressFunc progress_callback, + gpointer progress_data); +TileManager * gimp_drawable_transform_tiles_flip (GimpDrawable *drawable, + TileManager *orig, + InternalOrientationType flip_type); + +gboolean gimp_drawable_transform_affine (GimpDrawable *drawable, + gboolean interpolation, + gboolean clip_result, + GimpMatrix3 matrix, + GimpTransformDirection direction); +gboolean gimp_drawable_transform_flip (GimpDrawable *drawable, + InternalOrientationType flip_type); + + +TileManager * gimp_drawable_transform_cut (GimpDrawable *drawable, + gboolean *new_layer); +gboolean gimp_drawable_transform_paste (GimpDrawable *drawable, + TileManager *tiles, + gboolean new_layer); + + +#endif /* __GIMP_DRAWABLE_TRANSFORM_H__ */ diff --git a/app/display/gimpdisplay-foreach.c b/app/display/gimpdisplay-foreach.c index d7c48fe262..a7116da628 100644 --- a/app/display/gimpdisplay-foreach.c +++ b/app/display/gimpdisplay-foreach.c @@ -93,8 +93,8 @@ gdisplays_delete (void) { GimpDisplay *gdisp; - /* destroying the shell removes the GimpDisplay from the list, so - * do a while loop "around" the first element to get them all + /* this removes the GimpDisplay from the list, so do a while loop + * "around" the first element to get them all */ while (display_list) { diff --git a/app/tools/gimpfliptool.c b/app/tools/gimpfliptool.c index acbe049b21..1eab9c5750 100644 --- a/app/tools/gimpfliptool.c +++ b/app/tools/gimpfliptool.c @@ -27,15 +27,11 @@ #include "tools-types.h" -#include "base/pixel-region.h" -#include "base/tile-manager.h" - -#include "paint-funcs/paint-funcs.h" - #include "core/gimpdrawable.h" +#include "core/gimpdrawable-transform.h" #include "core/gimpimage.h" #include "core/gimpimage-mask.h" -#include "core/gimplayer.h" +#include "core/gimptoolinfo.h" #include "display/gimpdisplay.h" #include "display/gimpdisplayshell.h" @@ -44,7 +40,6 @@ #include "tool_manager.h" #include "tool_options.h" -#include "undo.h" #include "path_transform.h" #include "libgimp/gimpintl.h" @@ -54,8 +49,6 @@ * the ORIENTATION_FOO constants. */ -#define FLIP_INFO 0 - typedef struct _FlipOptions FlipOptions; struct _FlipOptions @@ -140,75 +133,6 @@ gimp_flip_tool_get_type (void) return tool_type; } -TileManager * -flip_tool_flip (GimpImage *gimage, - GimpDrawable *drawable, - TileManager *orig, - gint flip, - InternalOrientationType type) -{ - TileManager *new; - PixelRegion srcPR, destPR; - gint orig_width; - gint orig_height; - gint orig_bpp; - gint orig_x, orig_y; - gint i; - - if (! orig) - return NULL; - - orig_width = tile_manager_width (orig); - orig_height = tile_manager_height (orig); - orig_bpp = tile_manager_bpp (orig); - tile_manager_get_offsets (orig, &orig_x, &orig_y); - - if (flip > 0) - { - new = tile_manager_new (orig_width, orig_height, orig_bpp); - pixel_region_init (&srcPR, orig, - 0, 0, orig_width, orig_height, FALSE); - pixel_region_init (&destPR, new, - 0, 0, orig_width, orig_height, TRUE); - - copy_region (&srcPR, &destPR); - tile_manager_set_offsets (new, orig_x, orig_y); - } - else - { - new = tile_manager_new (orig_width, orig_height, orig_bpp); - tile_manager_set_offsets (new, orig_x, orig_y); - - if (type == ORIENTATION_HORIZONTAL) - for (i = 0; i < orig_width; i++) - { - pixel_region_init (&srcPR, orig, i, 0, 1, orig_height, FALSE); - pixel_region_init (&destPR, new, - (orig_width - i - 1), 0, 1, orig_height, TRUE); - copy_region (&srcPR, &destPR); - } - else - for (i = 0; i < orig_height; i++) - { - pixel_region_init (&srcPR, orig, 0, i, orig_width, 1, FALSE); - pixel_region_init (&destPR, new, - 0, (orig_height - i - 1), orig_width, 1, TRUE); - copy_region (&srcPR, &destPR); - } - - /* flip locked paths */ - /* Note that the undo structures etc are setup before we enter this - * function. - */ - if (type == ORIENTATION_HORIZONTAL) - path_transform_flip_horz (gimage); - else - path_transform_flip_vert (gimage); - } - - return new; -} - /* private functions */ @@ -237,10 +161,10 @@ static void gimp_flip_tool_init (GimpFlipTool *flip_tool) { GimpTool *tool; - GimpTransformTool *tr_tool; + GimpTransformTool *transform_tool; - tool = GIMP_TOOL (flip_tool); - tr_tool = GIMP_TRANSFORM_TOOL (flip_tool); + tool = GIMP_TOOL (flip_tool); + transform_tool = GIMP_TRANSFORM_TOOL (flip_tool); /* The tool options */ if (! flip_options) @@ -251,12 +175,12 @@ gimp_flip_tool_init (GimpFlipTool *flip_tool) (GimpToolOptions *) flip_options); } - tr_tool->trans_info[FLIP_INFO] = -1.0; - tool->tool_cursor = GIMP_FLIP_HORIZONTAL_TOOL_CURSOR; tool->toggle_cursor = GIMP_FLIP_VERTICAL_TOOL_CURSOR; tool->auto_snap_to = FALSE; /* Don't snap to guides */ + + transform_tool->use_grid = FALSE; } static void @@ -266,18 +190,22 @@ gimp_flip_tool_modifier_key (GimpTool *tool, GdkModifierType state, GimpDisplay *gdisp) { + FlipOptions *options; + + options = (FlipOptions *) tool->tool_info->tool_options; + if (key == GDK_CONTROL_MASK) { - switch (flip_options->type) + switch (options->type) { case ORIENTATION_HORIZONTAL: gtk_toggle_button_set_active - (GTK_TOGGLE_BUTTON (flip_options->type_w[ORIENTATION_VERTICAL - 1]), + (GTK_TOGGLE_BUTTON (options->type_w[ORIENTATION_VERTICAL - 1]), TRUE); break; case ORIENTATION_VERTICAL: gtk_toggle_button_set_active - (GTK_TOGGLE_BUTTON (flip_options->type_w[ORIENTATION_HORIZONTAL - 1]), + (GTK_TOGGLE_BUTTON (options->type_w[ORIENTATION_HORIZONTAL - 1]), TRUE); break; default: @@ -296,9 +224,12 @@ gimp_flip_tool_cursor_update (GimpTool *tool, GimpDrawable *drawable; GdkCursorType ctype = GIMP_BAD_CURSOR; GimpToolCursorType tool_cursor = GIMP_FLIP_HORIZONTAL_TOOL_CURSOR; + FlipOptions *options; shell = GIMP_DISPLAY_SHELL (gdisp->shell); + options = (FlipOptions *) tool->tool_info->tool_options; + if ((drawable = gimp_image_active_drawable (gdisp->gimage))) { gint off_x, off_y; @@ -314,7 +245,7 @@ gimp_flip_tool_cursor_update (GimpTool *tool, if (gimage_mask_is_empty (gdisp->gimage) || gimage_mask_value (gdisp->gimage, coords->x, coords->y)) { - if (flip_options->type == ORIENTATION_HORIZONTAL) + if (options->type == ORIENTATION_HORIZONTAL) ctype = GDK_SB_H_DOUBLE_ARROW; else ctype = GDK_SB_V_DOUBLE_ARROW; @@ -322,7 +253,7 @@ gimp_flip_tool_cursor_update (GimpTool *tool, } } - if (flip_options->type == ORIENTATION_HORIZONTAL) + if (options->type == ORIENTATION_HORIZONTAL) tool_cursor = GIMP_FLIP_HORIZONTAL_TOOL_CURSOR; else tool_cursor = GIMP_FLIP_VERTICAL_TOOL_CURSOR; @@ -338,9 +269,9 @@ gimp_flip_tool_transform (GimpTransformTool *trans_tool, GimpDisplay *gdisp, TransformState state) { - GimpTool *tool; + FlipOptions *options; - tool = GIMP_TOOL (trans_tool); + options = (FlipOptions *) GIMP_TOOL (trans_tool)->tool_info->tool_options; switch (state) { @@ -355,11 +286,9 @@ gimp_flip_tool_transform (GimpTransformTool *trans_tool, break; case TRANSFORM_FINISH: - return flip_tool_flip (gdisp->gimage, - gimp_image_active_drawable (gdisp->gimage), - trans_tool->original, - (gint) trans_tool->trans_info[FLIP_INFO], - flip_options->type); + return gimp_drawable_transform_tiles_flip (gimp_image_active_drawable (gdisp->gimage), + trans_tool->original, + options->type); break; } @@ -383,18 +312,20 @@ flip_options_new (void) vbox = options->tool_options.main_vbox; /* tool toggle */ - frame = - gimp_radio_group_new2 (TRUE, _("Tool Toggle"), - G_CALLBACK (gimp_radio_button_update), - &options->type, - (gpointer) options->type, + frame = gimp_radio_group_new2 (TRUE, _("Tool Toggle"), + G_CALLBACK (gimp_radio_button_update), + &options->type, + GINT_TO_POINTER (options->type), - _("Horizontal"), (gpointer) ORIENTATION_HORIZONTAL, - &options->type_w[0], - _("Vertical"), (gpointer) ORIENTATION_VERTICAL, - &options->type_w[1], + _("Horizontal"), + GINT_TO_POINTER (ORIENTATION_HORIZONTAL), + &options->type_w[0], - NULL); + _("Vertical"), + GINT_TO_POINTER (ORIENTATION_VERTICAL), + &options->type_w[1], + + NULL); gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); gtk_widget_show (frame); diff --git a/app/tools/gimpfliptool.h b/app/tools/gimpfliptool.h index 367f2a4839..2ba13bd0d2 100644 --- a/app/tools/gimpfliptool.h +++ b/app/tools/gimpfliptool.h @@ -45,15 +45,9 @@ struct _GimpFlipToolClass }; -void gimp_flip_tool_register (Gimp *gimp); +void gimp_flip_tool_register (Gimp *gimp); -GType gimp_flip_tool_get_type (void); - -TileManager * flip_tool_flip (GimpImage *gimage, - GimpDrawable *drawable, - TileManager *orig, - gint flip, - InternalOrientationType type); +GType gimp_flip_tool_get_type (void); #endif /* __GIMP_FLIP_TOOL_H__ */ diff --git a/app/tools/gimpperspectivetool.c b/app/tools/gimpperspectivetool.c index ae889dae5a..7815ef9ab9 100644 --- a/app/tools/gimpperspectivetool.c +++ b/app/tools/gimpperspectivetool.c @@ -27,34 +27,35 @@ #include "gui/gui-types.h" #include "core/gimpimage.h" - -#include "gui/info-dialog.h" +#include "core/gimpdrawable-transform.h" +#include "core/gimpdrawable-transform-utils.h" +#include "core/gimptoolinfo.h" #include "display/gimpdisplay.h" +#include "gui/info-dialog.h" + #include "gimpperspectivetool.h" #include "tool_manager.h" -#include "tool_options.h" #include "transform_options.h" -#include "gimpprogress.h" -#include "undo.h" - #include "libgimp/gimpintl.h" -/* forward function declarations */ -static void gimp_perspective_tool_class_init (GimpPerspectiveToolClass *klass); -static void gimp_perspective_tool_init (GimpPerspectiveTool *perspective_tool); +/* local function prototypes */ -static TileManager * gimp_perspective_tool_transform (GimpTransformTool *transform_tool, - GimpDisplay *gdisp, - TransformState state); -static void perspective_tool_recalc (GimpTool *tool, - GimpDisplay *gdisp); -static void perspective_tool_motion (GimpTool *tool, - GimpDisplay *gdisp); -static void perspective_info_update (GimpTool *tool); +static void gimp_perspective_tool_class_init (GimpPerspectiveToolClass *klass); +static void gimp_perspective_tool_init (GimpPerspectiveTool *perspective_tool); + +static TileManager * gimp_perspective_tool_transform (GimpTransformTool *transform_tool, + GimpDisplay *gdisp, + TransformState state); + +static void perspective_tool_recalc (GimpTransformTool *tr_tool, + GimpDisplay *gdisp); +static void perspective_tool_motion (GimpTransformTool *tr_tool, + GimpDisplay *gdisp); +static void perspective_info_update (GimpTransformTool *tr_tool); /* storage for information dialog fields */ @@ -125,10 +126,10 @@ static void gimp_perspective_tool_init (GimpPerspectiveTool *perspective_tool) { GimpTool *tool; - GimpTransformTool *tr_tool; + GimpTransformTool *transform_tool; - tool = GIMP_TOOL (perspective_tool); - tr_tool = GIMP_TRANSFORM_TOOL (perspective_tool); + tool = GIMP_TOOL (perspective_tool); + transform_tool = GIMP_TRANSFORM_TOOL (perspective_tool); if (! perspective_options) { @@ -139,93 +140,7 @@ gimp_perspective_tool_init (GimpPerspectiveTool *perspective_tool) (GimpToolOptions *) perspective_options); } - tool->tool_cursor = GIMP_PERSPECTIVE_TOOL_CURSOR; - - tr_tool->trans_info[X0] = 0; - tr_tool->trans_info[Y0] = 0; - tr_tool->trans_info[X1] = 0; - tr_tool->trans_info[Y1] = 0; - tr_tool->trans_info[X2] = 0; - tr_tool->trans_info[Y2] = 0; - tr_tool->trans_info[X3] = 0; - tr_tool->trans_info[Y3] = 0; - - /* assemble the transformation matrix */ - gimp_matrix3_identity (tr_tool->transform); - -} - -TileManager * -gimp_perspective_tool_perspective (GimpImage *gimage, - GimpDrawable *drawable, - GimpDisplay *gdisp, - TileManager *float_tiles, - gboolean interpolation, - GimpMatrix3 matrix) -{ - GimpProgress *progress; - TileManager *ret; - - progress = progress_start (gdisp, _("Perspective..."), FALSE, NULL, NULL); - - ret = gimp_transform_tool_do (gimage, drawable, float_tiles, - interpolation, matrix, - progress ? progress_update_and_flush : - (GimpProgressFunc) NULL, - progress); - - if (progress) - progress_end (progress); - - return ret; -} - -void -gimp_perspective_tool_find_transform (gdouble *coords, - GimpMatrix3 matrix) -{ - gdouble dx1, dx2, dx3, dy1, dy2, dy3; - gdouble det1, det2; - - dx1 = coords[X1] - coords[X3]; - dx2 = coords[X2] - coords[X3]; - dx3 = coords[X0] - coords[X1] + coords[X3] - coords[X2]; - - dy1 = coords[Y1] - coords[Y3]; - dy2 = coords[Y2] - coords[Y3]; - dy3 = coords[Y0] - coords[Y1] + coords[Y3] - coords[Y2]; - - /* Is the mapping affine? */ - if ((dx3 == 0.0) && (dy3 == 0.0)) - { - matrix[0][0] = coords[X1] - coords[X0]; - matrix[0][1] = coords[X3] - coords[X1]; - matrix[0][2] = coords[X0]; - matrix[1][0] = coords[Y1] - coords[Y0]; - matrix[1][1] = coords[Y3] - coords[Y1]; - matrix[1][2] = coords[Y0]; - matrix[2][0] = 0.0; - matrix[2][1] = 0.0; - } - else - { - det1 = dx3 * dy2 - dy3 * dx2; - det2 = dx1 * dy2 - dy1 * dx2; - matrix[2][0] = det1 / det2; - det1 = dx1 * dy3 - dy1 * dx3; - det2 = dx1 * dy2 - dy1 * dx2; - matrix[2][1] = det1 / det2; - - matrix[0][0] = coords[X1] - coords[X0] + matrix[2][0] * coords[X1]; - matrix[0][1] = coords[X2] - coords[X0] + matrix[2][1] * coords[X2]; - matrix[0][2] = coords[X0]; - - matrix[1][0] = coords[Y1] - coords[Y0] + matrix[2][0] * coords[Y1]; - matrix[1][1] = coords[Y2] - coords[Y0] + matrix[2][1] * coords[Y2]; - matrix[1][2] = coords[Y0]; - } - - matrix[2][2] = 1.0; + tool->tool_cursor = GIMP_PERSPECTIVE_TOOL_CURSOR; } static TileManager * @@ -233,57 +148,46 @@ gimp_perspective_tool_transform (GimpTransformTool *transform_tool, GimpDisplay *gdisp, TransformState state) { - GimpTool *tool; - - tool = GIMP_TOOL (transform_tool); - switch (state) { case TRANSFORM_INIT: - if (!transform_info) + if (! transform_info) { transform_info = info_dialog_new (_("Perspective Transform Information"), gimp_standard_help_func, "tools/transform_perspective.html"); + info_dialog_add_label (transform_info, _("Matrix:"), matrix_row_buf[0]); info_dialog_add_label (transform_info, "", matrix_row_buf[1]); info_dialog_add_label (transform_info, "", matrix_row_buf[2]); } + gtk_widget_set_sensitive (GTK_WIDGET (transform_info->shell), TRUE); - transform_tool->trans_info [X0] = (double) transform_tool->x1; - transform_tool->trans_info [Y0] = (double) transform_tool->y1; - transform_tool->trans_info [X1] = (double) transform_tool->x2; - transform_tool->trans_info [Y1] = (double) transform_tool->y1; - transform_tool->trans_info [X2] = (double) transform_tool->x1; - transform_tool->trans_info [Y2] = (double) transform_tool->y2; - transform_tool->trans_info [X3] = (double) transform_tool->x2; - transform_tool->trans_info [Y3] = (double) transform_tool->y2; - - return NULL; + transform_tool->trans_info [X0] = (gdouble) transform_tool->x1; + transform_tool->trans_info [Y0] = (gdouble) transform_tool->y1; + transform_tool->trans_info [X1] = (gdouble) transform_tool->x2; + transform_tool->trans_info [Y1] = (gdouble) transform_tool->y1; + transform_tool->trans_info [X2] = (gdouble) transform_tool->x1; + transform_tool->trans_info [Y2] = (gdouble) transform_tool->y2; + transform_tool->trans_info [X3] = (gdouble) transform_tool->x2; + transform_tool->trans_info [Y3] = (gdouble) transform_tool->y2; break; case TRANSFORM_MOTION: - perspective_tool_motion (tool, gdisp); - perspective_tool_recalc (tool, gdisp); + perspective_tool_motion (transform_tool, gdisp); + perspective_tool_recalc (transform_tool, gdisp); break; case TRANSFORM_RECALC: - perspective_tool_recalc (tool, gdisp); + perspective_tool_recalc (transform_tool, gdisp); break; case TRANSFORM_FINISH: - /* Let the transform tool handle the inverse mapping */ - gtk_widget_set_sensitive (GTK_WIDGET (transform_info->shell), FALSE); - return - gimp_perspective_tool_perspective (gdisp->gimage, - gimp_image_active_drawable (gdisp->gimage), - gdisp, - transform_tool->original, - gimp_transform_tool_smoothing (), - transform_tool->transform); + return gimp_transform_tool_transform_tiles (transform_tool, + _("Perspective...")); break; } @@ -291,18 +195,15 @@ gimp_perspective_tool_transform (GimpTransformTool *transform_tool, } static void -perspective_info_update (GimpTool *tool) +perspective_info_update (GimpTransformTool *transform_tool) { - GimpTransformTool *transform_tool; - gint i; + gint i; - transform_tool = GIMP_TRANSFORM_TOOL (tool); - for (i = 0; i < 3; i++) { gchar *p = matrix_row_buf[i]; gint j; - + for (j = 0; j < 3; j++) { p += g_snprintf (p, MAX_INFO_BUF - (p - matrix_row_buf[i]), @@ -312,18 +213,13 @@ perspective_info_update (GimpTool *tool) info_dialog_update (transform_info); info_dialog_popup (transform_info); - - return; } static void -perspective_tool_motion (GimpTool *tool, - GimpDisplay *gdisp) +perspective_tool_motion (GimpTransformTool *transform_tool, + GimpDisplay *gdisp) { - GimpTransformTool *transform_tool; - gint diff_x, diff_y; - - transform_tool = GIMP_TRANSFORM_TOOL (tool); + gint diff_x, diff_y; diff_x = transform_tool->curx - transform_tool->lastx; diff_y = transform_tool->cury - transform_tool->lasty; @@ -352,41 +248,26 @@ perspective_tool_motion (GimpTool *tool, } static void -perspective_tool_recalc (GimpTool *tool, - GimpDisplay *gdisp) +perspective_tool_recalc (GimpTransformTool *transform_tool, + GimpDisplay *gdisp) { - GimpTransformTool *transform_tool; - GimpMatrix3 m; - gdouble cx, cy; - gdouble scalex, scaley; - - transform_tool = GIMP_TRANSFORM_TOOL (tool); - - /* determine the perspective transform that maps from - * the unit cube to the trans_info coordinates - */ - gimp_perspective_tool_find_transform (transform_tool->trans_info, m); - - cx = transform_tool->x1; - cy = transform_tool->y1; - scalex = 1.0; - scaley = 1.0; - - if (transform_tool->x2 - transform_tool->x1) - scalex = 1.0 / (transform_tool->x2 - transform_tool->x1); - if (transform_tool->y2 - transform_tool->y1) - scaley = 1.0 / (transform_tool->y2 - transform_tool->y1); - - /* assemble the transformation matrix */ - gimp_matrix3_identity (transform_tool->transform); - gimp_matrix3_translate (transform_tool->transform, -cx, -cy); - gimp_matrix3_scale (transform_tool->transform, scalex, scaley); - gimp_matrix3_mult (m, transform_tool->transform); + gimp_drawable_transform_matrix_perspective (transform_tool->x1, + transform_tool->y1, + transform_tool->x2, + transform_tool->y2, + transform_tool->trans_info[X0], + transform_tool->trans_info[Y0], + transform_tool->trans_info[X1], + transform_tool->trans_info[Y1], + transform_tool->trans_info[X2], + transform_tool->trans_info[Y2], + transform_tool->trans_info[X3], + transform_tool->trans_info[Y3], + transform_tool->transform); /* transform the bounding box */ gimp_transform_tool_transform_bounding_box (transform_tool); /* update the information dialog */ - perspective_info_update (tool); + perspective_info_update (transform_tool); } - diff --git a/app/tools/gimpperspectivetool.h b/app/tools/gimpperspectivetool.h index f6f1614359..d1bc5fe8f6 100644 --- a/app/tools/gimpperspectivetool.h +++ b/app/tools/gimpperspectivetool.h @@ -45,19 +45,9 @@ struct _GimpPerspectiveToolClass }; -void gimp_perspective_tool_register (Gimp *gimp); +void gimp_perspective_tool_register (Gimp *gimp); -GType gimp_perspective_tool_get_type (void); - - -TileManager * gimp_perspective_tool_perspective (GimpImage *gimage, - GimpDrawable *drawable, - GimpDisplay *gdisp, - TileManager *float_tiles, - gboolean interpolation, - GimpMatrix3 matrix); -void gimp_perspective_tool_find_transform (gdouble *coords, - GimpMatrix3 matrix); +GType gimp_perspective_tool_get_type (void); #endif /* __GIMP_PERSPECTIVE_TOOL_H__ */ diff --git a/app/tools/gimprotatetool.c b/app/tools/gimprotatetool.c index 7645d38f6a..3f670f6462 100644 --- a/app/tools/gimprotatetool.c +++ b/app/tools/gimprotatetool.c @@ -26,23 +26,19 @@ #include "tools-types.h" #include "gui/gui-types.h" -#include "paint-funcs/paint-funcs.h" - #include "core/gimpimage.h" - -#include "gui/info-dialog.h" +#include "core/gimpdrawable-transform.h" +#include "core/gimpdrawable-transform-utils.h" +#include "core/gimptoolinfo.h" #include "display/gimpdisplay.h" +#include "gui/info-dialog.h" + #include "gimprotatetool.h" #include "tool_manager.h" -#include "tool_options.h" #include "transform_options.h" -#include "gimpprogress.h" -#include "undo.h" -#include "path_transform.h" - #include "libgimp/gimpintl.h" @@ -56,24 +52,25 @@ #define FIFTEEN_DEG (G_PI / 12.0) -/* local function declarations */ -static void gimp_rotate_tool_class_init (GimpRotateToolClass *klass); -static void gimp_rotate_tool_init (GimpRotateTool *rotate_tool); +/* local function prototypes */ -static TileManager * gimp_rotate_tool_transform (GimpTransformTool *transform_tool, +static void gimp_rotate_tool_class_init (GimpRotateToolClass *klass); +static void gimp_rotate_tool_init (GimpRotateTool *rotate_tool); + +static TileManager * gimp_rotate_tool_transform (GimpTransformTool *tr_tool, GimpDisplay *gdisp, TransformState state); -static void rotate_tool_recalc (GimpTool *tool, - GimpDisplay *gdisp); -static void rotate_tool_motion (GimpTool *tool, - GimpDisplay *gdisp); -static void rotate_info_update (GimpTool *tool); +static void rotate_tool_recalc (GimpTransformTool *tr_tool, + GimpDisplay *gdisp); +static void rotate_tool_motion (GimpTransformTool *tr_tool, + GimpDisplay *gdisp); +static void rotate_info_update (GimpTransformTool *tr_tool); -static void rotate_angle_changed (GtkWidget *entry, - gpointer data); -static void rotate_center_changed (GtkWidget *entry, - gpointer data); +static void rotate_angle_changed (GtkWidget *entry, + gpointer data); +static void rotate_center_changed (GtkWidget *entry, + gpointer data); /* variables local to this file */ @@ -132,6 +129,9 @@ gimp_rotate_tool_get_type (void) return tool_type; } + +/* private functions */ + static void gimp_rotate_tool_class_init (GimpRotateToolClass *klass) { @@ -148,10 +148,10 @@ static void gimp_rotate_tool_init (GimpRotateTool *rotate_tool) { GimpTool *tool; - GimpTransformTool *tr_tool; + GimpTransformTool *transform_tool; - tool = GIMP_TOOL (rotate_tool); - tr_tool = GIMP_TRANSFORM_TOOL (rotate_tool); + tool = GIMP_TOOL (rotate_tool); + transform_tool = GIMP_TRANSFORM_TOOL (rotate_tool); if (! rotate_options) { @@ -162,63 +162,26 @@ gimp_rotate_tool_init (GimpRotateTool *rotate_tool) (GimpToolOptions *) rotate_options); } - tool->tool_cursor = GIMP_ROTATE_TOOL_CURSOR; - - tr_tool->trans_info[ANGLE] = 0.0; - tr_tool->trans_info[REAL_ANGLE] = 0.0; - tr_tool->trans_info[CENTER_X] = 0.0; - tr_tool->trans_info[CENTER_Y] = 0.0; - - /* assemble the transformation matrix */ - gimp_matrix3_identity (tr_tool->transform); -} - -TileManager * -gimp_rotate_tool_rotate (GimpImage *gimage, - GimpDrawable *drawable, - GimpDisplay *gdisp, - gdouble angle, - TileManager *float_tiles, - gboolean interpolation, - GimpMatrix3 matrix) -{ - GimpProgress *progress; - TileManager *ret; - - progress = progress_start (gdisp, _("Rotating..."), FALSE, NULL, NULL); - - ret = gimp_transform_tool_do (gimage, drawable, float_tiles, - interpolation, matrix, - progress ? progress_update_and_flush : - (GimpProgressFunc) NULL, - progress); - - if (progress) - progress_end (progress); - - return ret; + tool->tool_cursor = GIMP_ROTATE_TOOL_CURSOR; } static TileManager * -gimp_rotate_tool_transform (GimpTransformTool *transform_tool, - GimpDisplay *gdisp, - TransformState state) +gimp_rotate_tool_transform (GimpTransformTool *transform_tool, + GimpDisplay *gdisp, + TransformState state) { - GimpTool *tool; - GtkWidget *widget; - GtkWidget *spinbutton2; - - tool = GIMP_TOOL (transform_tool); - switch (state) { case TRANSFORM_INIT: - angle_val = 0.0; + angle_val = 0.0; center_vals[0] = transform_tool->cx; center_vals[1] = transform_tool->cy; - if (!transform_info) + if (! transform_info) { + GtkWidget *widget; + GtkWidget *spinbutton2; + transform_info = info_dialog_new (_("Rotation Information"), gimp_standard_help_func, "tools/transform_rotate.html"); @@ -228,14 +191,14 @@ gimp_rotate_tool_transform (GimpTransformTool *transform_tool, &angle_val, -180, 180, 1, 15, 1, 1, 2, G_CALLBACK (rotate_angle_changed), - tool); + transform_tool); gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (widget), TRUE); /* this looks strange (-180, 181), but it works */ widget = info_dialog_add_scale (transform_info, "", &angle_val, -180, 181, 0.01, 0.1, 1, -1, G_CALLBACK (rotate_angle_changed), - tool); + transform_tool); gtk_widget_set_usize (widget, 180, 0); spinbutton2 = @@ -248,7 +211,7 @@ gimp_rotate_tool_transform (GimpTransformTool *transform_tool, TRUE, TRUE, FALSE, GIMP_SIZE_ENTRY_UPDATE_SIZE, G_CALLBACK (rotate_center_changed), - tool); + transform_tool); gimp_size_entry_add_field (GIMP_SIZE_ENTRY (sizeentry), GTK_SPIN_BUTTON (spinbutton2), NULL); @@ -261,7 +224,7 @@ gimp_rotate_tool_transform (GimpTransformTool *transform_tool, g_signal_handlers_block_by_func (G_OBJECT (sizeentry), rotate_center_changed, - tool); + transform_tool); gimp_size_entry_set_unit (GIMP_SIZE_ENTRY (sizeentry), gdisp->gimage->unit); @@ -290,38 +253,30 @@ gimp_rotate_tool_transform (GimpTransformTool *transform_tool, gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (sizeentry), 1, center_vals[1]); - gtk_widget_set_sensitive (transform_info->shell, TRUE); - g_signal_handlers_unblock_by_func (G_OBJECT (sizeentry), rotate_center_changed, - tool); + transform_tool); + + gtk_widget_set_sensitive (transform_info->shell, TRUE); transform_tool->trans_info[ANGLE] = angle_val; transform_tool->trans_info[REAL_ANGLE] = angle_val; transform_tool->trans_info[CENTER_X] = center_vals[0]; transform_tool->trans_info[CENTER_Y] = center_vals[1]; - - return NULL; break; case TRANSFORM_MOTION: - rotate_tool_motion (tool, gdisp); - rotate_tool_recalc (tool, gdisp); + rotate_tool_motion (transform_tool, gdisp); + rotate_tool_recalc (transform_tool, gdisp); break; case TRANSFORM_RECALC: - rotate_tool_recalc (tool, gdisp); + rotate_tool_recalc (transform_tool, gdisp); break; case TRANSFORM_FINISH: - gtk_widget_set_sensitive (GTK_WIDGET (transform_info->shell), FALSE); - return gimp_rotate_tool_rotate (gdisp->gimage, - gimp_image_active_drawable (gdisp->gimage), - gdisp, - transform_tool->trans_info[ANGLE], - transform_tool->original, - gimp_transform_tool_smoothing (), - transform_tool->transform); + return gimp_transform_tool_transform_tiles (transform_tool, + _("Rotating...")); break; } @@ -329,12 +284,8 @@ gimp_rotate_tool_transform (GimpTransformTool *transform_tool, } static void -rotate_info_update (GimpTool *tool) +rotate_info_update (GimpTransformTool *transform_tool) { - GimpTransformTool *transform_tool; - - transform_tool = GIMP_TRANSFORM_TOOL (tool); - angle_val = gimp_rad_to_deg (transform_tool->trans_info[ANGLE]); center_vals[0] = transform_tool->trans_info[CENTER_X]; center_vals[1] = transform_tool->trans_info[CENTER_Y]; @@ -348,26 +299,23 @@ rotate_angle_changed (GtkWidget *widget, gpointer data) { GimpTool *tool; - GimpDrawTool *draw_tool; GimpTransformTool *transform_tool; gdouble value; - tool = (GimpTool *) data; + tool = GIMP_TOOL (data); + transform_tool = GIMP_TRANSFORM_TOOL (data); - if (tool) + value = gimp_deg_to_rad (GTK_ADJUSTMENT (widget)->value); + + if (value != transform_tool->trans_info[ANGLE]) { - transform_tool = GIMP_TRANSFORM_TOOL (tool); - draw_tool = GIMP_DRAW_TOOL (tool); + gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool)); - value = gimp_deg_to_rad (GTK_ADJUSTMENT (widget)->value); + transform_tool->trans_info[ANGLE] = value; - if (value != transform_tool->trans_info[ANGLE]) - { - gimp_draw_tool_pause (draw_tool); - transform_tool->trans_info[ANGLE] = value; - rotate_tool_recalc (tool, tool->gdisp); - gimp_draw_tool_resume (draw_tool); - } + rotate_tool_recalc (transform_tool, tool->gdisp); + + gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool)); } } @@ -376,55 +324,46 @@ rotate_center_changed (GtkWidget *widget, gpointer data) { GimpTool *tool; - GimpDrawTool *draw_tool; GimpTransformTool *transform_tool; gint cx; gint cy; - tool = (GimpTool *) data; + tool = GIMP_TOOL (data); + transform_tool = GIMP_TRANSFORM_TOOL (data); - if (tool) + cx = RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (widget), 0)); + cy = RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (widget), 1)); + + if ((cx != transform_tool->trans_info[CENTER_X]) || + (cy != transform_tool->trans_info[CENTER_Y])) { - transform_tool = GIMP_TRANSFORM_TOOL (tool); - draw_tool = GIMP_DRAW_TOOL (tool); + gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool)); - cx = RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (widget), 0)); - cy = RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (widget), 1)); + transform_tool->trans_info[CENTER_X] = cx; + transform_tool->trans_info[CENTER_Y] = cy; + transform_tool->cx = cx; + transform_tool->cy = cy; - if ((cx != transform_tool->trans_info[CENTER_X]) || - (cy != transform_tool->trans_info[CENTER_Y])) - { - gimp_draw_tool_pause (draw_tool); + rotate_tool_recalc (transform_tool, tool->gdisp); - transform_tool->trans_info[CENTER_X] = cx; - transform_tool->trans_info[CENTER_Y] = cy; - transform_tool->cx = cx; - transform_tool->cy = cy; - - rotate_tool_recalc (tool, tool->gdisp); - - gimp_draw_tool_resume (draw_tool); - } + gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool)); } } static void -rotate_tool_motion (GimpTool *tool, - GimpDisplay *gdisp) +rotate_tool_motion (GimpTransformTool *transform_tool, + GimpDisplay *gdisp) { - GimpTransformTool *transform_tool; - gdouble angle1, angle2, angle; - gdouble cx, cy; - gdouble x1, y1, x2, y2; - - transform_tool = GIMP_TRANSFORM_TOOL (tool); + gdouble angle1, angle2, angle; + gdouble cx, cy; + gdouble x1, y1, x2, y2; if (transform_tool->function == TRANSFORM_HANDLE_CENTER) { transform_tool->trans_info[CENTER_X] = transform_tool->curx; transform_tool->trans_info[CENTER_Y] = transform_tool->cury; - transform_tool->cx = transform_tool->curx; - transform_tool->cy = transform_tool->cury; + transform_tool->cx = transform_tool->curx; + transform_tool->cy = transform_tool->cury; return; } @@ -470,13 +409,10 @@ rotate_tool_motion (GimpTool *tool, } static void -rotate_tool_recalc (GimpTool *tool, - GimpDisplay *gdisp) +rotate_tool_recalc (GimpTransformTool *transform_tool, + GimpDisplay *gdisp) { - GimpTransformTool *transform_tool; - gdouble cx, cy; - - transform_tool = GIMP_TRANSFORM_TOOL (tool); + gdouble cx, cy; cx = transform_tool->trans_info[CENTER_X]; cy = transform_tool->trans_info[CENTER_Y]; @@ -484,16 +420,16 @@ rotate_tool_recalc (GimpTool *tool, transform_tool->cx = cx; transform_tool->cy = cy; - /* assemble the transformation matrix */ - gimp_matrix3_identity (transform_tool->transform); - gimp_matrix3_translate (transform_tool->transform, -cx, -cy); - gimp_matrix3_rotate (transform_tool->transform, - transform_tool->trans_info[ANGLE]); - gimp_matrix3_translate (transform_tool->transform, +cx, +cy); + gimp_drawable_transform_matrix_rotate (transform_tool->cx, + transform_tool->cy, + transform_tool->cx, + transform_tool->cy, + transform_tool->trans_info[ANGLE], + transform_tool->transform); /* transform the bounding box */ gimp_transform_tool_transform_bounding_box (transform_tool); /* update the information dialog */ - rotate_info_update (tool); + rotate_info_update (transform_tool); } diff --git a/app/tools/gimprotatetool.h b/app/tools/gimprotatetool.h index 315f28016e..37d67056ab 100644 --- a/app/tools/gimprotatetool.h +++ b/app/tools/gimprotatetool.h @@ -45,17 +45,9 @@ struct _GimpRotateToolClass }; -void gimp_rotate_tool_register (Gimp *gimp); +void gimp_rotate_tool_register (Gimp *gimp); -GType gimp_rotate_tool_get_type (void); +GType gimp_rotate_tool_get_type (void); -TileManager * gimp_rotate_tool_rotate (GimpImage *gimage, - GimpDrawable *drawable, - GimpDisplay *gdisp, - gdouble angle, - TileManager *float_tiles, - gboolean interpolation, - GimpMatrix3 matrix); - #endif /* __GIMP_ROTATE_TOOL_H__ */ diff --git a/app/tools/gimpscaletool.c b/app/tools/gimpscaletool.c index 23eab7e6bd..fedcef5bfa 100644 --- a/app/tools/gimpscaletool.c +++ b/app/tools/gimpscaletool.c @@ -28,39 +28,41 @@ #include "gui/gui-types.h" #include "core/gimpimage.h" - -#include "gui/info-dialog.h" +#include "core/gimpdrawable-transform.h" +#include "core/gimpdrawable-transform-utils.h" +#include "core/gimptoolinfo.h" #include "display/gimpdisplay.h" +#include "gui/info-dialog.h" + #include "gimpscaletool.h" #include "tool_manager.h" -#include "tool_options.h" #include "transform_options.h" -#include "gimpprogress.h" -#include "undo.h" - #include "libgimp/gimpintl.h" -/* forward function declarations */ -static TileManager * gimp_scale_tool_transform (GimpTransformTool *tool, - GimpDisplay *gdisp, - TransformState state); -static void gimp_scale_tool_recalc (GimpScaleTool *tool, - GimpDisplay *gdisp); -static void gimp_scale_tool_motion (GimpScaleTool *tool, - GimpDisplay *gdisp); -static void gimp_scale_tool_info_update (GimpScaleTool *tool); +/* local function prototypes */ -static void gimp_scale_tool_size_changed (GtkWidget *widget, - gpointer data); -static void gimp_scale_tool_unit_changed (GtkWidget *widget, - gpointer data); -static void gimp_scale_tool_class_init (GimpScaleToolClass *klass); +static void gimp_scale_tool_class_init (GimpScaleToolClass *klass); -static void gimp_scale_tool_init (GimpScaleTool *sc_tool); +static void gimp_scale_tool_init (GimpScaleTool *sc_tool); + +static TileManager * gimp_scale_tool_transform (GimpTransformTool *tr_tool, + GimpDisplay *gdisp, + TransformState state); + +static void gimp_scale_tool_recalc (GimpTransformTool *tr_tool, + GimpDisplay *gdisp); +static void gimp_scale_tool_motion (GimpTransformTool *tr_tool, + GimpDisplay *gdisp); +static void gimp_scale_tool_info_update (GimpTransformTool *tr_tool); + +static void gimp_scale_tool_size_changed (GtkWidget *widget, + gpointer data); +static void gimp_scale_tool_unit_changed (GtkWidget *widget, + gpointer data); /* storage for information dialog fields */ @@ -78,6 +80,8 @@ static GimpTransformToolClass *parent_class = NULL; static TransformOptions *scale_options = NULL; +/* public functions */ + void gimp_scale_tool_register (Gimp *gimp) { @@ -120,6 +124,9 @@ gimp_scale_tool_get_type (void) return tool_type; } + +/* private functions */ + static void gimp_scale_tool_class_init (GimpScaleToolClass *klass) { @@ -137,13 +144,13 @@ gimp_scale_tool_class_init (GimpScaleToolClass *klass) } static void -gimp_scale_tool_init (GimpScaleTool *sc_tool) +gimp_scale_tool_init (GimpScaleTool *scale_tool) { GimpTool *tool; - GimpTransformTool *tr_tool; + GimpTransformTool *transform_tool; - tool = GIMP_TOOL (sc_tool); - tr_tool = GIMP_TRANSFORM_TOOL (sc_tool); + tool = GIMP_TOOL (scale_tool); + transform_tool = GIMP_TRANSFORM_TOOL (scale_tool); if (! scale_options) { @@ -155,38 +162,23 @@ gimp_scale_tool_init (GimpScaleTool *sc_tool) } tool->tool_cursor = GIMP_RESIZE_TOOL_CURSOR; - - /* set the scale specific transformation attributes */ - tr_tool->trans_info[X0] = 0.0; - tr_tool->trans_info[Y0] = 0.0; - tr_tool->trans_info[X1] = 0.0; - tr_tool->trans_info[Y1] = 0.0; - - /* assemble the transformation matrix */ - gimp_matrix3_identity (tr_tool->transform); /* FIXME name is confusing */ } static TileManager * -gimp_scale_tool_transform (GimpTransformTool *tr_tool, - GimpDisplay *gdisp, - TransformState state) +gimp_scale_tool_transform (GimpTransformTool *transform_tool, + GimpDisplay *gdisp, + TransformState state) { - GimpScaleTool *sc_tool; - GtkWidget *spinbutton; - GimpTool *tool; - - sc_tool = GIMP_SCALE_TOOL (tr_tool); - tool = GIMP_TOOL (sc_tool); - - switch (state) { case TRANSFORM_INIT: - size_vals[0] = tr_tool->x2 - tr_tool->x1; - size_vals[1] = tr_tool->y2 - tr_tool->y1; + size_vals[0] = transform_tool->x2 - transform_tool->x1; + size_vals[1] = transform_tool->y2 - transform_tool->y1; - if (!transform_info) + if (! transform_info) { + GtkWidget *spinbutton; + transform_info = info_dialog_new (_("Scaling Information"), gimp_standard_help_func, "tools/transform_scale.html"); @@ -206,10 +198,10 @@ gimp_scale_tool_transform (GimpTransformTool *tr_tool, TRUE, TRUE, FALSE, GIMP_SIZE_ENTRY_UPDATE_SIZE, G_CALLBACK (gimp_scale_tool_size_changed), - tool); + transform_tool); g_signal_connect (G_OBJECT (sizeentry), "unit_changed", G_CALLBACK (gimp_scale_tool_unit_changed), - tool); + transform_tool); gimp_size_entry_add_field (GIMP_SIZE_ENTRY (sizeentry), GTK_SPIN_BUTTON (spinbutton), NULL); @@ -227,10 +219,10 @@ gimp_scale_tool_transform (GimpTransformTool *tr_tool, g_signal_handlers_block_by_func (G_OBJECT (sizeentry), gimp_scale_tool_size_changed, - tool); + transform_tool); g_signal_handlers_block_by_func (G_OBJECT (sizeentry), gimp_scale_tool_unit_changed, - tool); + transform_tool); gimp_size_entry_set_unit (GIMP_SIZE_ENTRY (sizeentry), gdisp->gimage->unit); @@ -259,53 +251,43 @@ gimp_scale_tool_transform (GimpTransformTool *tr_tool, gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (sizeentry), 1, size_vals[1]); - gtk_widget_set_sensitive (GTK_WIDGET (transform_info->shell), TRUE); - g_signal_handlers_unblock_by_func (G_OBJECT (sizeentry), gimp_scale_tool_size_changed, - tool); + transform_tool); g_signal_handlers_unblock_by_func (G_OBJECT (sizeentry), gimp_scale_tool_unit_changed, - tool); + transform_tool); - tr_tool->trans_info [X0] = (double) tr_tool->x1; - tr_tool->trans_info [Y0] = (double) tr_tool->y1; - tr_tool->trans_info [X1] = (double) tr_tool->x2; - tr_tool->trans_info [Y1] = (double) tr_tool->y2; + gtk_widget_set_sensitive (GTK_WIDGET (transform_info->shell), TRUE); - return NULL; + transform_tool->trans_info[X0] = (gdouble) transform_tool->x1; + transform_tool->trans_info[Y0] = (gdouble) transform_tool->y1; + transform_tool->trans_info[X1] = (gdouble) transform_tool->x2; + transform_tool->trans_info[Y1] = (gdouble) transform_tool->y2; break; case TRANSFORM_MOTION: - gimp_scale_tool_motion (sc_tool, gdisp); - gimp_scale_tool_recalc (sc_tool, gdisp); + gimp_scale_tool_motion (transform_tool, gdisp); + gimp_scale_tool_recalc (transform_tool, gdisp); break; case TRANSFORM_RECALC: - gimp_scale_tool_recalc (sc_tool, gdisp); + gimp_scale_tool_recalc (transform_tool, gdisp); break; case TRANSFORM_FINISH: - gtk_widget_set_sensitive (GTK_WIDGET (transform_info->shell), FALSE); - return gimp_scale_tool_scale (gdisp->gimage, - gimp_image_active_drawable (gdisp->gimage), - gdisp, - tr_tool->trans_info, - tr_tool->original, - gimp_transform_tool_smoothing (), - tr_tool->transform); + return gimp_transform_tool_transform_tiles (transform_tool, + _("Scaling...")); break; } return NULL; } - static void -gimp_scale_tool_info_update (GimpScaleTool *sc_tool) +gimp_scale_tool_info_update (GimpTransformTool *transform_tool) { GimpTool *tool; - GimpTransformTool *tr_tool; gdouble ratio_x, ratio_y; gint x1, y1, x2, y2, x3, y3, x4, y4; GimpUnit unit; @@ -314,15 +296,15 @@ gimp_scale_tool_info_update (GimpScaleTool *sc_tool) static GimpUnit label_unit = GIMP_UNIT_PIXEL; - tool = GIMP_TOOL (sc_tool); - tr_tool = GIMP_TRANSFORM_TOOL (sc_tool); - unit = gimp_size_entry_get_unit (GIMP_SIZE_ENTRY (sizeentry));; + tool = GIMP_TOOL (transform_tool); + + unit = gimp_size_entry_get_unit (GIMP_SIZE_ENTRY (sizeentry));; /* Find original sizes */ - x1 = tr_tool->x1; - y1 = tr_tool->y1; - x2 = tr_tool->x2; - y2 = tr_tool->y2; + x1 = transform_tool->x1; + y1 = transform_tool->y1; + x2 = transform_tool->x2; + y2 = transform_tool->y2; if (unit != GIMP_UNIT_PERCENT) label_unit = unit; @@ -346,10 +328,10 @@ gimp_scale_tool_info_update (GimpScaleTool *sc_tool) } /* Find current sizes */ - x3 = (int) tr_tool->trans_info [X0]; - y3 = (int) tr_tool->trans_info [Y0]; - x4 = (int) tr_tool->trans_info [X1]; - y4 = (int) tr_tool->trans_info [Y1]; + x3 = (gint) transform_tool->trans_info [X0]; + y3 = (gint) transform_tool->trans_info [Y0]; + x4 = (gint) transform_tool->trans_info [X1]; + y4 = (gint) transform_tool->trans_info [Y1]; size_vals[0] = x4 - x3; size_vals[1] = y4 - y3; @@ -361,8 +343,8 @@ gimp_scale_tool_info_update (GimpScaleTool *sc_tool) if (y2 - y1) ratio_y = (double) (y4 - y3) / (double) (y2 - y1); - g_snprintf (x_ratio_buf, MAX_INFO_BUF, "%0.2f", ratio_x); - g_snprintf (y_ratio_buf, MAX_INFO_BUF, "%0.2f", ratio_y); + g_snprintf (x_ratio_buf, sizeof (x_ratio_buf), "%0.2f", ratio_x); + g_snprintf (y_ratio_buf, sizeof (y_ratio_buf), "%0.2f", ratio_y); info_dialog_update (transform_info); info_dialog_popup (transform_info); @@ -372,35 +354,30 @@ static void gimp_scale_tool_size_changed (GtkWidget *widget, gpointer data) { + GimpTransformTool *transform_tool; GimpTool *tool; - GimpTransformTool *tr_tool; - GimpDrawTool *dr_tool; gint width; gint height; - tool = GIMP_TOOL(data); + transform_tool = GIMP_TRANSFORM_TOOL (data); + tool = GIMP_TOOL (data); - if (tool) + width = RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (widget), 0)); + height = RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (widget), 1)); + + if ((width != (transform_tool->trans_info[X1] - + transform_tool->trans_info[X0])) || + (height != (transform_tool->trans_info[Y1] - + transform_tool->trans_info[Y0]))) { - tr_tool = GIMP_TRANSFORM_TOOL(tool); - dr_tool = GIMP_DRAW_TOOL(tool); + gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool)); - width = RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (widget), 0)); - height = RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (widget), 1)); + transform_tool->trans_info[X1] = transform_tool->trans_info[X0] + width; + transform_tool->trans_info[Y1] = transform_tool->trans_info[Y0] + height; - if ((width != (tr_tool->trans_info[X1] - - tr_tool->trans_info[X0])) || - (height != (tr_tool->trans_info[Y1] - - tr_tool->trans_info[Y0]))) - { - gimp_draw_tool_pause (dr_tool); - tr_tool->trans_info[X1] = - tr_tool->trans_info[X0] + width; - tr_tool->trans_info[Y1] = - tr_tool->trans_info[Y0] + height; - gimp_scale_tool_recalc (GIMP_SCALE_TOOL(tool), tool->gdisp); - gimp_draw_tool_resume (dr_tool); - } + gimp_scale_tool_recalc (transform_tool, tool->gdisp); + + gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool)); } } @@ -408,58 +385,55 @@ static void gimp_scale_tool_unit_changed (GtkWidget *widget, gpointer data) { - gimp_scale_tool_info_update (GIMP_SCALE_TOOL (data)); + gimp_scale_tool_info_update (GIMP_TRANSFORM_TOOL (data)); } static void -gimp_scale_tool_motion (GimpScaleTool *sc_tool, - GimpDisplay *gdisp) +gimp_scale_tool_motion (GimpTransformTool *transform_tool, + GimpDisplay *gdisp) { - GimpTransformTool *tr_tool; - gdouble ratio; - gdouble *x1; - gdouble *y1; - gdouble *x2; - gdouble *y2; - gint w, h; - gint dir_x, dir_y; - gint diff_x, diff_y; + gdouble ratio; + gdouble *x1; + gdouble *y1; + gdouble *x2; + gdouble *y2; + gint w, h; + gint dir_x, dir_y; + gint diff_x, diff_y; - tr_tool = GIMP_TRANSFORM_TOOL(sc_tool); + diff_x = transform_tool->curx - transform_tool->lastx; + diff_y = transform_tool->cury - transform_tool->lasty; - diff_x = tr_tool->curx - tr_tool->lastx; - diff_y = tr_tool->cury - tr_tool->lasty; - - switch (tr_tool->function) + switch (transform_tool->function) { case TRANSFORM_HANDLE_1: - x1 = &tr_tool->trans_info [X0]; - y1 = &tr_tool->trans_info [Y0]; - x2 = &tr_tool->trans_info [X1]; - y2 = &tr_tool->trans_info [Y1]; + x1 = &transform_tool->trans_info [X0]; + y1 = &transform_tool->trans_info [Y0]; + x2 = &transform_tool->trans_info [X1]; + y2 = &transform_tool->trans_info [Y1]; dir_x = dir_y = 1; break; case TRANSFORM_HANDLE_2: - x1 = &tr_tool->trans_info [X1]; - y1 = &tr_tool->trans_info [Y0]; - x2 = &tr_tool->trans_info [X0]; - y2 = &tr_tool->trans_info [Y1]; + x1 = &transform_tool->trans_info [X1]; + y1 = &transform_tool->trans_info [Y0]; + x2 = &transform_tool->trans_info [X0]; + y2 = &transform_tool->trans_info [Y1]; dir_x = -1; dir_y = 1; break; case TRANSFORM_HANDLE_3: - x1 = &tr_tool->trans_info [X0]; - y1 = &tr_tool->trans_info [Y1]; - x2 = &tr_tool->trans_info [X1]; - y2 = &tr_tool->trans_info [Y0]; + x1 = &transform_tool->trans_info [X0]; + y1 = &transform_tool->trans_info [Y1]; + x2 = &transform_tool->trans_info [X1]; + y2 = &transform_tool->trans_info [Y0]; dir_x = 1; dir_y = -1; break; case TRANSFORM_HANDLE_4: - x1 = &tr_tool->trans_info [X1]; - y1 = &tr_tool->trans_info [Y1]; - x2 = &tr_tool->trans_info [X0]; - y2 = &tr_tool->trans_info [Y0]; + x1 = &transform_tool->trans_info [X1]; + y1 = &transform_tool->trans_info [Y1]; + x2 = &transform_tool->trans_info [X0]; + y2 = &transform_tool->trans_info [Y0]; dir_x = dir_y = -1; break; case TRANSFORM_HANDLE_CENTER: @@ -469,12 +443,12 @@ gimp_scale_tool_motion (GimpScaleTool *sc_tool, } /* if just the mod1 key is down, affect only the height */ - if (tr_tool->state & GDK_MOD1_MASK && - ! (tr_tool->state & GDK_CONTROL_MASK)) + if (transform_tool->state & GDK_MOD1_MASK && + ! (transform_tool->state & GDK_CONTROL_MASK)) diff_x = 0; /* if just the control key is down, affect only the width */ - else if (tr_tool->state & GDK_CONTROL_MASK && - ! (tr_tool->state & GDK_MOD1_MASK)) + else if (transform_tool->state & GDK_CONTROL_MASK && + ! (transform_tool->state & GDK_MOD1_MASK)) diff_y = 0; *x1 += diff_x; @@ -501,11 +475,11 @@ gimp_scale_tool_motion (GimpScaleTool *sc_tool, /* if both the control key & mod1 keys are down, * keep the aspect ratio intact */ - if (tr_tool->state & GDK_CONTROL_MASK && - tr_tool->state & GDK_MOD1_MASK) + if (transform_tool->state & GDK_CONTROL_MASK && + transform_tool->state & GDK_MOD1_MASK) { - ratio = (double) (tr_tool->x2 - tr_tool->x1) / - (double) (tr_tool->y2 - tr_tool->y1); + ratio = ((gdouble) (transform_tool->x2 - transform_tool->x1) / + (gdouble) (transform_tool->y2 - transform_tool->y1)); w = ABS ((*x2 - *x1)); h = ABS ((*y2 - *y1)); @@ -521,96 +495,22 @@ gimp_scale_tool_motion (GimpScaleTool *sc_tool, } static void -gimp_scale_tool_recalc (GimpScaleTool *sc_tool, - GimpDisplay *gdisp) +gimp_scale_tool_recalc (GimpTransformTool *transform_tool, + GimpDisplay *gdisp) { - GimpTransformTool *tr_tool; - gint x1, y1, x2, y2; - gint diffx, diffy; - gint cx, cy; - gdouble scalex, scaley; - - tr_tool = GIMP_TRANSFORM_TOOL (sc_tool); - - x1 = (int) tr_tool->trans_info [X0]; - y1 = (int) tr_tool->trans_info [Y0]; - x2 = (int) tr_tool->trans_info [X1]; - y2 = (int) tr_tool->trans_info [Y1]; - - scalex = scaley = 1.0; - if (tr_tool->x2 - tr_tool->x1) - scalex = (double) (x2 - x1) / (double) (tr_tool->x2 - tr_tool->x1); - if (tr_tool->y2 - tr_tool->y1) - scaley = (double) (y2 - y1) / (double) (tr_tool->y2 - tr_tool->y1); - - switch (tr_tool->function) - { - case TRANSFORM_HANDLE_1: - cx = x2; cy = y2; - diffx = x2 - tr_tool->x2; - diffy = y2 - tr_tool->y2; - break; - case TRANSFORM_HANDLE_2: - cx = x1; cy = y2; - diffx = x1 - tr_tool->x1; - diffy = y2 - tr_tool->y2; - break; - case TRANSFORM_HANDLE_3: - cx = x2; cy = y1; - diffx = x2 - tr_tool->x2; - diffy = y1 - tr_tool->y1; - break; - case TRANSFORM_HANDLE_4: - cx = x1; cy = y1; - diffx = x1 - tr_tool->x1; - diffy = y1 - tr_tool->y1; - break; - case TRANSFORM_HANDLE_CENTER: - cx = x1; cy = y1; - diffx = diffy = 0; - break; - default: - cx = x1; cy = y1; - diffx = diffy = 0; - break; - } - - /* assemble the transformation matrix */ - gimp_matrix3_identity (tr_tool->transform); - gimp_matrix3_translate (tr_tool->transform, - (double) -cx + diffx, (double) -cy + diffy); - gimp_matrix3_scale (tr_tool->transform, scalex, scaley); - gimp_matrix3_translate (tr_tool->transform, (double) cx, (double) cy); + gimp_drawable_transform_matrix_scale (transform_tool->x1, + transform_tool->y1, + transform_tool->x2, + transform_tool->y2, + transform_tool->trans_info[X0], + transform_tool->trans_info[Y0], + transform_tool->trans_info[X1], + transform_tool->trans_info[Y1], + transform_tool->transform); /* transform the bounding box */ - gimp_transform_tool_transform_bounding_box (tr_tool); + gimp_transform_tool_transform_bounding_box (transform_tool); /* update the information dialog */ - gimp_scale_tool_info_update (sc_tool); -} - -TileManager * -gimp_scale_tool_scale (GimpImage *gimage, - GimpDrawable *drawable, - GimpDisplay *gdisp, - gdouble *trans_info, - TileManager *float_tiles, - gboolean interpolation, - GimpMatrix3 matrix) -{ - GimpProgress *progress; - TileManager *ret; - - progress = progress_start (gdisp, _("Scaling..."), FALSE, NULL, NULL); - - ret = gimp_transform_tool_do (gimage, drawable, float_tiles, - interpolation, matrix, - progress ? progress_update_and_flush : - (GimpProgressFunc) NULL, - progress); - - if (progress) - progress_end (progress); - - return ret; + gimp_scale_tool_info_update (transform_tool); } diff --git a/app/tools/gimpscaletool.h b/app/tools/gimpscaletool.h index f4e3366c69..120a7b178c 100644 --- a/app/tools/gimpscaletool.h +++ b/app/tools/gimpscaletool.h @@ -44,17 +44,9 @@ struct _GimpScaleToolClass }; -void gimp_scale_tool_register (Gimp *gimp); +void gimp_scale_tool_register (Gimp *gimp); -GType gimp_scale_tool_get_type (void); - -TileManager * gimp_scale_tool_scale (GimpImage *gimage, - GimpDrawable *drawable, - GimpDisplay *gdisp, - gdouble *trans_info, - TileManager *float_tiles, - gboolean interpolation, - GimpMatrix3 matrix); +GType gimp_scale_tool_get_type (void); #endif /* __GIMP_SCALE_TOOL_H__ */ diff --git a/app/tools/gimpsheartool.c b/app/tools/gimpsheartool.c index bce4fb99ba..62c241b871 100644 --- a/app/tools/gimpsheartool.c +++ b/app/tools/gimpsheartool.c @@ -29,20 +29,18 @@ #include "gui/gui-types.h" #include "core/gimpimage.h" - -#include "gui/info-dialog.h" +#include "core/gimpdrawable-transform.h" +#include "core/gimpdrawable-transform-utils.h" +#include "core/gimptoolinfo.h" #include "display/gimpdisplay.h" +#include "gui/info-dialog.h" + #include "gimpsheartool.h" #include "tool_manager.h" -#include "tool_options.h" #include "transform_options.h" -#include "floating_sel.h" -#include "gimpprogress.h" -#include "undo.h" - #include "libgimp/gimpintl.h" @@ -58,22 +56,22 @@ /* forward function declarations */ static void gimp_shear_tool_class_init (GimpShearToolClass *klass); -static void gimp_shear_tool_init (GimpShearTool *shear_tool); +static void gimp_shear_tool_init (GimpShearTool *shear_tool); -static TileManager * gimp_shear_tool_transform (GimpTransformTool *transform_tool, - GimpDisplay *gdisp, - TransformState state); +static TileManager * gimp_shear_tool_transform (GimpTransformTool *tr_tool, + GimpDisplay *gdisp, + TransformState state); -static void shear_tool_recalc (GimpTool *tool, - GimpDisplay *gdisp); -static void shear_tool_motion (GimpTool *tool, - GimpDisplay *gdisp); -static void shear_info_update (GimpTool *tool); +static void shear_tool_recalc (GimpTransformTool *tr_tool, + GimpDisplay *gdisp); +static void shear_tool_motion (GimpTransformTool *tr_tool, + GimpDisplay *gdisp); +static void shear_info_update (GimpTransformTool *tr_tool); -static void shear_x_mag_changed (GtkWidget *widget, - gpointer data); -static void shear_y_mag_changed (GtkWidget *widget, - gpointer data); +static void shear_x_mag_changed (GtkWidget *widget, + gpointer data); +static void shear_y_mag_changed (GtkWidget *widget, + gpointer data); /* variables local to this file */ @@ -145,64 +143,32 @@ static void gimp_shear_tool_init (GimpShearTool *shear_tool) { GimpTool *tool; - GimpTransformTool *tr_tool; + GimpTransformTool *transform_tool; - tool = GIMP_TOOL (shear_tool); - tr_tool = GIMP_TRANSFORM_TOOL (shear_tool); + tool = GIMP_TOOL (shear_tool); + transform_tool = GIMP_TRANSFORM_TOOL (shear_tool); if (! shear_options) { shear_options = transform_options_new (GIMP_TYPE_SHEAR_TOOL, - transform_options_reset); + transform_options_reset); tool_manager_register_tool_options (GIMP_TYPE_SHEAR_TOOL, (GimpToolOptions *) shear_options); } - tool->tool_cursor = GIMP_SHEAR_TOOL_CURSOR; - - /* assemble the transformation matrix */ - gimp_matrix3_identity (tr_tool->transform); - -} - -TileManager * -gimp_shear_tool_shear (GimpImage *gimage, - GimpDrawable *drawable, - GimpDisplay *gdisp, - TileManager *float_tiles, - gboolean interpolation, - GimpMatrix3 matrix) -{ - GimpProgress *progress; - TileManager *ret; - - progress = progress_start (gdisp, _("Shearing..."), FALSE, NULL, NULL); - - ret = gimp_transform_tool_do (gimage, drawable, float_tiles, - interpolation, matrix, - progress ? progress_update_and_flush : - (GimpProgressFunc) NULL, - progress); - - if (progress) - progress_end (progress); - - return ret; + tool->tool_cursor = GIMP_SHEAR_TOOL_CURSOR; } static TileManager * -gimp_shear_tool_transform (GimpTransformTool *transform_tool, - GimpDisplay *gdisp, - TransformState state) +gimp_shear_tool_transform (GimpTransformTool *transform_tool, + GimpDisplay *gdisp, + TransformState state) { - GimpTool *tool; - tool = GIMP_TOOL (transform_tool); - switch (state) { case TRANSFORM_INIT: - if (!transform_info) + if (! transform_info) { transform_info = info_dialog_new (_("Shear Information"), gimp_standard_help_func, @@ -213,40 +179,35 @@ gimp_shear_tool_transform (GimpTransformTool *transform_tool, &xshear_val, -65536, 65536, 1, 15, 1, 1, 0, G_CALLBACK (shear_x_mag_changed), - tool); + transform_tool); info_dialog_add_spinbutton (transform_info, _("Y:"), &yshear_val, -65536, 65536, 1, 15, 1, 1, 0, G_CALLBACK (shear_y_mag_changed), - tool); + transform_tool); } - gtk_widget_set_sensitive (GTK_WIDGET (transform_info->shell), TRUE); - transform_tool->trans_info[HORZ_OR_VERT] = ORIENTATION_UNKNOWN; - transform_tool->trans_info[XSHEAR] = 0.0; - transform_tool->trans_info[YSHEAR] = 0.0; - return NULL; + gtk_widget_set_sensitive (GTK_WIDGET (transform_info->shell), TRUE); + + transform_tool->trans_info[HORZ_OR_VERT] = ORIENTATION_UNKNOWN; + transform_tool->trans_info[XSHEAR] = 0.0; + transform_tool->trans_info[YSHEAR] = 0.0; break; case TRANSFORM_MOTION: - shear_tool_motion (tool, gdisp); - shear_tool_recalc (tool, gdisp); + shear_tool_motion (transform_tool, gdisp); + shear_tool_recalc (transform_tool, gdisp); break; case TRANSFORM_RECALC: - shear_tool_recalc (tool, gdisp); + shear_tool_recalc (transform_tool, gdisp); break; case TRANSFORM_FINISH: - gtk_widget_set_sensitive (GTK_WIDGET (transform_info->shell), FALSE); - return gimp_shear_tool_shear (gdisp->gimage, - gimp_image_active_drawable (gdisp->gimage), - gdisp, - transform_tool->original, - gimp_transform_tool_smoothing (), - transform_tool->transform); + return gimp_transform_tool_transform_tiles (transform_tool, + _("Shearing...")); break; } @@ -254,12 +215,8 @@ gimp_shear_tool_transform (GimpTransformTool *transform_tool, } static void -shear_info_update (GimpTool *tool) +shear_info_update (GimpTransformTool *transform_tool) { - GimpTransformTool *transform_tool; - - transform_tool = GIMP_TRANSFORM_TOOL (tool); - xshear_val = transform_tool->trans_info[XSHEAR]; yshear_val = transform_tool->trans_info[YSHEAR]; @@ -272,26 +229,23 @@ shear_x_mag_changed (GtkWidget *widget, gpointer data) { GimpTool *tool; - GimpDrawTool *draw_tool; GimpTransformTool *transform_tool; gint value; - tool = (GimpTool *) data; + tool = GIMP_TOOL (data); + transform_tool = GIMP_TRANSFORM_TOOL (data); - if (tool) + value = GTK_ADJUSTMENT (widget)->value; + + if (value != transform_tool->trans_info[XSHEAR]) { - draw_tool = GIMP_DRAW_TOOL (tool); - transform_tool = GIMP_TRANSFORM_TOOL (tool); + gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool)); - value = GTK_ADJUSTMENT (widget)->value; + transform_tool->trans_info[XSHEAR] = value; - if (value != transform_tool->trans_info[XSHEAR]) - { - gimp_draw_tool_pause (draw_tool); - transform_tool->trans_info[XSHEAR] = value; - shear_tool_recalc (tool, tool->gdisp); - gimp_draw_tool_resume (draw_tool); - } + shear_tool_recalc (transform_tool, tool->gdisp); + + gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool)); } } @@ -300,38 +254,32 @@ shear_y_mag_changed (GtkWidget *widget, gpointer data) { GimpTool *tool; - GimpDrawTool *draw_tool; GimpTransformTool *transform_tool; gint value; - tool = (GimpTool *) data; + tool = GIMP_TOOL (data); + transform_tool = GIMP_TRANSFORM_TOOL (data); - if (tool) + value = GTK_ADJUSTMENT (widget)->value; + + if (value != transform_tool->trans_info[YSHEAR]) { - draw_tool = GIMP_DRAW_TOOL (tool); - transform_tool = GIMP_TRANSFORM_TOOL (tool); + gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool)); - value = GTK_ADJUSTMENT (widget)->value; + transform_tool->trans_info[YSHEAR] = value; - if (value != transform_tool->trans_info[YSHEAR]) - { - gimp_draw_tool_pause (draw_tool); - transform_tool->trans_info[YSHEAR] = value; - shear_tool_recalc (tool, tool->gdisp); - gimp_draw_tool_resume (draw_tool); - } + shear_tool_recalc (transform_tool, tool->gdisp); + + gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool)); } } static void -shear_tool_motion (GimpTool *tool, - GimpDisplay *gdisp) +shear_tool_motion (GimpTransformTool *transform_tool, + GimpDisplay *gdisp) { - GimpTransformTool *transform_tool; - gint diffx, diffy; - gint dir; - - transform_tool = GIMP_TRANSFORM_TOOL (tool); + gint diffx, diffy; + gint dir; diffx = transform_tool->curx - transform_tool->lastx; diffy = transform_tool->cury - transform_tool->lasty; @@ -400,43 +348,27 @@ shear_tool_motion (GimpTool *tool, } static void -shear_tool_recalc (GimpTool *tool, - GimpDisplay *gdisp) +shear_tool_recalc (GimpTransformTool *transform_tool, + GimpDisplay *gdisp) { - GimpTransformTool *transform_tool; - gfloat width, height; - gfloat cx, cy; + gdouble amount; - transform_tool = GIMP_TRANSFORM_TOOL (tool); - - cx = (transform_tool->x1 + transform_tool->x2) / 2.0; - cy = (transform_tool->y1 + transform_tool->y2) / 2.0; - - width = transform_tool->x2 - transform_tool->x1; - height = transform_tool->y2 - transform_tool->y1; - - if (width == 0) - width = 1; - if (height == 0) - height = 1; - - /* assemble the transformation matrix */ - gimp_matrix3_identity (transform_tool->transform); - gimp_matrix3_translate (transform_tool->transform, -cx, -cy); - - /* shear matrix */ if (transform_tool->trans_info[HORZ_OR_VERT] == ORIENTATION_HORIZONTAL) - gimp_matrix3_xshear (transform_tool->transform, - (float) transform_tool->trans_info [XSHEAR] / height); + amount = transform_tool->trans_info[XSHEAR]; else - gimp_matrix3_yshear (transform_tool->transform, - (float) transform_tool->trans_info [YSHEAR] / width); + amount = transform_tool->trans_info[YSHEAR]; - gimp_matrix3_translate (transform_tool->transform, +cx, +cy); + gimp_drawable_transform_matrix_shear (transform_tool->x1, + transform_tool->y1, + transform_tool->x2, + transform_tool->y2, + transform_tool->trans_info[HORZ_OR_VERT], + amount, + transform_tool->transform); /* transform the bounding box */ gimp_transform_tool_transform_bounding_box (transform_tool); /* update the information dialog */ - shear_info_update (tool); + shear_info_update (transform_tool); } diff --git a/app/tools/gimpsheartool.h b/app/tools/gimpsheartool.h index fa25333c25..c506e971c4 100644 --- a/app/tools/gimpsheartool.h +++ b/app/tools/gimpsheartool.h @@ -45,17 +45,9 @@ struct _GimpShearToolClass }; -void gimp_shear_tool_register (Gimp *gimp); +void gimp_shear_tool_register (Gimp *gimp); -GType gimp_shear_tool_get_type (void); - - -TileManager * gimp_shear_tool_shear (GimpImage *gimage, - GimpDrawable *drawable, - GimpDisplay *gdisp, - TileManager *float_tiles, - gboolean interpolation, - GimpMatrix3 matrix); +GType gimp_shear_tool_get_type (void); #endif /* __GIMP_SHEAR_TOOL_H__ */ diff --git a/app/tools/gimptransformoptions.c b/app/tools/gimptransformoptions.c index c056160337..1b794b5fd4 100644 --- a/app/tools/gimptransformoptions.c +++ b/app/tools/gimptransformoptions.c @@ -27,160 +27,38 @@ #include "core/gimptoolinfo.h" -#include "gimprc.h" - -#include "gimptool.h" #include "gimptransformtool.h" #include "transform_options.h" #include "tool_manager.h" +#include "app_procs.h" +#include "gimprc.h" + #include "libgimp/gimpintl.h" -static TransformOptions *transform_options = NULL; +/* local function prototypes */ -/* Callback functions - need prototypes */ +static void gimp_transform_tool_grid_density_update (GtkWidget *widget, + gpointer data); +static void gimp_transform_tool_show_grid_update (GtkWidget *widget, + gpointer data); +static void gimp_transform_tool_show_path_update (GtkWidget *widget, + gpointer data); -static void -gimp_transform_tool_direction_callback (GtkWidget *widget, - gpointer data) -{ - long dir = (long) data; - if (dir == TRANSFORM_TRADITIONAL) - transform_options->direction = TRANSFORM_TRADITIONAL; - else - transform_options->direction = TRANSFORM_CORRECTIVE; -} +/* public functions */ -static void -gimp_transform_tool_grid_density_callback (GtkWidget *widget, - gpointer data) -{ - transform_options->grid_size = - (int) (pow (2.0, 7.0 - GTK_ADJUSTMENT (widget)->value) + 0.5); - - gimp_transform_tool_grid_density_changed (); -} - -static void -gimp_transform_tool_show_grid_update (GtkWidget *widget, - gpointer data) -{ - static gboolean first_call = TRUE; /* eek, this hack avoids a segfault */ - - if (first_call) - { - first_call = FALSE; - return; - } - - gimp_toggle_button_update (widget, data); - - gimp_transform_tool_grid_density_changed (); -} - -static void -gimp_transform_tool_show_path_update (GtkWidget *widget, - gpointer data) -{ - static gboolean first_call = TRUE; /* eek, this hack avoids a segfault */ - - if (first_call) - { - first_call = FALSE; - return; - } - - gimp_transform_tool_showpath_changed (1); /* pause */ - gimp_toggle_button_update (widget, data); - gimp_transform_tool_showpath_changed (0); /* resume */ -} - -/* Global functions. No magic needed yet. */ - -/* Unhappy with this - making this stuff global is wrong. */ - -gboolean -gimp_transform_tool_smoothing (void) -{ - if (!transform_options) - return TRUE; - else - return transform_options->smoothing; -} - -gboolean -gimp_transform_tool_showpath (void) -{ - if (!transform_options) - return TRUE; - else - return transform_options->showpath; -} - -gboolean -gimp_transform_tool_clip (void) -{ - if (!transform_options) - return FALSE; - else - return transform_options->clip; -} - -gint -gimp_transform_tool_direction (void) -{ - if (!transform_options) - return TRANSFORM_TRADITIONAL; - else - return transform_options->direction; -} - -gint -gimp_transform_tool_grid_size (void) -{ - if (!transform_options) - return 32; - else - return transform_options->grid_size; -} - -gboolean -gimp_transform_tool_show_grid (void) -{ - if (!transform_options) - return TRUE; - else - return transform_options->show_grid; -} - -/* Main options stuff - the rest doesn't need to be here (default - * callbacks is good, but none of this stuff should depend on having - * access to the options) - */ - -void -transform_options_reset (GimpToolOptions *tool_options) +TransformOptions * +transform_options_new (GType tool_type, + ToolOptionsResetFunc reset_func) { TransformOptions *options; - options = (TransformOptions *) tool_options; + options = g_new (TransformOptions, 1); + transform_options_init (options, tool_type, reset_func); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->smoothing_w), - options->smoothing_d); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->showpath_w), - options->showpath_d); - gtk_toggle_button_set_active (((options->direction_d == TRANSFORM_TRADITIONAL) ? - GTK_TOGGLE_BUTTON (options->direction_w[0]) : - GTK_TOGGLE_BUTTON (options->direction_w[1])), - TRUE); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->show_grid_w), - options->show_grid_d); - gtk_adjustment_set_value (GTK_ADJUSTMENT (options->grid_size_w), - 7.0 - log (options->grid_size_d) / log (2.0)); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->clip_w), - options->clip_d); + return options; } void @@ -202,23 +80,26 @@ transform_options_init (TransformOptions *options, vbox = options->tool_options.main_vbox; options->smoothing = options->smoothing_d = TRUE; - options->showpath = options->showpath_d = TRUE; + options->show_path = options->show_path_d = TRUE; options->clip = options->clip_d = FALSE; - options->direction = options->direction_d = TRANSFORM_TRADITIONAL; + options->direction = options->direction_d = GIMP_TRANSFORM_FORWARD; options->grid_size = options->grid_size_d = 32; options->show_grid = options->show_grid_d = TRUE; - frame = gimp_radio_group_new (TRUE, _("Tool Paradigm"), + frame = gimp_radio_group_new2 (TRUE, _("Tool Paradigm"), + G_CALLBACK (gimp_radio_button_update), + &options->direction, + GINT_TO_POINTER (options->direction), - _("Traditional"), gimp_transform_tool_direction_callback, - TRANSFORM_TRADITIONAL, NULL, - &options->direction_w[0], TRUE, + _("Traditional"), + GINT_TO_POINTER (GIMP_TRANSFORM_FORWARD), + &options->direction_w[0], - _("Corrective"), gimp_transform_tool_direction_callback, - TRANSFORM_CORRECTIVE, NULL, - &options->direction_w[1], FALSE, + _("Corrective"), + GINT_TO_POINTER (GIMP_TRANSFORM_BACKWARD), + &options->direction_w[1], - NULL); + NULL); gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); gtk_widget_show (frame); @@ -257,24 +138,24 @@ transform_options_init (TransformOptions *options, gtk_spin_button_new (GTK_ADJUSTMENT (options->grid_size_w), 0, 0); gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (grid_density), TRUE); g_signal_connect (G_OBJECT (options->grid_size_w), "value_changed", - G_CALLBACK (gimp_transform_tool_grid_density_callback), - &options->grid_size); + G_CALLBACK (gimp_transform_tool_grid_density_update), + options); gtk_box_pack_start (GTK_BOX (hbox), grid_density, FALSE, FALSE, 0); gtk_widget_show (grid_density); gtk_widget_set_sensitive (label, options->show_grid_d); gtk_widget_set_sensitive (grid_density, options->show_grid_d); g_object_set_data (G_OBJECT (options->show_grid_w), "set_sensitive", - grid_density); + grid_density); g_object_set_data (G_OBJECT (grid_density), "set_sensitive", label); - /* the showpath toggle button */ - options->showpath_w = gtk_check_button_new_with_label (_("Show Path")); - g_signal_connect (G_OBJECT (options->showpath_w), "toggled", + /* the show_path toggle button */ + options->show_path_w = gtk_check_button_new_with_label (_("Show Path")); + g_signal_connect (G_OBJECT (options->show_path_w), "toggled", G_CALLBACK (gimp_transform_tool_show_path_update), - &options->showpath); - gtk_box_pack_start (GTK_BOX (vbox), options->showpath_w, FALSE, FALSE, 0); - gtk_widget_show (options->showpath_w); + &options->show_path); + gtk_box_pack_start (GTK_BOX (vbox), options->show_path_w, FALSE, FALSE, 0); + gtk_widget_show (options->show_path_w); /* the smoothing toggle button */ options->smoothing_w = gtk_check_button_new_with_label (_("Smoothing")); @@ -296,21 +177,97 @@ transform_options_init (TransformOptions *options, transform_options_reset ((GimpToolOptions *) options); } -TransformOptions * -transform_options_new (GType tool_type, - ToolOptionsResetFunc reset_func) +void +transform_options_reset (GimpToolOptions *tool_options) { TransformOptions *options; - options = g_new (TransformOptions, 1); - transform_options_init (options, tool_type, reset_func); + options = (TransformOptions *) tool_options; - /* Set our local copy of the active tool's options (so that - * the methods/functions to access them work) */ - transform_options = options; - - return options; + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->smoothing_w), + options->smoothing_d); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->show_path_w), + options->show_path_d); + gtk_toggle_button_set_active (((options->direction_d == GIMP_TRANSFORM_FORWARD) ? + GTK_TOGGLE_BUTTON (options->direction_w[0]) : + GTK_TOGGLE_BUTTON (options->direction_w[1])), + TRUE); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->show_grid_w), + options->show_grid_d); + gtk_adjustment_set_value (GTK_ADJUSTMENT (options->grid_size_w), + 7.0 - log (options->grid_size_d) / log (2.0)); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->clip_w), + options->clip_d); } +/* private functions */ +static void +gimp_transform_tool_grid_density_update (GtkWidget *widget, + gpointer data) +{ + TransformOptions *options; + GimpTool *active_tool; + + options = (TransformOptions *) data; + + options->grid_size = + (gint) (pow (2.0, 7.0 - GTK_ADJUSTMENT (widget)->value) + 0.5); + + active_tool = tool_manager_get_active (the_gimp); + + if (GIMP_IS_TRANSFORM_TOOL (active_tool)) + gimp_transform_tool_grid_density_changed (GIMP_TRANSFORM_TOOL (active_tool)); +} + +static void +gimp_transform_tool_show_grid_update (GtkWidget *widget, + gpointer data) +{ + static gboolean first_call = TRUE; /* eek, this hack avoids a segfault */ + + GimpTool *active_tool; + + if (first_call) + { + first_call = FALSE; + return; + } + + gimp_toggle_button_update (widget, data); + + active_tool = tool_manager_get_active (the_gimp); + + if (GIMP_IS_TRANSFORM_TOOL (active_tool)) + gimp_transform_tool_grid_density_changed (GIMP_TRANSFORM_TOOL (active_tool)); +} + +static void +gimp_transform_tool_show_path_update (GtkWidget *widget, + gpointer data) +{ + static gboolean first_call = TRUE; /* eek, this hack avoids a segfault */ + + GimpTool *active_tool; + GimpTransformTool *transform_tool = NULL; + + if (first_call) + { + first_call = FALSE; + return; + } + + active_tool = tool_manager_get_active (the_gimp); + + if (GIMP_IS_TRANSFORM_TOOL (active_tool)) + transform_tool = GIMP_TRANSFORM_TOOL (active_tool); + + if (transform_tool) + gimp_transform_tool_show_path_changed (transform_tool, 1); /* pause */ + + gimp_toggle_button_update (widget, data); + + if (transform_tool) + gimp_transform_tool_show_path_changed (transform_tool, 0); /* resume */ +} diff --git a/app/tools/gimptransformoptions.h b/app/tools/gimptransformoptions.h index 3829ad9dd0..ed54e87c35 100644 --- a/app/tools/gimptransformoptions.h +++ b/app/tools/gimptransformoptions.h @@ -19,37 +19,39 @@ #ifndef __TRANSFORM_OPTIONS_H__ #define __TRANSFORM_OPTIONS_H_ + #include "tool_options.h" + typedef struct _TransformOptions TransformOptions; struct _TransformOptions { - GimpToolOptions tool_options; + GimpToolOptions tool_options; - gboolean smoothing; - gboolean smoothing_d; - GtkWidget *smoothing_w; + gboolean smoothing; + gboolean smoothing_d; + GtkWidget *smoothing_w; - gint direction; - gint direction_d; - GtkWidget *direction_w[2]; /* 2 radio buttons */ + GimpTransformDirection direction; + GimpTransformDirection direction_d; + GtkWidget *direction_w[2]; /* 2 radio buttons */ - gboolean show_grid; - gboolean show_grid_d; - GtkWidget *show_grid_w; + gboolean show_grid; + gboolean show_grid_d; + GtkWidget *show_grid_w; - gint grid_size; - gint grid_size_d; - GtkObject *grid_size_w; + gint grid_size; + gint grid_size_d; + GtkObject *grid_size_w; - gboolean clip; - gboolean clip_d; - GtkWidget *clip_w; + gboolean clip; + gboolean clip_d; + GtkWidget *clip_w; - gboolean showpath; - gboolean showpath_d; - GtkWidget *showpath_w; + gboolean show_path; + gboolean show_path_d; + GtkWidget *show_path_w; }; @@ -61,12 +63,5 @@ void transform_options_init (TransformOptions *options, ToolOptionsResetFunc reset_func); void transform_options_reset (GimpToolOptions *tool_options); -gboolean gimp_transform_tool_smoothing (void); -gboolean gimp_transform_tool_showpath (void); -gboolean gimp_transform_tool_clip (void); -gint gimp_transform_tool_direction (void); -gint gimp_transform_tool_grid_size (void); -gboolean gimp_transform_tool_show_grid (void); - #endif /* __TRANSFORM_OPTIONS_H__ */ diff --git a/app/tools/gimptransformtool.c b/app/tools/gimptransformtool.c index a775e89581..2c3c1a7a0f 100644 --- a/app/tools/gimptransformtool.c +++ b/app/tools/gimptransformtool.c @@ -28,18 +28,13 @@ #include "tools-types.h" #include "gui/gui-types.h" -#include "base/base-config.h" -#include "base/pixel-region.h" -#include "base/pixel-surround.h" #include "base/tile-manager.h" -#include "base/tile.h" - -#include "paint-funcs/paint-funcs.h" #include "core/gimp.h" #include "core/gimpchannel.h" #include "core/gimpcontext.h" #include "core/gimpdrawable.h" +#include "core/gimpdrawable-transform.h" #include "core/gimpimage.h" #include "core/gimpimage-mask.h" #include "core/gimplayer.h" @@ -53,7 +48,6 @@ #include "display/gimpdisplayshell.h" #include "tool_manager.h" -#include "tool_options.h" #include "transform_options.h" #include "gimptransformtool.h" #include "gimpperspectivetool.h" @@ -62,91 +56,78 @@ #include "gimpsheartool.h" #include "gimpfliptool.h" -#include "app_procs.h" #include "floating_sel.h" +#include "gimpprogress.h" #include "undo.h" #include "path_transform.h" #include "libgimp/gimpintl.h" +#define HANDLE 10 + enum { TRANSFORM, LAST_SIGNAL }; -#define HANDLE 10 -#define BILINEAR(jk,j1k,jk1,j1k1,dx,dy) \ - ((1-dy) * (jk + dx * (j1k - jk)) + \ - dy * (jk1 + dx * (j1k1 - jk1))) +/* local function prototypes */ -/* access interleaved pixels */ -#define CUBIC_ROW(dx, row, step) \ - gimp_transform_tool_cubic(dx, (row)[0], (row)[step], (row)[step+step], (row)[step+step+step]) -#define CUBIC_SCALED_ROW(dx, row, step, i) \ - gimp_transform_tool_cubic(dx, (row)[0] * (row)[i], \ - (row)[step] * (row)[step + i], \ - (row)[step+step]* (row)[step+step + i], \ - (row)[step+step+step] * (row)[step+step+step + i]) +static void gimp_transform_tool_init (GimpTransformTool *tool); +static void gimp_transform_tool_class_init (GimpTransformToolClass *tool); -#define REF_TILE(i,x,y) \ - tile[i] = tile_manager_get_tile (float_tiles, x, y, TRUE, FALSE); \ - src[i] = tile_data_pointer (tile[i], (x) % TILE_WIDTH, (y) % TILE_HEIGHT); +static void gimp_transform_tool_finalize (GObject *object); +static void gimp_transform_tool_control (GimpTool *tool, + ToolAction action, + GimpDisplay *gdisp); +static void gimp_transform_tool_button_press (GimpTool *tool, + GimpCoords *coords, + guint32 time, + GdkModifierType state, + GimpDisplay *gdisp); +static void gimp_transform_tool_button_release (GimpTool *tool, + GimpCoords *coords, + guint32 time, + GdkModifierType state, + GimpDisplay *gdisp); +static void gimp_transform_tool_motion (GimpTool *tool, + GimpCoords *coords, + guint32 time, + GdkModifierType state, + GimpDisplay *gdisp); +static void gimp_transform_tool_cursor_update (GimpTool *tool, + GimpCoords *coords, + GdkModifierType state, + GimpDisplay *gdisp); -/* forward function declarations */ -static void gimp_transform_tool_bounds (GimpTransformTool *tool, - GimpDisplay *gdisp); -static void gimp_transform_tool_recalc (GimpTransformTool *tool, - GimpDisplay *gdisp); -static void gimp_transform_tool_doit (GimpTransformTool *tool, - GimpDisplay *gdisp); -static gdouble gimp_transform_tool_cubic (gdouble dx, - gint jm1, - gint j, - gint jp1, - gint jp2); -static void gimp_transform_tool_setup_grid (GimpTransformTool *tool); -static void gimp_transform_tool_grid_recalc (GimpTransformTool *gimp_transform_tool); -static void gimp_transform_tool_init (GimpTransformTool *tool); -static void gimp_transform_tool_class_init (GimpTransformToolClass *tool); +static void gimp_transform_tool_draw (GimpDrawTool *draw_tool); -static void gimp_transform_tool_finalize (GObject *object); +static TileManager * gimp_transform_tool_transform (GimpTransformTool *tr_tool, + GimpDisplay *gdisp, + TransformState state); +static void gimp_transform_tool_reset (GimpTransformTool *tr_tool, + GimpDisplay *gdisp); +static void gimp_transform_tool_bounds (GimpTransformTool *tr_tool, + GimpDisplay *gdisp); +static void gimp_transform_tool_recalc (GimpTransformTool *tr_tool, + GimpDisplay *gdisp); +static void gimp_transform_tool_doit (GimpTransformTool *tr_tool, + GimpDisplay *gdisp); +static void gimp_transform_tool_setup_grid (GimpTransformTool *tr_tool, + TransformOptions *options); +static void gimp_transform_tool_grid_recalc (GimpTransformTool *tr_tool); -static void gimp_transform_tool_button_press (GimpTool *tool, - GimpCoords *coords, - guint32 time, - GdkModifierType state, - GimpDisplay *gdisp); - -static void gimp_transform_tool_button_release (GimpTool *tool, - GimpCoords *coords, - guint32 time, - GdkModifierType state, - GimpDisplay *gdisp); - -static void gimp_transform_tool_motion (GimpTool *tool, - GimpCoords *coords, - guint32 time, - GdkModifierType state, - GimpDisplay *gdisp); - -static void gimp_transform_tool_cursor_update (GimpTool *tool, - GimpCoords *coords, - GdkModifierType state, - GimpDisplay *gdisp); - -static void gimp_transform_tool_control (GimpTool *tool, - ToolAction action, - GimpDisplay *gdisp); - -static void gimp_transform_tool_draw (GimpDrawTool *draw_tool); +static void transform_ok_callback (GtkWidget *widget, + gpointer data); +static void transform_reset_callback (GtkWidget *widget, + gpointer data); /* variables */ -static TranInfo old_trans_info; +static TransInfo old_trans_info; InfoDialog *transform_info = NULL; static gboolean transform_info_inited = FALSE; @@ -219,78 +200,32 @@ gimp_transform_tool_class_init (GimpTransformToolClass *klass) } static void -gimp_transform_tool_init (GimpTransformTool *tr_tool) +gimp_transform_tool_init (GimpTransformTool *transform_tool) { - GimpTool *tool = GIMP_TOOL (tr_tool); + GimpTool *tool; gint i; - tr_tool->function = TRANSFORM_CREATING; - tr_tool->original = NULL; + tool = GIMP_TOOL (transform_tool); + + transform_tool->function = TRANSFORM_CREATING; + transform_tool->original = NULL; for (i = 0; i < TRAN_INFO_SIZE; i++) - tr_tool->trans_info[i] = 0; + transform_tool->trans_info[i] = 0.0; - tr_tool->grid_coords = tr_tool->tgrid_coords = NULL; + gimp_matrix3_identity (transform_tool->transform); - /* FIXME */ - tr_tool->interactive = TRUE; + transform_tool->use_grid = TRUE; + transform_tool->ngx = 0; + transform_tool->ngy = 0; + transform_tool->grid_coords = NULL; + transform_tool->tgrid_coords = NULL; tool->scroll_lock = TRUE; /* Disallow scrolling */ tool->preserve = FALSE; /* Don't preserve on drawable change */ } -TileManager * -gimp_transform_tool_transform (GimpTransformTool *tool, - GimpDisplay *gdisp, - TransformState state) -{ - TileManager *retval; - - g_return_val_if_fail (tool, NULL); - g_return_val_if_fail (GIMP_IS_TRANSFORM_TOOL (tool), NULL); - - g_signal_emit (G_OBJECT (tool), gimp_transform_tool_signals[TRANSFORM], 0, - gdisp, state, &retval); - - return retval; -} - -static void -transform_ok_callback (GtkWidget *widget, - gpointer data) -{ - GimpTool *tool; - - tool = GIMP_TOOL(data); - gimp_transform_tool_doit (GIMP_TRANSFORM_TOOL(tool), tool->gdisp); -} - -static void -transform_reset_callback (GtkWidget *widget, - gpointer data) -{ - GimpTransformTool *tool; - GimpDrawTool *dr_tool; - gint i; - - tool = GIMP_TRANSFORM_TOOL (data); - dr_tool = GIMP_DRAW_TOOL (data); - - /* stop the current tool drawing process */ - gimp_draw_tool_pause (dr_tool); - - /* Restore the previous transformation info */ - for (i = 0; i < TRAN_INFO_SIZE; i++) - tool->trans_info [i] = old_trans_info [i]; - - /* recalculate the tool's transformation matrix */ - gimp_transform_tool_recalc (tool, GIMP_TOOL(tool)->gdisp); - - /* resume drawing the current tool */ - gimp_draw_tool_resume (dr_tool); -} - static void gimp_transform_tool_finalize (GObject *object) { @@ -331,11 +266,9 @@ gimp_transform_tool_control (GimpTool *tool, ToolAction action, GimpDisplay *gdisp) { - GimpDrawTool *dr_tool; - GimpTransformTool *tr_tool; + GimpTransformTool *transform_tool; - dr_tool = GIMP_DRAW_TOOL (tool); - tr_tool = GIMP_TRANSFORM_TOOL (tool); + transform_tool = GIMP_TRANSFORM_TOOL (tool); switch (action) { @@ -343,19 +276,18 @@ gimp_transform_tool_control (GimpTool *tool, break; case RESUME: - gimp_transform_tool_recalc (tr_tool, gdisp); + gimp_transform_tool_recalc (transform_tool, gdisp); break; case HALT: - gimp_transform_tool_reset (tr_tool, gdisp); + gimp_transform_tool_reset (transform_tool, gdisp); break; default: break; } - if (GIMP_TOOL_CLASS (parent_class)->control) - GIMP_TOOL_CLASS (parent_class)->control (tool, action, gdisp); + GIMP_TOOL_CLASS (parent_class)->control (tool, action, gdisp); } static void @@ -365,7 +297,7 @@ gimp_transform_tool_button_press (GimpTool *tool, GdkModifierType state, GimpDisplay *gdisp) { - GimpTransformTool *gt_tool; + GimpTransformTool *tr_tool; GimpDrawTool *draw_tool; GimpDisplayShell *shell; GimpDrawable *drawable; @@ -374,75 +306,75 @@ gimp_transform_tool_button_press (GimpTool *tool, gint i; gint off_x, off_y; - gt_tool = GIMP_TRANSFORM_TOOL (tool); + tr_tool = GIMP_TRANSFORM_TOOL (tool); draw_tool = GIMP_DRAW_TOOL (tool); shell = GIMP_DISPLAY_SHELL (gdisp->shell); drawable = gimp_image_active_drawable (gdisp->gimage); - if (gt_tool->function == TRANSFORM_CREATING && tool->state == ACTIVE) + if (tr_tool->function == TRANSFORM_CREATING && tool->state == ACTIVE) { /* Save the current transformation info */ for (i = 0; i < TRAN_INFO_SIZE; i++) - old_trans_info [i] = gt_tool->trans_info [i]; + old_trans_info[i] = tr_tool->trans_info[i]; } /* if we have already displayed the bounding box and handles, * check to make sure that the display which currently owns the * tool is the one which just received the button pressed event */ - if ((gdisp == tool->gdisp) && gt_tool->interactive) + if (gdisp == tool->gdisp) { /* start drawing the bounding box and handles... */ gimp_draw_tool_start (GIMP_DRAW_TOOL (tool), shell->canvas->window); closest_dist = gimp_draw_tool_calc_distance (draw_tool, gdisp, coords->x, coords->y, - gt_tool->tx1, gt_tool->ty1); - gt_tool->function = TRANSFORM_HANDLE_1; + tr_tool->tx1, tr_tool->ty1); + tr_tool->function = TRANSFORM_HANDLE_1; dist = gimp_draw_tool_calc_distance (draw_tool, gdisp, coords->x, coords->y, - gt_tool->tx2, gt_tool->ty2); + tr_tool->tx2, tr_tool->ty2); if (dist < closest_dist) { closest_dist = dist; - gt_tool->function = TRANSFORM_HANDLE_2; + tr_tool->function = TRANSFORM_HANDLE_2; } dist = gimp_draw_tool_calc_distance (draw_tool, gdisp, coords->x, coords->y, - gt_tool->tx3, gt_tool->ty3); + tr_tool->tx3, tr_tool->ty3); if (dist < closest_dist) { closest_dist = dist; - gt_tool->function = TRANSFORM_HANDLE_3; + tr_tool->function = TRANSFORM_HANDLE_3; } dist = gimp_draw_tool_calc_distance (draw_tool, gdisp, coords->x, coords->y, - gt_tool->tx4, gt_tool->ty4); + tr_tool->tx4, tr_tool->ty4); if (dist < closest_dist) { closest_dist = dist; - gt_tool->function = TRANSFORM_HANDLE_4; + tr_tool->function = TRANSFORM_HANDLE_4; } if (gimp_draw_tool_on_handle (draw_tool, gdisp, coords->x, coords->y, GIMP_HANDLE_CIRCLE, - gt_tool->tcx, gt_tool->tcy, + tr_tool->tcx, tr_tool->tcy, HANDLE, HANDLE, GIMP_HANDLE_CIRCLE, FALSE)) { - gt_tool->function = TRANSFORM_HANDLE_CENTER; + tr_tool->function = TRANSFORM_HANDLE_CENTER; } /* Save the current pointer position */ - gt_tool->lastx = gt_tool->startx = coords->x; - gt_tool->lasty = gt_tool->starty = coords->y; + tr_tool->lastx = tr_tool->startx = coords->x; + tr_tool->lasty = tr_tool->starty = coords->y; gdk_pointer_grab (shell->canvas->window, FALSE, GDK_POINTER_MOTION_HINT_MASK | @@ -480,31 +412,29 @@ gimp_transform_tool_button_press (GimpTool *tool, * and reset */ if (tool->state == ACTIVE) - gimp_transform_tool_reset (gt_tool, gdisp); + gimp_transform_tool_reset (tr_tool, gdisp); /* Set the pointer to the active display */ tool->gdisp = gdisp; tool->drawable = drawable; tool->state = ACTIVE; - /* Grab the pointer if we're in non-interactive mode */ - if (! gt_tool->interactive) - gdk_pointer_grab (shell->canvas->window, FALSE, - GDK_POINTER_MOTION_HINT_MASK | - GDK_BUTTON1_MOTION_MASK | - GDK_BUTTON_RELEASE_MASK, - NULL, NULL, time); + gdk_pointer_grab (shell->canvas->window, FALSE, + GDK_POINTER_MOTION_HINT_MASK | + GDK_BUTTON1_MOTION_MASK | + GDK_BUTTON_RELEASE_MASK, + NULL, NULL, time); /* Find the transform bounds for some tools (like scale, * perspective) that actually need the bounds for * initializing */ - gimp_transform_tool_bounds (gt_tool, gdisp); + gimp_transform_tool_bounds (tr_tool, gdisp); /* Initialize the transform tool */ - gimp_transform_tool_transform (gt_tool, gdisp, TRANSFORM_INIT); + gimp_transform_tool_transform (tr_tool, gdisp, TRANSFORM_INIT); - if (transform_info && !transform_info_inited) + if (transform_info && ! transform_info_inited) { GType tool_type; @@ -532,11 +462,10 @@ gimp_transform_tool_button_press (GimpTool *tool, } /* Recalculate the transform tool */ - gimp_transform_tool_recalc (gt_tool, gdisp); + gimp_transform_tool_recalc (tr_tool, gdisp); /* recall this function to find which handle we're dragging */ - if (gt_tool->interactive) - gimp_transform_tool_button_press (tool, coords, time, state, gdisp); + gimp_transform_tool_button_press (tool, coords, time, state, gdisp); } } } @@ -548,13 +477,13 @@ gimp_transform_tool_button_release (GimpTool *tool, GdkModifierType state, GimpDisplay *gdisp) { - GimpTransformTool *gt_tool; + GimpTransformTool *tr_tool; gint i; - gt_tool = GIMP_TRANSFORM_TOOL (tool); + tr_tool = GIMP_TRANSFORM_TOOL (tool); /* if we are creating, there is nothing to be done...exit */ - if (gt_tool->function == TRANSFORM_CREATING && gt_tool->interactive) + if (tr_tool->function == TRANSFORM_CREATING) return; /* release of the pointer grab */ @@ -567,13 +496,13 @@ gimp_transform_tool_button_release (GimpTool *tool, /* Shift-clicking is another way to approve the transform */ if ((state & GDK_SHIFT_MASK) || GIMP_IS_FLIP_TOOL (tool)) { - gimp_transform_tool_doit (gt_tool, gdisp); + gimp_transform_tool_doit (tr_tool, gdisp); } else { /* Only update the paths preview */ path_transform_current_path (gdisp->gimage, - gt_tool->transform, TRUE); + tr_tool->transform, TRUE); } } else @@ -583,159 +512,20 @@ gimp_transform_tool_button_release (GimpTool *tool, /* Restore the previous transformation info */ for (i = 0; i < TRAN_INFO_SIZE; i++) - gt_tool->trans_info [i] = old_trans_info [i]; + tr_tool->trans_info[i] = old_trans_info[i]; /* recalculate the tool's transformation matrix */ - gimp_transform_tool_recalc (gt_tool, gdisp); + gimp_transform_tool_recalc (tr_tool, gdisp); /* resume drawing the current tool */ gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool)); /* Update the paths preview */ path_transform_current_path (gdisp->gimage, - gt_tool->transform, TRUE); + tr_tool->transform, TRUE); } - /* if this tool is non-interactive, make it inactive after use */ - if (! gt_tool->interactive) - tool->state = INACTIVE; -} - -static void -gimp_transform_tool_doit (GimpTransformTool *gt_tool, - GimpDisplay *gdisp) -{ - GimpDisplayShell *shell; - GimpTool *tool; - TileManager *new_tiles; - TransformUndo *tu; - PathUndo *pundo; - gboolean new_layer; - gint i; - - gimp_set_busy (gdisp->gimage->gimp); - - tool = GIMP_TOOL (gt_tool); - - shell = GIMP_DISPLAY_SHELL (gdisp->shell); - - /* undraw the tool before we muck around with the transform matrix */ - gimp_draw_tool_pause (GIMP_DRAW_TOOL (gt_tool)); - - /* We're going to dirty this image, but we want to keep the tool - * around - */ - tool->preserve = TRUE; - - /* Start a transform undo group */ - undo_push_group_start (gdisp->gimage, TRANSFORM_CORE_UNDO); - - /* With the old UI, if original is NULL, then this is the - * first transformation. In the new UI, it is always so, right? - */ - g_assert (gt_tool->original == NULL); - - /* If we're in interactive mode, we need to copy the current - * selection to the transform tool's private selection pointer, so - * that the original source can be repeatedly modified. - */ - tool->drawable = gimp_image_active_drawable (gdisp->gimage); - - gt_tool->original = gimp_transform_tool_cut (gdisp->gimage, - tool->drawable, - &new_layer); - - pundo = path_transform_start_undo (gdisp->gimage); - - /* Send the request for the transformation to the tool... - */ - new_tiles = gimp_transform_tool_transform (gt_tool, gdisp, - TRANSFORM_FINISH); - - gimp_transform_tool_transform (gt_tool, gdisp, TRANSFORM_INIT); - - gimp_transform_tool_recalc (gt_tool, gdisp); - - if (new_tiles) - { - /* paste the new transformed image to the gimage...also implement - * undo... - */ - /* FIXME: we should check if the drawable is still valid */ - gimp_transform_tool_paste (gdisp->gimage, tool->drawable, - new_tiles, new_layer); - - /* create and initialize the transform_undo structure */ - tu = g_new0 (TransformUndo, 1); - tu->tool_ID = tool->ID; - tu->tool_type = G_TYPE_FROM_INSTANCE (tool); - - for (i = 0; i < TRAN_INFO_SIZE; i++) - tu->trans_info[i] = old_trans_info[i]; - - tu->original = NULL; - tu->path_undo = pundo; - - /* Make a note of the new current drawable (since we may have - * a floating selection, etc now. - */ - tool->drawable = gimp_image_active_drawable (gdisp->gimage); - - undo_push_transform (gdisp->gimage, tu); - } - - /* push the undo group end */ - undo_push_group_end (gdisp->gimage); - - /* We're done dirtying the image, and would like to be restarted - * if the image gets dirty while the tool exists - */ - tool->preserve = FALSE; - -#ifdef __GNUC__ -#warning FIXME: investigate why display update was done here -#endif -#if 0 - /* Flush the gdisplays */ - if (gdisp->disp_xoffset || gdisp->disp_yoffset) - { - gint x, y; - - x = shell->disp_width; - y = shell->disp_height; - - if (gdisp->disp_yoffset) - { - gimp_display_shell_add_expose_area (shell, - 0, 0, - gdisp->disp_width, - gdisp->disp_yoffset); - gimp_display_shell_add_expose_area (shell, - 0, gdisp->disp_yoffset + y, - gdisp->disp_width, gdisp->disp_height); - } - - if (gdisp->disp_xoffset) - { - gimp_display_shell_add_expose_area (shell, - 0, 0, - gdisp->disp_xoffset, gdisp->disp_height); - gimp_display_shell_add_expose_area (shell, - gdisp->disp_xoffset + x, 0, - gdisp->disp_width, gdisp->disp_height); - } - } -#endif - - gimp_unset_busy (gdisp->gimage->gimp); - - gdisplays_flush (); - - gimp_transform_tool_reset (gt_tool, gdisp); - - /* if this tool is non-interactive, make it inactive after use */ - if (!gt_tool->interactive) - tool->state = INACTIVE; + tool->state = INACTIVE; } static void @@ -745,27 +535,27 @@ gimp_transform_tool_motion (GimpTool *tool, GdkModifierType state, GimpDisplay *gdisp) { - GimpTransformTool *tr_tool; + GimpTransformTool *transform_tool; - tr_tool = GIMP_TRANSFORM_TOOL (tool); + transform_tool = GIMP_TRANSFORM_TOOL (tool); /* if we are creating or this tool is non-interactive, there is * nothing to be done so exit. */ - if (tr_tool->function == TRANSFORM_CREATING || ! tr_tool->interactive) + if (transform_tool->function == TRANSFORM_CREATING) return; gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool)); - tr_tool->curx = coords->x; - tr_tool->cury = coords->y; - tr_tool->state = state; + transform_tool->curx = coords->x; + transform_tool->cury = coords->y; + transform_tool->state = state; /* recalculate the tool's transformation matrix */ - gimp_transform_tool_transform (tr_tool, gdisp, TRANSFORM_MOTION); + gimp_transform_tool_transform (transform_tool, gdisp, TRANSFORM_MOTION); - tr_tool->lastx = tr_tool->curx; - tr_tool->lasty = tr_tool->cury; + transform_tool->lastx = transform_tool->curx; + transform_tool->lasty = transform_tool->cury; gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool)); } @@ -776,11 +566,8 @@ gimp_transform_tool_cursor_update (GimpTool *tool, GdkModifierType state, GimpDisplay *gdisp) { - GimpTransformTool *tr_tool; - GimpDrawable *drawable; - GdkCursorType ctype = GDK_TOP_LEFT_ARROW; - - tr_tool = GIMP_TRANSFORM_TOOL (tool); + GimpDrawable *drawable; + GdkCursorType ctype = GDK_TOP_LEFT_ARROW; if ((drawable = gimp_image_active_drawable (gdisp->gimage))) { @@ -816,10 +603,13 @@ static void gimp_transform_tool_draw (GimpDrawTool *draw_tool) { GimpTransformTool *tr_tool; + TransformOptions *options; gint i, k, gci; tr_tool = GIMP_TRANSFORM_TOOL (draw_tool); + options = (TransformOptions *) GIMP_TOOL (draw_tool)->tool_info->tool_options; + /* draw the bounding box */ gimp_draw_tool_draw_line (draw_tool, tr_tool->tx1, tr_tool->ty1, @@ -895,11 +685,11 @@ gimp_transform_tool_draw (GimpDrawTool *draw_tool) GTK_ANCHOR_CENTER, FALSE); - if (gimp_transform_tool_showpath ()) + if (options->show_path) { GimpMatrix3 tmp_matrix; - if (gimp_transform_tool_direction () == TRANSFORM_CORRECTIVE) + if (options->direction == GIMP_TRANSFORM_BACKWARD) { gimp_matrix3_invert (tr_tool->transform, tmp_matrix); } @@ -913,6 +703,156 @@ gimp_transform_tool_draw (GimpDrawTool *draw_tool) } } +static TileManager * +gimp_transform_tool_transform (GimpTransformTool *tool, + GimpDisplay *gdisp, + TransformState state) +{ + TileManager *retval; + + g_return_val_if_fail (GIMP_IS_TRANSFORM_TOOL (tool), NULL); + + g_signal_emit (G_OBJECT (tool), gimp_transform_tool_signals[TRANSFORM], 0, + gdisp, state, &retval); + + return retval; +} + +static void +gimp_transform_tool_doit (GimpTransformTool *tr_tool, + GimpDisplay *gdisp) +{ + GimpDisplayShell *shell; + GimpTool *tool; + TileManager *new_tiles; + TransformUndo *tu; + PathUndo *pundo; + gboolean new_layer; + gint i; + + gimp_set_busy (gdisp->gimage->gimp); + + tool = GIMP_TOOL (tr_tool); + + shell = GIMP_DISPLAY_SHELL (gdisp->shell); + + /* undraw the tool before we muck around with the transform matrix */ + gimp_draw_tool_pause (GIMP_DRAW_TOOL (tr_tool)); + + /* We're going to dirty this image, but we want to keep the tool + * around + */ + tool->preserve = TRUE; + + /* Start a transform undo group */ + undo_push_group_start (gdisp->gimage, TRANSFORM_CORE_UNDO); + + /* With the old UI, if original is NULL, then this is the + * first transformation. In the new UI, it is always so, right? + */ + g_assert (tr_tool->original == NULL); + + /* Copy the current selection to the transform tool's private + * selection pointer, so that the original source can be repeatedly + * modified. + */ + tool->drawable = gimp_image_active_drawable (gdisp->gimage); + + tr_tool->original = gimp_drawable_transform_cut (tool->drawable, + &new_layer); + + pundo = path_transform_start_undo (gdisp->gimage); + + /* Send the request for the transformation to the tool... + */ + new_tiles = gimp_transform_tool_transform (tr_tool, gdisp, TRANSFORM_FINISH); + + gimp_transform_tool_transform (tr_tool, gdisp, TRANSFORM_INIT); + + gimp_transform_tool_recalc (tr_tool, gdisp); + + if (new_tiles) + { + /* paste the new transformed image to the gimage...also implement + * undo... + */ + /* FIXME: we should check if the drawable is still valid */ + gimp_drawable_transform_paste (tool->drawable, + new_tiles, + new_layer); + + /* create and initialize the transform_undo structure */ + tu = g_new0 (TransformUndo, 1); + tu->tool_ID = tool->ID; + tu->tool_type = G_TYPE_FROM_INSTANCE (tool); + + for (i = 0; i < TRAN_INFO_SIZE; i++) + tu->trans_info[i] = old_trans_info[i]; + + tu->original = NULL; + tu->path_undo = pundo; + + /* Make a note of the new current drawable (since we may have + * a floating selection, etc now. + */ + tool->drawable = gimp_image_active_drawable (gdisp->gimage); + + undo_push_transform (gdisp->gimage, tu); + } + + /* push the undo group end */ + undo_push_group_end (gdisp->gimage); + + /* We're done dirtying the image, and would like to be restarted + * if the image gets dirty while the tool exists + */ + tool->preserve = FALSE; + + gimp_unset_busy (gdisp->gimage->gimp); + + gdisplays_flush (); + + gimp_transform_tool_reset (tr_tool, gdisp); + + tool->state = INACTIVE; +} + +TileManager * +gimp_transform_tool_transform_tiles (GimpTransformTool *transform_tool, + const gchar *progress_text) +{ + GimpTool *tool; + TransformOptions *options; + GimpProgress *progress; + TileManager *ret; + + g_return_val_if_fail (GIMP_IS_TRANSFORM_TOOL (transform_tool), NULL); + g_return_val_if_fail (progress_text != NULL, NULL); + + gtk_widget_set_sensitive (GTK_WIDGET (transform_info->shell), FALSE); + + tool = GIMP_TOOL (transform_tool); + + options = (TransformOptions *) tool->tool_info->tool_options; + + progress = progress_start (tool->gdisp, progress_text, FALSE, NULL, NULL); + + ret = gimp_drawable_transform_tiles_affine (gimp_image_active_drawable (tool->gdisp->gimage), + transform_tool->original, + options->smoothing, + options->clip, + transform_tool->transform, + options->direction, + progress ? progress_update_and_flush : + (GimpProgressFunc) NULL, + progress); + + if (progress) + progress_end (progress); + + return ret; +} + void gimp_transform_tool_transform_bounding_box (GimpTransformTool *tr_tool) { @@ -1016,52 +956,47 @@ gimp_transform_tool_bounds (GimpTransformTool *tr_tool, tr_tool->cx = (tr_tool->x1 + tr_tool->x2) / 2; tr_tool->cy = (tr_tool->y1 + tr_tool->y2) / 2; - /* changing the bounds invalidates any grid we may have */ - gimp_transform_tool_grid_recalc (tr_tool); + if (tr_tool->use_grid) + { + /* changing the bounds invalidates any grid we may have */ + gimp_transform_tool_grid_recalc (tr_tool); + } } void -gimp_transform_tool_grid_density_changed (void) +gimp_transform_tool_grid_density_changed (GimpTransformTool *transform_tool) { - GimpTransformTool *tr_tool; - GimpDrawTool *dr_tool; - - /* EEEK!!! */ - tr_tool = GIMP_TRANSFORM_TOOL (tool_manager_get_active (the_gimp)); - - dr_tool = GIMP_DRAW_TOOL (tr_tool); - - if (tr_tool->function == TRANSFORM_CREATING) + if (transform_tool->function == TRANSFORM_CREATING) return; - gimp_draw_tool_pause (dr_tool); + gimp_draw_tool_pause (GIMP_DRAW_TOOL (transform_tool)); - gimp_transform_tool_grid_recalc (tr_tool); - gimp_transform_tool_transform_bounding_box (tr_tool); + gimp_transform_tool_grid_recalc (transform_tool); + gimp_transform_tool_transform_bounding_box (transform_tool); - gimp_draw_tool_resume (dr_tool); + gimp_draw_tool_resume (GIMP_DRAW_TOOL (transform_tool)); } void -gimp_transform_tool_showpath_changed (gint type /* a truly undescriptive name */) +gimp_transform_tool_show_path_changed (GimpTransformTool *transform_tool, + gint type /* a truly undescriptive name */) { - GimpTransformTool *tr_tool; - - /* EEEEEEEK!!! */ - tr_tool = GIMP_TRANSFORM_TOOL (tool_manager_get_active (the_gimp)); - - if (tr_tool->function == TRANSFORM_CREATING) + if (transform_tool->function == TRANSFORM_CREATING) return; if (type) - gimp_draw_tool_pause (GIMP_DRAW_TOOL (tr_tool)); + gimp_draw_tool_pause (GIMP_DRAW_TOOL (transform_tool)); else - gimp_draw_tool_resume (GIMP_DRAW_TOOL (tr_tool)); + gimp_draw_tool_resume (GIMP_DRAW_TOOL (transform_tool)); } static void gimp_transform_tool_grid_recalc (GimpTransformTool *tr_tool) { + TransformOptions *options; + + options = (TransformOptions *) GIMP_TOOL (tr_tool)->tool_info->tool_options; + if (tr_tool->grid_coords != NULL) { g_free (tr_tool->grid_coords); @@ -1074,12 +1009,15 @@ gimp_transform_tool_grid_recalc (GimpTransformTool *tr_tool) tr_tool->tgrid_coords = NULL; } - if (gimp_transform_tool_show_grid ()) - gimp_transform_tool_setup_grid (tr_tool); + if (options->show_grid) + { + gimp_transform_tool_setup_grid (tr_tool, options); + } } static void -gimp_transform_tool_setup_grid (GimpTransformTool *tr_tool) +gimp_transform_tool_setup_grid (GimpTransformTool *tr_tool, + TransformOptions *options) { GimpTool *tool; gint i, gci; @@ -1091,11 +1029,11 @@ gimp_transform_tool_setup_grid (GimpTransformTool *tr_tool) * if the user changes the grid size in the middle of an * operation, nothing happens. */ - tr_tool->ngx = (tr_tool->x2 - tr_tool->x1) / gimp_transform_tool_grid_size (); + tr_tool->ngx = (tr_tool->x2 - tr_tool->x1) / options->grid_size; if (tr_tool->ngx > 0) tr_tool->ngx--; - tr_tool->ngy = (tr_tool->y2 - tr_tool->y1) / gimp_transform_tool_grid_size (); + tr_tool->ngy = (tr_tool->y2 - tr_tool->y1) / options->grid_size; if (tr_tool->ngy > 0) tr_tool->ngy--; @@ -1139,596 +1077,35 @@ gimp_transform_tool_recalc (GimpTransformTool *tr_tool, gimp_transform_tool_transform (tr_tool, gdisp, TRANSFORM_RECALC); } -/* Actually carry out a transformation */ -TileManager * -gimp_transform_tool_do (GimpImage *gimage, - GimpDrawable *drawable, - TileManager *float_tiles, - gboolean interpolation, - GimpMatrix3 matrix, - GimpProgressFunc progress_callback, - gpointer progress_data) +static void +transform_ok_callback (GtkWidget *widget, + gpointer data) { - PixelRegion destPR; - TileManager *tiles; - GimpMatrix3 m; - GimpMatrix3 im; - gint itx, ity; - gint tx1, ty1, tx2, ty2; - gint width, height; - gint alpha; - gint bytes, b; - gint x, y; - gint sx, sy; - gint x1, y1, x2, y2; - gdouble xinc, yinc, winc; - gdouble tx, ty, tw; - gdouble ttx = 0.0, tty = 0.0; - guchar *dest; - guchar *d; - guchar *src[16]; - Tile *tile[16]; - guchar bg_col[MAX_CHANNELS]; - gint i; - gdouble a_val, a_recip; - gint newval; + GimpTool *tool; - PixelSurround surround; - - alpha = 0; - - /* turn interpolation off for simple transformations (e.g. rot90) */ - if (gimp_matrix3_is_simple (matrix) || - base_config->interpolation_type == NEAREST_NEIGHBOR_INTERPOLATION) - interpolation = FALSE; - - /* Get the background color */ - gimp_image_get_background (gimage, drawable, bg_col); - - switch (gimp_drawable_type (drawable)) - { - case RGB_GIMAGE: case RGBA_GIMAGE: - bg_col[ALPHA_PIX] = TRANSPARENT_OPACITY; - alpha = ALPHA_PIX; - break; - case GRAY_GIMAGE: case GRAYA_GIMAGE: - bg_col[ALPHA_G_PIX] = TRANSPARENT_OPACITY; - alpha = ALPHA_G_PIX; - break; - case INDEXED_GIMAGE: case INDEXEDA_GIMAGE: - bg_col[ALPHA_I_PIX] = TRANSPARENT_OPACITY; - alpha = ALPHA_I_PIX; - /* If the gimage is indexed color, ignore smoothing value */ - interpolation = FALSE; - break; - default: - g_assert_not_reached (); - break; - } - - /* enable rotating un-floated non-layers */ - if (tile_manager_bpp (float_tiles) == 1) - { - bg_col[0] = OPAQUE_OPACITY; - - /* setting alpha = 0 will cause the channel's value to be treated - * as alpha and the color channel loops never to be entered - */ - alpha = 0; - } - - if (gimp_transform_tool_direction () == TRANSFORM_CORRECTIVE) - { - /* keep the original matrix here, so we dont need to recalculate - the inverse later */ - gimp_matrix3_duplicate (matrix, m); - gimp_matrix3_invert (matrix, im); - matrix = im; - } - else - { - /* Find the inverse of the transformation matrix */ - gimp_matrix3_invert (matrix, m); - } - - path_transform_current_path (gimage, matrix, FALSE); - - tile_manager_get_offsets (float_tiles, &x1, &y1); - x2 = x1 + tile_manager_width (float_tiles); - y2 = y1 + tile_manager_height (float_tiles); - - /* Find the bounding coordinates */ - if (alpha == 0 || (tool_manager_get_active (gimage->gimp) && - gimp_transform_tool_clip ())) - { - tx1 = x1; - ty1 = y1; - tx2 = x2; - ty2 = y2; - } - else - { - gdouble dx1, dy1; - gdouble dx2, dy2; - gdouble dx3, dy3; - gdouble dx4, dy4; - - gimp_matrix3_transform_point (matrix, x1, y1, &dx1, &dy1); - gimp_matrix3_transform_point (matrix, x2, y1, &dx2, &dy2); - gimp_matrix3_transform_point (matrix, x1, y2, &dx3, &dy3); - gimp_matrix3_transform_point (matrix, x2, y2, &dx4, &dy4); - - tx1 = MIN (dx1, dx2); - tx1 = MIN (tx1, dx3); - tx1 = MIN (tx1, dx4); - ty1 = MIN (dy1, dy2); - ty1 = MIN (ty1, dy3); - ty1 = MIN (ty1, dy4); - - tx2 = MAX (dx1, dx2); - tx2 = MAX (tx2, dx3); - tx2 = MAX (tx2, dx4); - ty2 = MAX (dy1, dy2); - ty2 = MAX (ty2, dy3); - ty2 = MAX (ty2, dy4); - } - - /* Get the new temporary buffer for the transformed result */ - tiles = tile_manager_new ((tx2 - tx1), (ty2 - ty1), - tile_manager_bpp (float_tiles)); - pixel_region_init (&destPR, tiles, 0, 0, (tx2 - tx1), (ty2 - ty1), TRUE); - tile_manager_set_offsets (tiles, tx1, ty1); - - /* initialise the pixel_surround accessor */ - if (interpolation) - { - if (base_config->interpolation_type == CUBIC_INTERPOLATION) - { - pixel_surround_init (&surround, float_tiles, 4, 4, bg_col); - } - else - { - pixel_surround_init (&surround, float_tiles, 2, 2, bg_col); - } - } - else - { - /* not actually useful, keeps the code cleaner */ - pixel_surround_init (&surround, float_tiles, 1, 1, bg_col); - } - - width = tile_manager_width (tiles); - height = tile_manager_height (tiles); - bytes = tile_manager_bpp (tiles); - - dest = g_new (guchar, width * bytes); - - xinc = m[0][0]; - yinc = m[1][0]; - winc = m[2][0]; - - /* these loops could be rearranged, depending on which bit of code - * you'd most like to write more than once. - */ - - for (y = ty1; y < ty2; y++) - { - if (progress_callback && !(y & 0xf)) - (* progress_callback) (ty1, ty2, y, progress_data); - - /* set up inverse transform steps */ - tx = xinc * tx1 + m[0][1] * y + m[0][2]; - ty = yinc * tx1 + m[1][1] * y + m[1][2]; - tw = winc * tx1 + m[2][1] * y + m[2][2]; - - d = dest; - for (x = tx1; x < tx2; x++) - { - /* normalize homogeneous coords */ - if (tw == 0.0) - { - g_warning ("homogeneous coordinate = 0...\n"); - } - else if (tw != 1.0) - { - ttx = tx / tw; - tty = ty / tw; - } - else - { - ttx = tx; - tty = ty; - } - - /* Set the destination pixels */ - - if (interpolation) - { - if (base_config->interpolation_type == CUBIC_INTERPOLATION) - { - /* ttx & tty are the subpixel coordinates of the point in - * the original selection's floating buffer. - * We need the four integer pixel coords around them: - * itx to itx + 3, ity to ity + 3 - */ - itx = floor (ttx); - ity = floor (tty); - - /* check if any part of our region overlaps the buffer */ - - if ((itx + 2) >= x1 && (itx - 1) < x2 && - (ity + 2) >= y1 && (ity - 1) < y2 ) - { - guchar *data; - gint row; - gdouble dx, dy; - guchar *start; - - /* lock the pixel surround */ - data = pixel_surround_lock (&surround, - itx - 1 - x1, ity - 1 - y1); - - row = pixel_surround_rowstride (&surround); - - /* the fractional error */ - dx = ttx - itx; - dy = tty - ity; - - /* calculate alpha of result */ - start = &data[alpha]; - a_val = gimp_transform_tool_cubic - (dy, - CUBIC_ROW (dx, start, bytes), - CUBIC_ROW (dx, start + row, bytes), - CUBIC_ROW (dx, start + row + row, bytes), - CUBIC_ROW (dx, start + row + row + row, bytes)); - - if (a_val <= 0.0) - { - a_recip = 0.0; - d[alpha] = 0; - } - else if (a_val > 255.0) - { - a_recip = 1.0 / a_val; - d[alpha] = 255; - } - else - { - a_recip = 1.0 / a_val; - d[alpha] = RINT(a_val); - } - - /* for colour channels c, - * result = bicubic (c * alpha) / bicubic (alpha) - * - * never entered for alpha == 0 - */ - for (i = -alpha; i < 0; ++i) - { - start = &data[alpha]; - newval = - RINT (a_recip * - gimp_transform_tool_cubic - (dy, - CUBIC_SCALED_ROW (dx, start, bytes, i), - CUBIC_SCALED_ROW (dx, start + row, bytes, i), - CUBIC_SCALED_ROW (dx, start + row + row, bytes, i), - CUBIC_SCALED_ROW (dx, start + row + row + row, bytes, i))); - if (newval <= 0) - { - *d++ = 0; - } - else if (newval > 255) - { - *d++ = 255; - } - else - { - *d++ = newval; - } - } - - /* alpha already done */ - d++; - - pixel_surround_release (&surround); - } - else /* not in source range */ - { - /* increment the destination pointers */ - for (b = 0; b < bytes; b++) - *d++ = bg_col[b]; - } - } - - else /* linear */ - { - itx = floor (ttx); - ity = floor (tty); - - /* expand source area to cover interpolation region - * (which runs from itx to itx + 1, same in y) - */ - if ((itx + 1) >= x1 && itx < x2 && - (ity + 1) >= y1 && ity < y2 ) - { - guchar *data; - gint row; - double dx, dy; - guchar *chan; - - /* lock the pixel surround */ - data = pixel_surround_lock (&surround, itx - x1, ity - y1); - - row = pixel_surround_rowstride (&surround); - - /* the fractional error */ - dx = ttx - itx; - dy = tty - ity; - - /* calculate alpha value of result pixel */ - chan = &data[alpha]; - a_val = BILINEAR (chan[0], chan[bytes], chan[row], - chan[row+bytes], dx, dy); - if (a_val <= 0.0) - { - a_recip = 0.0; - d[alpha] = 0.0; - } - else if (a_val >= 255.0) - { - a_recip = 1.0 / a_val; - d[alpha] = 255; - } - else - { - a_recip = 1.0 / a_val; - d[alpha] = RINT (a_val); - } - - /* for colour channels c, - * result = bilinear (c * alpha) / bilinear (alpha) - * - * never entered for alpha == 0 - */ - for (i = -alpha; i < 0; ++i) - { - chan = &data[alpha]; - newval = - RINT (a_recip * - BILINEAR (chan[0] * chan[i], - chan[bytes] * chan[bytes+i], - chan[row] * chan[row+i], - chan[row+bytes] * chan[row+bytes+i], - dx, dy)); - if (newval <= 0) - { - *d++ = 0; - } - else if (newval > 255) - { - *d++ = 255; - } - else - { - *d++ = newval; - } - } - - /* alpha already done */ - d++; - - pixel_surround_release (&surround); - } - else /* not in source range */ - { - /* increment the destination pointers */ - for (b = 0; b < bytes; b++) - *d++ = bg_col[b]; - } - } - } - else /* no interpolation */ - { - itx = floor (ttx); - ity = floor (tty); - - if (itx >= x1 && itx < x2 && - ity >= y1 && ity < y2 ) - { - /* x, y coordinates into source tiles */ - sx = itx - x1; - sy = ity - y1; - - REF_TILE (0, sx, sy); - - for (b = 0; b < bytes; b++) - *d++ = src[0][b]; - - tile_release (tile[0], FALSE); - } - else /* not in source range */ - { - /* increment the destination pointers */ - for (b = 0; b < bytes; b++) - *d++ = bg_col[b]; - } - } - - /* increment the transformed coordinates */ - tx += xinc; - ty += yinc; - tw += winc; - } - - /* set the pixel region row */ - pixel_region_set_row (&destPR, 0, (y - ty1), width, dest); - } - - pixel_surround_clear (&surround); - - g_free (dest); - - return tiles; + tool = GIMP_TOOL(data); + gimp_transform_tool_doit (GIMP_TRANSFORM_TOOL(tool), tool->gdisp); } -TileManager * -gimp_transform_tool_cut (GimpImage *gimage, - GimpDrawable *drawable, - gboolean *new_layer) +static void +transform_reset_callback (GtkWidget *widget, + gpointer data) { - TileManager *tiles; + GimpTransformTool *transform_tool; + GimpTool *tool; + gint i; - /* extract the selected mask if there is a selection */ - if (! gimage_mask_is_empty (gimage)) - { - /* set the keep_indexed flag to FALSE here, since we use - gimp_layer_new_from_tiles() later which assumes that the tiles - are either RGB or GRAY. Eeek!!! (Sven) - */ - tiles = gimage_mask_extract (gimage, drawable, TRUE, FALSE, TRUE); - *new_layer = TRUE; - } - /* otherwise, just copy the layer */ - else - { - if (GIMP_IS_LAYER (drawable)) - tiles = gimage_mask_extract (gimage, drawable, FALSE, TRUE, TRUE); - else - tiles = gimage_mask_extract (gimage, drawable, FALSE, TRUE, FALSE); - *new_layer = FALSE; - } + transform_tool = GIMP_TRANSFORM_TOOL (data); + tool = GIMP_TOOL (data); - return tiles; -} - - -/* Paste a transform to the gdisplay */ -gboolean -gimp_transform_tool_paste (GimpImage *gimage, - GimpDrawable *drawable, - TileManager *tiles, - gboolean new_layer) -{ - GimpLayer *layer = NULL; - GimpChannel *channel = NULL; - GimpLayer *floating_layer; - - if (new_layer) - { - layer = - gimp_layer_new_from_tiles (gimage, - gimp_drawable_type_with_alpha (drawable), - tiles, - _("Transformation"), - OPAQUE_OPACITY, NORMAL_MODE); - if (! layer) - { - g_warning ("%s: gimp_layer_new_frome_tiles() failed", - G_GNUC_FUNCTION); - return FALSE; - } - - tile_manager_get_offsets (tiles, - &(GIMP_DRAWABLE (layer)->offset_x), - &(GIMP_DRAWABLE (layer)->offset_y)); - - /* Start a group undo */ - undo_push_group_start (gimage, EDIT_PASTE_UNDO); - - floating_sel_attach (layer, drawable); - - /* End the group undo */ - undo_push_group_end (gimage); - - /* Free the tiles */ - tile_manager_destroy (tiles); - - return TRUE; - } - else - { - if (GIMP_IS_LAYER (drawable)) - layer = GIMP_LAYER (drawable); - else if (GIMP_IS_CHANNEL (drawable)) - channel = GIMP_CHANNEL (drawable); - else - return FALSE; - - if (layer) - gimp_layer_add_alpha (layer); - - floating_layer = gimp_image_floating_sel (gimage); - - if (floating_layer) - floating_sel_relax (floating_layer, TRUE); - - gimp_image_update (gimage, - drawable->offset_x, - drawable->offset_y, - drawable->width, - drawable->height); - - /* Push an undo */ - if (layer) - undo_push_layer_mod (gimage, layer); - else if (channel) - undo_push_channel_mod (gimage, channel); - - /* set the current layer's data */ - drawable->tiles = tiles; - - /* Fill in the new layer's attributes */ - drawable->width = tile_manager_width (tiles); - drawable->height = tile_manager_height (tiles); - drawable->bytes = tile_manager_bpp (tiles); - tile_manager_get_offsets (tiles, - &drawable->offset_x, &drawable->offset_y); - - if (floating_layer) - floating_sel_rigor (floating_layer, TRUE); - - gimp_drawable_update (drawable, - 0, 0, - gimp_drawable_width (drawable), - gimp_drawable_height (drawable)); - - /* if we were operating on the floating selection, then it's boundary - * and previews need invalidating - */ - if (drawable == (GimpDrawable *) floating_layer) - floating_sel_invalidate (floating_layer); - - return TRUE; - } -} - -/* Note: cubic function no longer clips result */ -static gdouble -gimp_transform_tool_cubic (gdouble dx, - gint jm1, - gint j, - gint jp1, - gint jp2) -{ - gdouble result; - -#if 0 - /* Equivalent to Gimp 1.1.1 and earlier - some ringing */ - result = ((( ( - jm1 + j - jp1 + jp2 ) * dx + - ( jm1 + jm1 - j - j + jp1 - jp2 ) ) * dx + - ( - jm1 + jp1 ) ) * dx + j ); - /* Recommended by Mitchell and Netravali - too blurred? */ - result = ((( ( - 7 * jm1 + 21 * j - 21 * jp1 + 7 * jp2 ) * dx + - ( 15 * jm1 - 36 * j + 27 * jp1 - 6 * jp2 ) ) * dx + - ( - 9 * jm1 + 9 * jp1 ) ) * dx + (jm1 + 16 * j + jp1) ) / 18.0; -#endif - - /* Catmull-Rom - not bad */ - result = ((( ( - jm1 + 3 * j - 3 * jp1 + jp2 ) * dx + - ( 2 * jm1 - 5 * j + 4 * jp1 - jp2 ) ) * dx + - ( - jm1 + jp1 ) ) * dx + (j + j) ) / 2.0; - - return result; + gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool)); + + /* Restore the previous transformation info */ + for (i = 0; i < TRAN_INFO_SIZE; i++) + transform_tool->trans_info [i] = old_trans_info [i]; + + /* recalculate the tool's transformation matrix */ + gimp_transform_tool_recalc (transform_tool, tool->gdisp); + + gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool)); } diff --git a/app/tools/gimptransformtool.h b/app/tools/gimptransformtool.h index 1472ce4b84..7664995d2c 100644 --- a/app/tools/gimptransformtool.h +++ b/app/tools/gimptransformtool.h @@ -31,12 +31,8 @@ #define MAX_INFO_BUF 40 #define TRAN_INFO_SIZE 8 -enum BoundingBox -{ - X0, Y0, X1, Y1, X2, Y2, X3, Y3 -}; -typedef gdouble TranInfo[TRAN_INFO_SIZE]; +typedef gdouble TransInfo[TRAN_INFO_SIZE]; #define GIMP_TYPE_TRANSFORM_TOOL (gimp_transform_tool_get_type ()) @@ -75,13 +71,14 @@ struct _GimpTransformTool gdouble tcx, tcy; /* */ GimpMatrix3 transform; /* transformation matrix */ - TranInfo trans_info; /* transformation info */ + TransInfo trans_info; /* transformation info */ TileManager *original; /* pointer to original tiles */ TransformAction function; /* current tool activity */ - gboolean interactive; /* tool is interactive */ + gboolean use_grid; /* does the tool use the grid */ + gint ngx, ngy; /* number of grid lines in original * x and y directions */ @@ -102,6 +99,7 @@ struct _GimpTransformToolClass }; + /* Special undo type */ typedef struct _TransformUndo TransformUndo; @@ -110,59 +108,26 @@ struct _TransformUndo gint tool_ID; GType tool_type; - TranInfo trans_info; + TransInfo trans_info; TileManager *original; gpointer path_undo; }; -/* transform directions */ -#define TRANSFORM_TRADITIONAL 0 -#define TRANSFORM_CORRECTIVE 1 - /* make this variable available to all */ /* Do we still need to do this? -- rock */ extern InfoDialog * transform_info; -/* transform tool functions */ -/* make PDB compile: ToolType doesn't exist any more -Tool * gimp_transform_tool_new (GimpTransformToolType tool_type, - gboolean interactive); -*/ -GType gimp_transform_tool_get_type (void); +GType gimp_transform_tool_get_type (void); -void gimp_transform_tool_transform_bounding_box (GimpTransformTool *tool); -void gimp_transform_tool_reset (GimpTransformTool *tool, - GimpDisplay *gdisp); -void gimp_transform_tool_grid_density_changed (void); -void gimp_transform_tool_showpath_changed (gint type); -TileManager * gimp_transform_tool_transform (GimpTransformTool *tool, - GimpDisplay *gdisp, - TransformState state); -/* transform functions */ -/* FIXME this function needs to be renamed */ -TileManager * gimp_transform_tool_do (GimpImage *gimage, - GimpDrawable *drawable, - TileManager *float_tiles, - gboolean interpolation, - GimpMatrix3 matrix, - GimpProgressFunc progress_callback, - gpointer progress_data); -TileManager * gimp_transform_tool_cut (GimpImage *gimage, - GimpDrawable *drawable, - gboolean *new_layer); -gboolean gimp_transform_tool_paste (GimpImage *gimage, - GimpDrawable *drawable, - TileManager *tiles, - gboolean new_layer); +TileManager * gimp_transform_tool_transform_tiles (GimpTransformTool *tr_tool, + const gchar *progress_text); +void gimp_transform_tool_transform_bounding_box (GimpTransformTool *tr_tool); -gboolean gimp_transform_tool_smoothing (void); -gboolean gimp_transform_tool_showpath (void); -gboolean gimp_transform_tool_clip (void); -gint gimp_transform_tool_direction (void); -gint gimp_transform_tool_grid_size (void); -gboolean gimp_transform_tool_show_grid (void); +void gimp_transform_tool_grid_density_changed (GimpTransformTool *tr_tool); +void gimp_transform_tool_show_path_changed (GimpTransformTool *tr_tool, + gint type); #endif /* __GIMP_TRANSFORM_TOOL_H__ */ diff --git a/app/tools/transform_options.c b/app/tools/transform_options.c index c056160337..1b794b5fd4 100644 --- a/app/tools/transform_options.c +++ b/app/tools/transform_options.c @@ -27,160 +27,38 @@ #include "core/gimptoolinfo.h" -#include "gimprc.h" - -#include "gimptool.h" #include "gimptransformtool.h" #include "transform_options.h" #include "tool_manager.h" +#include "app_procs.h" +#include "gimprc.h" + #include "libgimp/gimpintl.h" -static TransformOptions *transform_options = NULL; +/* local function prototypes */ -/* Callback functions - need prototypes */ +static void gimp_transform_tool_grid_density_update (GtkWidget *widget, + gpointer data); +static void gimp_transform_tool_show_grid_update (GtkWidget *widget, + gpointer data); +static void gimp_transform_tool_show_path_update (GtkWidget *widget, + gpointer data); -static void -gimp_transform_tool_direction_callback (GtkWidget *widget, - gpointer data) -{ - long dir = (long) data; - if (dir == TRANSFORM_TRADITIONAL) - transform_options->direction = TRANSFORM_TRADITIONAL; - else - transform_options->direction = TRANSFORM_CORRECTIVE; -} +/* public functions */ -static void -gimp_transform_tool_grid_density_callback (GtkWidget *widget, - gpointer data) -{ - transform_options->grid_size = - (int) (pow (2.0, 7.0 - GTK_ADJUSTMENT (widget)->value) + 0.5); - - gimp_transform_tool_grid_density_changed (); -} - -static void -gimp_transform_tool_show_grid_update (GtkWidget *widget, - gpointer data) -{ - static gboolean first_call = TRUE; /* eek, this hack avoids a segfault */ - - if (first_call) - { - first_call = FALSE; - return; - } - - gimp_toggle_button_update (widget, data); - - gimp_transform_tool_grid_density_changed (); -} - -static void -gimp_transform_tool_show_path_update (GtkWidget *widget, - gpointer data) -{ - static gboolean first_call = TRUE; /* eek, this hack avoids a segfault */ - - if (first_call) - { - first_call = FALSE; - return; - } - - gimp_transform_tool_showpath_changed (1); /* pause */ - gimp_toggle_button_update (widget, data); - gimp_transform_tool_showpath_changed (0); /* resume */ -} - -/* Global functions. No magic needed yet. */ - -/* Unhappy with this - making this stuff global is wrong. */ - -gboolean -gimp_transform_tool_smoothing (void) -{ - if (!transform_options) - return TRUE; - else - return transform_options->smoothing; -} - -gboolean -gimp_transform_tool_showpath (void) -{ - if (!transform_options) - return TRUE; - else - return transform_options->showpath; -} - -gboolean -gimp_transform_tool_clip (void) -{ - if (!transform_options) - return FALSE; - else - return transform_options->clip; -} - -gint -gimp_transform_tool_direction (void) -{ - if (!transform_options) - return TRANSFORM_TRADITIONAL; - else - return transform_options->direction; -} - -gint -gimp_transform_tool_grid_size (void) -{ - if (!transform_options) - return 32; - else - return transform_options->grid_size; -} - -gboolean -gimp_transform_tool_show_grid (void) -{ - if (!transform_options) - return TRUE; - else - return transform_options->show_grid; -} - -/* Main options stuff - the rest doesn't need to be here (default - * callbacks is good, but none of this stuff should depend on having - * access to the options) - */ - -void -transform_options_reset (GimpToolOptions *tool_options) +TransformOptions * +transform_options_new (GType tool_type, + ToolOptionsResetFunc reset_func) { TransformOptions *options; - options = (TransformOptions *) tool_options; + options = g_new (TransformOptions, 1); + transform_options_init (options, tool_type, reset_func); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->smoothing_w), - options->smoothing_d); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->showpath_w), - options->showpath_d); - gtk_toggle_button_set_active (((options->direction_d == TRANSFORM_TRADITIONAL) ? - GTK_TOGGLE_BUTTON (options->direction_w[0]) : - GTK_TOGGLE_BUTTON (options->direction_w[1])), - TRUE); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->show_grid_w), - options->show_grid_d); - gtk_adjustment_set_value (GTK_ADJUSTMENT (options->grid_size_w), - 7.0 - log (options->grid_size_d) / log (2.0)); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->clip_w), - options->clip_d); + return options; } void @@ -202,23 +80,26 @@ transform_options_init (TransformOptions *options, vbox = options->tool_options.main_vbox; options->smoothing = options->smoothing_d = TRUE; - options->showpath = options->showpath_d = TRUE; + options->show_path = options->show_path_d = TRUE; options->clip = options->clip_d = FALSE; - options->direction = options->direction_d = TRANSFORM_TRADITIONAL; + options->direction = options->direction_d = GIMP_TRANSFORM_FORWARD; options->grid_size = options->grid_size_d = 32; options->show_grid = options->show_grid_d = TRUE; - frame = gimp_radio_group_new (TRUE, _("Tool Paradigm"), + frame = gimp_radio_group_new2 (TRUE, _("Tool Paradigm"), + G_CALLBACK (gimp_radio_button_update), + &options->direction, + GINT_TO_POINTER (options->direction), - _("Traditional"), gimp_transform_tool_direction_callback, - TRANSFORM_TRADITIONAL, NULL, - &options->direction_w[0], TRUE, + _("Traditional"), + GINT_TO_POINTER (GIMP_TRANSFORM_FORWARD), + &options->direction_w[0], - _("Corrective"), gimp_transform_tool_direction_callback, - TRANSFORM_CORRECTIVE, NULL, - &options->direction_w[1], FALSE, + _("Corrective"), + GINT_TO_POINTER (GIMP_TRANSFORM_BACKWARD), + &options->direction_w[1], - NULL); + NULL); gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); gtk_widget_show (frame); @@ -257,24 +138,24 @@ transform_options_init (TransformOptions *options, gtk_spin_button_new (GTK_ADJUSTMENT (options->grid_size_w), 0, 0); gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (grid_density), TRUE); g_signal_connect (G_OBJECT (options->grid_size_w), "value_changed", - G_CALLBACK (gimp_transform_tool_grid_density_callback), - &options->grid_size); + G_CALLBACK (gimp_transform_tool_grid_density_update), + options); gtk_box_pack_start (GTK_BOX (hbox), grid_density, FALSE, FALSE, 0); gtk_widget_show (grid_density); gtk_widget_set_sensitive (label, options->show_grid_d); gtk_widget_set_sensitive (grid_density, options->show_grid_d); g_object_set_data (G_OBJECT (options->show_grid_w), "set_sensitive", - grid_density); + grid_density); g_object_set_data (G_OBJECT (grid_density), "set_sensitive", label); - /* the showpath toggle button */ - options->showpath_w = gtk_check_button_new_with_label (_("Show Path")); - g_signal_connect (G_OBJECT (options->showpath_w), "toggled", + /* the show_path toggle button */ + options->show_path_w = gtk_check_button_new_with_label (_("Show Path")); + g_signal_connect (G_OBJECT (options->show_path_w), "toggled", G_CALLBACK (gimp_transform_tool_show_path_update), - &options->showpath); - gtk_box_pack_start (GTK_BOX (vbox), options->showpath_w, FALSE, FALSE, 0); - gtk_widget_show (options->showpath_w); + &options->show_path); + gtk_box_pack_start (GTK_BOX (vbox), options->show_path_w, FALSE, FALSE, 0); + gtk_widget_show (options->show_path_w); /* the smoothing toggle button */ options->smoothing_w = gtk_check_button_new_with_label (_("Smoothing")); @@ -296,21 +177,97 @@ transform_options_init (TransformOptions *options, transform_options_reset ((GimpToolOptions *) options); } -TransformOptions * -transform_options_new (GType tool_type, - ToolOptionsResetFunc reset_func) +void +transform_options_reset (GimpToolOptions *tool_options) { TransformOptions *options; - options = g_new (TransformOptions, 1); - transform_options_init (options, tool_type, reset_func); + options = (TransformOptions *) tool_options; - /* Set our local copy of the active tool's options (so that - * the methods/functions to access them work) */ - transform_options = options; - - return options; + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->smoothing_w), + options->smoothing_d); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->show_path_w), + options->show_path_d); + gtk_toggle_button_set_active (((options->direction_d == GIMP_TRANSFORM_FORWARD) ? + GTK_TOGGLE_BUTTON (options->direction_w[0]) : + GTK_TOGGLE_BUTTON (options->direction_w[1])), + TRUE); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->show_grid_w), + options->show_grid_d); + gtk_adjustment_set_value (GTK_ADJUSTMENT (options->grid_size_w), + 7.0 - log (options->grid_size_d) / log (2.0)); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->clip_w), + options->clip_d); } +/* private functions */ +static void +gimp_transform_tool_grid_density_update (GtkWidget *widget, + gpointer data) +{ + TransformOptions *options; + GimpTool *active_tool; + + options = (TransformOptions *) data; + + options->grid_size = + (gint) (pow (2.0, 7.0 - GTK_ADJUSTMENT (widget)->value) + 0.5); + + active_tool = tool_manager_get_active (the_gimp); + + if (GIMP_IS_TRANSFORM_TOOL (active_tool)) + gimp_transform_tool_grid_density_changed (GIMP_TRANSFORM_TOOL (active_tool)); +} + +static void +gimp_transform_tool_show_grid_update (GtkWidget *widget, + gpointer data) +{ + static gboolean first_call = TRUE; /* eek, this hack avoids a segfault */ + + GimpTool *active_tool; + + if (first_call) + { + first_call = FALSE; + return; + } + + gimp_toggle_button_update (widget, data); + + active_tool = tool_manager_get_active (the_gimp); + + if (GIMP_IS_TRANSFORM_TOOL (active_tool)) + gimp_transform_tool_grid_density_changed (GIMP_TRANSFORM_TOOL (active_tool)); +} + +static void +gimp_transform_tool_show_path_update (GtkWidget *widget, + gpointer data) +{ + static gboolean first_call = TRUE; /* eek, this hack avoids a segfault */ + + GimpTool *active_tool; + GimpTransformTool *transform_tool = NULL; + + if (first_call) + { + first_call = FALSE; + return; + } + + active_tool = tool_manager_get_active (the_gimp); + + if (GIMP_IS_TRANSFORM_TOOL (active_tool)) + transform_tool = GIMP_TRANSFORM_TOOL (active_tool); + + if (transform_tool) + gimp_transform_tool_show_path_changed (transform_tool, 1); /* pause */ + + gimp_toggle_button_update (widget, data); + + if (transform_tool) + gimp_transform_tool_show_path_changed (transform_tool, 0); /* resume */ +} diff --git a/app/tools/transform_options.h b/app/tools/transform_options.h index 3829ad9dd0..ed54e87c35 100644 --- a/app/tools/transform_options.h +++ b/app/tools/transform_options.h @@ -19,37 +19,39 @@ #ifndef __TRANSFORM_OPTIONS_H__ #define __TRANSFORM_OPTIONS_H_ + #include "tool_options.h" + typedef struct _TransformOptions TransformOptions; struct _TransformOptions { - GimpToolOptions tool_options; + GimpToolOptions tool_options; - gboolean smoothing; - gboolean smoothing_d; - GtkWidget *smoothing_w; + gboolean smoothing; + gboolean smoothing_d; + GtkWidget *smoothing_w; - gint direction; - gint direction_d; - GtkWidget *direction_w[2]; /* 2 radio buttons */ + GimpTransformDirection direction; + GimpTransformDirection direction_d; + GtkWidget *direction_w[2]; /* 2 radio buttons */ - gboolean show_grid; - gboolean show_grid_d; - GtkWidget *show_grid_w; + gboolean show_grid; + gboolean show_grid_d; + GtkWidget *show_grid_w; - gint grid_size; - gint grid_size_d; - GtkObject *grid_size_w; + gint grid_size; + gint grid_size_d; + GtkObject *grid_size_w; - gboolean clip; - gboolean clip_d; - GtkWidget *clip_w; + gboolean clip; + gboolean clip_d; + GtkWidget *clip_w; - gboolean showpath; - gboolean showpath_d; - GtkWidget *showpath_w; + gboolean show_path; + gboolean show_path_d; + GtkWidget *show_path_w; }; @@ -61,12 +63,5 @@ void transform_options_init (TransformOptions *options, ToolOptionsResetFunc reset_func); void transform_options_reset (GimpToolOptions *tool_options); -gboolean gimp_transform_tool_smoothing (void); -gboolean gimp_transform_tool_showpath (void); -gboolean gimp_transform_tool_clip (void); -gint gimp_transform_tool_direction (void); -gint gimp_transform_tool_grid_size (void); -gboolean gimp_transform_tool_show_grid (void); - #endif /* __TRANSFORM_OPTIONS_H__ */ diff --git a/libgimp/Makefile.am b/libgimp/Makefile.am index aadb51dcf6..13adafed36 100644 --- a/libgimp/Makefile.am +++ b/libgimp/Makefile.am @@ -56,6 +56,7 @@ PDB_WRAPPERS_C = \ gimpselectiontools_pdb.c \ gimptexttool_pdb.c \ gimptools_pdb.c \ + gimptransformtools_pdb.c \ gimpundo_pdb.c \ gimpunit_pdb.c @@ -91,6 +92,7 @@ PDB_WRAPPERS_H = \ gimpselectiontools_pdb.h \ gimptexttool_pdb.h \ gimptools_pdb.h \ + gimptransformtools_pdb.h \ gimpundo_pdb.h \ gimpunit_pdb.h diff --git a/libgimp/gimp_pdb.h b/libgimp/gimp_pdb.h index 44b04da9d6..870727394f 100644 --- a/libgimp/gimp_pdb.h +++ b/libgimp/gimp_pdb.h @@ -52,6 +52,7 @@ #include #include #include +#include #include #include diff --git a/libgimp/gimptools_pdb.c b/libgimp/gimptools_pdb.c index 7b4ade39a9..415f75cc8b 100644 --- a/libgimp/gimptools_pdb.c +++ b/libgimp/gimptools_pdb.c @@ -650,48 +650,6 @@ gimp_eraser_default (gint32 drawable_ID, return success; } -/** - * gimp_flip: - * @drawable_ID: The affected drawable. - * @flip_type: Type of flip. - * - * Flip the specified drawable about its center 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 flipd by the specified amount. The return - * value is the ID of the flipped drawable. If there was no selection, - * this will be equal to the drawable ID supplied as input. Otherwise, - * this will be the newly created and flipped drawable. The flip type - * parameter indicates whether the flip will be applied horizontally or - * vertically. - * - * Returns: The flipped drawable. - */ -gint32 -gimp_flip (gint32 drawable_ID, - GimpOrientationType flip_type) -{ - GimpParam *return_vals; - gint nreturn_vals; - gint32 ret_drawable_ID = -1; - - return_vals = gimp_run_procedure ("gimp_flip", - &nreturn_vals, - GIMP_PDB_DRAWABLE, drawable_ID, - GIMP_PDB_INT32, flip_type, - 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; -} - /** * gimp_paintbrush: * @drawable_ID: The affected drawable. @@ -834,233 +792,6 @@ gimp_pencil (gint32 drawable_ID, return success; } -/** - * gimp_perspective: - * @drawable_ID: The affected drawable. - * @interpolation: Whether to use interpolation. - * @x0: The new x coordinate of upper-left corner of original bounding box. - * @y0: The new y coordinate of upper-left corner of original bounding box. - * @x1: The new x coordinate of upper-right corner of original bounding box. - * @y1: The new y coordinate of upper-right corner of original bounding box. - * @x2: The new x coordinate of lower-left corner of original bounding box. - * @y2: The new y coordinate of lower-left corner of original bounding box. - * @x3: The new x coordinate of lower-right corner of original bounding box. - * @y3: The new y coordinate of lower-right corner of original bounding box. - * - * Perform a possibly non-affine transformation on the specified - * drawable. - * - * This tool performs a possibly non-affine transformation on the - * specified drawable by allowing the corners of the original bounding - * box to be arbitrarily remapped to any values. The specified drawable - * is remapped if no selection exists. However, if a selection exists, - * the portion of the drawable which lies under the selection is cut - * from the drawable and made into a floating selection which is then - * remapped as specified. The interpolation parameter can be set to - * TRUE to indicate that either linear or cubic interpolation should be - * used to smooth the resulting remapped drawable. The return value is - * the ID of the remapped drawable. If there was no selection, this - * will be equal to the drawable ID supplied as input. Otherwise, this - * will be the newly created and remapped drawable. The 4 coordinates - * specify the new locations of each corner of the original bounding - * box. By specifying these values, any affine transformation - * (rotation, scaling, translation) can be affected. Additionally, - * these values can be specified such that the resulting transformed - * drawable will appear to have been projected via a perspective - * transform. - * - * Returns: The newly mapped drawable. - */ -gint32 -gimp_perspective (gint32 drawable_ID, - gboolean interpolation, - gdouble x0, - gdouble y0, - gdouble x1, - gdouble y1, - gdouble x2, - gdouble y2, - gdouble x3, - gdouble y3) -{ - GimpParam *return_vals; - gint nreturn_vals; - gint32 ret_drawable_ID = -1; - - return_vals = gimp_run_procedure ("gimp_perspective", - &nreturn_vals, - GIMP_PDB_DRAWABLE, drawable_ID, - GIMP_PDB_INT32, interpolation, - 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_FLOAT, x3, - GIMP_PDB_FLOAT, y3, - 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; -} - -/** - * gimp_rotate: - * @drawable_ID: The affected drawable. - * @interpolation: Whether to use interpolation. - * @angle: The angle of rotation (radians). - * - * Rotate the specified drawable about its center 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. - * - * Returns: The rotated drawable. - */ -gint32 -gimp_rotate (gint32 drawable_ID, - gboolean interpolation, - gdouble angle) -{ - GimpParam *return_vals; - gint nreturn_vals; - gint32 ret_drawable_ID = -1; - - return_vals = gimp_run_procedure ("gimp_rotate", - &nreturn_vals, - GIMP_PDB_DRAWABLE, drawable_ID, - GIMP_PDB_INT32, interpolation, - GIMP_PDB_FLOAT, angle, - 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; -} - -/** - * gimp_scale: - * @drawable_ID: The affected drawable. - * @interpolation: Whether to use interpolation. - * @x0: The new x coordinate of upper-left corner of newly scaled region. - * @y0: The new y coordinate of upper-left corner of newly scaled region. - * @x1: The new x coordinate of lower-right corner of newly scaled region. - * @y1: The new y coordinate of lower-right corner of newly scaled region. - * - * Scale the specified drawable. - * - * This tool scales the specified drawable if no selection exists. If a - * selection exists, the portion of the drawable which lies under the - * selection is cut from the drawable and made into a floating - * selection which is then scaled by the specified amount. The - * interpolation parameter can be set to TRUE to indicate that either - * linear or cubic interpolation should be used to smooth the resulting - * scaled drawable. The return value is the ID of the scaled drawable. - * If there was no selection, this will be equal to the drawable ID - * supplied as input. Otherwise, this will be the newly created and - * scaled drawable. - * - * Returns: The scaled drawable. - */ -gint32 -gimp_scale (gint32 drawable_ID, - gboolean interpolation, - gdouble x0, - gdouble y0, - gdouble x1, - gdouble y1) -{ - GimpParam *return_vals; - gint nreturn_vals; - gint32 ret_drawable_ID = -1; - - return_vals = gimp_run_procedure ("gimp_scale", - &nreturn_vals, - GIMP_PDB_DRAWABLE, drawable_ID, - GIMP_PDB_INT32, interpolation, - GIMP_PDB_FLOAT, x0, - GIMP_PDB_FLOAT, y0, - GIMP_PDB_FLOAT, x1, - GIMP_PDB_FLOAT, y1, - 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; -} - -/** - * gimp_shear: - * @drawable_ID: The affected drawable. - * @interpolation: Whether to use interpolation. - * @shear_type: Type of shear. - * @magnitude: The magnitude of the shear. - * - * Shear the specified drawable about its center by the specified - * magnitude. - * - * This tool shears the specified drawable if no selection exists. If a - * selection exists, the portion of the drawable which lies under the - * selection is cut from the drawable and made into a floating - * selection which is then sheard by the specified amount. The - * interpolation parameter can be set to TRUE to indicate that either - * linear or cubic interpolation should be used to smooth the resulting - * sheared drawable. The return value is the ID of the sheard drawable. - * If there was no selection, this will be equal to the drawable ID - * supplied as input. Otherwise, this will be the newly created and - * sheard drawable. The shear type parameter indicates whether the - * shear will be applied horizontally or vertically. The magnitude can - * be either positive or negative and indicates the extent (in pixels) - * to shear by. - * - * Returns: The sheared drawable. - */ -gint32 -gimp_shear (gint32 drawable_ID, - gboolean interpolation, - GimpOrientationType shear_type, - gdouble magnitude) -{ - GimpParam *return_vals; - gint nreturn_vals; - gint32 ret_drawable_ID = -1; - - return_vals = gimp_run_procedure ("gimp_shear", - &nreturn_vals, - GIMP_PDB_DRAWABLE, drawable_ID, - GIMP_PDB_INT32, interpolation, - GIMP_PDB_INT32, shear_type, - GIMP_PDB_FLOAT, magnitude, - 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; -} - /** * gimp_smudge: * @drawable_ID: The affected drawable. @@ -1138,68 +869,3 @@ gimp_smudge_default (gint32 drawable_ID, return success; } - -/** - * gimp_transform_2d: - * @drawable_ID: The affected drawable. - * @interpolation: Whether to use interpolation. - * @source_x: X coordinate of the transformation center. - * @source_y: Y coordinate of the transformation center. - * @scale_x: Amount to scale in x direction. - * @scale_y: Amount to scale in y direction. - * @angle: The angle of rotation (radians). - * @dest_x: X coordinate of where the centre goes. - * @dest_y: Y coordinate of where the centre goes. - * - * Transform the specified drawable in 2d. - * - * This tool transforms the specified drawable if no selection exists. - * If a selection exists, the portion of the drawable which lies under - * the selection is cut from the drawable and made into a floating - * selection which is then transformed. The interpolation parameter can - * be set to TRUE to indicate that either linear or cubic interpolation - * should be used to smooth the resulting drawable. The transformation - * is done by scaling the image by the x and y scale factors about the - * point (source_x, source_y), then rotating around the same point, - * then translating that point to the new position (dest_x, dest_y). - * The return value is the ID of the rotated drawable. If there was no - * selection, this will be equal to the drawable ID supplied as input. - * Otherwise, this will be the newly created and transformed drawable. - * - * Returns: The transformed drawable. - */ -gint32 -gimp_transform_2d (gint32 drawable_ID, - gboolean interpolation, - gdouble source_x, - gdouble source_y, - gdouble scale_x, - gdouble scale_y, - gdouble angle, - gdouble dest_x, - gdouble dest_y) -{ - GimpParam *return_vals; - gint nreturn_vals; - gint32 ret_drawable_ID = -1; - - return_vals = gimp_run_procedure ("gimp_transform_2d", - &nreturn_vals, - GIMP_PDB_DRAWABLE, drawable_ID, - GIMP_PDB_INT32, interpolation, - GIMP_PDB_FLOAT, source_x, - GIMP_PDB_FLOAT, source_y, - GIMP_PDB_FLOAT, scale_x, - GIMP_PDB_FLOAT, scale_y, - GIMP_PDB_FLOAT, angle, - GIMP_PDB_FLOAT, dest_x, - GIMP_PDB_FLOAT, dest_y, - 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; -} diff --git a/libgimp/gimptools_pdb.h b/libgimp/gimptools_pdb.h index 44586e72e4..f3f0996498 100644 --- a/libgimp/gimptools_pdb.h +++ b/libgimp/gimptools_pdb.h @@ -104,8 +104,6 @@ gboolean gimp_eraser (gint32 drawable_ID, gboolean gimp_eraser_default (gint32 drawable_ID, gint num_strokes, gdouble *strokes); -gint32 gimp_flip (gint32 drawable_ID, - GimpOrientationType flip_type); gboolean gimp_paintbrush (gint32 drawable_ID, gdouble fade_out, gint num_strokes, @@ -118,29 +116,6 @@ gboolean gimp_paintbrush_default (gint32 drawable_ID, gboolean gimp_pencil (gint32 drawable_ID, gint num_strokes, gdouble *strokes); -gint32 gimp_perspective (gint32 drawable_ID, - gboolean interpolation, - gdouble x0, - gdouble y0, - gdouble x1, - gdouble y1, - gdouble x2, - gdouble y2, - gdouble x3, - gdouble y3); -gint32 gimp_rotate (gint32 drawable_ID, - gboolean interpolation, - gdouble angle); -gint32 gimp_scale (gint32 drawable_ID, - gboolean interpolation, - gdouble x0, - gdouble y0, - gdouble x1, - gdouble y1); -gint32 gimp_shear (gint32 drawable_ID, - gboolean interpolation, - GimpOrientationType shear_type, - gdouble magnitude); gboolean gimp_smudge (gint32 drawable_ID, gdouble pressure, gint num_strokes, @@ -148,15 +123,6 @@ gboolean gimp_smudge (gint32 drawable_ID, gboolean gimp_smudge_default (gint32 drawable_ID, gint num_strokes, gdouble *strokes); -gint32 gimp_transform_2d (gint32 drawable_ID, - gboolean interpolation, - gdouble source_x, - gdouble source_y, - gdouble scale_x, - gdouble scale_y, - gdouble angle, - gdouble dest_x, - gdouble dest_y); #ifdef __cplusplus diff --git a/libgimp/gimptransformtools_pdb.c b/libgimp/gimptransformtools_pdb.c new file mode 100644 index 0000000000..1a91feb8a6 --- /dev/null +++ b/libgimp/gimptransformtools_pdb.c @@ -0,0 +1,358 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-2000 Peter Mattis and Spencer Kimball + * + * gimptransformtools_pdb.c + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* NOTE: This file is autogenerated by pdbgen.pl */ + +#include "gimp.h" + +/** + * gimp_flip: + * @drawable_ID: The affected drawable. + * @flip_type: Type of flip. + * + * Flip the specified drawable about its center 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 flipd by the specified amount. The return + * value is the ID of the flipped drawable. If there was no selection, + * this will be equal to the drawable ID supplied as input. Otherwise, + * this will be the newly created and flipped drawable. The flip type + * parameter indicates whether the flip will be applied horizontally or + * vertically. + * + * Returns: The flipped drawable. + */ +gint32 +gimp_flip (gint32 drawable_ID, + GimpOrientationType flip_type) +{ + GimpParam *return_vals; + gint nreturn_vals; + gint32 ret_drawable_ID = -1; + + return_vals = gimp_run_procedure ("gimp_flip", + &nreturn_vals, + GIMP_PDB_DRAWABLE, drawable_ID, + GIMP_PDB_INT32, flip_type, + 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; +} + +/** + * gimp_perspective: + * @drawable_ID: The affected drawable. + * @interpolation: Whether to use interpolation. + * @x0: The new x coordinate of upper-left corner of original bounding box. + * @y0: The new y coordinate of upper-left corner of original bounding box. + * @x1: The new x coordinate of upper-right corner of original bounding box. + * @y1: The new y coordinate of upper-right corner of original bounding box. + * @x2: The new x coordinate of lower-left corner of original bounding box. + * @y2: The new y coordinate of lower-left corner of original bounding box. + * @x3: The new x coordinate of lower-right corner of original bounding box. + * @y3: The new y coordinate of lower-right corner of original bounding box. + * + * Perform a possibly non-affine transformation on the specified + * drawable. + * + * This tool performs a possibly non-affine transformation on the + * specified drawable by allowing the corners of the original bounding + * box to be arbitrarily remapped to any values. The specified drawable + * is remapped if no selection exists. However, if a selection exists, + * the portion of the drawable which lies under the selection is cut + * from the drawable and made into a floating selection which is then + * remapped as specified. The interpolation parameter can be set to + * TRUE to indicate that either linear or cubic interpolation should be + * used to smooth the resulting remapped drawable. The return value is + * the ID of the remapped drawable. If there was no selection, this + * will be equal to the drawable ID supplied as input. Otherwise, this + * will be the newly created and remapped drawable. The 4 coordinates + * specify the new locations of each corner of the original bounding + * box. By specifying these values, any affine transformation + * (rotation, scaling, translation) can be affected. Additionally, + * these values can be specified such that the resulting transformed + * drawable will appear to have been projected via a perspective + * transform. + * + * Returns: The newly mapped drawable. + */ +gint32 +gimp_perspective (gint32 drawable_ID, + gboolean interpolation, + gdouble x0, + gdouble y0, + gdouble x1, + gdouble y1, + gdouble x2, + gdouble y2, + gdouble x3, + gdouble y3) +{ + GimpParam *return_vals; + gint nreturn_vals; + gint32 ret_drawable_ID = -1; + + return_vals = gimp_run_procedure ("gimp_perspective", + &nreturn_vals, + GIMP_PDB_DRAWABLE, drawable_ID, + GIMP_PDB_INT32, interpolation, + 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_FLOAT, x3, + GIMP_PDB_FLOAT, y3, + 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; +} + +/** + * gimp_rotate: + * @drawable_ID: The affected drawable. + * @interpolation: Whether to use interpolation. + * @angle: The angle of rotation (radians). + * + * Rotate the specified drawable about its center 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. + * + * Returns: The rotated drawable. + */ +gint32 +gimp_rotate (gint32 drawable_ID, + gboolean interpolation, + gdouble angle) +{ + GimpParam *return_vals; + gint nreturn_vals; + gint32 ret_drawable_ID = -1; + + return_vals = gimp_run_procedure ("gimp_rotate", + &nreturn_vals, + GIMP_PDB_DRAWABLE, drawable_ID, + GIMP_PDB_INT32, interpolation, + GIMP_PDB_FLOAT, angle, + 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; +} + +/** + * gimp_scale: + * @drawable_ID: The affected drawable. + * @interpolation: Whether to use interpolation. + * @x0: The new x coordinate of upper-left corner of newly scaled region. + * @y0: The new y coordinate of upper-left corner of newly scaled region. + * @x1: The new x coordinate of lower-right corner of newly scaled region. + * @y1: The new y coordinate of lower-right corner of newly scaled region. + * + * Scale the specified drawable. + * + * This tool scales the specified drawable if no selection exists. If a + * selection exists, the portion of the drawable which lies under the + * selection is cut from the drawable and made into a floating + * selection which is then scaled by the specified amount. The + * interpolation parameter can be set to TRUE to indicate that either + * linear or cubic interpolation should be used to smooth the resulting + * scaled drawable. The return value is the ID of the scaled drawable. + * If there was no selection, this will be equal to the drawable ID + * supplied as input. Otherwise, this will be the newly created and + * scaled drawable. + * + * Returns: The scaled drawable. + */ +gint32 +gimp_scale (gint32 drawable_ID, + gboolean interpolation, + gdouble x0, + gdouble y0, + gdouble x1, + gdouble y1) +{ + GimpParam *return_vals; + gint nreturn_vals; + gint32 ret_drawable_ID = -1; + + return_vals = gimp_run_procedure ("gimp_scale", + &nreturn_vals, + GIMP_PDB_DRAWABLE, drawable_ID, + GIMP_PDB_INT32, interpolation, + GIMP_PDB_FLOAT, x0, + GIMP_PDB_FLOAT, y0, + GIMP_PDB_FLOAT, x1, + GIMP_PDB_FLOAT, y1, + 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; +} + +/** + * gimp_shear: + * @drawable_ID: The affected drawable. + * @interpolation: Whether to use interpolation. + * @shear_type: Type of shear. + * @magnitude: The magnitude of the shear. + * + * Shear the specified drawable about its center by the specified + * magnitude. + * + * This tool shears the specified drawable if no selection exists. If a + * selection exists, the portion of the drawable which lies under the + * selection is cut from the drawable and made into a floating + * selection which is then sheard by the specified amount. The + * interpolation parameter can be set to TRUE to indicate that either + * linear or cubic interpolation should be used to smooth the resulting + * sheared drawable. The return value is the ID of the sheard drawable. + * If there was no selection, this will be equal to the drawable ID + * supplied as input. Otherwise, this will be the newly created and + * sheard drawable. The shear type parameter indicates whether the + * shear will be applied horizontally or vertically. The magnitude can + * be either positive or negative and indicates the extent (in pixels) + * to shear by. + * + * Returns: The sheared drawable. + */ +gint32 +gimp_shear (gint32 drawable_ID, + gboolean interpolation, + GimpOrientationType shear_type, + gdouble magnitude) +{ + GimpParam *return_vals; + gint nreturn_vals; + gint32 ret_drawable_ID = -1; + + return_vals = gimp_run_procedure ("gimp_shear", + &nreturn_vals, + GIMP_PDB_DRAWABLE, drawable_ID, + GIMP_PDB_INT32, interpolation, + GIMP_PDB_INT32, shear_type, + GIMP_PDB_FLOAT, magnitude, + 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; +} + +/** + * gimp_transform_2d: + * @drawable_ID: The affected drawable. + * @interpolation: Whether to use interpolation. + * @source_x: X coordinate of the transformation center. + * @source_y: Y coordinate of the transformation center. + * @scale_x: Amount to scale in x direction. + * @scale_y: Amount to scale in y direction. + * @angle: The angle of rotation (radians). + * @dest_x: X coordinate of where the centre goes. + * @dest_y: Y coordinate of where the centre goes. + * + * Transform the specified drawable in 2d. + * + * This tool transforms the specified drawable if no selection exists. + * If a selection exists, the portion of the drawable which lies under + * the selection is cut from the drawable and made into a floating + * selection which is then transformed. The interpolation parameter can + * be set to TRUE to indicate that either linear or cubic interpolation + * should be used to smooth the resulting drawable. The transformation + * is done by scaling the image by the x and y scale factors about the + * point (source_x, source_y), then rotating around the same point, + * then translating that point to the new position (dest_x, dest_y). + * The return value is the ID of the rotated drawable. If there was no + * selection, this will be equal to the drawable ID supplied as input. + * Otherwise, this will be the newly created and transformed drawable. + * + * Returns: The transformed drawable. + */ +gint32 +gimp_transform_2d (gint32 drawable_ID, + gboolean interpolation, + gdouble source_x, + gdouble source_y, + gdouble scale_x, + gdouble scale_y, + gdouble angle, + gdouble dest_x, + gdouble dest_y) +{ + GimpParam *return_vals; + gint nreturn_vals; + gint32 ret_drawable_ID = -1; + + return_vals = gimp_run_procedure ("gimp_transform_2d", + &nreturn_vals, + GIMP_PDB_DRAWABLE, drawable_ID, + GIMP_PDB_INT32, interpolation, + GIMP_PDB_FLOAT, source_x, + GIMP_PDB_FLOAT, source_y, + GIMP_PDB_FLOAT, scale_x, + GIMP_PDB_FLOAT, scale_y, + GIMP_PDB_FLOAT, angle, + GIMP_PDB_FLOAT, dest_x, + GIMP_PDB_FLOAT, dest_y, + 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; +} diff --git a/libgimp/gimptransformtools_pdb.h b/libgimp/gimptransformtools_pdb.h new file mode 100644 index 0000000000..078c8102be --- /dev/null +++ b/libgimp/gimptransformtools_pdb.h @@ -0,0 +1,74 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-2000 Peter Mattis and Spencer Kimball + * + * gimptransformtools_pdb.h + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* NOTE: This file is autogenerated by pdbgen.pl */ + +#ifndef __GIMP_TRANSFORM_TOOLS_PDB_H__ +#define __GIMP_TRANSFORM_TOOLS_PDB_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* For information look into the C source or the html documentation */ + + +gint32 gimp_flip (gint32 drawable_ID, + GimpOrientationType flip_type); +gint32 gimp_perspective (gint32 drawable_ID, + gboolean interpolation, + gdouble x0, + gdouble y0, + gdouble x1, + gdouble y1, + gdouble x2, + gdouble y2, + gdouble x3, + gdouble y3); +gint32 gimp_rotate (gint32 drawable_ID, + gboolean interpolation, + gdouble angle); +gint32 gimp_scale (gint32 drawable_ID, + gboolean interpolation, + gdouble x0, + gdouble y0, + gdouble x1, + gdouble y1); +gint32 gimp_shear (gint32 drawable_ID, + gboolean interpolation, + GimpOrientationType shear_type, + gdouble magnitude); +gint32 gimp_transform_2d (gint32 drawable_ID, + gboolean interpolation, + gdouble source_x, + gdouble source_y, + gdouble scale_x, + gdouble scale_y, + gdouble angle, + gdouble dest_x, + gdouble dest_y); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __GIMP_TRANSFORM_TOOLS_PDB_H__ */ diff --git a/tools/pdbgen/Makefile.am b/tools/pdbgen/Makefile.am index 76a39d40a3..899e3e92d0 100644 --- a/tools/pdbgen/Makefile.am +++ b/tools/pdbgen/Makefile.am @@ -32,6 +32,7 @@ pdb_sources = \ pdb/selection_tools.pdb \ pdb/text_tool.pdb \ pdb/tools.pdb \ + pdb/transform_tools.pdb \ pdb/undo.pdb \ pdb/unit.pdb diff --git a/tools/pdbgen/groups.pl b/tools/pdbgen/groups.pl index 07b8b4ed45..ceea7aa926 100644 --- a/tools/pdbgen/groups.pl +++ b/tools/pdbgen/groups.pl @@ -30,6 +30,7 @@ selection_tools text_tool tools + transform_tools undo unit ); diff --git a/tools/pdbgen/pdb/misc_tools.pdb b/tools/pdbgen/pdb/misc_tools.pdb index 87b4499a81..a7ecf8e5af 100644 --- a/tools/pdbgen/pdb/misc_tools.pdb +++ b/tools/pdbgen/pdb/misc_tools.pdb @@ -544,79 +544,6 @@ CODE ); } -sub flip { - $blurb = <<'BLURB'; -Flip the specified drawable about its center either vertically or -horizontally. -BLURB - - $help = <<'HELP'; -This tool flips the specified drawable if no selection exists. If a selection -exists, the portion of the drawable which lies under the selection is cut from -the drawable and made into a floating selection which is then flipd by the -specified amount. The return value is the ID of the flipped drawable. If there -was no selection, this will be equal to the drawable ID supplied as input. -Otherwise, this will be the newly created and flipped drawable. The flip type -parameter indicates whether the flip will be applied horizontally or -vertically. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - { name => 'flip_type', type => &std_orientation_enum, - desc => 'Type of flip: %%desc%%' } - ); - - @outargs = ( &drawable_out_arg('flipped') ); - - %invoke = ( - headers => [ qw("tools/gimpfliptool.h" "tools/gimptransformtool.h" - "undo.h") ], - vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles', - 'gboolean new_layer' ], - code => <<'CODE' -{ - gimage = gimp_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 = gimp_transform_tool_cut (gimage, drawable, &new_layer); - - flip_type = flip_type == HORIZONTAL ? ORIENTATION_HORIZONTAL : - flip_type == VERTICAL ? ORIENTATION_VERTICAL : - ORIENTATION_UNKNOWN; - - /* flip the buffer */ - switch (flip_type) - { - case ORIENTATION_HORIZONTAL: - case ORIENTATION_VERTICAL: - new_tiles = flip_tool_flip (gimage, drawable, float_tiles, -1, flip_type); - break; - default: - new_tiles = NULL; - break; - } - - /* free the cut/copied buffer */ - tile_manager_destroy (float_tiles); - - if (new_tiles) - success = gimp_transform_tool_paste (gimage, drawable, new_tiles, new_layer); - else - success = FALSE; - - /* push the undo group end */ - undo_push_group_end (gimage); -} -CODE - ); -} - sub paintbrush { $blurb = <<'BLURB'; Paint in the current brush with optional fade out parameter and pull colors @@ -716,442 +643,6 @@ HELP ); } -sub perspective { - $blurb = <<'BLURB'; -Perform a possibly non-affine transformation on the specified drawable. -BLURB - - $help = <<'HELP'; -This tool performs a possibly non-affine transformation on the specified -drawable by allowing the corners of the original bounding box to be arbitrarily -remapped to any values. The specified drawable is remapped if no selection -exists. However, if a selection exists, the portion of the drawable which lies -under the selection is cut from the drawable and made into a floating selection -which is then remapped as specified. The interpolation parameter can be set to -TRUE to indicate that either linear or cubic interpolation should be used to -smooth the resulting remapped drawable. The return value is the ID of the -remapped drawable. If there was no selection, this will be equal to the -drawable ID supplied as input. Otherwise, this will be the newly created and -remapped drawable. The 4 coordinates specify the new locations of each corner -of the original bounding box. By specifying these values, any affine -transformation (rotation, scaling, translation) can be affected. Additionally, -these values can be specified such that the resulting transformed drawable will -appear to have been projected via a perspective transform. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - { name => 'interpolation', type => 'boolean', - desc => 'Whether to use interpolation' } - ); - - my $pos = 0; - foreach $where (qw(upper-left upper-right lower-left lower-right)) { - foreach (qw(x y)) { - push @inargs, - { name => "$_$pos", type => 'float', - desc => "The new $_ coordinate of $where corner of original - bounding box", - alias => "trans_info[\U$_\E$pos]", no_declare => 1 } - } - $pos++; - } - - @outargs = ( &drawable_out_arg('newly mapped') ); - - %invoke = ( - headers => [ qw("tools/gimpperspectivetool.h" "tools/gimptransformtool.h") ], - vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles', - 'gboolean new_layer', 'gint offset_x, offset_y', - 'gdouble cx, cy', 'gdouble scalex, scaley', - 'gdouble trans_info[8]', 'GimpMatrix3 m, matrix' ], - code => <<'CODE' -{ - gimage = gimp_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 = gimp_transform_tool_cut (gimage, drawable, &new_layer); - - /* Determine the perspective transform that maps from - * the unit cube to the trans_info coordinates - */ - gimp_perspective_tool_find_transform (trans_info, m); - - tile_manager_get_offsets (float_tiles, &offset_x, &offset_y); - cx = (gdouble) offset_x; - cy = (gdouble) offset_y; - scalex = 1.0; - scaley = 1.0; - if (tile_manager_width (float_tiles)) - scalex = 1.0 / tile_manager_width (float_tiles); - if (tile_manager_height (float_tiles)) - scaley = 1.0 / tile_manager_height (float_tiles); - - /* Assemble the transformation matrix */ - gimp_matrix3_identity (matrix); - gimp_matrix3_translate (matrix, -cx, -cy); - gimp_matrix3_scale (matrix, scalex, scaley); - gimp_matrix3_mult (m, matrix); - - /* Perspective the buffer */ - new_tiles = gimp_perspective_tool_perspective (gimage, drawable, NULL, - float_tiles, interpolation, - matrix); - - /* Free the cut/copied buffer */ - tile_manager_destroy (float_tiles); - - if (new_tiles) - success = gimp_transform_tool_paste (gimage, drawable, new_tiles, new_layer); - else - success = FALSE; - - /* push the undo group end */ - undo_push_group_end (gimage); -} -CODE - ); -} - -sub rotate { - $blurb = <<'BLURB'; -Rotate the specified drawable about its center through the specified angle. -BLURB - - $help = <<'HELP'; -This tool rotates the specified drawable if no selection exists. If a selection -exists, the portion of the drawable which lies under the selection is cut from -the drawable and made into a floating selection which is then rotated by the -specified amount. The interpolation parameter can be set to TRUE to indicate -that either linear or cubic interpolation should be used to smooth the -resulting rotated drawable. The return value is the ID of the rotated drawable. -If there was no selection, this will be equal to the drawable ID supplied as -input. Otherwise, this will be the newly created and rotated drawable. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - { name => 'interpolation', type => 'boolean', - desc => 'Whether to use interpolation' }, - { name => 'angle', type => 'float', - desc => 'The angle of rotation (radians)' } - ); - - @outargs = ( &drawable_out_arg('rotated') ); - - %invoke = ( - headers => [ qw("tools/gimprotatetool.h" "tools/gimptransformtool.h") ], - vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles', - 'gboolean new_layer', 'gint offset_x, offset_y', - 'gdouble cx, cy', 'GimpMatrix3 matrix' ], - code => <<'CODE' -{ - gimage = gimp_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 = gimp_transform_tool_cut (gimage, drawable, &new_layer); - - tile_manager_get_offsets (float_tiles, &offset_x, &offset_y); - cx = offset_x + tile_manager_width (float_tiles) / 2.0; - cy = offset_y + tile_manager_height (float_tiles) / 2.0; - - /* 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 = gimp_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 = gimp_transform_tool_paste (gimage, drawable, new_tiles, new_layer); - else - success = FALSE; - - /* Push the undo group end */ - undo_push_group_end (gimage); -} -CODE - ); -} - -sub scale { - $blurb = 'Scale the specified drawable.'; - - $help = <<'HELP'; -This tool scales the specified drawable if no selection exists. If a selection -exists, the portion of the drawable which lies under the selection is cut from -the drawable and made into a floating selection which is then scaled by the -specified amount. The interpolation parameter can be set to TRUE to indicate -that either linear or cubic interpolation should be used to smooth the -resulting scaled drawable. The return value is the ID of the scaled drawable. -If there was no selection, this will be equal to the drawable ID supplied as -input. Otherwise, this will be the newly created and scaled drawable. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - { name => 'interpolation', type => 'boolean', - desc => 'Whether to use interpolation' } - ); - - my $pos = 0; - foreach $where (qw(upper-left lower-right)) { - foreach (qw(x y)) { - push @inargs, - { name => "$_$pos", type => 'float', - desc => "The new $_ coordinate of $where corner of newly - scaled region", - alias => "trans_info[\U$_\E$pos]", no_declare => 1 } - } - $pos++; - } - - @outargs = ( &drawable_out_arg('scaled') ); - - %invoke = ( - headers => [ qw("tools/gimpscaletool.h" "tools/gimptransformtool.h") ], - vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles', - 'gboolean new_layer', 'gint offset_x, offset_y', - 'gdouble scalex, scaley', 'gdouble trans_info[4]', - 'GimpMatrix3 matrix' ], - code => <<'CODE' -{ - if (trans_info[X0] < trans_info[X1] && - trans_info[Y0] < trans_info[X1]) - { - gimage = gimp_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 = gimp_transform_tool_cut (gimage, drawable, &new_layer); - - scalex = scaley = 1.0; - if (tile_manager_width (float_tiles)) - scalex = (trans_info[X1] - trans_info[X0]) / - (gdouble) tile_manager_width (float_tiles); - if (tile_manager_height (float_tiles)) - scaley = (trans_info[Y1] - trans_info[Y0]) / - (gdouble) tile_manager_height (float_tiles); - - tile_manager_get_offsets (float_tiles, &offset_x, &offset_y); - - /* Assemble the transformation matrix */ - gimp_matrix3_identity (matrix); - gimp_matrix3_translate (matrix, offset_x, offset_y); - gimp_matrix3_scale (matrix, scalex, scaley); - gimp_matrix3_translate (matrix, trans_info[X0], trans_info[Y0]); - - /* Scale the buffer */ - new_tiles = gimp_scale_tool_scale (gimage, drawable, NULL, trans_info, - float_tiles, interpolation, matrix); - - /* Free the cut/copied buffer */ - tile_manager_destroy (float_tiles); - - if (new_tiles) - success = gimp_transform_tool_paste (gimage, drawable, new_tiles, new_layer); - else - success = FALSE; - - /* push the undo group end */ - undo_push_group_end (gimage); - } - else - success = FALSE; -} -CODE - ); -} - -sub shear { - $blurb = <<'BLURB'; -Shear the specified drawable about its center by the specified magnitude. -BLURB - - $help = <<'HELP'; -This tool shears the specified drawable if no selection exists. If a selection -exists, the portion of the drawable which lies under the selection is cut from -the drawable and made into a floating selection which is then sheard by the -specified amount. The interpolation parameter can be set to TRUE to indicate -that either linear or cubic interpolation should be used to smooth the -resulting sheared drawable. The return value is the ID of the sheard drawable. -If there was no selection, this will be equal to the drawable ID supplied as -input. Otherwise, this will be the newly created and sheard drawable. The shear -type parameter indicates whether the shear will be applied horizontally or -vertically. The magnitude can be either positive or negative and indicates the -extent (in pixels) to shear by. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - { name => 'interpolation', type => 'boolean', - desc => 'Whether to use interpolation' }, - { name => 'shear_type', type => &std_orientation_enum, - desc => 'Type of shear: %%desc%%' }, - { name => 'magnitude', type => 'float', - desc => 'The magnitude of the shear' } - ); - - @outargs = ( &drawable_out_arg('sheared') ); - - %invoke = ( - headers => [ qw("tools/gimpsheartool.h" "tools/gimptransformtool.h") ], - vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles', - 'gboolean new_layer', 'gdouble cx, cy', - 'gint offset_x, offset_y', 'GimpMatrix3 matrix' ], - code => <<'CODE' -{ - gimage = gimp_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 = gimp_transform_tool_cut (gimage, drawable, &new_layer); - - tile_manager_get_offsets (float_tiles, &offset_x, &offset_y); - - cx = offset_x + tile_manager_width (float_tiles) / 2.0; - cy = offset_y + tile_manager_height (float_tiles) / 2.0; - - gimp_matrix3_identity (matrix); - gimp_matrix3_translate (matrix, -cx, -cy); - /* Shear matrix */ - shear_type = shear_type == HORIZONTAL ? ORIENTATION_HORIZONTAL : - shear_type == VERTICAL ? ORIENTATION_VERTICAL : - ORIENTATION_UNKNOWN; - - if (shear_type == ORIENTATION_HORIZONTAL) - gimp_matrix3_xshear (matrix, magnitude / tile_manager_height (float_tiles)); - else if (shear_type == ORIENTATION_VERTICAL) - gimp_matrix3_yshear (matrix, magnitude / tile_manager_width (float_tiles)); - - gimp_matrix3_translate (matrix, +cx, +cy); - - /* Shear the buffer */ - new_tiles = gimp_shear_tool_shear (gimage, drawable, NULL, float_tiles, - interpolation, matrix); - - /* Free the cut/copied buffer */ - tile_manager_destroy (float_tiles); - - if (new_tiles) - success = gimp_transform_tool_paste (gimage, drawable, new_tiles, new_layer); - else - success = FALSE; - - /* Push the undo group end */ - undo_push_group_end (gimage); -} -CODE - ); -} - -sub transform_2d { - $blurb = <<'BLURB'; -Transform the specified drawable in 2d. -BLURB - - $help = <<'HELP'; -This tool transforms the specified drawable if no selection exists. If a -selection exists, the portion of the drawable which lies under the -selection is cut from the drawable and made into a floating selection which -is then transformed. The interpolation parameter can be set to TRUE to -indicate that either linear or cubic interpolation should be used to smooth -the resulting drawable. The transformation is done by scaling the image by -the x and y scale factors about the point (source_x, source_y), then rotating -around the same point, then translating that point to the new position -(dest_x, dest_y). The return value is the ID of the rotated drawable. If -there was no selection, this will be equal to the drawable ID supplied as -input. Otherwise, this will be the newly created and transformed drawable. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - { name => 'interpolation', type => 'boolean', - desc => 'Whether to use interpolation' }, - { name => 'source_x', type => 'float', - desc => 'X coordinate of the transformation center' }, - { name => 'source_y', type => 'float', - desc => 'Y coordinate of the transformation center' }, - { name => 'scale_x', type => 'float', - desc => 'Amount to scale in x direction' }, - { name => 'scale_y', type => 'float', - desc => 'Amount to scale in y direction' }, - { name => 'angle', type => 'float', - desc => 'The angle of rotation (radians)' }, - { name => 'dest_x', type => 'float', - desc => 'X coordinate of where the centre goes' }, - { name => 'dest_y', type => 'float', - desc => 'Y coordinate of where the centre goes' } - ); - - @outargs = ( &drawable_out_arg('transformed') ); - - %invoke = ( - headers => [ qw("tools/gimptransformtool.h") ], - vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles', - 'gboolean new_layer', 'GimpMatrix3 matrix' ], - code => <<'CODE' -{ - gimage = gimp_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 = gimp_transform_tool_cut (gimage, drawable, &new_layer); - - /* Assemble the transformation matrix */ - gimp_matrix3_identity (matrix); - gimp_matrix3_translate (matrix, -source_x, -source_y); - gimp_matrix3_scale (matrix, scale_x, scale_y); - gimp_matrix3_rotate (matrix, angle); - gimp_matrix3_translate (matrix, dest_x, dest_y); - - /* Transform the buffer */ - new_tiles = gimp_transform_tool_do (gimage, drawable, float_tiles, - interpolation, matrix, NULL, NULL); - - /* Free the cut/copied buffer */ - tile_manager_destroy (float_tiles); - - if (new_tiles) - success = gimp_transform_tool_paste (gimage, drawable, new_tiles, new_layer); - else - success = FALSE; - - /* Push the undo group end */ - undo_push_group_end (gimage); -} -CODE - ); -} - sub smudge { $blurb = <<'BLURB'; Smudge image with varying pressure. @@ -1288,9 +779,9 @@ sub ink { @procs = qw(airbrush airbrush_default blend bucket_fill clone clone_default color_picker convolve convolve_default dodgeburn dodgeburn_default - eraser eraser_default flip paintbrush paintbrush_default - pencil perspective rotate scale shear smudge smudge_default - transform_2d); + eraser eraser_default paintbrush paintbrush_default + pencil smudge smudge_default); + %exports = (app => [@procs], lib => [@procs]); $desc = 'Tool procedures'; diff --git a/tools/pdbgen/pdb/paint_tools.pdb b/tools/pdbgen/pdb/paint_tools.pdb index 87b4499a81..a7ecf8e5af 100644 --- a/tools/pdbgen/pdb/paint_tools.pdb +++ b/tools/pdbgen/pdb/paint_tools.pdb @@ -544,79 +544,6 @@ CODE ); } -sub flip { - $blurb = <<'BLURB'; -Flip the specified drawable about its center either vertically or -horizontally. -BLURB - - $help = <<'HELP'; -This tool flips the specified drawable if no selection exists. If a selection -exists, the portion of the drawable which lies under the selection is cut from -the drawable and made into a floating selection which is then flipd by the -specified amount. The return value is the ID of the flipped drawable. If there -was no selection, this will be equal to the drawable ID supplied as input. -Otherwise, this will be the newly created and flipped drawable. The flip type -parameter indicates whether the flip will be applied horizontally or -vertically. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - { name => 'flip_type', type => &std_orientation_enum, - desc => 'Type of flip: %%desc%%' } - ); - - @outargs = ( &drawable_out_arg('flipped') ); - - %invoke = ( - headers => [ qw("tools/gimpfliptool.h" "tools/gimptransformtool.h" - "undo.h") ], - vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles', - 'gboolean new_layer' ], - code => <<'CODE' -{ - gimage = gimp_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 = gimp_transform_tool_cut (gimage, drawable, &new_layer); - - flip_type = flip_type == HORIZONTAL ? ORIENTATION_HORIZONTAL : - flip_type == VERTICAL ? ORIENTATION_VERTICAL : - ORIENTATION_UNKNOWN; - - /* flip the buffer */ - switch (flip_type) - { - case ORIENTATION_HORIZONTAL: - case ORIENTATION_VERTICAL: - new_tiles = flip_tool_flip (gimage, drawable, float_tiles, -1, flip_type); - break; - default: - new_tiles = NULL; - break; - } - - /* free the cut/copied buffer */ - tile_manager_destroy (float_tiles); - - if (new_tiles) - success = gimp_transform_tool_paste (gimage, drawable, new_tiles, new_layer); - else - success = FALSE; - - /* push the undo group end */ - undo_push_group_end (gimage); -} -CODE - ); -} - sub paintbrush { $blurb = <<'BLURB'; Paint in the current brush with optional fade out parameter and pull colors @@ -716,442 +643,6 @@ HELP ); } -sub perspective { - $blurb = <<'BLURB'; -Perform a possibly non-affine transformation on the specified drawable. -BLURB - - $help = <<'HELP'; -This tool performs a possibly non-affine transformation on the specified -drawable by allowing the corners of the original bounding box to be arbitrarily -remapped to any values. The specified drawable is remapped if no selection -exists. However, if a selection exists, the portion of the drawable which lies -under the selection is cut from the drawable and made into a floating selection -which is then remapped as specified. The interpolation parameter can be set to -TRUE to indicate that either linear or cubic interpolation should be used to -smooth the resulting remapped drawable. The return value is the ID of the -remapped drawable. If there was no selection, this will be equal to the -drawable ID supplied as input. Otherwise, this will be the newly created and -remapped drawable. The 4 coordinates specify the new locations of each corner -of the original bounding box. By specifying these values, any affine -transformation (rotation, scaling, translation) can be affected. Additionally, -these values can be specified such that the resulting transformed drawable will -appear to have been projected via a perspective transform. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - { name => 'interpolation', type => 'boolean', - desc => 'Whether to use interpolation' } - ); - - my $pos = 0; - foreach $where (qw(upper-left upper-right lower-left lower-right)) { - foreach (qw(x y)) { - push @inargs, - { name => "$_$pos", type => 'float', - desc => "The new $_ coordinate of $where corner of original - bounding box", - alias => "trans_info[\U$_\E$pos]", no_declare => 1 } - } - $pos++; - } - - @outargs = ( &drawable_out_arg('newly mapped') ); - - %invoke = ( - headers => [ qw("tools/gimpperspectivetool.h" "tools/gimptransformtool.h") ], - vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles', - 'gboolean new_layer', 'gint offset_x, offset_y', - 'gdouble cx, cy', 'gdouble scalex, scaley', - 'gdouble trans_info[8]', 'GimpMatrix3 m, matrix' ], - code => <<'CODE' -{ - gimage = gimp_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 = gimp_transform_tool_cut (gimage, drawable, &new_layer); - - /* Determine the perspective transform that maps from - * the unit cube to the trans_info coordinates - */ - gimp_perspective_tool_find_transform (trans_info, m); - - tile_manager_get_offsets (float_tiles, &offset_x, &offset_y); - cx = (gdouble) offset_x; - cy = (gdouble) offset_y; - scalex = 1.0; - scaley = 1.0; - if (tile_manager_width (float_tiles)) - scalex = 1.0 / tile_manager_width (float_tiles); - if (tile_manager_height (float_tiles)) - scaley = 1.0 / tile_manager_height (float_tiles); - - /* Assemble the transformation matrix */ - gimp_matrix3_identity (matrix); - gimp_matrix3_translate (matrix, -cx, -cy); - gimp_matrix3_scale (matrix, scalex, scaley); - gimp_matrix3_mult (m, matrix); - - /* Perspective the buffer */ - new_tiles = gimp_perspective_tool_perspective (gimage, drawable, NULL, - float_tiles, interpolation, - matrix); - - /* Free the cut/copied buffer */ - tile_manager_destroy (float_tiles); - - if (new_tiles) - success = gimp_transform_tool_paste (gimage, drawable, new_tiles, new_layer); - else - success = FALSE; - - /* push the undo group end */ - undo_push_group_end (gimage); -} -CODE - ); -} - -sub rotate { - $blurb = <<'BLURB'; -Rotate the specified drawable about its center through the specified angle. -BLURB - - $help = <<'HELP'; -This tool rotates the specified drawable if no selection exists. If a selection -exists, the portion of the drawable which lies under the selection is cut from -the drawable and made into a floating selection which is then rotated by the -specified amount. The interpolation parameter can be set to TRUE to indicate -that either linear or cubic interpolation should be used to smooth the -resulting rotated drawable. The return value is the ID of the rotated drawable. -If there was no selection, this will be equal to the drawable ID supplied as -input. Otherwise, this will be the newly created and rotated drawable. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - { name => 'interpolation', type => 'boolean', - desc => 'Whether to use interpolation' }, - { name => 'angle', type => 'float', - desc => 'The angle of rotation (radians)' } - ); - - @outargs = ( &drawable_out_arg('rotated') ); - - %invoke = ( - headers => [ qw("tools/gimprotatetool.h" "tools/gimptransformtool.h") ], - vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles', - 'gboolean new_layer', 'gint offset_x, offset_y', - 'gdouble cx, cy', 'GimpMatrix3 matrix' ], - code => <<'CODE' -{ - gimage = gimp_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 = gimp_transform_tool_cut (gimage, drawable, &new_layer); - - tile_manager_get_offsets (float_tiles, &offset_x, &offset_y); - cx = offset_x + tile_manager_width (float_tiles) / 2.0; - cy = offset_y + tile_manager_height (float_tiles) / 2.0; - - /* 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 = gimp_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 = gimp_transform_tool_paste (gimage, drawable, new_tiles, new_layer); - else - success = FALSE; - - /* Push the undo group end */ - undo_push_group_end (gimage); -} -CODE - ); -} - -sub scale { - $blurb = 'Scale the specified drawable.'; - - $help = <<'HELP'; -This tool scales the specified drawable if no selection exists. If a selection -exists, the portion of the drawable which lies under the selection is cut from -the drawable and made into a floating selection which is then scaled by the -specified amount. The interpolation parameter can be set to TRUE to indicate -that either linear or cubic interpolation should be used to smooth the -resulting scaled drawable. The return value is the ID of the scaled drawable. -If there was no selection, this will be equal to the drawable ID supplied as -input. Otherwise, this will be the newly created and scaled drawable. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - { name => 'interpolation', type => 'boolean', - desc => 'Whether to use interpolation' } - ); - - my $pos = 0; - foreach $where (qw(upper-left lower-right)) { - foreach (qw(x y)) { - push @inargs, - { name => "$_$pos", type => 'float', - desc => "The new $_ coordinate of $where corner of newly - scaled region", - alias => "trans_info[\U$_\E$pos]", no_declare => 1 } - } - $pos++; - } - - @outargs = ( &drawable_out_arg('scaled') ); - - %invoke = ( - headers => [ qw("tools/gimpscaletool.h" "tools/gimptransformtool.h") ], - vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles', - 'gboolean new_layer', 'gint offset_x, offset_y', - 'gdouble scalex, scaley', 'gdouble trans_info[4]', - 'GimpMatrix3 matrix' ], - code => <<'CODE' -{ - if (trans_info[X0] < trans_info[X1] && - trans_info[Y0] < trans_info[X1]) - { - gimage = gimp_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 = gimp_transform_tool_cut (gimage, drawable, &new_layer); - - scalex = scaley = 1.0; - if (tile_manager_width (float_tiles)) - scalex = (trans_info[X1] - trans_info[X0]) / - (gdouble) tile_manager_width (float_tiles); - if (tile_manager_height (float_tiles)) - scaley = (trans_info[Y1] - trans_info[Y0]) / - (gdouble) tile_manager_height (float_tiles); - - tile_manager_get_offsets (float_tiles, &offset_x, &offset_y); - - /* Assemble the transformation matrix */ - gimp_matrix3_identity (matrix); - gimp_matrix3_translate (matrix, offset_x, offset_y); - gimp_matrix3_scale (matrix, scalex, scaley); - gimp_matrix3_translate (matrix, trans_info[X0], trans_info[Y0]); - - /* Scale the buffer */ - new_tiles = gimp_scale_tool_scale (gimage, drawable, NULL, trans_info, - float_tiles, interpolation, matrix); - - /* Free the cut/copied buffer */ - tile_manager_destroy (float_tiles); - - if (new_tiles) - success = gimp_transform_tool_paste (gimage, drawable, new_tiles, new_layer); - else - success = FALSE; - - /* push the undo group end */ - undo_push_group_end (gimage); - } - else - success = FALSE; -} -CODE - ); -} - -sub shear { - $blurb = <<'BLURB'; -Shear the specified drawable about its center by the specified magnitude. -BLURB - - $help = <<'HELP'; -This tool shears the specified drawable if no selection exists. If a selection -exists, the portion of the drawable which lies under the selection is cut from -the drawable and made into a floating selection which is then sheard by the -specified amount. The interpolation parameter can be set to TRUE to indicate -that either linear or cubic interpolation should be used to smooth the -resulting sheared drawable. The return value is the ID of the sheard drawable. -If there was no selection, this will be equal to the drawable ID supplied as -input. Otherwise, this will be the newly created and sheard drawable. The shear -type parameter indicates whether the shear will be applied horizontally or -vertically. The magnitude can be either positive or negative and indicates the -extent (in pixels) to shear by. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - { name => 'interpolation', type => 'boolean', - desc => 'Whether to use interpolation' }, - { name => 'shear_type', type => &std_orientation_enum, - desc => 'Type of shear: %%desc%%' }, - { name => 'magnitude', type => 'float', - desc => 'The magnitude of the shear' } - ); - - @outargs = ( &drawable_out_arg('sheared') ); - - %invoke = ( - headers => [ qw("tools/gimpsheartool.h" "tools/gimptransformtool.h") ], - vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles', - 'gboolean new_layer', 'gdouble cx, cy', - 'gint offset_x, offset_y', 'GimpMatrix3 matrix' ], - code => <<'CODE' -{ - gimage = gimp_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 = gimp_transform_tool_cut (gimage, drawable, &new_layer); - - tile_manager_get_offsets (float_tiles, &offset_x, &offset_y); - - cx = offset_x + tile_manager_width (float_tiles) / 2.0; - cy = offset_y + tile_manager_height (float_tiles) / 2.0; - - gimp_matrix3_identity (matrix); - gimp_matrix3_translate (matrix, -cx, -cy); - /* Shear matrix */ - shear_type = shear_type == HORIZONTAL ? ORIENTATION_HORIZONTAL : - shear_type == VERTICAL ? ORIENTATION_VERTICAL : - ORIENTATION_UNKNOWN; - - if (shear_type == ORIENTATION_HORIZONTAL) - gimp_matrix3_xshear (matrix, magnitude / tile_manager_height (float_tiles)); - else if (shear_type == ORIENTATION_VERTICAL) - gimp_matrix3_yshear (matrix, magnitude / tile_manager_width (float_tiles)); - - gimp_matrix3_translate (matrix, +cx, +cy); - - /* Shear the buffer */ - new_tiles = gimp_shear_tool_shear (gimage, drawable, NULL, float_tiles, - interpolation, matrix); - - /* Free the cut/copied buffer */ - tile_manager_destroy (float_tiles); - - if (new_tiles) - success = gimp_transform_tool_paste (gimage, drawable, new_tiles, new_layer); - else - success = FALSE; - - /* Push the undo group end */ - undo_push_group_end (gimage); -} -CODE - ); -} - -sub transform_2d { - $blurb = <<'BLURB'; -Transform the specified drawable in 2d. -BLURB - - $help = <<'HELP'; -This tool transforms the specified drawable if no selection exists. If a -selection exists, the portion of the drawable which lies under the -selection is cut from the drawable and made into a floating selection which -is then transformed. The interpolation parameter can be set to TRUE to -indicate that either linear or cubic interpolation should be used to smooth -the resulting drawable. The transformation is done by scaling the image by -the x and y scale factors about the point (source_x, source_y), then rotating -around the same point, then translating that point to the new position -(dest_x, dest_y). The return value is the ID of the rotated drawable. If -there was no selection, this will be equal to the drawable ID supplied as -input. Otherwise, this will be the newly created and transformed drawable. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - { name => 'interpolation', type => 'boolean', - desc => 'Whether to use interpolation' }, - { name => 'source_x', type => 'float', - desc => 'X coordinate of the transformation center' }, - { name => 'source_y', type => 'float', - desc => 'Y coordinate of the transformation center' }, - { name => 'scale_x', type => 'float', - desc => 'Amount to scale in x direction' }, - { name => 'scale_y', type => 'float', - desc => 'Amount to scale in y direction' }, - { name => 'angle', type => 'float', - desc => 'The angle of rotation (radians)' }, - { name => 'dest_x', type => 'float', - desc => 'X coordinate of where the centre goes' }, - { name => 'dest_y', type => 'float', - desc => 'Y coordinate of where the centre goes' } - ); - - @outargs = ( &drawable_out_arg('transformed') ); - - %invoke = ( - headers => [ qw("tools/gimptransformtool.h") ], - vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles', - 'gboolean new_layer', 'GimpMatrix3 matrix' ], - code => <<'CODE' -{ - gimage = gimp_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 = gimp_transform_tool_cut (gimage, drawable, &new_layer); - - /* Assemble the transformation matrix */ - gimp_matrix3_identity (matrix); - gimp_matrix3_translate (matrix, -source_x, -source_y); - gimp_matrix3_scale (matrix, scale_x, scale_y); - gimp_matrix3_rotate (matrix, angle); - gimp_matrix3_translate (matrix, dest_x, dest_y); - - /* Transform the buffer */ - new_tiles = gimp_transform_tool_do (gimage, drawable, float_tiles, - interpolation, matrix, NULL, NULL); - - /* Free the cut/copied buffer */ - tile_manager_destroy (float_tiles); - - if (new_tiles) - success = gimp_transform_tool_paste (gimage, drawable, new_tiles, new_layer); - else - success = FALSE; - - /* Push the undo group end */ - undo_push_group_end (gimage); -} -CODE - ); -} - sub smudge { $blurb = <<'BLURB'; Smudge image with varying pressure. @@ -1288,9 +779,9 @@ sub ink { @procs = qw(airbrush airbrush_default blend bucket_fill clone clone_default color_picker convolve convolve_default dodgeburn dodgeburn_default - eraser eraser_default flip paintbrush paintbrush_default - pencil perspective rotate scale shear smudge smudge_default - transform_2d); + eraser eraser_default paintbrush paintbrush_default + pencil smudge smudge_default); + %exports = (app => [@procs], lib => [@procs]); $desc = 'Tool procedures'; diff --git a/tools/pdbgen/pdb/tools.pdb b/tools/pdbgen/pdb/tools.pdb index 87b4499a81..a7ecf8e5af 100644 --- a/tools/pdbgen/pdb/tools.pdb +++ b/tools/pdbgen/pdb/tools.pdb @@ -544,79 +544,6 @@ CODE ); } -sub flip { - $blurb = <<'BLURB'; -Flip the specified drawable about its center either vertically or -horizontally. -BLURB - - $help = <<'HELP'; -This tool flips the specified drawable if no selection exists. If a selection -exists, the portion of the drawable which lies under the selection is cut from -the drawable and made into a floating selection which is then flipd by the -specified amount. The return value is the ID of the flipped drawable. If there -was no selection, this will be equal to the drawable ID supplied as input. -Otherwise, this will be the newly created and flipped drawable. The flip type -parameter indicates whether the flip will be applied horizontally or -vertically. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - { name => 'flip_type', type => &std_orientation_enum, - desc => 'Type of flip: %%desc%%' } - ); - - @outargs = ( &drawable_out_arg('flipped') ); - - %invoke = ( - headers => [ qw("tools/gimpfliptool.h" "tools/gimptransformtool.h" - "undo.h") ], - vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles', - 'gboolean new_layer' ], - code => <<'CODE' -{ - gimage = gimp_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 = gimp_transform_tool_cut (gimage, drawable, &new_layer); - - flip_type = flip_type == HORIZONTAL ? ORIENTATION_HORIZONTAL : - flip_type == VERTICAL ? ORIENTATION_VERTICAL : - ORIENTATION_UNKNOWN; - - /* flip the buffer */ - switch (flip_type) - { - case ORIENTATION_HORIZONTAL: - case ORIENTATION_VERTICAL: - new_tiles = flip_tool_flip (gimage, drawable, float_tiles, -1, flip_type); - break; - default: - new_tiles = NULL; - break; - } - - /* free the cut/copied buffer */ - tile_manager_destroy (float_tiles); - - if (new_tiles) - success = gimp_transform_tool_paste (gimage, drawable, new_tiles, new_layer); - else - success = FALSE; - - /* push the undo group end */ - undo_push_group_end (gimage); -} -CODE - ); -} - sub paintbrush { $blurb = <<'BLURB'; Paint in the current brush with optional fade out parameter and pull colors @@ -716,442 +643,6 @@ HELP ); } -sub perspective { - $blurb = <<'BLURB'; -Perform a possibly non-affine transformation on the specified drawable. -BLURB - - $help = <<'HELP'; -This tool performs a possibly non-affine transformation on the specified -drawable by allowing the corners of the original bounding box to be arbitrarily -remapped to any values. The specified drawable is remapped if no selection -exists. However, if a selection exists, the portion of the drawable which lies -under the selection is cut from the drawable and made into a floating selection -which is then remapped as specified. The interpolation parameter can be set to -TRUE to indicate that either linear or cubic interpolation should be used to -smooth the resulting remapped drawable. The return value is the ID of the -remapped drawable. If there was no selection, this will be equal to the -drawable ID supplied as input. Otherwise, this will be the newly created and -remapped drawable. The 4 coordinates specify the new locations of each corner -of the original bounding box. By specifying these values, any affine -transformation (rotation, scaling, translation) can be affected. Additionally, -these values can be specified such that the resulting transformed drawable will -appear to have been projected via a perspective transform. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - { name => 'interpolation', type => 'boolean', - desc => 'Whether to use interpolation' } - ); - - my $pos = 0; - foreach $where (qw(upper-left upper-right lower-left lower-right)) { - foreach (qw(x y)) { - push @inargs, - { name => "$_$pos", type => 'float', - desc => "The new $_ coordinate of $where corner of original - bounding box", - alias => "trans_info[\U$_\E$pos]", no_declare => 1 } - } - $pos++; - } - - @outargs = ( &drawable_out_arg('newly mapped') ); - - %invoke = ( - headers => [ qw("tools/gimpperspectivetool.h" "tools/gimptransformtool.h") ], - vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles', - 'gboolean new_layer', 'gint offset_x, offset_y', - 'gdouble cx, cy', 'gdouble scalex, scaley', - 'gdouble trans_info[8]', 'GimpMatrix3 m, matrix' ], - code => <<'CODE' -{ - gimage = gimp_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 = gimp_transform_tool_cut (gimage, drawable, &new_layer); - - /* Determine the perspective transform that maps from - * the unit cube to the trans_info coordinates - */ - gimp_perspective_tool_find_transform (trans_info, m); - - tile_manager_get_offsets (float_tiles, &offset_x, &offset_y); - cx = (gdouble) offset_x; - cy = (gdouble) offset_y; - scalex = 1.0; - scaley = 1.0; - if (tile_manager_width (float_tiles)) - scalex = 1.0 / tile_manager_width (float_tiles); - if (tile_manager_height (float_tiles)) - scaley = 1.0 / tile_manager_height (float_tiles); - - /* Assemble the transformation matrix */ - gimp_matrix3_identity (matrix); - gimp_matrix3_translate (matrix, -cx, -cy); - gimp_matrix3_scale (matrix, scalex, scaley); - gimp_matrix3_mult (m, matrix); - - /* Perspective the buffer */ - new_tiles = gimp_perspective_tool_perspective (gimage, drawable, NULL, - float_tiles, interpolation, - matrix); - - /* Free the cut/copied buffer */ - tile_manager_destroy (float_tiles); - - if (new_tiles) - success = gimp_transform_tool_paste (gimage, drawable, new_tiles, new_layer); - else - success = FALSE; - - /* push the undo group end */ - undo_push_group_end (gimage); -} -CODE - ); -} - -sub rotate { - $blurb = <<'BLURB'; -Rotate the specified drawable about its center through the specified angle. -BLURB - - $help = <<'HELP'; -This tool rotates the specified drawable if no selection exists. If a selection -exists, the portion of the drawable which lies under the selection is cut from -the drawable and made into a floating selection which is then rotated by the -specified amount. The interpolation parameter can be set to TRUE to indicate -that either linear or cubic interpolation should be used to smooth the -resulting rotated drawable. The return value is the ID of the rotated drawable. -If there was no selection, this will be equal to the drawable ID supplied as -input. Otherwise, this will be the newly created and rotated drawable. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - { name => 'interpolation', type => 'boolean', - desc => 'Whether to use interpolation' }, - { name => 'angle', type => 'float', - desc => 'The angle of rotation (radians)' } - ); - - @outargs = ( &drawable_out_arg('rotated') ); - - %invoke = ( - headers => [ qw("tools/gimprotatetool.h" "tools/gimptransformtool.h") ], - vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles', - 'gboolean new_layer', 'gint offset_x, offset_y', - 'gdouble cx, cy', 'GimpMatrix3 matrix' ], - code => <<'CODE' -{ - gimage = gimp_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 = gimp_transform_tool_cut (gimage, drawable, &new_layer); - - tile_manager_get_offsets (float_tiles, &offset_x, &offset_y); - cx = offset_x + tile_manager_width (float_tiles) / 2.0; - cy = offset_y + tile_manager_height (float_tiles) / 2.0; - - /* 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 = gimp_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 = gimp_transform_tool_paste (gimage, drawable, new_tiles, new_layer); - else - success = FALSE; - - /* Push the undo group end */ - undo_push_group_end (gimage); -} -CODE - ); -} - -sub scale { - $blurb = 'Scale the specified drawable.'; - - $help = <<'HELP'; -This tool scales the specified drawable if no selection exists. If a selection -exists, the portion of the drawable which lies under the selection is cut from -the drawable and made into a floating selection which is then scaled by the -specified amount. The interpolation parameter can be set to TRUE to indicate -that either linear or cubic interpolation should be used to smooth the -resulting scaled drawable. The return value is the ID of the scaled drawable. -If there was no selection, this will be equal to the drawable ID supplied as -input. Otherwise, this will be the newly created and scaled drawable. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - { name => 'interpolation', type => 'boolean', - desc => 'Whether to use interpolation' } - ); - - my $pos = 0; - foreach $where (qw(upper-left lower-right)) { - foreach (qw(x y)) { - push @inargs, - { name => "$_$pos", type => 'float', - desc => "The new $_ coordinate of $where corner of newly - scaled region", - alias => "trans_info[\U$_\E$pos]", no_declare => 1 } - } - $pos++; - } - - @outargs = ( &drawable_out_arg('scaled') ); - - %invoke = ( - headers => [ qw("tools/gimpscaletool.h" "tools/gimptransformtool.h") ], - vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles', - 'gboolean new_layer', 'gint offset_x, offset_y', - 'gdouble scalex, scaley', 'gdouble trans_info[4]', - 'GimpMatrix3 matrix' ], - code => <<'CODE' -{ - if (trans_info[X0] < trans_info[X1] && - trans_info[Y0] < trans_info[X1]) - { - gimage = gimp_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 = gimp_transform_tool_cut (gimage, drawable, &new_layer); - - scalex = scaley = 1.0; - if (tile_manager_width (float_tiles)) - scalex = (trans_info[X1] - trans_info[X0]) / - (gdouble) tile_manager_width (float_tiles); - if (tile_manager_height (float_tiles)) - scaley = (trans_info[Y1] - trans_info[Y0]) / - (gdouble) tile_manager_height (float_tiles); - - tile_manager_get_offsets (float_tiles, &offset_x, &offset_y); - - /* Assemble the transformation matrix */ - gimp_matrix3_identity (matrix); - gimp_matrix3_translate (matrix, offset_x, offset_y); - gimp_matrix3_scale (matrix, scalex, scaley); - gimp_matrix3_translate (matrix, trans_info[X0], trans_info[Y0]); - - /* Scale the buffer */ - new_tiles = gimp_scale_tool_scale (gimage, drawable, NULL, trans_info, - float_tiles, interpolation, matrix); - - /* Free the cut/copied buffer */ - tile_manager_destroy (float_tiles); - - if (new_tiles) - success = gimp_transform_tool_paste (gimage, drawable, new_tiles, new_layer); - else - success = FALSE; - - /* push the undo group end */ - undo_push_group_end (gimage); - } - else - success = FALSE; -} -CODE - ); -} - -sub shear { - $blurb = <<'BLURB'; -Shear the specified drawable about its center by the specified magnitude. -BLURB - - $help = <<'HELP'; -This tool shears the specified drawable if no selection exists. If a selection -exists, the portion of the drawable which lies under the selection is cut from -the drawable and made into a floating selection which is then sheard by the -specified amount. The interpolation parameter can be set to TRUE to indicate -that either linear or cubic interpolation should be used to smooth the -resulting sheared drawable. The return value is the ID of the sheard drawable. -If there was no selection, this will be equal to the drawable ID supplied as -input. Otherwise, this will be the newly created and sheard drawable. The shear -type parameter indicates whether the shear will be applied horizontally or -vertically. The magnitude can be either positive or negative and indicates the -extent (in pixels) to shear by. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - { name => 'interpolation', type => 'boolean', - desc => 'Whether to use interpolation' }, - { name => 'shear_type', type => &std_orientation_enum, - desc => 'Type of shear: %%desc%%' }, - { name => 'magnitude', type => 'float', - desc => 'The magnitude of the shear' } - ); - - @outargs = ( &drawable_out_arg('sheared') ); - - %invoke = ( - headers => [ qw("tools/gimpsheartool.h" "tools/gimptransformtool.h") ], - vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles', - 'gboolean new_layer', 'gdouble cx, cy', - 'gint offset_x, offset_y', 'GimpMatrix3 matrix' ], - code => <<'CODE' -{ - gimage = gimp_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 = gimp_transform_tool_cut (gimage, drawable, &new_layer); - - tile_manager_get_offsets (float_tiles, &offset_x, &offset_y); - - cx = offset_x + tile_manager_width (float_tiles) / 2.0; - cy = offset_y + tile_manager_height (float_tiles) / 2.0; - - gimp_matrix3_identity (matrix); - gimp_matrix3_translate (matrix, -cx, -cy); - /* Shear matrix */ - shear_type = shear_type == HORIZONTAL ? ORIENTATION_HORIZONTAL : - shear_type == VERTICAL ? ORIENTATION_VERTICAL : - ORIENTATION_UNKNOWN; - - if (shear_type == ORIENTATION_HORIZONTAL) - gimp_matrix3_xshear (matrix, magnitude / tile_manager_height (float_tiles)); - else if (shear_type == ORIENTATION_VERTICAL) - gimp_matrix3_yshear (matrix, magnitude / tile_manager_width (float_tiles)); - - gimp_matrix3_translate (matrix, +cx, +cy); - - /* Shear the buffer */ - new_tiles = gimp_shear_tool_shear (gimage, drawable, NULL, float_tiles, - interpolation, matrix); - - /* Free the cut/copied buffer */ - tile_manager_destroy (float_tiles); - - if (new_tiles) - success = gimp_transform_tool_paste (gimage, drawable, new_tiles, new_layer); - else - success = FALSE; - - /* Push the undo group end */ - undo_push_group_end (gimage); -} -CODE - ); -} - -sub transform_2d { - $blurb = <<'BLURB'; -Transform the specified drawable in 2d. -BLURB - - $help = <<'HELP'; -This tool transforms the specified drawable if no selection exists. If a -selection exists, the portion of the drawable which lies under the -selection is cut from the drawable and made into a floating selection which -is then transformed. The interpolation parameter can be set to TRUE to -indicate that either linear or cubic interpolation should be used to smooth -the resulting drawable. The transformation is done by scaling the image by -the x and y scale factors about the point (source_x, source_y), then rotating -around the same point, then translating that point to the new position -(dest_x, dest_y). The return value is the ID of the rotated drawable. If -there was no selection, this will be equal to the drawable ID supplied as -input. Otherwise, this will be the newly created and transformed drawable. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - { name => 'interpolation', type => 'boolean', - desc => 'Whether to use interpolation' }, - { name => 'source_x', type => 'float', - desc => 'X coordinate of the transformation center' }, - { name => 'source_y', type => 'float', - desc => 'Y coordinate of the transformation center' }, - { name => 'scale_x', type => 'float', - desc => 'Amount to scale in x direction' }, - { name => 'scale_y', type => 'float', - desc => 'Amount to scale in y direction' }, - { name => 'angle', type => 'float', - desc => 'The angle of rotation (radians)' }, - { name => 'dest_x', type => 'float', - desc => 'X coordinate of where the centre goes' }, - { name => 'dest_y', type => 'float', - desc => 'Y coordinate of where the centre goes' } - ); - - @outargs = ( &drawable_out_arg('transformed') ); - - %invoke = ( - headers => [ qw("tools/gimptransformtool.h") ], - vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles', - 'gboolean new_layer', 'GimpMatrix3 matrix' ], - code => <<'CODE' -{ - gimage = gimp_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 = gimp_transform_tool_cut (gimage, drawable, &new_layer); - - /* Assemble the transformation matrix */ - gimp_matrix3_identity (matrix); - gimp_matrix3_translate (matrix, -source_x, -source_y); - gimp_matrix3_scale (matrix, scale_x, scale_y); - gimp_matrix3_rotate (matrix, angle); - gimp_matrix3_translate (matrix, dest_x, dest_y); - - /* Transform the buffer */ - new_tiles = gimp_transform_tool_do (gimage, drawable, float_tiles, - interpolation, matrix, NULL, NULL); - - /* Free the cut/copied buffer */ - tile_manager_destroy (float_tiles); - - if (new_tiles) - success = gimp_transform_tool_paste (gimage, drawable, new_tiles, new_layer); - else - success = FALSE; - - /* Push the undo group end */ - undo_push_group_end (gimage); -} -CODE - ); -} - sub smudge { $blurb = <<'BLURB'; Smudge image with varying pressure. @@ -1288,9 +779,9 @@ sub ink { @procs = qw(airbrush airbrush_default blend bucket_fill clone clone_default color_picker convolve convolve_default dodgeburn dodgeburn_default - eraser eraser_default flip paintbrush paintbrush_default - pencil perspective rotate scale shear smudge smudge_default - transform_2d); + eraser eraser_default paintbrush paintbrush_default + pencil smudge smudge_default); + %exports = (app => [@procs], lib => [@procs]); $desc = 'Tool procedures'; diff --git a/tools/pdbgen/pdb/transform_tools.pdb b/tools/pdbgen/pdb/transform_tools.pdb index 87b4499a81..d5bd6c68e4 100644 --- a/tools/pdbgen/pdb/transform_tools.pdb +++ b/tools/pdbgen/pdb/transform_tools.pdb @@ -35,515 +35,8 @@ sub drawable_out_arg { $arg; } -sub sample_merged_arg () {{ - name => 'sample_merged', - type => 'boolean', - desc => 'Use the composite image, not the drawable' -}} - -sub threshold_arg () {{ - name => 'threshold', - type => '0 <= int32 <= 255', - desc => 'Threshold in intensity levels %%desc%%' -}} - -sub feather_select_args () {( - { name => 'feather', type => 'boolean', - desc => 'Feather option for selections' }, - { name => 'feather_radius', type => 'float', - desc => 'Radius for feather operation' } -)} - -sub stroke_arg () { - { name => 'strokes', type => 'floatarray', - desc => 'Array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ..., - sn.x, sn.y }', - array => { type => '2 <= int32', on_success => 'num_strokes /= 2;', - desc => 'Number of stroke control points (count each - coordinate as 2 points)' } } -} - # The defs -sub airbrush { - $blurb = <<'BLURB'; -Paint in the current brush with varying pressure. Paint application is -time-dependent. -BLURB - - $help = <<'HELP'; -This tool simulates the use of an airbrush. Paint pressure represents the -relative intensity of the paint application. High pressure results in a thicker -layer of paint while low pressure results in a thinner layer. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - { name => 'pressure', type => '0 <= float <= 100', - desc => 'The pressure of the airbrush strokes (%%desc%%)' }, - &stroke_arg - ); - - %invoke = ( - headers => [ qw("tools/gimpairbrushtool.h") ], - code => <<'CODE' -success = airbrush_non_gui (drawable, pressure, num_strokes, strokes); -CODE - ); -} - -sub airbrush_default { - $blurb = <<'BLURB'; -Paint in the current brush with varying pressure. Paint application is -time-dependent. -BLURB - - $help = <<'HELP'; -This tool simulates the use of an airbrush. It is similar to gimp_airbrush -except that the pressure is derived from the airbrush tools options box. -It the option has not been set the default for the option will be used. -HELP - - $author = $copyright = 'Andy Thomas'; - $date = '1999'; - - @inargs = ( - &drawable_arg, - &stroke_arg - ); - - %invoke = ( - headers => [ qw("tools/gimpairbrushtool.h") ], - code => <<'CODE' -success = airbrush_non_gui_default (drawable, num_strokes, strokes); -CODE - ); -} - - -sub blend { - $blurb = <<'BLURB'; -Blend between the starting and ending coordinates with the specified blend mode -and gradient type. -BLURB - - $help = <<'HELP'; -This tool requires information on the paint application mode, the blend mode, -and the gradient type. It creates the specified variety of blend using the -starting and ending coordinates as defined for each gradient type. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - { name => 'blend_mode', type => 'enum BlendMode', - desc => 'The type of blend: { %%desc%% }' }, - { name => 'paint_mode', type => 'enum LayerModeEffects', - desc => 'The paint application mode: { %%desc%% }' }, - { name => 'gradient_type', type => 'enum GradientType', - desc => 'The type of gradient: { %%desc%% }' }, - { name => 'opacity', type => '0 <= float <= 100', - desc => 'The opacity of the final blend (%%desc%%)' }, - { name => 'offset', type => '0 <= float', - desc => 'Offset relates to the starting and ending coordinates - specified for the blend. This parameter is mode dependent - (%%desc%%)' }, - { name => 'repeat', type => 'enum RepeatMode', - desc => 'Repeat mode: { %%desc%% }' }, - { name => 'supersample', type => 'boolean', - desc => 'Do adaptive supersampling (%%desc%%)' }, - { name => 'max_depth', type => '1 <= int32 <= 9', - desc => 'Maximum recursion levels for supersampling', - cond => [ 'supersample' ] }, - { name => 'threshold', type => '0 <= float <= 4', - desc => 'Supersampling threshold', - cond => [ 'supersample' ] }, - { name => 'x1', type => 'float', - desc => "The x coordinate of this blend's starting point" }, - { name => 'y1', type => 'float', - desc => "The y coordinate of this blend's starting point" }, - { name => 'x2', type => 'float', - desc => "The x coordinate of this blend's ending point" }, - { name => 'y2', type => 'float', - desc => "The y coordinate of this blend's ending point" } - ); - - %invoke = ( - headers => [ qw("core/gimpdrawable-blend.h") ], - code => <<'CODE' -{ - if (! gimp_drawable_gimage (drawable)) - { - success = FALSE; - } - else - { - gimp_drawable_blend (drawable, - blend_mode, - paint_mode, - gradient_type, - opacity / 100.0, - offset, repeat, - supersample, max_depth, - threshold, - x1, y1, x2, y2, - NULL, NULL); - } -} -CODE - ); -} - -sub bucket_fill { - $blurb = <<'BLURB'; -Fill the area specified either by the current selection if there is one, or by -a seed fill starting at the specified coordinates. -BLURB - - $help = <<'HELP'; -This tool requires information on the paint application mode, and the fill -mode, which can either be in the foreground color, or in the currently active -pattern. If there is no selection, a seed fill is executed at the specified -coordinates and extends outward in keeping with the threshold parameter. If -there is a selection in the target image, the threshold, sample merged, x, and -y arguments are unused. If the sample_merged parameter is non-zero, the data of -the composite image will be used instead of that for the specified drawable. -This is equivalent to sampling for colors after merging all visible layers. In -the case of merged sampling, the x,y coordinates are relative to the image's -origin; otherwise, they are relative to the drawable's origin. -HELP - - &std_pdb_misc; - - my $validity = 'This parameter is only valid when there is no selection in - the specified image.'; - - @inargs = ( - &drawable_arg, - { name => 'fill_mode', type => 'enum BucketFillMode', - desc => 'The type of fill: { %%desc%% }' }, - { name => paint_mode, type => 'enum LayerModeEffects', - desc => 'The paint application mode: { %%desc%% }' }, - { name => 'opacity', type => '0 <= float <= 100', - desc => 'The opacity of the final bucket fill (%%desc%%)' }, - { name => 'threshold', type => '0 <= float <= 255', - desc => "The threshold determines how extensive the seed fill will - be. It's value is specified in terms of intensity levels - (%%desc%%). $validity" }, - &sample_merged_arg, - ); - - foreach (qw(x y)) { - push @inargs, { name => $_, type => 'float', - desc => "The $_ coordinate of this bucket fill's - application. $validity" } - } - - %invoke = ( - headers => [ qw ("core/gimpdrawable-bucket-fill.h") ], - code => <<'CODE' -{ - if (! gimp_drawable_gimage (GIMP_DRAWABLE (drawable))) - { - success = FALSE; - } - else - { - gimp_drawable_bucket_fill (drawable, fill_mode, - paint_mode, opacity / 100.0, - threshold, sample_merged, x, y); - } -} -CODE - ); -} - -sub clone { - $blurb = <<'BLURB'; -Clone from the source to the dest drawable using the current brush -BLURB - - $help = <<'HELP'; -This tool clones (copies) from the source drawable starting at the specified -source coordinates to the dest drawable. If the "clone_type" argument is set -to PATTERN-CLONE, then the current pattern is used as the source and the -"src_drawable" argument is ignored. Pattern cloning assumes a tileable -pattern and mods the sum of the src coordinates and subsequent stroke offsets -with the width and height of the pattern. For image cloning, if the sum of the -src coordinates and subsequent stroke offsets exceeds the extents of the src -drawable, then no paint is transferred. The clone tool is capable of -transforming between any image types including RGB->Indexed--although -converting from any type to indexed is significantly slower. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - { name => 'src_drawable', type => 'drawable', - desc => 'The source drawable' }, - { name => 'clone_type', type => 'enum CloneType', - desc => 'The type of clone: { %%desc%% }' }, - { name => 'src_x', type => 'float', - desc => 'The x coordinate in the source image' }, - { name => 'src_y', type => 'float', - desc => 'The y coordinate in the source image' }, - &stroke_arg - ); - - %invoke = ( - headers => [ qw("tools/gimpclonetool.h") ], - code => <<'CODE' -success = clone_non_gui (drawable, src_drawable, clone_type, src_x, src_y, - num_strokes, strokes); -CODE - ); -} - -sub clone_default { - $blurb = <<'BLURB'; -Clone from the source to the dest drawable using the current brush -BLURB - - $help = <<'HELP'; -This tool clones (copies) from the source drawable starting at the specified -source coordinates to the dest drawable. This function performs exactly -the same as the gimp_clone function except that the tools arguments are -obtained from the clones option dialog. It this dialog has not been activated -then the dialogs default values will be used. -HELP - - $author = $copyright = 'Andy Thomas'; - $date = '1999'; - - @inargs = ( - &drawable_arg, - &stroke_arg - ); - - %invoke = ( - headers => [ qw("tools/gimpclonetool.h") ], - code => <<'CODE' -success = clone_non_gui_default (drawable, num_strokes, strokes); -CODE - ); -} - -sub color_picker { - $blurb = <<'BLURB'; -Determine the color at the given drawable coordinates -BLURB - - $help = <<'HELP'; -This tool determines the color at the specified coordinates. The returned color -is an RGB triplet even for grayscale and indexed drawables. If the coordinates -lie outside of the extents of the specified drawable, then an error is -returned. If the drawable has an alpha channel, the algorithm examines the -alpha value of the drawable at the coordinates. If the alpha value is -completely transparent (0), then an error is returned. If the sample_merged -parameter is non-zero, the data of the composite image will be used instead of -that for the specified drawable. This is equivalent to sampling for colors -after merging all visible layers. In the case of a merged sampling, the -supplied drawable is ignored. -HELP - - &std_pdb_misc; - - @inargs = ( - &std_image_arg, - &drawable_arg, - { name => 'x', type => 'float', - desc => 'x coordinate of upper-left corner of rectangle' }, - { name => 'y', type => 'float', - desc => 'y coordinate of upper-left corner of rectangle' }, - &sample_merged_arg, - { name => 'sample_average', type => 'boolean', - desc => 'Average the color of all the pixels in a specified - radius' }, - { name => 'average_radius', type => '0 < float', - desc => 'The radius of pixels to average', - cond => [ 'sample_average' ] }, - { name => 'save_color', type => 'boolean', - desc => 'Save the color to the active palette' } - ); - $inargs[1]->{no_success} = 1; - - @outargs = ( - { name => 'color', type => 'color', void_ret => 1, - desc => 'The return color', init => 1 } - ); - - %invoke = ( - headers => [ qw("tools/gimpcolorpickertool.h") ], - code => <<'CODE' -{ - if (!sample_merged) - if (!drawable || (gimp_drawable_gimage (drawable) != gimage)) - success = FALSE; - - if (success) - success = pick_color (gimage, drawable, (int) x, (int) y, - sample_merged, sample_average, average_radius, - save_color); - if (success) - { - gimp_rgba_set_uchar (&color, - col_value[RED_PIX], - col_value[GREEN_PIX], - col_value[BLUE_PIX], - col_value[ALPHA_PIX]); - } -} -CODE - ); -} - -sub convolve_default { - $blurb = 'Convolve (Blur, Sharpen) using the current brush.'; - - $help = <<'HELP'; -This tool convolves the specified drawable with either a sharpening or blurring -kernel. This function performs exactly the same as the gimp_convolve -function except that the tools arguments are obtained from the convolve -option dialog. It this dialog has not been activated then the dialogs -default values will be used. -HELP - - $author = $copyright = 'Andy Thomas'; - $date = '1999'; - - @inargs = ( - &drawable_arg, - &stroke_arg - ); - - %invoke = ( - headers => [ qw("tools/gimpconvolvetool.h") ], - code => <<'CODE' -success = convolve_non_gui_default (drawable, num_strokes, strokes); -CODE - ); -} - -sub convolve { - $blurb = 'Convolve (Blur, Sharpen) using the current brush.'; - - $help = <<'HELP'; -This tool convolves the specified drawable with either a sharpening or blurring -kernel. The pressure parameter controls the magnitude of the operation. Like -the paintbrush, this tool linearly interpolates between the specified stroke -coordinates. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - { name => 'pressure', type => '0 <= float <= 100', - desc => 'The pressure: %%desc%%' }, - { name => 'convolve_type', - type => 'enum ConvolveType (no CUSTOM_CONVOLVE)', - desc => 'Convolve type: { %%desc%% }' }, - &stroke_arg - ); - - %invoke = ( - headers => [ qw("tools/gimpconvolvetool.h") ], - code => <<'CODE' -success = convolve_non_gui (drawable, pressure, convolve_type, num_strokes, strokes); -CODE - ); -} - -sub eraser_default { - $blurb = 'Erase using the current brush.'; - - $help = <<'HELP'; -This tool erases using the current brush mask. This function performs exactly -the same as the gimp_eraser function except that the tools arguments are -obtained from the eraser option dialog. It this dialog has not been activated -then the dialogs default values will be used. -HELP - - $author = $copyright = 'Andy Thomas'; - $date = '1999'; - - @inargs = ( - &drawable_arg, - &stroke_arg - ); - - %invoke = ( - headers => [ qw("tools/gimperasertool.h") ], - code => <<'CODE' -success = eraser_non_gui_default (drawable, num_strokes, strokes); -CODE - ); -} - -sub eraser { - $blurb = 'Erase using the current brush.'; - - $help = <<'HELP'; -This tool erases using the current brush mask. If the specified drawable -contains an alpha channel, then the erased pixels will become transparent. -Otherwise, the eraser tool replaces the contents of the drawable with the -background color. Like paintbrush, this tool linearly interpolates between the -specified stroke coordinates. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - &stroke_arg, - { name => 'hardness', type => 'enum BrushApplicationMode (no PRESSURE)', - desc => '%%desc%%' }, - { name => 'method', type => 'enum PaintApplicationMode', - desc => '%%desc%%' } - ); - - %invoke = ( - headers => [ qw("tools/gimperasertool.h") ], - code => <<'CODE' -success = eraser_non_gui (drawable, num_strokes, strokes, hardness, method, TRUE, FALSE); -CODE - ); -} - -sub anti_eraser { - $blurb = 'Anti-erase using the current brush.'; - - $help = <<'HELP'; -This tool anti-erases using the current brush mask. If the specified drawable -contains an alpha channel, then the erased pixels will become opaque. -Otherwise, the eraser tool replaces the contents of the drawable with the -background color. Like paintbrush, this tool linearly interpolates between the -specified stroke coordinates. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - &stroke_arg, - { name => 'hardness', type => 'enum BrushApplicationMode (no PRESSURE)', - desc => '%%desc%%' }, - { name => 'method', type => 'enum PaintApplicationMode', - desc => '%%desc%%' } - ); - - %invoke = ( - headers => [ qw("tools/gimperasertool.h") ], - code => <<'CODE' -success = eraser_non_gui (drawable, num_strokes, strokes, hardness, method, TRUE, FALSE); -CODE - ); -} - sub flip { $blurb = <<'BLURB'; Flip the specified drawable about its center either vertically or @@ -572,150 +65,18 @@ HELP @outargs = ( &drawable_out_arg('flipped') ); %invoke = ( - headers => [ qw("tools/gimpfliptool.h" "tools/gimptransformtool.h" - "undo.h") ], - vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles', - 'gboolean new_layer' ], code => <<'CODE' { - gimage = gimp_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 = gimp_transform_tool_cut (gimage, drawable, &new_layer); - flip_type = flip_type == HORIZONTAL ? ORIENTATION_HORIZONTAL : flip_type == VERTICAL ? ORIENTATION_VERTICAL : ORIENTATION_UNKNOWN; - /* flip the buffer */ - switch (flip_type) - { - case ORIENTATION_HORIZONTAL: - case ORIENTATION_VERTICAL: - new_tiles = flip_tool_flip (gimage, drawable, float_tiles, -1, flip_type); - break; - default: - new_tiles = NULL; - break; - } - - /* free the cut/copied buffer */ - tile_manager_destroy (float_tiles); - - if (new_tiles) - success = gimp_transform_tool_paste (gimage, drawable, new_tiles, new_layer); - else - success = FALSE; - - /* push the undo group end */ - undo_push_group_end (gimage); + success = gimp_drawable_transform_flip (drawable, flip_type); } CODE ); } -sub paintbrush { - $blurb = <<'BLURB'; -Paint in the current brush with optional fade out parameter and pull colors -from a gradient. -BLURB - - $help = <<'HELP'; -This tool is the standard paintbrush. It draws linearly interpolated lines -through the specified stroke coordinates. It operates on the specified drawable -in the foreground color with the active brush. The "fade_out" parameter is -measured in pixels and allows the brush stroke to linearly fall off. The -pressure is set to the maximum at the beginning of the stroke. As the distance -of the stroke nears the fade_out value, the pressure will approach zero. The -gradient_length is the distance to spread the gradient over. It is measured in -pixels. If the gradient_length is 0, no gradient is used. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - { name => 'fade_out', type => '0 <= float', - desc => 'Fade out parameter: %%desc%%' }, - &stroke_arg, - { name => 'method', type => 'enum PaintApplicationMode', - desc => '%%desc%%' }, - { name => 'gradient_length', type => '0 <= float', - desc => 'Length of gradient to draw: %%desc%%' } - ); - - %invoke = ( - headers => [ qw("tools/gimppaintbrushtool.h") ], - code => <<'CODE' -success = gimp_paintbrush_tool_non_gui (drawable, num_strokes, strokes, - fade_out, method, gradient_length); -CODE - ); -} - -sub paintbrush_default { - $blurb = <<'BLURB'; -Paint in the current brush. The fade out parameter and pull colors -from a gradient parameter are set from the paintbrush options dialog. If this -dialog has not been activated then the dialog defaults will be used. -BLURB - - $help = <<'HELP'; -This tool is similar to the standard paintbrush. It draws linearly interpolated lines -through the specified stroke coordinates. It operates on the specified drawable -in the foreground color with the active brush. The "fade_out" parameter is -measured in pixels and allows the brush stroke to linearly fall -off (value obtained from the option dialog). The pressure is set -to the maximum at the beginning of the stroke. As the distance -of the stroke nears the fade_out value, the pressure will approach zero. The -gradient_length (value obtained from the option dialog) is the -distance to spread the gradient over. It is measured in pixels. If -the gradient_length is 0, no gradient is used. -HELP - - $author = $copyright = 'Andy Thomas'; - $date = '1999'; - - @inargs = ( - &drawable_arg, - &stroke_arg - ); - - %invoke = ( - headers => [ qw("tools/gimppaintbrushtool.h") ], - code => <<'CODE' -success = gimp_paintbrush_tool_non_gui_default (drawable, num_strokes, strokes); -CODE - ); -} - -sub pencil { - $blurb = 'Paint in the current brush without sub-pixel sampling.'; - - $help = <<'HELP'; -This tool is the standard pencil. It draws linearly interpolated lines through -the specified stroke coordinates. It operates on the specified drawable in the -foreground color with the active brush. The brush mask is treated as though it -contains only black and white values. Any value below half is treated as black; -any above half, as white. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - &stroke_arg - ); - - %invoke = ( - headers => [ qw("tools/gimppenciltool.h") ], - code => 'success = pencil_non_gui (drawable, num_strokes, strokes);' - ); -} - sub perspective { $blurb = <<'BLURB'; Perform a possibly non-affine transformation on the specified drawable. @@ -762,57 +123,30 @@ HELP @outargs = ( &drawable_out_arg('newly mapped') ); %invoke = ( - headers => [ qw("tools/gimpperspectivetool.h" "tools/gimptransformtool.h") ], - vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles', - 'gboolean new_layer', 'gint offset_x, offset_y', - 'gdouble cx, cy', 'gdouble scalex, scaley', - 'gdouble trans_info[8]', 'GimpMatrix3 m, matrix' ], + vars => [ 'gint x1, y1, x2, y2', 'gdouble trans_info[8]', + 'GimpMatrix3 matrix' ], code => <<'CODE' { - gimage = gimp_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 = gimp_transform_tool_cut (gimage, drawable, &new_layer); - - /* Determine the perspective transform that maps from - * the unit cube to the trans_info coordinates - */ - gimp_perspective_tool_find_transform (trans_info, m); - - tile_manager_get_offsets (float_tiles, &offset_x, &offset_y); - cx = (gdouble) offset_x; - cy = (gdouble) offset_y; - scalex = 1.0; - scaley = 1.0; - if (tile_manager_width (float_tiles)) - scalex = 1.0 / tile_manager_width (float_tiles); - if (tile_manager_height (float_tiles)) - scaley = 1.0 / tile_manager_height (float_tiles); + gimp_drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2); /* Assemble the transformation matrix */ - gimp_matrix3_identity (matrix); - gimp_matrix3_translate (matrix, -cx, -cy); - gimp_matrix3_scale (matrix, scalex, scaley); - gimp_matrix3_mult (m, matrix); + gimp_drawable_transform_matrix_perspective (x1, y1, x2, y2, + trans_info[X0], + trans_info[Y0], + trans_info[X1], + trans_info[Y1], + trans_info[X2], + trans_info[Y2], + trans_info[X3], + trans_info[Y3], + matrix); - /* Perspective the buffer */ - new_tiles = gimp_perspective_tool_perspective (gimage, drawable, NULL, - float_tiles, interpolation, - matrix); - - /* Free the cut/copied buffer */ - tile_manager_destroy (float_tiles); - - if (new_tiles) - success = gimp_transform_tool_paste (gimage, drawable, new_tiles, new_layer); - else - success = FALSE; - - /* push the undo group end */ - undo_push_group_end (gimage); + /* Perspective the selection */ + success = gimp_drawable_transform_affine (drawable, + interpolation, + FALSE, + matrix, + GIMP_TRANSFORM_FORWARD); } CODE ); @@ -847,44 +181,22 @@ HELP @outargs = ( &drawable_out_arg('rotated') ); %invoke = ( - headers => [ qw("tools/gimprotatetool.h" "tools/gimptransformtool.h") ], - vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles', - 'gboolean new_layer', 'gint offset_x, offset_y', - 'gdouble cx, cy', 'GimpMatrix3 matrix' ], + vars => [ 'gint x1, y1, x2, y2', 'GimpMatrix3 matrix' ], code => <<'CODE' { - gimage = gimp_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 = gimp_transform_tool_cut (gimage, drawable, &new_layer); - - tile_manager_get_offsets (float_tiles, &offset_x, &offset_y); - cx = offset_x + tile_manager_width (float_tiles) / 2.0; - cy = offset_y + tile_manager_height (float_tiles) / 2.0; + gimp_drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2); /* 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); + gimp_drawable_transform_matrix_rotate (x1, y1, x2, y2, + angle, + matrix); - /* Rotate the buffer */ - new_tiles = gimp_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 = gimp_transform_tool_paste (gimage, drawable, new_tiles, new_layer); - else - success = FALSE; - - /* Push the undo group end */ - undo_push_group_end (gimage); + /* Rotate the selection */ + success = gimp_drawable_transform_affine (drawable, + interpolation, + FALSE, + matrix, + GIMP_TRANSFORM_FORWARD); } CODE ); @@ -927,57 +239,34 @@ HELP @outargs = ( &drawable_out_arg('scaled') ); %invoke = ( - headers => [ qw("tools/gimpscaletool.h" "tools/gimptransformtool.h") ], - vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles', - 'gboolean new_layer', 'gint offset_x, offset_y', - 'gdouble scalex, scaley', 'gdouble trans_info[4]', - 'GimpMatrix3 matrix' ], + vars => [ 'gint x1, y1, x2, y2', 'gdouble trans_info[4]', + 'GimpMatrix3 matrix' ], code => <<'CODE' { if (trans_info[X0] < trans_info[X1] && trans_info[Y0] < trans_info[X1]) { - gimage = gimp_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 = gimp_transform_tool_cut (gimage, drawable, &new_layer); - - scalex = scaley = 1.0; - if (tile_manager_width (float_tiles)) - scalex = (trans_info[X1] - trans_info[X0]) / - (gdouble) tile_manager_width (float_tiles); - if (tile_manager_height (float_tiles)) - scaley = (trans_info[Y1] - trans_info[Y0]) / - (gdouble) tile_manager_height (float_tiles); - - tile_manager_get_offsets (float_tiles, &offset_x, &offset_y); + gimp_drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2); /* Assemble the transformation matrix */ - gimp_matrix3_identity (matrix); - gimp_matrix3_translate (matrix, offset_x, offset_y); - gimp_matrix3_scale (matrix, scalex, scaley); - gimp_matrix3_translate (matrix, trans_info[X0], trans_info[Y0]); + gimp_drawable_transform_matrix_scale (x1, y1, x2, y2, + trans_info[X0], + trans_info[Y0], + trans_info[X1], + trans_info[Y1], + matrix); - /* Scale the buffer */ - new_tiles = gimp_scale_tool_scale (gimage, drawable, NULL, trans_info, - float_tiles, interpolation, matrix); - - /* Free the cut/copied buffer */ - tile_manager_destroy (float_tiles); - - if (new_tiles) - success = gimp_transform_tool_paste (gimage, drawable, new_tiles, new_layer); - else - success = FALSE; - - /* push the undo group end */ - undo_push_group_end (gimage); + /* Scale the selection */ + success = gimp_drawable_transform_affine (drawable, + interpolation, + FALSE, + matrix, + GIMP_TRANSFORM_FORWARD); } else - success = FALSE; + { + success = FALSE; + } } CODE ); @@ -1017,53 +306,27 @@ HELP @outargs = ( &drawable_out_arg('sheared') ); %invoke = ( - headers => [ qw("tools/gimpsheartool.h" "tools/gimptransformtool.h") ], - vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles', - 'gboolean new_layer', 'gdouble cx, cy', - 'gint offset_x, offset_y', 'GimpMatrix3 matrix' ], + vars => [ 'gint x1, y1, x2, y2', 'GimpMatrix3 matrix' ], code => <<'CODE' { - gimage = gimp_drawable_gimage (GIMP_DRAWABLE (drawable)); + gimp_drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2); - /* Start a transform undo group */ - undo_push_group_start (gimage, TRANSFORM_CORE_UNDO); - - /* Cut/Copy from the specified drawable */ - float_tiles = gimp_transform_tool_cut (gimage, drawable, &new_layer); - - tile_manager_get_offsets (float_tiles, &offset_x, &offset_y); - - cx = offset_x + tile_manager_width (float_tiles) / 2.0; - cy = offset_y + tile_manager_height (float_tiles) / 2.0; - - gimp_matrix3_identity (matrix); - gimp_matrix3_translate (matrix, -cx, -cy); - /* Shear matrix */ shear_type = shear_type == HORIZONTAL ? ORIENTATION_HORIZONTAL : shear_type == VERTICAL ? ORIENTATION_VERTICAL : ORIENTATION_UNKNOWN; - if (shear_type == ORIENTATION_HORIZONTAL) - gimp_matrix3_xshear (matrix, magnitude / tile_manager_height (float_tiles)); - else if (shear_type == ORIENTATION_VERTICAL) - gimp_matrix3_yshear (matrix, magnitude / tile_manager_width (float_tiles)); + /* Assemble the transformation matrix */ + gimp_drawable_transform_matrix_shear (x1, y1, x2, y2, + shear_type, + magnitude, + matrix); - gimp_matrix3_translate (matrix, +cx, +cy); - - /* Shear the buffer */ - new_tiles = gimp_shear_tool_shear (gimage, drawable, NULL, float_tiles, - interpolation, matrix); - - /* Free the cut/copied buffer */ - tile_manager_destroy (float_tiles); - - if (new_tiles) - success = gimp_transform_tool_paste (gimage, drawable, new_tiles, new_layer); - else - success = FALSE; - - /* Push the undo group end */ - undo_push_group_end (gimage); + /* Shear the selection */ + success = gimp_drawable_transform_affine (drawable, + interpolation, + FALSE, + matrix, + GIMP_TRANSFORM_FORWARD); } CODE ); @@ -1113,184 +376,32 @@ HELP @outargs = ( &drawable_out_arg('transformed') ); %invoke = ( - headers => [ qw("tools/gimptransformtool.h") ], - vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles', - 'gboolean new_layer', 'GimpMatrix3 matrix' ], + vars => [ 'GimpMatrix3 matrix' ], code => <<'CODE' { - gimage = gimp_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 = gimp_transform_tool_cut (gimage, drawable, &new_layer); - /* Assemble the transformation matrix */ gimp_matrix3_identity (matrix); gimp_matrix3_translate (matrix, -source_x, -source_y); gimp_matrix3_scale (matrix, scale_x, scale_y); gimp_matrix3_rotate (matrix, angle); gimp_matrix3_translate (matrix, dest_x, dest_y); - - /* Transform the buffer */ - new_tiles = gimp_transform_tool_do (gimage, drawable, float_tiles, - interpolation, matrix, NULL, NULL); - - /* Free the cut/copied buffer */ - tile_manager_destroy (float_tiles); - - if (new_tiles) - success = gimp_transform_tool_paste (gimage, drawable, new_tiles, new_layer); - else - success = FALSE; - /* Push the undo group end */ - undo_push_group_end (gimage); + /* Transform the selection */ + success = gimp_drawable_transform_affine (drawable, + interpolation, + FALSE, + matrix, + GIMP_TRANSFORM_FORWARD); } CODE ); } -sub smudge { - $blurb = <<'BLURB'; -Smudge image with varying pressure. -BLURB +@headers = qw("libgimpmath/gimpmath.h" "core/gimpdrawable-transform.h" + "core/gimpdrawable-transform-utils.h" "core/gimpdrawable.h"); - $help = <<'HELP'; -This tool simulates a smudge using the current brush. High pressure results -in a greater smudge of paint while low pressure results in a lesser smudge. -HELP +@procs = qw(flip perspective rotate scale shear transform_2d); - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - { name => 'pressure', type => '0 <= float <= 100', - desc => 'The pressure of the smudge strokes (%%desc%%)' }, - &stroke_arg - ); - - %invoke = ( - headers => [ qw("tools/gimpsmudgetool.h") ], - code => <<'CODE' -success = gimp_smudge_tool_non_gui (drawable, pressure, num_strokes, strokes); -CODE - ); -} - -sub smudge_default { - $blurb = <<'BLURB'; -Smudge image with varying pressure. -BLURB - - $help = <<'HELP'; -This tool simulates a smudge using the current brush. It behaves exactly -the same as gimp_smudge except that the pressure value is taken from the -smudge tool options or the options default if the tools option dialog has -not been activated. -HELP - - $author = $copyright = 'Andy Thomas'; - $date = '1999'; - - @inargs = ( - &drawable_arg, - &stroke_arg - ); - - %invoke = ( - headers => [ qw("tools/gimpsmudgetool.h") ], - code => <<'CODE' -success = gimp_smudge_tool_non_gui_default (drawable, num_strokes, strokes); -CODE - ); -} - -sub dodgeburn { - $blurb = <<'BLURB'; -Dodgeburn image with varying exposure. -BLURB - - $help = <<'HELP'; -Dodgebure. More details here later. -HELP - - - $author = $copyright = 'Andy Thomas'; - $date = '1999'; - - @inargs = ( - &drawable_arg, - { name => 'exposure', type => '0 <= float <= 100', - desc => 'The exposer of the strokes (%%desc%%)' }, - { name => 'dodgeburn_type', type => 'enum DodgeBurnType', - desc => 'The type either dodge or burn: { %%desc%% }' }, - { name => 'dodgeburn_mode', type => 'enum GimpTransferMode', - desc => 'The mode: { %%desc%% }' }, - &stroke_arg - ); - - %invoke = ( - headers => [ qw("tools/gimpdodgeburntool.h") ], - code => <<'CODE' -success = gimp_dodgeburn_tool_non_gui (drawable, exposure, dodgeburn_type, dodgeburn_mode, num_strokes, strokes); -CODE - ); -} - -sub dodgeburn_default { - $blurb = <<'BLURB'; -Dodgeburn image with varying exposure. This is the same as the gimp_dodgeburn -function except that the exposure, type and mode are taken from the tools -option dialog. If the dialog has not been activated then the defaults -as used by the dialog will be used. -BLURB - - $help = <<'HELP'; -Dodgeburn. More details here later. -HELP - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - &stroke_arg - ); - - %invoke = ( - headers => [ qw("tools/gimpdodgeburntool.h") ], - code => <<'CODE' -success = gimp_dodgeburn_tool_non_gui_default (drawable, num_strokes, strokes); -CODE - ); -} - - -# Incomplete - -sub ink { - $blurb = 'Paint in the current brush without sub-pixel sampling.'; - - $help = 'fixme fixme'; - - &std_pdb_misc; - - @inargs = ( - &drawable_arg, - &stroke_arg - ); -} - -@headers = qw("libgimpmath/gimpmath.h" "core/gimpimage-mask-select.h" - "tools/tools-types.h" "core/gimpdrawable.h" - "base/tile-manager.h"); - -@procs = qw(airbrush airbrush_default blend bucket_fill clone clone_default - color_picker convolve convolve_default dodgeburn dodgeburn_default - eraser eraser_default flip paintbrush paintbrush_default - pencil perspective rotate scale shear smudge smudge_default - transform_2d); %exports = (app => [@procs], lib => [@procs]); $desc = 'Tool procedures';