[gimp/gimp-2-10] Issue #1646 - Transform preview looks wrong with selection



commit 32993ab12d21ca7ed8cd79e4f5117b00c69b2c45
Author: Ell <ell_se yahoo com>
Date:   Fri Jun 15 01:52:44 2018 -0400

    Issue #1646 - Transform preview looks wrong with selection
    
    In GimpCanvasTransformPreview, when the image mask is not empty,
    make sure to align it with the drawable using a gegl:translate
    node, before combining both at the gegl:opacity node.  Otherwise,
    the mask is applied at the wrong offset when the drawable's offset
    is not (0, 0).
    
    (cherry picked from commit d3a3c35317381dd1294dc8e4d6c77439e72e33d7)

 app/display/gimpcanvastransformpreview.c | 90 ++++++++++++++++++++++++--------
 1 file changed, 68 insertions(+), 22 deletions(-)
---
diff --git a/app/display/gimpcanvastransformpreview.c b/app/display/gimpcanvastransformpreview.c
index 65d008e7dd..90b7b47957 100644
--- a/app/display/gimpcanvastransformpreview.c
+++ b/app/display/gimpcanvastransformpreview.c
@@ -61,23 +61,27 @@ typedef struct _GimpCanvasTransformPreviewPrivate GimpCanvasTransformPreviewPriv
 
 struct _GimpCanvasTransformPreviewPrivate
 {
-  GimpDrawable *drawable;
-  GimpMatrix3   transform;
-  gdouble       x1, y1;
-  gdouble       x2, y2;
-  gdouble       opacity;
-
-  GeglNode     *node;
-  GeglNode     *source_node;
-  GeglNode     *convert_format_node;
-  GeglNode     *mask_source_node;
-  GeglNode     *opacity_node;
-  GeglNode     *cache_node;
-  GeglNode     *transform_node;
-  GimpDrawable *node_drawable;
-  GimpDrawable *node_mask;
-  gdouble       node_opacity;
-  GimpMatrix3   node_matrix;
+  GimpDrawable  *drawable;
+  GimpMatrix3    transform;
+  gdouble        x1, y1;
+  gdouble        x2, y2;
+  gdouble        opacity;
+
+  GeglNode      *node;
+  GeglNode      *source_node;
+  GeglNode      *convert_format_node;
+  GeglNode      *mask_source_node;
+  GeglNode      *mask_translate_node;
+  GeglNode      *mask_crop_node;
+  GeglNode      *opacity_node;
+  GeglNode      *cache_node;
+  GeglNode      *transform_node;
+
+  GimpDrawable  *node_drawable;
+  GimpDrawable  *node_mask;
+  GeglRectangle  node_rect;
+  gdouble        node_opacity;
+  GimpMatrix3    node_matrix;
 };
 
 #define GET_PRIVATE(transform_preview) \
@@ -451,6 +455,18 @@ gimp_canvas_transform_preview_sync_node (GimpCanvasItem *item)
                              "operation", "gimp:buffer-source-validate",
                              NULL);
 
+      private->mask_translate_node =
+        gegl_node_new_child (private->node,
+                             "operation", "gegl:translate",
+                             NULL);
+
+      private->mask_crop_node =
+        gegl_node_new_child (private->node,
+                             "operation", "gegl:crop",
+                             "width",     0.0,
+                             "height",    0.0,
+                             NULL);
+
       private->opacity_node =
         gegl_node_new_child (private->node,
                              "operation", "gegl:opacity",
@@ -473,8 +489,14 @@ gimp_canvas_transform_preview_sync_node (GimpCanvasItem *item)
                            private->transform_node,
                            NULL);
 
+      gegl_node_link_many (private->mask_source_node,
+                           private->mask_translate_node,
+                           private->mask_crop_node,
+                           NULL);
+
       private->node_drawable = NULL;
       private->node_mask     = NULL;
+      private->node_rect     = *GEGL_RECTANGLE (0, 0, 0, 0);
       private->node_opacity  = 1.0;
       gimp_matrix3_identity (&private->node_matrix);
     }
@@ -527,19 +549,43 @@ gimp_canvas_transform_preview_sync_node (GimpCanvasItem *item)
 
   if (has_mask)
     {
-      GimpDrawable *mask = GIMP_DRAWABLE (gimp_image_get_mask (image));
+      GimpDrawable  *mask = GIMP_DRAWABLE (gimp_image_get_mask (image));
+      GeglRectangle  rect;
+
+      rect.x      = offset_x;
+      rect.y      = offset_y;
+      rect.width  = gimp_item_get_width  (GIMP_ITEM (private->drawable));
+      rect.height = gimp_item_get_height (GIMP_ITEM (private->drawable));
 
       if (mask != private->node_mask)
         {
-          private->node_mask = mask;
-
           gegl_node_set (private->mask_source_node,
                          "buffer", gimp_drawable_get_buffer (mask),
                          NULL);
+        }
+
+      if (! gegl_rectangle_equal (&rect, &private->node_rect))
+        {
+          private->node_rect = rect;
+
+          gegl_node_set (private->mask_translate_node,
+                         "x", (gdouble) -rect.x,
+                         "y", (gdouble) -rect.y,
+                         NULL);
 
-          gegl_node_connect_to (private->mask_source_node, "output",
-                                private->opacity_node,     "aux");
+          gegl_node_set (private->mask_crop_node,
+                         "width",  (gdouble) rect.width,
+                         "height", (gdouble) rect.height,
+                         NULL);
         }
+
+      if (! private->node_mask)
+        {
+          gegl_node_connect_to (private->mask_crop_node, "output",
+                                private->opacity_node,   "aux");
+        }
+
+      private->node_mask = mask;
     }
   else if (private->node_mask)
     {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]