[gimp] app: in GimpTransformGridTool, allow linking forward/backward transforms
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: in GimpTransformGridTool, allow linking forward/backward transforms
- Date: Mon, 4 Feb 2019 21:53:55 +0000 (UTC)
commit 39e23267f7ac76030f02e5f68bf7994a02bb81a1
Author: Ell <ell_se yahoo com>
Date: Mon Feb 4 15:33:44 2019 -0500
app: in GimpTransformGridTool, allow linking forward/backward transforms
Add a GimpTransformGridTool::matrix_to_info() virtual function,
which should extract the tool-specific transformation parameters
given a transformation matrix, and the old parameter set (which is
needed in some tools, to derive the parameters that aren't encoded
in the matrix, such as the pivot point). The transformation matrix
can be any combination of matrices calculated by the tool, and
their inverses. Subclasses should only implement this function if
every such matrix can be mapped back to transformation parameters.
This is currently the case for all the transform-grid tools, except
for the shear tool (since it only supports shearing along one of
the horizontal or the vertical directions, however, the combined
matrix may require shearing in both directions).
When a transform-grid tool implements this function, show a chain-
button between the two transform-direction radio-buttons in the
tool options. When the chain-button is linked, whenever the
transform corresponding to the active direction is modified, adjust
the transform corresponding to the non-active direction such that
the overall transform remains the same.
One notable workflow that this enables is transforming a layer
while adjusting a different area than its boundary, by first
defining the area while the transform-directions are linked, and
then transforming the area while the transform-directions are
unlinked.
app/tools/gimphandletransformtool.c | 29 ++++++++++++
app/tools/gimpperspectivetool.c | 31 ++++++++++++
app/tools/gimprotatetool.c | 44 +++++++++++++++++
app/tools/gimpscaletool.c | 26 ++++++++++
app/tools/gimptransformgridoptions.c | 66 ++++++++++++++++++++++----
app/tools/gimptransformgridoptions.h | 1 +
app/tools/gimptransformgridtool.c | 92 +++++++++++++++++++++++++++++++-----
app/tools/gimptransformgridtool.h | 4 ++
app/tools/gimptransformoptions.c | 2 +
app/tools/gimptransformoptions.h | 1 +
app/tools/gimpunifiedtransformtool.c | 42 ++++++++++++++++
11 files changed, 319 insertions(+), 19 deletions(-)
---
diff --git a/app/tools/gimphandletransformtool.c b/app/tools/gimphandletransformtool.c
index bedbe6aefc..1a20e182c5 100644
--- a/app/tools/gimphandletransformtool.c
+++ b/app/tools/gimphandletransformtool.c
@@ -83,6 +83,8 @@ static void gimp_handle_transform_tool_modifier_key (GimpTool
GdkModifierType state,
GimpDisplay *display);
+static void gimp_handle_transform_tool_matrix_to_info (GimpTransformGridTool *tg_tool,
+ const GimpMatrix3 *transform);
static void gimp_handle_transform_tool_prepare (GimpTransformGridTool *tg_tool);
static GimpToolWidget * gimp_handle_transform_tool_get_widget (GimpTransformGridTool *tg_tool);
static void gimp_handle_transform_tool_update_widget (GimpTransformGridTool *tg_tool);
@@ -125,6 +127,7 @@ gimp_handle_transform_tool_class_init (GimpHandleTransformToolClass *klass)
tool_class->modifier_key = gimp_handle_transform_tool_modifier_key;
+ tg_class->matrix_to_info = gimp_handle_transform_tool_matrix_to_info;
tg_class->prepare = gimp_handle_transform_tool_prepare;
tg_class->get_widget = gimp_handle_transform_tool_get_widget;
tg_class->update_widget = gimp_handle_transform_tool_update_widget;
@@ -196,6 +199,32 @@ gimp_handle_transform_tool_modifier_key (GimpTool *tool,
state, display);
}
+static void
+gimp_handle_transform_tool_matrix_to_info (GimpTransformGridTool *tg_tool,
+ const GimpMatrix3 *transform)
+{
+ gimp_matrix3_transform_point (transform,
+ tg_tool->trans_info[OX0],
+ tg_tool->trans_info[OY0],
+ &tg_tool->trans_info[X0],
+ &tg_tool->trans_info[Y0]);
+ gimp_matrix3_transform_point (transform,
+ tg_tool->trans_info[OX1],
+ tg_tool->trans_info[OY1],
+ &tg_tool->trans_info[X1],
+ &tg_tool->trans_info[Y1]);
+ gimp_matrix3_transform_point (transform,
+ tg_tool->trans_info[OX2],
+ tg_tool->trans_info[OY2],
+ &tg_tool->trans_info[X2],
+ &tg_tool->trans_info[Y2]);
+ gimp_matrix3_transform_point (transform,
+ tg_tool->trans_info[OX3],
+ tg_tool->trans_info[OY3],
+ &tg_tool->trans_info[X3],
+ &tg_tool->trans_info[Y3]);
+}
+
static void
gimp_handle_transform_tool_prepare (GimpTransformGridTool *tg_tool)
{
diff --git a/app/tools/gimpperspectivetool.c b/app/tools/gimpperspectivetool.c
index 0599433618..185227cb73 100644
--- a/app/tools/gimpperspectivetool.c
+++ b/app/tools/gimpperspectivetool.c
@@ -54,6 +54,8 @@ enum
/* local function prototypes */
+static void gimp_perspective_tool_matrix_to_info (GimpTransformGridTool *tg_tool,
+ const GimpMatrix3 *transform);
static void gimp_perspective_tool_prepare (GimpTransformGridTool *tg_tool);
static GimpToolWidget * gimp_perspective_tool_get_widget (GimpTransformGridTool *tg_tool);
static void gimp_perspective_tool_update_widget (GimpTransformGridTool *tg_tool);
@@ -93,6 +95,7 @@ gimp_perspective_tool_class_init (GimpPerspectiveToolClass *klass)
GimpTransformGridToolClass *tg_class = GIMP_TRANSFORM_GRID_TOOL_CLASS (klass);
GimpGenericTransformToolClass *generic_class = GIMP_GENERIC_TRANSFORM_TOOL_CLASS (klass);
+ tg_class->matrix_to_info = gimp_perspective_tool_matrix_to_info;
tg_class->prepare = gimp_perspective_tool_prepare;
tg_class->get_widget = gimp_perspective_tool_get_widget;
tg_class->update_widget = gimp_perspective_tool_update_widget;
@@ -113,6 +116,34 @@ gimp_perspective_tool_init (GimpPerspectiveTool *perspective_tool)
GIMP_TOOL_CURSOR_PERSPECTIVE);
}
+static void
+gimp_perspective_tool_matrix_to_info (GimpTransformGridTool *tg_tool,
+ const GimpMatrix3 *transform)
+{
+ GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool);
+
+ gimp_matrix3_transform_point (transform,
+ tr_tool->x1,
+ tr_tool->y1,
+ &tg_tool->trans_info[X0],
+ &tg_tool->trans_info[Y0]);
+ gimp_matrix3_transform_point (transform,
+ tr_tool->x2,
+ tr_tool->y1,
+ &tg_tool->trans_info[X1],
+ &tg_tool->trans_info[Y1]);
+ gimp_matrix3_transform_point (transform,
+ tr_tool->x1,
+ tr_tool->y2,
+ &tg_tool->trans_info[X2],
+ &tg_tool->trans_info[Y2]);
+ gimp_matrix3_transform_point (transform,
+ tr_tool->x2,
+ tr_tool->y2,
+ &tg_tool->trans_info[X3],
+ &tg_tool->trans_info[Y3]);
+}
+
static void
gimp_perspective_tool_prepare (GimpTransformGridTool *tg_tool)
{
diff --git a/app/tools/gimprotatetool.c b/app/tools/gimprotatetool.c
index 6cf75e2a1f..7199fb8144 100644
--- a/app/tools/gimprotatetool.c
+++ b/app/tools/gimprotatetool.c
@@ -53,6 +53,7 @@ enum
#define SB_WIDTH 10
+#define EPSILON 1e-6
/* local function prototypes */
@@ -63,6 +64,8 @@ static gboolean gimp_rotate_tool_key_press (GimpTool *
static gboolean gimp_rotate_tool_info_to_matrix (GimpTransformGridTool *tg_tool,
GimpMatrix3 *transform);
+static void gimp_rotate_tool_matrix_to_info (GimpTransformGridTool *tg_tool,
+ const GimpMatrix3 *transform);
static gchar * gimp_rotate_tool_get_undo_desc (GimpTransformGridTool *tg_tool);
static void gimp_rotate_tool_dialog (GimpTransformGridTool *tg_tool);
static void gimp_rotate_tool_dialog_update (GimpTransformGridTool *tg_tool);
@@ -109,6 +112,7 @@ gimp_rotate_tool_class_init (GimpRotateToolClass *klass)
tool_class->key_press = gimp_rotate_tool_key_press;
tg_class->info_to_matrix = gimp_rotate_tool_info_to_matrix;
+ tg_class->matrix_to_info = gimp_rotate_tool_matrix_to_info;
tg_class->get_undo_desc = gimp_rotate_tool_get_undo_desc;
tg_class->dialog = gimp_rotate_tool_dialog;
tg_class->dialog_update = gimp_rotate_tool_dialog_update;
@@ -181,6 +185,46 @@ gimp_rotate_tool_info_to_matrix (GimpTransformGridTool *tg_tool,
return TRUE;
}
+static void
+gimp_rotate_tool_matrix_to_info (GimpTransformGridTool *tg_tool,
+ const GimpMatrix3 *transform)
+{
+ gdouble c;
+ gdouble s;
+ gdouble x;
+ gdouble y;
+ gdouble q;
+
+ c = transform->coeff[0][0];
+ s = transform->coeff[1][0];
+ x = transform->coeff[0][2];
+ y = transform->coeff[1][2];
+
+ tg_tool->trans_info[ANGLE] = atan2 (s, c);
+
+ q = 2.0 * (1.0 - transform->coeff[0][0]);
+
+ if (q > EPSILON)
+ {
+ tg_tool->trans_info[PIVOT_X] = ((1.0 - c) * x - s * y) / q;
+ tg_tool->trans_info[PIVOT_Y] = (s * x + (1.0 - c) * y) / q;
+ }
+ else
+ {
+ GimpMatrix3 transfer;
+
+ gimp_transform_grid_tool_info_to_matrix (tg_tool, &transfer);
+ gimp_matrix3_invert (&transfer);
+ gimp_matrix3_mult (transform, &transfer);
+
+ gimp_matrix3_transform_point (&transfer,
+ tg_tool->trans_info[PIVOT_X],
+ tg_tool->trans_info[PIVOT_Y],
+ &tg_tool->trans_info[PIVOT_X],
+ &tg_tool->trans_info[PIVOT_Y]);
+ }
+}
+
static gchar *
gimp_rotate_tool_get_undo_desc (GimpTransformGridTool *tg_tool)
{
diff --git a/app/tools/gimpscaletool.c b/app/tools/gimpscaletool.c
index 987ffb0ab8..10bbe18a0e 100644
--- a/app/tools/gimpscaletool.c
+++ b/app/tools/gimpscaletool.c
@@ -62,6 +62,8 @@ enum
static gboolean gimp_scale_tool_info_to_matrix (GimpTransformGridTool *tg_tool,
GimpMatrix3 *transform);
+static void gimp_scale_tool_matrix_to_info (GimpTransformGridTool *tg_tool,
+ const GimpMatrix3 *transform);
static gchar * gimp_scale_tool_get_undo_desc (GimpTransformGridTool *tg_tool);
static void gimp_scale_tool_dialog (GimpTransformGridTool *tg_tool);
static void gimp_scale_tool_dialog_update (GimpTransformGridTool *tg_tool);
@@ -104,6 +106,7 @@ gimp_scale_tool_class_init (GimpScaleToolClass *klass)
GimpTransformGridToolClass *tg_class = GIMP_TRANSFORM_GRID_TOOL_CLASS (klass);
tg_class->info_to_matrix = gimp_scale_tool_info_to_matrix;
+ tg_class->matrix_to_info = gimp_scale_tool_matrix_to_info;
tg_class->get_undo_desc = gimp_scale_tool_get_undo_desc;
tg_class->dialog = gimp_scale_tool_dialog;
tg_class->dialog_update = gimp_scale_tool_dialog_update;
@@ -145,6 +148,29 @@ gimp_scale_tool_info_to_matrix (GimpTransformGridTool *tg_tool,
return TRUE;
}
+static void
+gimp_scale_tool_matrix_to_info (GimpTransformGridTool *tg_tool,
+ const GimpMatrix3 *transform)
+{
+ GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool);
+ gdouble x;
+ gdouble y;
+ gdouble w;
+ gdouble h;
+
+ x = transform->coeff[0][2];
+ y = transform->coeff[1][2];
+ w = transform->coeff[0][0];
+ h = transform->coeff[1][1];
+
+ tg_tool->trans_info[X0] = x + w * tr_tool->x1;
+ tg_tool->trans_info[Y0] = y + h * tr_tool->y1;
+ tg_tool->trans_info[X1] = tg_tool->trans_info[X0] +
+ w * (tr_tool->x2 - tr_tool->x1);
+ tg_tool->trans_info[Y1] = tg_tool->trans_info[Y0] +
+ h * (tr_tool->y2 - tr_tool->y1);
+}
+
static gchar *
gimp_scale_tool_get_undo_desc (GimpTransformGridTool *tg_tool)
{
diff --git a/app/tools/gimptransformgridoptions.c b/app/tools/gimptransformgridoptions.c
index 69f19240bd..631bbe7b12 100644
--- a/app/tools/gimptransformgridoptions.c
+++ b/app/tools/gimptransformgridoptions.c
@@ -37,6 +37,7 @@
#include "gimpunifiedtransformtool.h"
#include "gimptooloptions-gui.h"
#include "gimptransformgridoptions.h"
+#include "gimptransformgridtool.h"
#include "gimp-intl.h"
@@ -45,6 +46,7 @@ enum
{
PROP_0,
PROP_DIRECTION,
+ PROP_DIRECTION_LINKED,
PROP_SHOW_PREVIEW,
PROP_PREVIEW_OPACITY,
PROP_GRID_TYPE,
@@ -94,6 +96,12 @@ gimp_transform_grid_options_class_init (GimpTransformGridOptionsClass *klass)
g_object_class_override_property (object_class, PROP_DIRECTION,
"direction");
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_DIRECTION_LINKED,
+ "direction-linked",
+ NULL, NULL,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_PREVIEW,
"show-preview",
_("Show image preview"),
@@ -212,6 +220,9 @@ gimp_transform_grid_options_set_property (GObject *object,
transform_options->direction != GIMP_TRANSFORM_BACKWARD,
NULL);
break;
+ case PROP_DIRECTION_LINKED:
+ options->direction_linked = g_value_get_boolean (value);
+ break;
case PROP_SHOW_PREVIEW:
options->show_preview = g_value_get_boolean (value);
break;
@@ -274,6 +285,9 @@ gimp_transform_grid_options_get_property (GObject *object,
case PROP_DIRECTION:
g_value_set_enum (value, transform_options->direction);
break;
+ case PROP_DIRECTION_LINKED:
+ g_value_set_boolean (value, options->direction_linked);
+ break;
case PROP_SHOW_PREVIEW:
g_value_set_boolean (value, options->show_preview);
break;
@@ -333,17 +347,53 @@ gimp_transform_grid_options_get_property (GObject *object,
GtkWidget *
gimp_transform_grid_options_gui (GimpToolOptions *tool_options)
{
- GObject *config = G_OBJECT (tool_options);
- GtkWidget *vbox;
- GtkWidget *frame;
- GtkWidget *combo;
- GtkWidget *scale;
- GtkWidget *grid_box;
- GdkModifierType extend_mask = gimp_get_extend_selection_mask ();
- GdkModifierType constrain_mask = gimp_get_constrain_behavior_mask ();
+ GObject *config = G_OBJECT (tool_options);
+ GimpTransformGridToolClass *tg_class;
+ GtkWidget *vbox;
+ GtkWidget *frame;
+ GtkWidget *combo;
+ GtkWidget *scale;
+ GtkWidget *grid_box;
+ GdkModifierType extend_mask = gimp_get_extend_selection_mask ();
+ GdkModifierType constrain_mask = gimp_get_constrain_behavior_mask ();
vbox = gimp_transform_options_gui (tool_options, TRUE, TRUE, TRUE);
+ tg_class = g_type_class_ref (tool_options->tool_info->tool_type);
+
+ /* the direction-link button */
+ if (tg_class->matrix_to_info)
+ {
+ GimpTransformOptions *tr_options = GIMP_TRANSFORM_OPTIONS (tool_options);
+ GtkWidget *vbox2;
+ GtkWidget *hbox;
+ GtkWidget *button;
+
+ vbox2 = gtk_bin_get_child (GTK_BIN (tr_options->direction_frame));
+ g_object_ref (vbox2);
+ gtk_container_remove (GTK_CONTAINER (tr_options->direction_frame), vbox2);
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 1);
+ gtk_container_add (GTK_CONTAINER (tr_options->direction_frame), hbox);
+ gtk_widget_show (hbox);
+
+ gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 0);
+ g_object_unref (vbox2);
+
+ button = gimp_chain_button_new (GIMP_CHAIN_RIGHT);
+ gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+ gimp_chain_button_set_icon_size (GIMP_CHAIN_BUTTON (button),
+ GTK_ICON_SIZE_MENU);
+ gtk_widget_show (button);
+
+ g_object_bind_property (config, "direction-linked",
+ button, "active",
+ G_BINDING_BIDIRECTIONAL |
+ G_BINDING_SYNC_CREATE);
+ }
+
+ g_type_class_unref (tg_class);
+
/* the preview frame */
scale = gimp_prop_spin_scale_new (config, "preview-opacity", NULL,
0.01, 0.1, 0);
diff --git a/app/tools/gimptransformgridoptions.h b/app/tools/gimptransformgridoptions.h
index dc959e5998..91d46bde09 100644
--- a/app/tools/gimptransformgridoptions.h
+++ b/app/tools/gimptransformgridoptions.h
@@ -37,6 +37,7 @@ struct _GimpTransformGridOptions
{
GimpTransformOptions parent_instance;
+ gboolean direction_linked;
gboolean show_preview;
gdouble preview_opacity;
GimpGuidesType grid_type;
diff --git a/app/tools/gimptransformgridtool.c b/app/tools/gimptransformgridtool.c
index 75d3872e2b..b54eec59e1 100644
--- a/app/tools/gimptransformgridtool.c
+++ b/app/tools/gimptransformgridtool.c
@@ -205,6 +205,7 @@ gimp_transform_grid_tool_class_init (GimpTransformGridToolClass *klass)
tr_class->transform = gimp_transform_grid_tool_transform;
klass->info_to_matrix = NULL;
+ klass->matrix_to_info = NULL;
klass->get_undo_desc = gimp_transform_grid_tool_real_get_undo_desc;
klass->dialog = NULL;
klass->dialog_update = NULL;
@@ -753,32 +754,76 @@ gimp_transform_grid_tool_draw (GimpDrawTool *draw_tool)
static void
gimp_transform_grid_tool_recalc_matrix (GimpTransformTool *tr_tool)
{
- GimpTransformGridTool *tg_tool = GIMP_TRANSFORM_GRID_TOOL (tr_tool);
- GimpTransformOptions *tr_options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool);
+ GimpTransformGridTool *tg_tool = GIMP_TRANSFORM_GRID_TOOL (tr_tool);
+ GimpTransformOptions *tr_options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool);
+ GimpTransformGridOptions *tg_options = GIMP_TRANSFORM_GRID_TOOL_GET_OPTIONS (tr_tool);
if (GIMP_TRANSFORM_GRID_TOOL_GET_CLASS (tg_tool)->info_to_matrix)
{
GimpMatrix3 forward_transform;
GimpMatrix3 backward_transform;
-
- tr_tool->transform_valid = TRUE;
+ gboolean forward_transform_valid;
+ gboolean backward_transform_valid;
tg_tool->trans_info = tg_tool->trans_infos[GIMP_TRANSFORM_FORWARD];
- tr_tool->transform_valid = tr_tool->transform_valid &&
- gimp_transform_grid_tool_info_to_matrix (
+ forward_transform_valid = gimp_transform_grid_tool_info_to_matrix (
tg_tool, &forward_transform);
tg_tool->trans_info = tg_tool->trans_infos[GIMP_TRANSFORM_BACKWARD];
- tr_tool->transform_valid = tr_tool->transform_valid &&
- gimp_transform_grid_tool_info_to_matrix (
+ backward_transform_valid = gimp_transform_grid_tool_info_to_matrix (
tg_tool, &backward_transform);
- if (tr_tool->transform_valid)
+ if (GIMP_TRANSFORM_GRID_TOOL_GET_CLASS (tg_tool)->matrix_to_info &&
+ tg_options->direction_linked)
+ {
+ GimpMatrix3 transform = tr_tool->transform;
+
+ switch (tr_options->direction)
+ {
+ case GIMP_TRANSFORM_FORWARD:
+ if (forward_transform_valid)
+ {
+ gimp_matrix3_invert (&transform);
+
+ backward_transform = forward_transform;
+ gimp_matrix3_mult (&transform, &backward_transform);
+
+ tg_tool->trans_info =
+ tg_tool->trans_infos[GIMP_TRANSFORM_BACKWARD];
+ gimp_transform_grid_tool_matrix_to_info (tg_tool,
+ &backward_transform);
+ backward_transform_valid =
+ gimp_transform_grid_tool_info_to_matrix (
+ tg_tool, &backward_transform);
+ }
+ break;
+
+ case GIMP_TRANSFORM_BACKWARD:
+ if (backward_transform_valid)
+ {
+ forward_transform = backward_transform;
+ gimp_matrix3_mult (&transform, &forward_transform);
+
+ tg_tool->trans_info =
+ tg_tool->trans_infos[GIMP_TRANSFORM_FORWARD];
+ gimp_transform_grid_tool_matrix_to_info (tg_tool,
+ &forward_transform);
+ forward_transform_valid =
+ gimp_transform_grid_tool_info_to_matrix (
+ tg_tool, &forward_transform);
+ }
+ break;
+ }
+ }
+ else if (forward_transform_valid && backward_transform_valid)
{
tr_tool->transform = backward_transform;
gimp_matrix3_invert (&tr_tool->transform);
gimp_matrix3_mult (&forward_transform, &tr_tool->transform);
}
+
+ tr_tool->transform_valid = forward_transform_valid &&
+ backward_transform_valid;
}
tg_tool->trans_info = tg_tool->trans_infos[tr_options->direction];
@@ -799,8 +844,19 @@ gimp_transform_grid_tool_get_undo_desc (GimpTransformTool *tr_tool)
GimpTransformOptions *tr_options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tr_tool);
gchar *result;
- if (! memcmp (tg_tool->trans_infos[GIMP_TRANSFORM_BACKWARD],
- tg_tool->init_trans_info, sizeof (TransInfo)))
+ if (GIMP_TRANSFORM_GRID_TOOL_GET_CLASS (tg_tool)->matrix_to_info)
+ {
+ TransInfo trans_info;
+
+ memcpy (&trans_info, &tg_tool->init_trans_info, sizeof (TransInfo));
+
+ tg_tool->trans_info = trans_info;
+ gimp_transform_grid_tool_matrix_to_info (tg_tool, &tr_tool->transform);
+ result = GIMP_TRANSFORM_GRID_TOOL_GET_CLASS (tg_tool)->get_undo_desc (
+ tg_tool);
+ }
+ else if (! memcmp (tg_tool->trans_infos[GIMP_TRANSFORM_BACKWARD],
+ tg_tool->init_trans_info, sizeof (TransInfo)))
{
tg_tool->trans_info = tg_tool->trans_infos[GIMP_TRANSFORM_FORWARD];
result = GIMP_TRANSFORM_GRID_TOOL_GET_CLASS (tg_tool)->get_undo_desc (
@@ -1345,6 +1401,20 @@ gimp_transform_grid_tool_info_to_matrix (GimpTransformGridTool *tg_tool,
return FALSE;
}
+void
+gimp_transform_grid_tool_matrix_to_info (GimpTransformGridTool *tg_tool,
+ const GimpMatrix3 *transform)
+{
+ g_return_if_fail (GIMP_IS_TRANSFORM_GRID_TOOL (tg_tool));
+ g_return_if_fail (transform != NULL);
+
+ if (GIMP_TRANSFORM_GRID_TOOL_GET_CLASS (tg_tool)->matrix_to_info)
+ {
+ return GIMP_TRANSFORM_GRID_TOOL_GET_CLASS (tg_tool)->matrix_to_info (
+ tg_tool, transform);
+ }
+}
+
void
gimp_transform_grid_tool_push_internal_undo (GimpTransformGridTool *tg_tool)
{
diff --git a/app/tools/gimptransformgridtool.h b/app/tools/gimptransformgridtool.h
index 401baaf456..ab31111ec8 100644
--- a/app/tools/gimptransformgridtool.h
+++ b/app/tools/gimptransformgridtool.h
@@ -76,6 +76,8 @@ struct _GimpTransformGridToolClass
/* virtual functions */
gboolean (* info_to_matrix) (GimpTransformGridTool *tg_tool,
GimpMatrix3 *transform);
+ void (* matrix_to_info) (GimpTransformGridTool *tg_tool,
+ const GimpMatrix3 *transform);
gchar * (* get_undo_desc) (GimpTransformGridTool *tg_tool);
void (* dialog) (GimpTransformGridTool *tg_tool);
void (* dialog_update) (GimpTransformGridTool *tg_tool);
@@ -100,6 +102,8 @@ GType gimp_transform_grid_tool_get_type (void) G_GNUC_CONST;
gboolean gimp_transform_grid_tool_info_to_matrix (GimpTransformGridTool *tg_tool,
GimpMatrix3 *transform);
+void gimp_transform_grid_tool_matrix_to_info (GimpTransformGridTool *tg_tool,
+ const GimpMatrix3 *transform);
void gimp_transform_grid_tool_push_internal_undo (GimpTransformGridTool *tg_tool);
diff --git a/app/tools/gimptransformoptions.c b/app/tools/gimptransformoptions.c
index a9311c98f7..d1c75e649c 100644
--- a/app/tools/gimptransformoptions.c
+++ b/app/tools/gimptransformoptions.c
@@ -243,6 +243,8 @@ gimp_transform_options_gui (GimpToolOptions *tool_options,
0, 0);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
+
+ options->direction_frame = frame;
}
/* the interpolation menu */
diff --git a/app/tools/gimptransformoptions.h b/app/tools/gimptransformoptions.h
index e5a42acd96..ca8d032fcb 100644
--- a/app/tools/gimptransformoptions.h
+++ b/app/tools/gimptransformoptions.h
@@ -44,6 +44,7 @@ struct _GimpTransformOptions
/* options gui */
GtkWidget *type_box;
+ GtkWidget *direction_frame;
};
struct _GimpTransformOptionsClass
diff --git a/app/tools/gimpunifiedtransformtool.c b/app/tools/gimpunifiedtransformtool.c
index 0c8ded9fc1..00a1934efa 100644
--- a/app/tools/gimpunifiedtransformtool.c
+++ b/app/tools/gimpunifiedtransformtool.c
@@ -56,6 +56,8 @@ enum
/* local function prototypes */
+static void gimp_unified_transform_tool_matrix_to_info (GimpTransformGridTool *tg_tool,
+ const GimpMatrix3 *transform);
static void gimp_unified_transform_tool_prepare (GimpTransformGridTool *tg_tool);
static GimpToolWidget * gimp_unified_transform_tool_get_widget (GimpTransformGridTool *tg_tool);
static void gimp_unified_transform_tool_update_widget (GimpTransformGridTool *tg_tool);
@@ -95,6 +97,7 @@ gimp_unified_transform_tool_class_init (GimpUnifiedTransformToolClass *klass)
GimpTransformGridToolClass *tg_class = GIMP_TRANSFORM_GRID_TOOL_CLASS (klass);
GimpGenericTransformToolClass *generic_class = GIMP_GENERIC_TRANSFORM_TOOL_CLASS (klass);
+ tg_class->matrix_to_info = gimp_unified_transform_tool_matrix_to_info;
tg_class->prepare = gimp_unified_transform_tool_prepare;
tg_class->get_widget = gimp_unified_transform_tool_get_widget;
tg_class->update_widget = gimp_unified_transform_tool_update_widget;
@@ -111,6 +114,45 @@ gimp_unified_transform_tool_init (GimpUnifiedTransformTool *unified_tool)
{
}
+static void
+gimp_unified_transform_tool_matrix_to_info (GimpTransformGridTool *tg_tool,
+ const GimpMatrix3 *transform)
+{
+ GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool);
+ GimpMatrix3 transfer;
+
+ gimp_transform_grid_tool_info_to_matrix (tg_tool, &transfer);
+ gimp_matrix3_invert (&transfer);
+ gimp_matrix3_mult (transform, &transfer);
+
+ gimp_matrix3_transform_point (&transfer,
+ tg_tool->trans_info[PIVOT_X],
+ tg_tool->trans_info[PIVOT_Y],
+ &tg_tool->trans_info[PIVOT_X],
+ &tg_tool->trans_info[PIVOT_Y]);
+
+ gimp_matrix3_transform_point (transform,
+ tr_tool->x1,
+ tr_tool->y1,
+ &tg_tool->trans_info[X0],
+ &tg_tool->trans_info[Y0]);
+ gimp_matrix3_transform_point (transform,
+ tr_tool->x2,
+ tr_tool->y1,
+ &tg_tool->trans_info[X1],
+ &tg_tool->trans_info[Y1]);
+ gimp_matrix3_transform_point (transform,
+ tr_tool->x1,
+ tr_tool->y2,
+ &tg_tool->trans_info[X2],
+ &tg_tool->trans_info[Y2]);
+ gimp_matrix3_transform_point (transform,
+ tr_tool->x2,
+ tr_tool->y2,
+ &tg_tool->trans_info[X3],
+ &tg_tool->trans_info[Y3]);
+}
+
static void
gimp_unified_transform_tool_prepare (GimpTransformGridTool *tg_tool)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]