mirror of https://github.com/GNOME/gimp.git
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.
This commit is contained in:
parent
9900573345
commit
4626190ac7
|
@ -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];
|
||||
|
||||
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);
|
||||
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 };
|
||||
|
||||
return gimp_transform_polygon_is_convex (*tx1, *ty1,
|
||||
*tx2, *ty2,
|
||||
*tx3, *ty3,
|
||||
*tx4, *ty4);
|
||||
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;
|
||||
|
||||
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);
|
||||
t_vertices, &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);
|
||||
gimp_canvas_item_transform_xy_f (item, x3, y3, &x3, &y3);
|
||||
gimp_canvas_item_transform_xy_f (item, x4, y4, &x4, &y4);
|
||||
if (n_t_vertices < 2)
|
||||
return;
|
||||
|
||||
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;
|
||||
for (i = 0; i < n_t_vertices; i++)
|
||||
{
|
||||
GimpVector2 v;
|
||||
|
||||
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);
|
||||
gimp_canvas_item_transform_xy_f (item, t_vertices[i].x, t_vertices[i].y,
|
||||
&v.x, &v.y);
|
||||
|
||||
if (! convex)
|
||||
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,
|
||||
&x1, &y1,
|
||||
&x2, &y2,
|
||||
&x3, &y3,
|
||||
&x4, &y4);
|
||||
gimp_canvas_transform_guides_transform (item, t_vertices, &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);
|
||||
gimp_canvas_item_transform_xy_f (item, x3, y3, &x3, &y3);
|
||||
gimp_canvas_item_transform_xy_f (item, x4, y4, &x4, &y4);
|
||||
if (n_t_vertices < 2)
|
||||
return cairo_region_create ();
|
||||
|
||||
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);
|
||||
for (i = 0; i < n_t_vertices; i++)
|
||||
{
|
||||
GimpVector2 v;
|
||||
|
||||
extents.width -= extents.x;
|
||||
extents.height -= extents.y;
|
||||
gimp_canvas_item_transform_xy_f (item,
|
||||
t_vertices[i].x, t_vertices[i].y,
|
||||
&v.x, &v.y);
|
||||
|
||||
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);
|
||||
|
||||
bottom_right.x = MAX (bottom_right.x, v.x);
|
||||
bottom_right.y = MAX (bottom_right.y, v.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);
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue