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



commit e884af8f42a524d46e1276157c157c5bf3e57aa0
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.
    
    (cherry picked from commit 7b2e6b7595ac082504c775f879f7964a1f12c43a)

 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 dffc133274..b32f9f2bad 100644
--- a/app/core/gimp-transform-resize.c
+++ b/app/core/gimp-transform-resize.c
@@ -118,13 +118,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,
@@ -136,17 +136,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 };
@@ -164,11 +164,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)
@@ -188,7 +187,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;
 
@@ -205,6 +204,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 36ad9d5e0a..e4d9c9a9ca 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
@@ -1421,19 +1423,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]