[gimp] app: clip transform-tools preview according to clipping mode
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: clip transform-tools preview according to clipping mode
- Date: Sat, 11 Jan 2020 15:15:03 +0000 (UTC)
commit 7b2e6b7595ac082504c775f879f7964a1f12c43a
Author: Ell <ell_se yahoo com>
Date: Sat Jan 11 17:10:25 2020 +0200
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.
app/core/gimp-transform-resize.c | 29 +++----
app/core/gimp-transform-resize.h | 20 ++---
app/display/gimpcanvastransformpreview.c | 136 +++++++++++++++----------------
app/tools/gimptransformgridtool.c | 25 ++++--
4 files changed, 107 insertions(+), 103 deletions(-)
---
diff --git a/app/core/gimp-transform-resize.c b/app/core/gimp-transform-resize.c
index b5a7880299..4594195219 100644
--- a/app/core/gimp-transform-resize.c
+++ b/app/core/gimp-transform-resize.c
@@ -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
diff --git a/app/core/gimp-transform-resize.h b/app/core/gimp-transform-resize.h
index 407bdd392a..4ebb53f0ed 100644
--- a/app/core/gimp-transform-resize.h
+++ b/app/core/gimp-transform-resize.h
@@ -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__ */
diff --git a/app/display/gimpcanvastransformpreview.c b/app/display/gimpcanvastransformpreview.c
index bf336ed0a4..8c8d9505e2 100644
--- a/app/display/gimpcanvastransformpreview.c
+++ b/app/display/gimpcanvastransformpreview.c
@@ -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;
}
diff --git a/app/tools/gimptransformgridtool.c b/app/tools/gimptransformgridtool.c
index d7f745dc1e..698014324d 100644
--- a/app/tools/gimptransformgridtool.c
+++ b/app/tools/gimptransformgridtool.c
@@ -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);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]