[gimp] app: clip transform-tools preview according to clipping mode



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]