[gimp] Bug 759287 - Canvas Tearing While in Rotated Canvas View



commit 8029508fbef8b2b5b3abd3be8a3fbb7d46654f86
Author: Ell <ell_se yahoo com>
Date:   Sat Dec 9 04:25:35 2017 -0500

    Bug 759287 - Canvas Tearing While in Rotated Canvas View
    
    Based on a patch by Massimo.
    
    Move the entire image-space/screen-space transformation logic from
    gimp_display_shell_render() to gimp_display_shell_draw_image(), so
    that the former works entirely in image space, and do the chunking
    and clipping in screen-space, making sure that image-space chunks
    are never larger than
    GIMP_DISPLAY_RENDER_BUF_WIDTH x GIMP_DISPLAY_RENDER_BUF_HEIGHT,
    even when the window's scale factor is greater than 1.
    
    Add a GIMP_BRICK_WALL environment variable, which, when set, shows
    the screen-space chunk bounds.

 app/display/gimpdisplayshell-callbacks.c |    4 +
 app/display/gimpdisplayshell-draw.c      |  145 +++++++++++++--------
 app/display/gimpdisplayshell-render.c    |  212 +++++++-----------------------
 app/display/gimpdisplayshell-render.h    |    3 +-
 4 files changed, 140 insertions(+), 224 deletions(-)
---
diff --git a/app/display/gimpdisplayshell-callbacks.c b/app/display/gimpdisplayshell-callbacks.c
index 7cd1f0c..1e11b2e 100644
--- a/app/display/gimpdisplayshell-callbacks.c
+++ b/app/display/gimpdisplayshell-callbacks.c
@@ -418,6 +418,7 @@ gimp_display_shell_canvas_draw_image (GimpDisplayShell *shell,
 {
   cairo_rectangle_list_t *clip_rectangles;
   cairo_rectangle_int_t   image_rect;
+  cairo_matrix_t          matrix;
 
   image_rect.x = - shell->offset_x;
   image_rect.y = - shell->offset_y;
@@ -456,6 +457,7 @@ gimp_display_shell_canvas_draw_image (GimpDisplayShell *shell,
 
   cairo_save (cr);
   clip_rectangles = cairo_copy_clip_rectangle_list (cr);
+  cairo_get_matrix (cr, &matrix);
 
   if (shell->rotate_transform)
     cairo_transform (cr, shell->rotate_transform);
@@ -475,6 +477,8 @@ gimp_display_shell_canvas_draw_image (GimpDisplayShell *shell,
       gimp_display_shell_draw_checkerboard (shell, cr);
       cairo_restore (cr);
 
+      cairo_set_matrix (cr, &matrix);
+
       for (i = 0; i < clip_rectangles->num_rectangles; i++)
         {
           cairo_rectangle_t rect = clip_rectangles->rectangles[i];
diff --git a/app/display/gimpdisplayshell-draw.c b/app/display/gimpdisplayshell-draw.c
index 9d0da93..819517a 100644
--- a/app/display/gimpdisplayshell-draw.c
+++ b/app/display/gimpdisplayshell-draw.c
@@ -42,6 +42,9 @@
 #include "gimpdisplayxfer.h"
 
 
+/* #define GIMP_DISPLAY_RENDER_ENABLE_SCALING 1 */
+
+
 /*  public functions  */
 
 void
@@ -137,77 +140,107 @@ gimp_display_shell_draw_image (GimpDisplayShell *shell,
                                gint              w,
                                gint              h)
 {
-  gint x1, y1, x2, y2;
-  gint i, j;
-  gint chunk_width;
-  gint chunk_height;
+  gdouble chunk_width;
+  gdouble chunk_height;
+  gdouble scale = 1.0;
+  gint    n_rows;
+  gint    n_cols;
+  gint    r, c;
 
   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
   g_return_if_fail (gimp_display_get_image (shell->display));
   g_return_if_fail (cr != NULL);
 
-  if (shell->rotate_untransform)
-    {
-      gdouble tx1, ty1;
-      gdouble tx2, ty2;
-      gint    image_width;
-      gint    image_height;
-
-      gimp_display_shell_unrotate_bounds (shell,
-                                          x, y, x + w, y + h,
-                                          &tx1, &ty1, &tx2, &ty2);
-
-      x1 = floor (tx1 - 0.5);
-      y1 = floor (ty1 - 0.5);
-      x2 = ceil (tx2 + 0.5);
-      y2 = ceil (ty2 + 0.5);
-
-      gimp_display_shell_scale_get_image_size (shell,
-                                               &image_width, &image_height);
-
-      x1 = CLAMP (x1, -shell->offset_x, -shell->offset_x + image_width);
-      y1 = CLAMP (y1, -shell->offset_y, -shell->offset_y + image_height);
-      x2 = CLAMP (x2, -shell->offset_x, -shell->offset_x + image_width);
-      y2 = CLAMP (y2, -shell->offset_y, -shell->offset_y + image_height);
-
-      if (!(x2 > x1) || !(y2 > y1))
-        return;
-    }
-  else
-    {
-      x1 = x;
-      y1 = y;
-      x2 = x + w;
-      y2 = y + h;
-    }
-
   /*  display the image in RENDER_BUF_WIDTH x RENDER_BUF_HEIGHT
-   *  sized chunks
+   *  maximally-sized image-space chunks.  adjust the screen-space
+   *  chunk size as necessary, to accommodate for the display
+   *  transform and window scale factor.
    */
   chunk_width  = GIMP_DISPLAY_RENDER_BUF_WIDTH;
   chunk_height = GIMP_DISPLAY_RENDER_BUF_HEIGHT;
 
-  if ((shell->scale_x / shell->scale_y) > 2.0)
-    {
-      while ((chunk_width / chunk_height) < (shell->scale_x / shell->scale_y))
-        chunk_height /= 2;
-    }
-  else if ((shell->scale_y / shell->scale_x) > 2.0)
+#ifdef GIMP_DISPLAY_RENDER_ENABLE_SCALING
+  /* if we had this future API, things would look pretty on hires (retina) */
+  scale *=
+    gdk_window_get_scale_factor (
+      gtk_widget_get_window (gtk_widget_get_toplevel (GTK_WIDGET (shell))));
+#endif
+
+  scale = MIN (scale, GIMP_DISPLAY_RENDER_MAX_SCALE);
+
+  scale        *= MAX (shell->scale_x, shell->scale_y);
+  chunk_width  *= shell->scale_x / scale;
+  chunk_height *= shell->scale_y / scale;
+
+  if (shell->rotate_untransform)
     {
-      while ((chunk_height / chunk_width) < (shell->scale_y / shell->scale_x))
-        chunk_width /= 2;
+      gdouble a = shell->rotate_angle * G_PI / 180.0;
+
+      chunk_width = chunk_height = MIN (chunk_width, chunk_height)   /
+                                   (fabs (sin (a)) + fabs (cos (a)));
     }
 
-  for (i = y1; i < y2; i += chunk_height)
-    {
-      for (j = x1; j < x2; j += chunk_width)
-        {
-          gint dx, dy;
+  /* divide the painted area to evenly-sized chunks */
+  n_rows = ceil (h / chunk_height);
+  n_cols = ceil (w / chunk_width);
 
-          dx = MIN (x2 - j, chunk_width);
-          dy = MIN (y2 - i, chunk_height);
+  for (r = 0; r < n_rows; r++)
+    {
+      gint y1 = y + (2 *  r      * h + n_rows) / (2 * n_rows);
+      gint y2 = y + (2 * (r + 1) * h + n_rows) / (2 * n_rows);
 
-          gimp_display_shell_render (shell, cr, j, i, dx, dy);
+      for (c = 0; c < n_cols; c++)
+        {
+          gint    x1 = x + (2 *  c      * w + n_cols) / (2 * n_cols);
+          gint    x2 = x + (2 * (c + 1) * w + n_cols) / (2 * n_cols);
+          gdouble ix1, iy1;
+          gdouble ix2, iy2;
+          gint    ix, iy;
+          gint    iw, ih;
+
+          /* map chunk from screen space to image space */
+          gimp_display_shell_untransform_bounds (shell,
+                                                 x1,   y1,   x2,   y2,
+                                                 &ix1, &iy1, &ix2, &iy2);
+
+          ix = floor (ix1 * scale);
+          iy = floor (iy1 * scale);
+          iw = ceil  (ix2 * scale) - ix;
+          ih = ceil  (iy2 * scale) - iy;
+
+          cairo_save (cr);
+
+          /* clip to chunk bounds, in screen space */
+          cairo_rectangle (cr, x1, y1, x2 - x1, y2 - y1);
+          cairo_clip (cr);
+
+          /* transform to image space, and apply uneven scaling */
+          if (shell->rotate_transform)
+            cairo_transform (cr, shell->rotate_transform);
+          cairo_translate (cr, -shell->offset_x, -shell->offset_y);
+          cairo_scale (cr, shell->scale_x / scale, shell->scale_y / scale);
+
+          /* render image */
+          gimp_display_shell_render (shell, cr, ix, iy, iw, ih, scale);
+
+          cairo_restore (cr);
+
+          /* if the GIMP_BRICK_WALL environment variable is defined,
+           * show chunk bounds
+           */
+          {
+            static gint brick_wall = -1;
+
+            if (brick_wall < 0)
+              brick_wall = (g_getenv ("GIMP_BRICK_WALL") != NULL);
+
+            if (brick_wall)
+              {
+                cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+                cairo_rectangle (cr, x1, y1, x2 - x1, y2 - y1);
+                cairo_stroke (cr);
+              }
+          }
         }
     }
 }
diff --git a/app/display/gimpdisplayshell-render.c b/app/display/gimpdisplayshell-render.c
index 21f0cc1..8032087 100644
--- a/app/display/gimpdisplayshell-render.c
+++ b/app/display/gimpdisplayshell-render.c
@@ -45,33 +45,20 @@
 #include "gimpdisplayxfer.h"
 
 
-/* #define GIMP_DISPLAY_RENDER_ENABLE_SCALING 1 */
-
-
 void
 gimp_display_shell_render (GimpDisplayShell *shell,
                            cairo_t          *cr,
                            gint              x,
                            gint              y,
                            gint              w,
-                           gint              h)
+                           gint              h,
+                           gdouble           scale)
 {
   GimpImage       *image;
   GeglBuffer      *buffer;
 #ifdef USE_NODE_BLIT
   GeglNode        *node;
 #endif
-  gdouble          scale_x       = 1.0;
-  gdouble          scale_y       = 1.0;
-  gdouble          buffer_scale  = 1.0;
-  gint             viewport_offset_x;
-  gint             viewport_offset_y;
-  gint             viewport_width;
-  gint             viewport_height;
-  gint             scaled_x;
-  gint             scaled_y;
-  gint             scaled_width;
-  gint             scaled_height;
   cairo_surface_t *xfer;
   gint             xfer_src_x;
   gint             xfer_src_y;
@@ -83,7 +70,9 @@ gimp_display_shell_render (GimpDisplayShell *shell,
 
   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
   g_return_if_fail (cr != NULL);
-  g_return_if_fail (w > 0 && h > 0);
+  g_return_if_fail (w > 0 && w <= GIMP_DISPLAY_RENDER_BUF_WIDTH);
+  g_return_if_fail (h > 0 && h <= GIMP_DISPLAY_RENDER_BUF_HEIGHT);
+  g_return_if_fail (scale > 0.0);
 
   image  = gimp_display_get_image (shell->display);
   buffer = gimp_pickable_get_buffer (GIMP_PICKABLE (image));
@@ -93,60 +82,8 @@ gimp_display_shell_render (GimpDisplayShell *shell,
   gimp_projectable_begin_render (GIMP_PROJECTABLE (image));
 #endif
 
-#ifdef GIMP_DISPLAY_RENDER_ENABLE_SCALING
-  /* if we had this future API, things would look pretty on hires (retina) */
-  scale_x = gdk_window_get_scale_factor (gtk_widget_get_window (gtk_widget_get_toplevel (GTK_WIDGET 
(shell))));
-#endif
-
-  scale_x = MIN (scale_x, GIMP_DISPLAY_RENDER_MAX_SCALE);
-  scale_y = scale_x;
-
-  if (shell->scale_x > shell->scale_y)
-    {
-      scale_y *= (shell->scale_x / shell->scale_y);
-
-      buffer_scale = shell->scale_y * scale_y;
-    }
-  else if (shell->scale_y > shell->scale_x)
-    {
-      scale_x *= (shell->scale_y / shell->scale_x);
-
-      buffer_scale = shell->scale_x * scale_x;
-    }
-  else
-    {
-      buffer_scale = shell->scale_x * scale_x;
-    }
-
-  gimp_display_shell_scroll_get_scaled_viewport (shell,
-                                                 &viewport_offset_x,
-                                                 &viewport_offset_y,
-                                                 &viewport_width,
-                                                 &viewport_height);
-
-  scaled_x      = floor ((x + viewport_offset_x) * scale_x);
-  scaled_y      = floor ((y + viewport_offset_y) * scale_y);
-  scaled_width  = ceil (w * scale_x);
-  scaled_height = ceil (h * scale_y);
-
-  if (shell->rotate_transform)
-    {
-      xfer = cairo_surface_create_similar_image (cairo_get_target (cr),
-                                                 CAIRO_FORMAT_ARGB32,
-                                                 scaled_width,
-                                                 scaled_height);
-      cairo_surface_mark_dirty (xfer);
-      xfer_src_x = 0;
-      xfer_src_y = 0;
-    }
-  else
-    {
-      xfer = gimp_display_xfer_get_surface (shell->xfer,
-                                            scaled_width,
-                                            scaled_height,
-                                            &xfer_src_x,
-                                            &xfer_src_y);
-    }
+  xfer = gimp_display_xfer_get_surface (shell->xfer, w, h,
+                                        &xfer_src_x, &xfer_src_y);
 
   cairo_stride = cairo_image_surface_get_stride (xfer);
   cairo_data   = cairo_image_surface_get_data (xfer) +
@@ -154,9 +91,7 @@ gimp_display_shell_render (GimpDisplayShell *shell,
 
   cairo_buffer = gegl_buffer_linear_new_from_data (cairo_data,
                                                    babl_format ("cairo-ARGB32"),
-                                                   GEGL_RECTANGLE (0, 0,
-                                                                   scaled_width,
-                                                                   scaled_height),
+                                                   GEGL_RECTANGLE (0, 0, w, h),
                                                    cairo_stride,
                                                    NULL, NULL);
 
@@ -177,19 +112,20 @@ gimp_display_shell_render (GimpDisplayShell *shell,
       if ((gimp_display_shell_has_filter (shell) || ! can_convert_to_u8) &&
           ! shell->filter_buffer)
         {
-          gint w = GIMP_DISPLAY_RENDER_BUF_WIDTH  * GIMP_DISPLAY_RENDER_MAX_SCALE;
-          gint h = GIMP_DISPLAY_RENDER_BUF_HEIGHT * GIMP_DISPLAY_RENDER_MAX_SCALE;
+          gint fw = GIMP_DISPLAY_RENDER_BUF_WIDTH;
+          gint fh = GIMP_DISPLAY_RENDER_BUF_HEIGHT;
 
           shell->filter_data =
-            gegl_malloc (w * h * babl_format_get_bytes_per_pixel (shell->filter_format));
+            gegl_malloc (fw * fh *
+                         babl_format_get_bytes_per_pixel (shell->filter_format));
 
           shell->filter_stride =
-            w * babl_format_get_bytes_per_pixel (shell->filter_format);
+            fw * babl_format_get_bytes_per_pixel (shell->filter_format);
 
           shell->filter_buffer =
             gegl_buffer_linear_new_from_data (shell->filter_data,
                                               shell->filter_format,
-                                              GEGL_RECTANGLE (0, 0, w, h),
+                                              GEGL_RECTANGLE (0, 0, fw, fh),
                                               GEGL_AUTO_ROWSTRIDE,
                                               (GDestroyNotify) gegl_free,
                                               shell->filter_data);
@@ -202,17 +138,13 @@ gimp_display_shell_render (GimpDisplayShell *shell,
            */
 #ifndef USE_NODE_BLIT
           gegl_buffer_get (buffer,
-                           GEGL_RECTANGLE (scaled_x, scaled_y,
-                                           scaled_width, scaled_height),
-                           buffer_scale,
+                           GEGL_RECTANGLE (x, y, w, h), scale,
                            gimp_projectable_get_format (GIMP_PROJECTABLE (image)),
                            shell->profile_data, shell->profile_stride,
                            GEGL_ABYSS_CLAMP);
 #else
           gegl_node_blit (node,
-                          buffer_scale,
-                          GEGL_RECTANGLE (scaled_x, scaled_y,
-                                          scaled_width, scaled_height),
+                          scale, GEGL_RECTANGLE (x, y, w, h),
                           gimp_projectable_get_format (GIMP_PROJECTABLE (image)),
                           shell->profile_data, shell->profile_stride,
                           GEGL_BLIT_CACHE);
@@ -224,17 +156,13 @@ gimp_display_shell_render (GimpDisplayShell *shell,
            */
 #ifndef USE_NODE_BLIT
           gegl_buffer_get (buffer,
-                           GEGL_RECTANGLE (scaled_x, scaled_y,
-                                           scaled_width, scaled_height),
-                           buffer_scale,
+                           GEGL_RECTANGLE (x, y, w, h), scale,
                            shell->filter_format,
                            shell->filter_data, shell->filter_stride,
                            GEGL_ABYSS_CLAMP);
 #else
           gegl_node_blit (node,
-                          buffer_scale,
-                          GEGL_RECTANGLE (scaled_x, scaled_y,
-                                          scaled_width, scaled_height),
+                          scale, GEGL_RECTANGLE (x, y, w, h),
                           shell->filter_format,
                           shell->filter_data, shell->filter_stride,
                           GEGL_BLIT_CACHE);
@@ -248,13 +176,9 @@ gimp_display_shell_render (GimpDisplayShell *shell,
         {
           gimp_color_transform_process_buffer (shell->filter_transform,
                                                shell->profile_buffer,
-                                               GEGL_RECTANGLE (0, 0,
-                                                               scaled_width,
-                                                               scaled_height),
+                                               GEGL_RECTANGLE (0, 0, w, h),
                                                shell->filter_buffer,
-                                               GEGL_RECTANGLE (0, 0,
-                                                               scaled_width,
-                                                               scaled_height));
+                                               GEGL_RECTANGLE (0, 0, w, h));
         }
 
       /*  if there are filters, apply them
@@ -269,17 +193,15 @@ gimp_display_shell_render (GimpDisplayShell *shell,
            */
           filter_buffer = g_object_new (GEGL_TYPE_BUFFER,
                                         "source", shell->filter_buffer,
-                                        "shift-x", -scaled_x,
-                                        "shift-y", -scaled_y,
+                                        "shift-x", -x,
+                                        "shift-y", -y,
                                         NULL);
 
           /*  convert the filter_buffer in place
            */
           gimp_color_display_stack_convert_buffer (shell->filter_stack,
                                                    filter_buffer,
-                                                   GEGL_RECTANGLE (scaled_x, scaled_y,
-                                                                   scaled_width,
-                                                                   scaled_height));
+                                                   GEGL_RECTANGLE (x, y, w, h));
 
           g_object_unref (filter_buffer);
         }
@@ -295,13 +217,9 @@ gimp_display_shell_render (GimpDisplayShell *shell,
                */
               gimp_color_transform_process_buffer (shell->profile_transform,
                                                    shell->filter_buffer,
-                                                   GEGL_RECTANGLE (0, 0,
-                                                                   scaled_width,
-                                                                   scaled_height),
+                                                   GEGL_RECTANGLE (0, 0, w, h),
                                                    shell->filter_buffer,
-                                                   GEGL_RECTANGLE (0, 0,
-                                                                   scaled_width,
-                                                                   scaled_height));
+                                                   GEGL_RECTANGLE (0, 0, w, h));
             }
           else if (! can_convert_to_u8)
             {
@@ -310,13 +228,9 @@ gimp_display_shell_render (GimpDisplayShell *shell,
                */
               gimp_color_transform_process_buffer (shell->profile_transform,
                                                    shell->profile_buffer,
-                                                   GEGL_RECTANGLE (0, 0,
-                                                                   scaled_width,
-                                                                   scaled_height),
+                                                   GEGL_RECTANGLE (0, 0, w, h),
                                                    shell->filter_buffer,
-                                                   GEGL_RECTANGLE (0, 0,
-                                                                   scaled_width,
-                                                                   scaled_height));
+                                                   GEGL_RECTANGLE (0, 0, w, h));
             }
           else
             {
@@ -325,13 +239,9 @@ gimp_display_shell_render (GimpDisplayShell *shell,
                */
               gimp_color_transform_process_buffer (shell->profile_transform,
                                                    shell->profile_buffer,
-                                                   GEGL_RECTANGLE (0, 0,
-                                                                   scaled_width,
-                                                                   scaled_height),
+                                                   GEGL_RECTANGLE (0, 0, w, h),
                                                    cairo_buffer,
-                                                   GEGL_RECTANGLE (0, 0,
-                                                                   scaled_width,
-                                                                   scaled_height));
+                                                   GEGL_RECTANGLE (0, 0, w, h));
             }
         }
 
@@ -341,10 +251,7 @@ gimp_display_shell_render (GimpDisplayShell *shell,
       if (gimp_display_shell_has_filter (shell) || ! can_convert_to_u8)
         {
           gegl_buffer_get (shell->filter_buffer,
-                           GEGL_RECTANGLE (0, 0,
-                                           scaled_width,
-                                           scaled_height),
-                           1.0,
+                           GEGL_RECTANGLE (0, 0, w, h), 1.0,
                            babl_format ("cairo-ARGB32"),
                            cairo_data, cairo_stride,
                            GEGL_ABYSS_CLAMP);
@@ -357,17 +264,13 @@ gimp_display_shell_render (GimpDisplayShell *shell,
        */
 #ifndef USE_NODE_BLIT
       gegl_buffer_get (buffer,
-                       GEGL_RECTANGLE (scaled_x, scaled_y,
-                                       scaled_width, scaled_height),
-                       buffer_scale,
+                       GEGL_RECTANGLE (x, y, w, h), scale,
                        babl_format ("cairo-ARGB32"),
                        cairo_data, cairo_stride,
                        GEGL_ABYSS_CLAMP);
 #else
       gegl_node_blit (node,
-                      buffer_scale,
-                      GEGL_RECTANGLE (scaled_x, scaled_y,
-                                      scaled_width, scaled_height),
+                      scale, GEGL_RECTANGLE (x, y, w, h),
                       babl_format ("cairo-ARGB32"),
                       cairo_data, cairo_stride,
                       GEGL_BLIT_CACHE);
@@ -386,34 +289,32 @@ gimp_display_shell_render (GimpDisplayShell *shell,
         {
           shell->mask_surface =
             cairo_image_surface_create (CAIRO_FORMAT_A8,
-                                        GIMP_DISPLAY_RENDER_BUF_WIDTH  *
-                                        GIMP_DISPLAY_RENDER_MAX_SCALE,
-                                        GIMP_DISPLAY_RENDER_BUF_HEIGHT *
-                                        GIMP_DISPLAY_RENDER_MAX_SCALE);
+                                        GIMP_DISPLAY_RENDER_BUF_WIDTH,
+                                        GIMP_DISPLAY_RENDER_BUF_HEIGHT);
         }
 
       cairo_surface_mark_dirty (shell->mask_surface);
 
       cairo_stride = cairo_image_surface_get_stride (shell->mask_surface);
       cairo_data   = cairo_image_surface_get_data (shell->mask_surface) +
-                     mask_src_y * cairo_stride + mask_src_x * 4;
+                     mask_src_y * cairo_stride + mask_src_x;
 
       gegl_buffer_get (shell->mask,
-                       GEGL_RECTANGLE (scaled_x - shell->mask_offset_x,
-                                       scaled_y - shell->mask_offset_y,
-                                       scaled_width, scaled_height),
-                       buffer_scale,
+                       GEGL_RECTANGLE (x - shell->mask_offset_x,
+                                       y - shell->mask_offset_y,
+                                       w, h),
+                       scale,
                        babl_format ("Y u8"),
                        cairo_data, cairo_stride,
                        GEGL_ABYSS_NONE);
 
       if (shell->mask_inverted)
         {
-          gint mask_height = scaled_height;
+          gint mask_height = h;
 
           while (mask_height--)
             {
-              gint    mask_width = scaled_width;
+              gint    mask_width = w;
               guchar *d          = cairo_data;
 
               while (mask_width--)
@@ -429,39 +330,16 @@ gimp_display_shell_render (GimpDisplayShell *shell,
     }
 
   /*  put it to the screen  */
-  cairo_save (cr);
-
-  cairo_rectangle (cr, x, y, w, h);
-
-  cairo_scale (cr, 1.0 / scale_x, 1.0 / scale_y);
-
   cairo_set_source_surface (cr, xfer,
-                            x * scale_x - xfer_src_x,
-                            y * scale_y - xfer_src_y);
-
-  if (shell->rotate_transform)
-    {
-      cairo_pattern_t *pattern;
-
-      pattern = cairo_get_source (cr);
-      cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
-
-      cairo_set_line_width (cr, 1.0);
-      cairo_stroke_preserve (cr);
-
-      cairo_surface_destroy (xfer);
-    }
-
-  cairo_clip (cr);
+                            x - xfer_src_x,
+                            y - xfer_src_y);
   cairo_paint (cr);
 
   if (shell->mask)
     {
       gimp_cairo_set_source_rgba (cr, &shell->mask_color);
       cairo_mask_surface (cr, shell->mask_surface,
-                          (x - mask_src_x) * scale_x,
-                          (y - mask_src_y) * scale_y);
+                          x - mask_src_x,
+                          y - mask_src_y);
     }
-
-  cairo_restore (cr);
 }
diff --git a/app/display/gimpdisplayshell-render.h b/app/display/gimpdisplayshell-render.h
index a84bc21..bc28cef 100644
--- a/app/display/gimpdisplayshell-render.h
+++ b/app/display/gimpdisplayshell-render.h
@@ -23,6 +23,7 @@ void  gimp_display_shell_render (GimpDisplayShell *shell,
                                  gint              x,
                                  gint              y,
                                  gint              w,
-                                 gint              h);
+                                 gint              h,
+                                 gdouble           scale);
 
 #endif  /*  __GIMP_DISPLAY_SHELL_RENDER_H__  */


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