Commit 7b2e6b75 authored by Ell's avatar Ell

app: clip transform-tools preview according to clipping mode

Add a "clip" property to GimpCanvasTransformPreview, specifying the
transform's clipping mode, and clip the preview accordingly.

In GimpTransformGridTool, sync the tool's clipping mode with the
preview's clipping mode.
parent d79ef34f
Pipeline #142935 passed with stages
in 33 minutes and 27 seconds
......@@ -108,13 +108,13 @@ static void find_maximum_aspect_rectangle (Rectangle *r,
/*
* This function wants to be passed the inverse transformation matrix!!
*/
void
gboolean
gimp_transform_resize_boundary (const GimpMatrix3 *inv,
GimpTransformResize resize,
gint u1,
gint v1,
gint u2,
gint v2,
gdouble u1,
gdouble v1,
gdouble u2,
gdouble v2,
gint *x1,
gint *y1,
gint *x2,
......@@ -126,17 +126,17 @@ gimp_transform_resize_boundary (const GimpMatrix3 *inv,
gboolean valid;
gint i;
g_return_if_fail (inv != NULL);
g_return_val_if_fail (inv != NULL, FALSE);
/* initialize with the original boundary */
*x1 = u1;
*y1 = v1;
*x2 = u2;
*y2 = v2;
*x1 = floor (u1);
*y1 = floor (v1);
*x2 = ceil (u2);
*y2 = ceil (v2);
/* if clipping then just return the original rectangle */
if (resize == GIMP_TRANSFORM_RESIZE_CLIP)
return;
return TRUE;
bounds[0] = (GimpVector2) { u1, v1 };
bounds[1] = (GimpVector2) { u2, v1 };
......@@ -154,11 +154,10 @@ gimp_transform_resize_boundary (const GimpMatrix3 *inv,
if (! valid)
{
g_warning ("invalid transform matrix");
/* since there is no sensible way to deal with this, just do the same as
* with GIMP_TRANSFORM_RESIZE_CLIP: return
*/
return;
return FALSE;
}
switch (resize)
......@@ -178,7 +177,7 @@ gimp_transform_resize_boundary (const GimpMatrix3 *inv,
case GIMP_TRANSFORM_RESIZE_CROP_WITH_ASPECT:
gimp_transform_resize_crop (points, n_points,
((gdouble) u2 - u1) / (v2 - v1),
(u2 - u1) / (v2 - v1),
x1, y1, x2, y2);
break;
......@@ -195,6 +194,8 @@ gimp_transform_resize_boundary (const GimpMatrix3 *inv,
if (*y1 == *y2)
(*y2)++;
return TRUE;
}
/* this calculates the smallest rectangle (with sides parallel to x- and
......
......@@ -19,16 +19,16 @@
#define __GIMP_TRANSFORM_RESIZE_H__
void gimp_transform_resize_boundary (const GimpMatrix3 *inv,
GimpTransformResize resize,
gint u1,
gint v1,
gint u2,
gint v2,
gint *x1,
gint *y1,
gint *x2,
gint *y2);
gboolean gimp_transform_resize_boundary (const GimpMatrix3 *inv,
GimpTransformResize resize,
gdouble u1,
gdouble v1,
gdouble u2,
gdouble v2,
gint *x1,
gint *y1,
gint *x2,
gint *y2);
#endif /* __GIMP_TRANSFORM_RESIZE_H__ */
......@@ -36,6 +36,7 @@
#include "gegl/gimp-gegl-utils.h"
#include "gegl/gimptilehandlervalidate.h"
#include "core/gimp-transform-resize.h"
#include "core/gimp-transform-utils.h"
#include "core/gimp-utils.h"
#include "core/gimpchannel.h"
......@@ -53,6 +54,7 @@ enum
PROP_0,
PROP_PICKABLE,
PROP_TRANSFORM,
PROP_CLIP,
PROP_X1,
PROP_Y1,
PROP_X2,
......@@ -65,31 +67,32 @@ typedef struct _GimpCanvasTransformPreviewPrivate GimpCanvasTransformPreviewPriv
struct _GimpCanvasTransformPreviewPrivate
{
GimpPickable *pickable;
GimpMatrix3 transform;
gdouble x1, y1;
gdouble x2, y2;
gdouble opacity;
GeglNode *node;
GeglNode *source_node;
GeglNode *convert_format_node;
GeglNode *layer_mask_source_node;
GeglNode *layer_mask_opacity_node;
GeglNode *mask_source_node;
GeglNode *mask_translate_node;
GeglNode *mask_crop_node;
GeglNode *opacity_node;
GeglNode *cache_node;
GeglNode *transform_node;
GimpPickable *node_pickable;
GimpDrawable *node_layer_mask;
GimpDrawable *node_mask;
GeglRectangle node_rect;
gdouble node_opacity;
GimpMatrix3 node_matrix;
GeglNode *node_output;
GimpPickable *pickable;
GimpMatrix3 transform;
GimpTransformResize clip;
gdouble x1, y1;
gdouble x2, y2;
gdouble opacity;
GeglNode *node;
GeglNode *source_node;
GeglNode *convert_format_node;
GeglNode *layer_mask_source_node;
GeglNode *layer_mask_opacity_node;
GeglNode *mask_source_node;
GeglNode *mask_translate_node;
GeglNode *mask_crop_node;
GeglNode *opacity_node;
GeglNode *cache_node;
GeglNode *transform_node;
GimpPickable *node_pickable;
GimpDrawable *node_layer_mask;
GimpDrawable *node_mask;
GeglRectangle node_rect;
gdouble node_opacity;
GimpMatrix3 node_matrix;
GeglNode *node_output;
};
#define GET_PRIVATE(transform_preview) \
......@@ -155,6 +158,13 @@ gimp_canvas_transform_preview_class_init (GimpCanvasTransformPreviewClass *klass
NULL,
GIMP_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_CLIP,
g_param_spec_enum ("clip",
NULL, NULL,
GIMP_TYPE_TRANSFORM_RESIZE,
GIMP_TRANSFORM_RESIZE_ADJUST,
GIMP_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_X1,
g_param_spec_double ("x1",
NULL, NULL,
......@@ -197,6 +207,10 @@ gimp_canvas_transform_preview_class_init (GimpCanvasTransformPreviewClass *klass
static void
gimp_canvas_transform_preview_init (GimpCanvasTransformPreview *transform_preview)
{
GimpCanvasTransformPreviewPrivate *private = GET_PRIVATE (transform_preview);
private->clip = GIMP_TRANSFORM_RESIZE_ADJUST;
private->opacity = 1.0;
}
static void
......@@ -239,6 +253,10 @@ gimp_canvas_transform_preview_set_property (GObject *object,
}
break;
case PROP_CLIP:
private->clip = g_value_get_enum (value);
break;
case PROP_X1:
private->x1 = g_value_get_double (value);
break;
......@@ -283,6 +301,10 @@ gimp_canvas_transform_preview_get_property (GObject *object,
g_value_set_boxed (value, &private->transform);
break;
case PROP_CLIP:
g_value_set_enum (value, private->clip);
break;
case PROP_X1:
g_value_set_double (value, private->x1);
break;
......@@ -314,54 +336,28 @@ gimp_canvas_transform_preview_transform (GimpCanvasItem *item,
cairo_rectangle_int_t *extents)
{
GimpCanvasTransformPreviewPrivate *private = GET_PRIVATE (item);
GimpVector2 vertices[4];
GimpVector2 t_vertices[5];
gint n_t_vertices;
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 };
gimp_transform_polygon (&private->transform, vertices, 4, TRUE,
t_vertices, &n_t_vertices);
if (n_t_vertices < 2)
return FALSE;
if (extents)
gint x1, y1;
gint x2, y2;
gdouble tx1, ty1;
gdouble tx2, ty2;
if (! gimp_transform_resize_boundary (&private->transform,
private->clip,
private->x1, private->y1,
private->x2, private->y2,
&x1, &y1,
&x2, &y2))
{
GimpVector2 top_left;
GimpVector2 bottom_right;
gint i;
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);
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);
return FALSE;
}
bottom_right.x = MAX (bottom_right.x, v.x);
bottom_right.y = MAX (bottom_right.y, v.y);
}
}
gimp_canvas_item_transform_xy_f (item, x1, y1, &tx1, &ty1);
gimp_canvas_item_transform_xy_f (item, x2, y2, &tx2, &ty2);
extents->x = (gint) floor (top_left.x);
extents->y = (gint) floor (top_left.y);
extents->width = (gint) ceil (bottom_right.x) - extents->x;
extents->height = (gint) ceil (bottom_right.y) - extents->y;
}
extents->x = (gint) floor (tx1);
extents->y = (gint) floor (ty1);
extents->width = (gint) ceil (tx2) - extents->x;
extents->height = (gint) ceil (ty2) - extents->y;
return TRUE;
}
......
......@@ -639,6 +639,11 @@ gimp_transform_grid_tool_options_notify (GimpTool *tool,
}
}
}
else if (! strcmp (pspec->name, "clip") ||
! strcmp (pspec->name, "preview-opacity"))
{
gimp_transform_grid_tool_update_preview (tg_tool);
}
else if (g_str_has_prefix (pspec->name, "constrain-") ||
g_str_has_prefix (pspec->name, "frompivot-") ||
! strcmp (pspec->name, "fixedpivot") ||
......@@ -697,11 +702,6 @@ gimp_transform_grid_tool_draw (GimpDrawTool *draw_tool)
gimp_canvas_item_set_visible (tg_tool->preview, show_preview);
g_object_bind_property (G_OBJECT (options), "preview-opacity",
G_OBJECT (tg_tool->preview), "opacity",
G_BINDING_SYNC_CREATE |
G_BINDING_BIDIRECTIONAL);
GIMP_DRAW_TOOL_CLASS (parent_class)->draw (draw_tool);
}
......@@ -781,6 +781,8 @@ gimp_transform_grid_tool_draw (GimpDrawTool *draw_tool)
}
}
}
gimp_transform_grid_tool_update_preview (tg_tool);
}
static void
......@@ -1420,19 +1422,24 @@ gimp_transform_grid_tool_update_sensitivity (GimpTransformGridTool *tg_tool)
static void
gimp_transform_grid_tool_update_preview (GimpTransformGridTool *tg_tool)
{
GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool);
GimpTransformGridOptions *options = GIMP_TRANSFORM_GRID_TOOL_GET_OPTIONS (tg_tool);
GimpTransformTool *tr_tool = GIMP_TRANSFORM_TOOL (tg_tool);
GimpTransformOptions *tr_options = GIMP_TRANSFORM_TOOL_GET_OPTIONS (tg_tool);
GimpTransformGridOptions *tg_options = GIMP_TRANSFORM_GRID_TOOL_GET_OPTIONS (tg_tool);
gint i;
if (tg_tool->preview)
{
gboolean show_preview = gimp_transform_grid_options_show_preview (options) &&
tr_tool->transform_valid;
gboolean show_preview;
show_preview = gimp_transform_grid_options_show_preview (tg_options) &&
tr_tool->transform_valid;
gimp_canvas_item_begin_change (tg_tool->preview);
gimp_canvas_item_set_visible (tg_tool->preview, show_preview);
g_object_set (tg_tool->preview,
"transform", &tr_tool->transform,
"clip", tr_options->clip,
"opacity", tg_options->preview_opacity,
NULL);
gimp_canvas_item_end_change (tg_tool->preview);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment