[gimp] app: refactor GimpCanvasTransformPreview to not know GimpTransformTool any more
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: refactor GimpCanvasTransformPreview to not know GimpTransformTool any more
- Date: Sun, 27 Mar 2011 19:21:58 +0000 (UTC)
commit 8a09fd1f342f6c5cf8cded6e580b3abc016894b4
Author: Michael Natterer <mitch gimp org>
Date: Sun Mar 27 21:19:38 2011 +0200
app: refactor GimpCanvasTransformPreview to not know GimpTransformTool any more
Instead, add drawable, transform, x1, y1 etc. properties. This is
cleaner and has the nice side effect of not leaving artifacts, because
the changed state of the transform tool doesn't affect the extents
calculation any longer.
app/display/gimpcanvastransformpreview.c | 308 ++++++++++++++++++++++--------
app/display/gimpcanvastransformpreview.h | 8 +-
app/tools/gimptransformtool.c | 9 +-
3 files changed, 245 insertions(+), 80 deletions(-)
---
diff --git a/app/display/gimpcanvastransformpreview.c b/app/display/gimpcanvastransformpreview.c
index bb70fd3..2a9d9d5 100644
--- a/app/display/gimpcanvastransformpreview.c
+++ b/app/display/gimpcanvastransformpreview.c
@@ -23,18 +23,17 @@
#include <gegl.h>
#include <gtk/gtk.h>
+#include "libgimpbase/gimpbase.h"
#include "libgimpmath/gimpmath.h"
#include "libgimpwidgets/gimpwidgets.h"
-#include "tools/tools-types.h" /* eek */
+#include "display/display-types.h"
#include "base/tile-manager.h"
#include "core/gimpchannel.h"
#include "core/gimpimage.h"
-#include "tools/gimpperspectivetool.h"
-
#include "gimpcanvas.h"
#include "gimpcanvastransformpreview.h"
#include "gimpdisplayshell.h"
@@ -55,7 +54,13 @@
enum
{
PROP_0,
- PROP_TRANSFORM_TOOL,
+ PROP_DRAWABLE,
+ PROP_TRANSFORM,
+ PROP_X1,
+ PROP_Y1,
+ PROP_X2,
+ PROP_Y2,
+ PROP_PERSPECTIVE,
PROP_OPACITY
};
@@ -64,7 +69,11 @@ typedef struct _GimpCanvasTransformPreviewPrivate GimpCanvasTransformPreviewPriv
struct _GimpCanvasTransformPreviewPrivate
{
- GimpTransformTool *transform_tool;
+ GimpDrawable *drawable;
+ GimpMatrix3 transform;
+ gdouble x1, y1;
+ gdouble x2, y2;
+ gboolean perspective;
gdouble opacity;
};
@@ -168,12 +177,56 @@ gimp_canvas_transform_preview_class_init (GimpCanvasTransformPreviewClass *klass
item_class->draw = gimp_canvas_transform_preview_draw;
item_class->get_extents = gimp_canvas_transform_preview_get_extents;
- g_object_class_install_property (object_class, PROP_TRANSFORM_TOOL,
- g_param_spec_object ("transform-tool",
+ g_object_class_install_property (object_class, PROP_DRAWABLE,
+ g_param_spec_object ("drawable",
+ NULL, NULL,
+ GIMP_TYPE_DRAWABLE,
+ GIMP_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class, PROP_TRANSFORM,
+ gimp_param_spec_matrix3 ("transform",
+ NULL, NULL,
+ NULL,
+ GIMP_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class, PROP_X1,
+ g_param_spec_double ("x1",
+ NULL, NULL,
+ -GIMP_MAX_IMAGE_SIZE,
+ GIMP_MAX_IMAGE_SIZE,
+ 0.0,
+ GIMP_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class, PROP_Y1,
+ g_param_spec_double ("y1",
NULL, NULL,
- GIMP_TYPE_TRANSFORM_TOOL,
+ -GIMP_MAX_IMAGE_SIZE,
+ GIMP_MAX_IMAGE_SIZE,
+ 0.0,
GIMP_PARAM_READWRITE));
+ g_object_class_install_property (object_class, PROP_X2,
+ g_param_spec_double ("x2",
+ NULL, NULL,
+ -GIMP_MAX_IMAGE_SIZE,
+ GIMP_MAX_IMAGE_SIZE,
+ 0.0,
+ GIMP_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class, PROP_Y2,
+ g_param_spec_double ("y2",
+ NULL, NULL,
+ -GIMP_MAX_IMAGE_SIZE,
+ GIMP_MAX_IMAGE_SIZE,
+ 0.0,
+ GIMP_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class, PROP_PERSPECTIVE,
+ g_param_spec_boolean ("perspective",
+ NULL, NULL,
+ FALSE,
+ GIMP_PARAM_READWRITE));
+
g_object_class_install_property (object_class, PROP_OPACITY,
g_param_spec_double ("opacity",
NULL, NULL,
@@ -198,8 +251,39 @@ gimp_canvas_transform_preview_set_property (GObject *object,
switch (property_id)
{
- case PROP_TRANSFORM_TOOL:
- private->transform_tool = g_value_get_object (value); /* don't ref */
+ case PROP_DRAWABLE:
+ private->drawable = g_value_get_object (value); /* don't ref */
+ break;
+
+ case PROP_TRANSFORM:
+ {
+ GimpMatrix3 *transform = g_value_get_boxed (value);
+
+ if (transform)
+ private->transform = *transform;
+ else
+ gimp_matrix3_identity (&private->transform);
+ }
+ break;
+
+ case PROP_X1:
+ private->x1 = g_value_get_double (value);
+ break;
+
+ case PROP_Y1:
+ private->y1 = g_value_get_double (value);
+ break;
+
+ case PROP_X2:
+ private->x2 = g_value_get_double (value);
+ break;
+
+ case PROP_Y2:
+ private->y2 = g_value_get_double (value);
+ break;
+
+ case PROP_PERSPECTIVE:
+ private->perspective = g_value_get_boolean (value);
break;
case PROP_OPACITY:
@@ -222,8 +306,32 @@ gimp_canvas_transform_preview_get_property (GObject *object,
switch (property_id)
{
- case PROP_TRANSFORM_TOOL:
- g_value_set_object (value, private->transform_tool);
+ case PROP_DRAWABLE:
+ g_value_set_object (value, private->drawable);
+ break;
+
+ case PROP_TRANSFORM:
+ g_value_set_boxed (value, &private->transform);
+ break;
+
+ case PROP_PERSPECTIVE:
+ g_value_set_boolean (value, private->perspective);
+ break;
+
+ case PROP_X1:
+ g_value_set_double (value, private->x1);
+ break;
+
+ case PROP_Y1:
+ g_value_set_double (value, private->y1);
+ break;
+
+ case PROP_X2:
+ g_value_set_double (value, private->x2);
+ break;
+
+ case PROP_Y2:
+ g_value_set_double (value, private->y2);
break;
case PROP_OPACITY:
@@ -236,16 +344,82 @@ gimp_canvas_transform_preview_get_property (GObject *object,
}
}
+static gboolean
+gimp_canvas_transform_preview_transform (GimpCanvasItem *item,
+ GimpDisplayShell *shell,
+ GdkRectangle *extents)
+{
+ GimpCanvasTransformPreviewPrivate *private = GET_PRIVATE (item);
+ gdouble tx1, ty1;
+ gdouble tx2, ty2;
+ gdouble tx3, ty3;
+ gdouble tx4, ty4;
+ gdouble z1, z2, z3, z4;
+
+ gimp_matrix3_transform_point (&private->transform,
+ private->x1, private->y1,
+ &tx1, &ty1);
+ gimp_matrix3_transform_point (&private->transform,
+ private->x2, private->y1,
+ &tx2, &ty2);
+ gimp_matrix3_transform_point (&private->transform,
+ private->x1, private->y2,
+ &tx3, &ty3);
+ gimp_matrix3_transform_point (&private->transform,
+ private->x2, private->y2,
+ &tx4, &ty4);
+
+ z1 = ((tx2 - tx1) * (ty4 - ty1) -
+ (tx4 - tx1) * (ty2 - ty1));
+ z2 = ((tx4 - tx1) * (ty3 - ty1) -
+ (tx3 - tx1) * (ty4 - ty1));
+ z3 = ((tx4 - tx2) * (ty3 - ty2) -
+ (tx3 - tx2) * (ty4 - ty2));
+ z4 = ((tx3 - tx2) * (ty1 - ty2) -
+ (tx1 - tx2) * (ty3 - ty2));
+
+ if (! ((z1 * z2 > 0) && (z3 * z4 > 0)))
+ return FALSE;
+
+ if (extents)
+ {
+ gdouble dx1, dy1;
+ gdouble dx2, dy2;
+ gdouble dx3, dy3;
+ gdouble dx4, dy4;
+
+ gimp_display_shell_transform_xy_f (shell,
+ tx1, ty1,
+ &dx1, &dy1);
+ gimp_display_shell_transform_xy_f (shell,
+ tx2, ty2,
+ &dx2, &dy2);
+ gimp_display_shell_transform_xy_f (shell,
+ tx3, ty3,
+ &dx3, &dy3);
+ gimp_display_shell_transform_xy_f (shell,
+ tx4, ty4,
+ &dx4, &dy4);
+
+ extents->x = (gint) floor (MIN4 (dx1, dx2, dx3, dx4));
+ extents->y = (gint) floor (MIN4 (dy1, dy2, dy3, dy4));
+ extents->width = (gint) ceil (MAX4 (dx1, dx2, dx3, dx4));
+ extents->height = (gint) ceil (MAX4 (dy1, dy2, dy3, dy4));
+
+ extents->width -= extents->x;
+ extents->height -= extents->y;
+ }
+
+ return TRUE;
+}
+
static void
gimp_canvas_transform_preview_draw (GimpCanvasItem *item,
GimpDisplayShell *shell,
cairo_t *cr)
{
GimpCanvasTransformPreviewPrivate *private = GET_PRIVATE (item);
- GimpTransformTool *tr_tool;
- GimpDrawable *drawable;
GimpChannel *mask;
- gdouble z1, z2, z3, z4;
gint mask_x1, mask_y1;
gint mask_x2, mask_y2;
gint mask_offx, mask_offy;
@@ -263,38 +437,29 @@ gimp_canvas_transform_preview_draw (GimpCanvasItem *item,
gfloat v[MAX_SUB_COLS * MAX_SUB_ROWS][4];
guchar opacity;
- tr_tool = private->transform_tool;
opacity = private->opacity * 255.999;
- z1 = ((tr_tool->tx2 - tr_tool->tx1) * (tr_tool->ty4 - tr_tool->ty1) -
- (tr_tool->tx4 - tr_tool->tx1) * (tr_tool->ty2 - tr_tool->ty1));
- z2 = ((tr_tool->tx4 - tr_tool->tx1) * (tr_tool->ty3 - tr_tool->ty1) -
- (tr_tool->tx3 - tr_tool->tx1) * (tr_tool->ty4 - tr_tool->ty1));
- z3 = ((tr_tool->tx4 - tr_tool->tx2) * (tr_tool->ty3 - tr_tool->ty2) -
- (tr_tool->tx3 - tr_tool->tx2) * (tr_tool->ty4 - tr_tool->ty2));
- z4 = ((tr_tool->tx3 - tr_tool->tx2) * (tr_tool->ty1 - tr_tool->ty2) -
- (tr_tool->tx1 - tr_tool->tx2) * (tr_tool->ty3 - tr_tool->ty2));
-
/* only draw convex polygons */
-
- if (! ((z1 * z2 > 0) && (z3 * z4 > 0)))
+ if (! gimp_canvas_transform_preview_transform (item, shell, NULL))
return;
- mask = NULL;
- mask_offx = mask_offy = 0;
+ mask = NULL;
+ mask_offx = 0;
+ mask_offy = 0;
- drawable = GIMP_TOOL (tr_tool)->drawable;
-
- if (gimp_item_mask_bounds (GIMP_ITEM (drawable),
+ if (gimp_item_mask_bounds (GIMP_ITEM (private->drawable),
&mask_x1, &mask_y1,
&mask_x2, &mask_y2))
{
- mask = gimp_image_get_mask (gimp_item_get_image (GIMP_ITEM (drawable)));
+ GimpImage *image = gimp_item_get_image (GIMP_ITEM (private->drawable));
+
+ mask = gimp_image_get_mask (image);
- gimp_item_get_offset (GIMP_ITEM (drawable), &mask_offx, &mask_offy);
+ gimp_item_get_offset (GIMP_ITEM (private->drawable),
+ &mask_offx, &mask_offy);
}
- if (GIMP_IS_PERSPECTIVE_TOOL (tr_tool))
+ if (private->perspective)
{
/* approximate perspective transform by subdivision
*
@@ -311,8 +476,8 @@ gimp_canvas_transform_preview_draw (GimpCanvasItem *item,
rows = 1;
}
- dx = (tr_tool->x2 - tr_tool->x1) / ((gfloat) columns);
- dy = (tr_tool->y2 - tr_tool->y1) / ((gfloat) rows);
+ dx = (private->x2 - private->x1) / ((gfloat) columns);
+ dy = (private->y2 - private->y1) / ((gfloat) rows);
du = (mask_x2 - mask_x1) / ((gfloat) columns);
dv = (mask_y2 - mask_y1) / ((gfloat) rows);
@@ -322,10 +487,10 @@ gimp_canvas_transform_preview_draw (GimpCanvasItem *item,
gdouble tx1, ty1; \
gdouble tx2, ty2; \
\
- u[sub][index] = tr_tool->x1 + (dx * (col + (index & 1))); \
- v[sub][index] = tr_tool->y1 + (dy * (row + (index >> 1))); \
+ u[sub][index] = private->x1 + (dx * (col + (index & 1))); \
+ v[sub][index] = private->y1 + (dy * (row + (index >> 1))); \
\
- gimp_matrix3_transform_point (&tr_tool->transform, \
+ gimp_matrix3_transform_point (&private->transform, \
u[sub][index], v[sub][index], \
&tx1, &ty1); \
\
@@ -400,7 +565,7 @@ gimp_canvas_transform_preview_draw (GimpCanvasItem *item,
k = columns * rows;
for (j = 0; j < k; j++)
- gimp_canvas_transform_preview_draw_quad (drawable, cr,
+ gimp_canvas_transform_preview_draw_quad (private->drawable, cr,
mask, mask_offx, mask_offy,
x[j], y[j], u[j], v[j],
opacity);
@@ -410,52 +575,39 @@ static cairo_region_t *
gimp_canvas_transform_preview_get_extents (GimpCanvasItem *item,
GimpDisplayShell *shell)
{
- GimpCanvasTransformPreviewPrivate *private = GET_PRIVATE (item);
- GimpTransformTool *tr_tool;
- gdouble dx1, dy1;
- gdouble dx2, dy2;
- gdouble dx3, dy3;
- gdouble dx4, dy4;
- GdkRectangle rectangle;
-
- tr_tool = private->transform_tool;
-
- gimp_display_shell_transform_xy_f (shell,
- tr_tool->tx1, tr_tool->ty1,
- &dx1, &dy1);
- gimp_display_shell_transform_xy_f (shell,
- tr_tool->tx2, tr_tool->ty2,
- &dx2, &dy2);
- gimp_display_shell_transform_xy_f (shell,
- tr_tool->tx3, tr_tool->ty3,
- &dx3, &dy3);
- gimp_display_shell_transform_xy_f (shell,
- tr_tool->tx4, tr_tool->ty4,
- &dx4, &dy4);
-
- rectangle.x = (gint) floor (MIN4 (dx1, dx2, dx3, dx4));
- rectangle.y = (gint) floor (MIN4 (dy1, dy2, dy3, dy4));
- rectangle.width = (gint) ceil (MAX4 (dx1, dx2, dx3, dx4));
- rectangle.height = (gint) ceil (MAX4 (dy1, dy2, dy3, dy4));
-
- rectangle.width -= rectangle.x;
- rectangle.height -= rectangle.y;
-
- return cairo_region_create_rectangle ((cairo_rectangle_int_t *) &rectangle);
+ GdkRectangle rectangle;
+
+ if (gimp_canvas_transform_preview_transform (item, shell, &rectangle))
+ return cairo_region_create_rectangle ((cairo_rectangle_int_t *) &rectangle);
+
+ return NULL;
}
GimpCanvasItem *
gimp_canvas_transform_preview_new (GimpDisplayShell *shell,
- GimpTransformTool *transform_tool,
+ GimpDrawable *drawable,
+ const GimpMatrix3 *transform,
+ gdouble x1,
+ gdouble y1,
+ gdouble x2,
+ gdouble y2,
+ gboolean perspective,
gdouble opacity)
{
g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), NULL);
- g_return_val_if_fail (GIMP_IS_TRANSFORM_TOOL (transform_tool), NULL);
+ g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
+ g_return_val_if_fail (transform != NULL, NULL);
return g_object_new (GIMP_TYPE_CANVAS_TRANSFORM_PREVIEW,
- "shell", shell,
- "transform-tool", transform_tool,
- "opacity", CLAMP (opacity, 0.0, 1.0),
+ "shell", shell,
+ "drawable", drawable,
+ "transform", transform,
+ "x1", x1,
+ "y1", y1,
+ "x2", x2,
+ "y2", y2,
+ "perspective", perspective,
+ "opacity", CLAMP (opacity, 0.0, 1.0),
NULL);
}
diff --git a/app/display/gimpcanvastransformpreview.h b/app/display/gimpcanvastransformpreview.h
index f03cca7..e49e0f9 100644
--- a/app/display/gimpcanvastransformpreview.h
+++ b/app/display/gimpcanvastransformpreview.h
@@ -50,7 +50,13 @@ struct _GimpCanvasTransformPreviewClass
GType gimp_canvas_transform_preview_get_type (void) G_GNUC_CONST;
GimpCanvasItem * gimp_canvas_transform_preview_new (GimpDisplayShell *shell,
- GimpTransformTool *transform_tool,
+ GimpDrawable *drawable,
+ const GimpMatrix3 *transform,
+ gdouble x1,
+ gdouble y1,
+ gdouble x2,
+ gdouble y2,
+ gboolean perspective,
gdouble opacity);
diff --git a/app/tools/gimptransformtool.c b/app/tools/gimptransformtool.c
index 81d339d..5c8f2f1 100644
--- a/app/tools/gimptransformtool.c
+++ b/app/tools/gimptransformtool.c
@@ -58,6 +58,7 @@
#include "display/gimptooldialog.h"
#include "gimptoolcontrol.h"
+#include "gimpperspectivetool.h"
#include "gimptransformoptions.h"
#include "gimptransformtool.h"
#include "gimptransformtoolundo.h"
@@ -759,7 +760,13 @@ gimp_transform_tool_draw (GimpDrawTool *draw_tool)
GimpCanvasItem *item;
item = gimp_canvas_transform_preview_new (gimp_display_get_shell (draw_tool->display),
- tr_tool,
+ tool->drawable,
+ &tr_tool->transform,
+ tr_tool->x1,
+ tr_tool->y1,
+ tr_tool->x2,
+ tr_tool->y2,
+ GIMP_IS_PERSPECTIVE_TOOL (tr_tool),
options->preview_opacity);
gimp_draw_tool_add_item (draw_tool, item);
g_object_unref (item);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]