[gimp] app: use gimp_transform_polygon() in GimpCanvasTransformGuides
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: use gimp_transform_polygon() in GimpCanvasTransformGuides
- Date: Sun, 28 Jan 2018 21:38:27 +0000 (UTC)
commit 4626190ac76fbbdfc829e671f2c27ff32e96e1ed
Author: Ell <ell_se yahoo com>
Date: Sun Jan 28 13:39:00 2018 -0500
app: use gimp_transform_polygon() in GimpCanvasTransformGuides
Add a "clip" property to GimpCavnasTransformGuides. When set, use
gimp_transform_polygon() for transforming the guides and the
bounding box, so that they're properly clipped.
Add a corresponding "clip-guides" property to
GimpToolTransformGrid, and set it to TRUE in GimpToolHandleGrid, so
that the handle-transform tool's guides are clipped properly.
app/display/gimpcanvastransformguides.c | 246 ++++++++++++++++++++-----------
app/display/gimpcanvastransformguides.h | 6 +-
app/display/gimptoolhandlegrid.c | 11 +-
app/display/gimptooltransformgrid.c | 20 +++-
app/display/gimptoolwidget.c | 5 +-
app/display/gimptoolwidget.h | 3 +-
6 files changed, 192 insertions(+), 99 deletions(-)
---
diff --git a/app/display/gimpcanvastransformguides.c b/app/display/gimpcanvastransformguides.c
index 586616f..379382a 100644
--- a/app/display/gimpcanvastransformguides.c
+++ b/app/display/gimpcanvastransformguides.c
@@ -47,7 +47,8 @@ enum
PROP_X2,
PROP_Y2,
PROP_TYPE,
- PROP_N_GUIDES
+ PROP_N_GUIDES,
+ PROP_CLIP
};
@@ -60,6 +61,7 @@ struct _GimpCanvasTransformGuidesPrivate
gdouble x2, y2;
GimpGuidesType type;
gint n_guides;
+ gboolean clip;
};
#define GET_PRIVATE(transform) \
@@ -150,6 +152,11 @@ gimp_canvas_transform_guides_class_init (GimpCanvasTransformGuidesClass *klass)
1, 128, 4,
GIMP_PARAM_READWRITE));
+ g_object_class_install_property (object_class, PROP_CLIP,
+ g_param_spec_boolean ("clip", NULL, NULL,
+ FALSE,
+ GIMP_PARAM_READWRITE));
+
g_type_class_add_private (klass, sizeof (GimpCanvasTransformGuidesPrivate));
}
@@ -203,6 +210,10 @@ gimp_canvas_transform_guides_set_property (GObject *object,
private->n_guides = g_value_get_int (value);
break;
+ case PROP_CLIP:
+ private->clip = g_value_get_boolean (value);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -247,6 +258,10 @@ gimp_canvas_transform_guides_get_property (GObject *object,
g_value_set_int (value, private->n_guides);
break;
+ case PROP_CLIP:
+ g_value_set_boolean (value, private->clip);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -255,34 +270,42 @@ gimp_canvas_transform_guides_get_property (GObject *object,
static gboolean
gimp_canvas_transform_guides_transform (GimpCanvasItem *item,
- gdouble *tx1,
- gdouble *ty1,
- gdouble *tx2,
- gdouble *ty2,
- gdouble *tx3,
- gdouble *ty3,
- gdouble *tx4,
- gdouble *ty4)
+ GimpVector2 *t_vertices,
+ gint *n_t_vertices)
{
GimpCanvasTransformGuidesPrivate *private = GET_PRIVATE (item);
+ GimpVector2 vertices[4];
+
+ vertices[0] = (GimpVector2) { private->x1, private->y1 };
+ vertices[1] = (GimpVector2) { private->x2, private->y1 };
+ vertices[2] = (GimpVector2) { private->x2, private->y2 };
+ vertices[3] = (GimpVector2) { private->x1, private->y2 };
+
+ if (private->clip)
+ {
+ gimp_transform_polygon (&private->transform, vertices, 4, TRUE,
+ t_vertices, n_t_vertices);
+
+ return TRUE;
+ }
+ else
+ {
+ gint i;
+
+ for (i = 0; i < 4; i++)
+ {
+ gimp_matrix3_transform_point (&private->transform,
+ vertices[i].x, vertices[i].y,
+ &t_vertices[i].x, &t_vertices[i].y);
+ }
+
+ *n_t_vertices = 4;
- 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);
-
- return gimp_transform_polygon_is_convex (*tx1, *ty1,
- *tx2, *ty2,
- *tx3, *ty3,
- *tx4, *ty4);
+ return gimp_transform_polygon_is_convex (t_vertices[0].x, t_vertices[0].y,
+ t_vertices[1].x, t_vertices[1].y,
+ t_vertices[3].x, t_vertices[3].y,
+ t_vertices[2].x, t_vertices[2].y);
+ }
}
static void
@@ -294,19 +317,54 @@ draw_line (cairo_t *cr,
gdouble x2,
gdouble y2)
{
- gimp_matrix3_transform_point (transform, x1, y1, &x1, &y1);
- gimp_matrix3_transform_point (transform, x2, y2, &x2, &y2);
+ GimpCanvasTransformGuidesPrivate *private = GET_PRIVATE (item);
+ GimpVector2 vertices[2];
+ GimpVector2 t_vertices[2];
+ gint n_t_vertices;
- gimp_canvas_item_transform_xy_f (item, x1, y1, &x1, &y1);
- gimp_canvas_item_transform_xy_f (item, x2, y2, &x2, &y2);
+ vertices[0] = (GimpVector2) { x1, y1 };
+ vertices[1] = (GimpVector2) { x2, y2 };
- x1 = floor (x1) + 0.5;
- y1 = floor (y1) + 0.5;
- x2 = floor (x2) + 0.5;
- y2 = floor (y2) + 0.5;
+ if (private->clip)
+ {
+ gimp_transform_polygon (transform, vertices, 2, FALSE,
+ t_vertices, &n_t_vertices);
+ }
+ else
+ {
+ gint i;
- cairo_move_to (cr, x1, y1);
- cairo_line_to (cr, x2, y2);
+ for (i = 0; i < 2; i++)
+ {
+ gimp_matrix3_transform_point (transform,
+ vertices[i].x, vertices[i].y,
+ &t_vertices[i].x, &t_vertices[i].y);
+ }
+
+ n_t_vertices = 2;
+ }
+
+ if (n_t_vertices == 2)
+ {
+ gint i;
+
+ for (i = 0; i < 2; i++)
+ {
+ GimpVector2 v;
+
+ gimp_canvas_item_transform_xy_f (item,
+ t_vertices[i].x, t_vertices[i].y,
+ &v.x, &v.y);
+
+ v.x = floor (v.x) + 0.5;
+ v.y = floor (v.y) + 0.5;
+
+ if (i == 0)
+ cairo_move_to (cr, v.x, v.y);
+ else
+ cairo_line_to (cr, v.x, v.y);
+ }
+ }
}
static void
@@ -336,40 +394,36 @@ gimp_canvas_transform_guides_draw (GimpCanvasItem *item,
cairo_t *cr)
{
GimpCanvasTransformGuidesPrivate *private = GET_PRIVATE (item);
- gdouble x1, y1;
- gdouble x2, y2;
- gdouble x3, y3;
- gdouble x4, y4;
+ GimpVector2 t_vertices[5];
+ gint n_t_vertices;
gboolean convex;
gint i;
convex = gimp_canvas_transform_guides_transform (item,
- &x1, &y1,
- &x2, &y2,
- &x3, &y3,
- &x4, &y4);
-
- gimp_canvas_item_transform_xy_f (item, x1, y1, &x1, &y1);
- gimp_canvas_item_transform_xy_f (item, x2, y2, &x2, &y2);
- gimp_canvas_item_transform_xy_f (item, x3, y3, &x3, &y3);
- gimp_canvas_item_transform_xy_f (item, x4, y4, &x4, &y4);
-
- x1 = floor (x1) + 0.5;
- y1 = floor (y1) + 0.5;
- x2 = floor (x2) + 0.5;
- y2 = floor (y2) + 0.5;
- x3 = floor (x3) + 0.5;
- y3 = floor (y3) + 0.5;
- x4 = floor (x4) + 0.5;
- y4 = floor (y4) + 0.5;
-
- cairo_move_to (cr, x1, y1);
- cairo_line_to (cr, x2, y2);
- cairo_line_to (cr, x4, y4);
- cairo_line_to (cr, x3, y3);
- cairo_line_to (cr, x1, y1);
-
- if (! convex)
+ t_vertices, &n_t_vertices);
+
+ if (n_t_vertices < 2)
+ return;
+
+ for (i = 0; i < n_t_vertices; i++)
+ {
+ GimpVector2 v;
+
+ gimp_canvas_item_transform_xy_f (item, t_vertices[i].x, t_vertices[i].y,
+ &v.x, &v.y);
+
+ v.x = floor (v.x) + 0.5;
+ v.y = floor (v.y) + 0.5;
+
+ if (i == 0)
+ cairo_move_to (cr, v.x, v.y);
+ else
+ cairo_line_to (cr, v.x, v.y);
+ }
+
+ cairo_close_path (cr);
+
+ if (! convex || n_t_vertices < 3)
{
_gimp_canvas_item_stroke (item, cr);
return;
@@ -535,30 +589,44 @@ gimp_canvas_transform_guides_draw (GimpCanvasItem *item,
static cairo_region_t *
gimp_canvas_transform_guides_get_extents (GimpCanvasItem *item)
{
- gdouble x1, y1;
- gdouble x2, y2;
- gdouble x3, y3;
- gdouble x4, y4;
+ GimpVector2 t_vertices[5];
+ gint n_t_vertices;
+ GimpVector2 top_left;
+ GimpVector2 bottom_right;
cairo_rectangle_int_t extents;
+ gint i;
+
+ gimp_canvas_transform_guides_transform (item, t_vertices, &n_t_vertices);
+
+ if (n_t_vertices < 2)
+ return cairo_region_create ();
+
+ for (i = 0; i < n_t_vertices; i++)
+ {
+ GimpVector2 v;
- gimp_canvas_transform_guides_transform (item,
- &x1, &y1,
- &x2, &y2,
- &x3, &y3,
- &x4, &y4);
+ gimp_canvas_item_transform_xy_f (item,
+ t_vertices[i].x, t_vertices[i].y,
+ &v.x, &v.y);
- gimp_canvas_item_transform_xy_f (item, x1, y1, &x1, &y1);
- gimp_canvas_item_transform_xy_f (item, x2, y2, &x2, &y2);
- gimp_canvas_item_transform_xy_f (item, x3, y3, &x3, &y3);
- gimp_canvas_item_transform_xy_f (item, x4, y4, &x4, &y4);
+ if (i == 0)
+ {
+ top_left = bottom_right = v;
+ }
+ else
+ {
+ top_left.x = MIN (top_left.x, v.x);
+ top_left.y = MIN (top_left.y, v.y);
- extents.x = (gint) floor (MIN4 (x1, x2, x3, x4) - 1.5);
- extents.y = (gint) floor (MIN4 (y1, y2, y3, y4) - 1.5);
- extents.width = (gint) ceil (MAX4 (x1, x2, x3, x4) + 1.5);
- extents.height = (gint) ceil (MAX4 (y1, y2, y3, y4) + 1.5);
+ bottom_right.x = MAX (bottom_right.x, v.x);
+ bottom_right.y = MAX (bottom_right.y, v.y);
+ }
+ }
- extents.width -= extents.x;
- extents.height -= extents.y;
+ extents.x = (gint) floor (top_left.x - 1.5);
+ extents.y = (gint) floor (top_left.y - 1.5);
+ extents.width = (gint) ceil (bottom_right.x + 1.5) - extents.x;
+ extents.height = (gint) ceil (bottom_right.y + 1.5) - extents.y;
return cairo_region_create_rectangle (&extents);
}
@@ -571,7 +639,8 @@ gimp_canvas_transform_guides_new (GimpDisplayShell *shell,
gdouble x2,
gdouble y2,
GimpGuidesType type,
- gint n_guides)
+ gint n_guides,
+ gboolean clip)
{
g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), NULL);
@@ -584,6 +653,7 @@ gimp_canvas_transform_guides_new (GimpDisplayShell *shell,
"y2", y2,
"type", type,
"n-guides", n_guides,
+ "clip", clip,
NULL);
}
@@ -595,7 +665,8 @@ gimp_canvas_transform_guides_set (GimpCanvasItem *guides,
gdouble x2,
gdouble y2,
GimpGuidesType type,
- gint n_guides)
+ gint n_guides,
+ gboolean clip)
{
g_return_if_fail (GIMP_IS_CANVAS_TRANSFORM_GUIDES (guides));
@@ -609,6 +680,7 @@ gimp_canvas_transform_guides_set (GimpCanvasItem *guides,
"y2", y2,
"type", type,
"n-guides", n_guides,
+ "clip", clip,
NULL);
gimp_canvas_item_end_change (guides);
diff --git a/app/display/gimpcanvastransformguides.h b/app/display/gimpcanvastransformguides.h
index 6067c35..792de8a 100644
--- a/app/display/gimpcanvastransformguides.h
+++ b/app/display/gimpcanvastransformguides.h
@@ -56,7 +56,8 @@ GimpCanvasItem * gimp_canvas_transform_guides_new (GimpDisplayShell *shell
gdouble x2,
gdouble y2,
GimpGuidesType type,
- gint n_guides);
+ gint n_guides,
+ gboolean clip);
void gimp_canvas_transform_guides_set (GimpCanvasItem *guides,
const GimpMatrix3 *transform,
@@ -65,7 +66,8 @@ void gimp_canvas_transform_guides_set (GimpCanvasItem *guide
gdouble x2,
gdouble y2,
GimpGuidesType type,
- gint n_guides);
+ gint n_guides,
+ gboolean clip);
#endif /* __GIMP_CANVAS_TRANSFORM_GUIDES_H__ */
diff --git a/app/display/gimptoolhandlegrid.c b/app/display/gimptoolhandlegrid.c
index dc1bfc9..acb83a9 100644
--- a/app/display/gimptoolhandlegrid.c
+++ b/app/display/gimptoolhandlegrid.c
@@ -1109,10 +1109,11 @@ gimp_tool_handle_grid_new (GimpDisplayShell *shell,
g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), NULL);
return g_object_new (GIMP_TYPE_TOOL_HANDLE_GRID,
- "shell", shell,
- "x1", x1,
- "y1", y1,
- "x2", x2,
- "y2", y2,
+ "shell", shell,
+ "x1", x1,
+ "y1", y1,
+ "x2", x2,
+ "y2", y2,
+ "clip-guides", TRUE,
NULL);
}
diff --git a/app/display/gimptooltransformgrid.c b/app/display/gimptooltransformgrid.c
index 15f250e..01236a9 100644
--- a/app/display/gimptooltransformgrid.c
+++ b/app/display/gimptooltransformgrid.c
@@ -59,6 +59,7 @@ enum
PROP_PIVOT_Y,
PROP_GUIDE_TYPE,
PROP_N_GUIDES,
+ PROP_CLIP_GUIDES,
PROP_SHOW_GUIDES,
PROP_INSIDE_FUNCTION,
PROP_OUTSIDE_FUNCTION,
@@ -90,6 +91,7 @@ struct _GimpToolTransformGridPrivate
gdouble pivot_y;
GimpGuidesType guide_type;
gint n_guides;
+ gboolean clip_guides;
gboolean show_guides;
GimpTransformFunction inside_function;
GimpTransformFunction outside_function;
@@ -292,6 +294,12 @@ gimp_tool_transform_grid_class_init (GimpToolTransformGridClass *klass)
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
+ g_object_class_install_property (object_class, PROP_CLIP_GUIDES,
+ g_param_spec_boolean ("clip-guides", NULL, NULL,
+ FALSE,
+ GIMP_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
g_object_class_install_property (object_class, PROP_SHOW_GUIDES,
g_param_spec_boolean ("show-guides", NULL, NULL,
TRUE,
@@ -455,7 +463,8 @@ gimp_tool_transform_grid_constructed (GObject *object)
private->x2,
private->y2,
private->guide_type,
- private->n_guides);
+ private->n_guides,
+ private->clip_guides);
for (i = 0; i < 4; i++)
{
@@ -586,6 +595,9 @@ gimp_tool_transform_grid_set_property (GObject *object,
case PROP_N_GUIDES:
private->n_guides = g_value_get_int (value);
break;
+ case PROP_CLIP_GUIDES:
+ private->clip_guides = g_value_get_boolean (value);
+ break;
case PROP_SHOW_GUIDES:
private->show_guides = g_value_get_boolean (value);
break;
@@ -702,6 +714,9 @@ gimp_tool_transform_grid_get_property (GObject *object,
case PROP_N_GUIDES:
g_value_set_int (value, private->n_guides);
break;
+ case PROP_CLIP_GUIDES:
+ g_value_set_boolean (value, private->clip_guides);
+ break;
case PROP_SHOW_GUIDES:
g_value_set_boolean (value, private->show_guides);
break;
@@ -1033,7 +1048,8 @@ gimp_tool_transform_grid_changed (GimpToolWidget *widget)
private->x2,
private->y2,
private->guide_type,
- private->n_guides);
+ private->n_guides,
+ private->clip_guides);
gimp_canvas_item_set_visible (private->guides, private->show_guides);
get_handle_geometry (grid, o, angle);
diff --git a/app/display/gimptoolwidget.c b/app/display/gimptoolwidget.c
index 38ae34a..ce777b5 100644
--- a/app/display/gimptoolwidget.c
+++ b/app/display/gimptoolwidget.c
@@ -697,7 +697,8 @@ gimp_tool_widget_add_transform_guides (GimpToolWidget *widget,
gdouble x2,
gdouble y2,
GimpGuidesType type,
- gint n_guides)
+ gint n_guides,
+ gboolean clip)
{
GimpCanvasItem *item;
@@ -705,7 +706,7 @@ gimp_tool_widget_add_transform_guides (GimpToolWidget *widget,
item = gimp_canvas_transform_guides_new (widget->private->shell,
transform, x1, y1, x2, y2,
- type, n_guides);
+ type, n_guides, clip);
gimp_tool_widget_add_item (widget, item);
g_object_unref (item);
diff --git a/app/display/gimptoolwidget.h b/app/display/gimptoolwidget.h
index 2728503..7f2cac1 100644
--- a/app/display/gimptoolwidget.h
+++ b/app/display/gimptoolwidget.h
@@ -225,7 +225,8 @@ GimpCanvasItem * gimp_tool_widget_add_transform_guides
gdouble x2,
gdouble y2,
GimpGuidesType type,
- gint n_guides);
+ gint n_guides,
+ gboolean clip);
/* for tools, to be called from the respective GimpTool method
* implementations
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]