[gimp] app: preserve projection priority rect across structure/bounds changes



commit 9d80ccc3e66ef1d9367bd1cdc80d7f01b076fe90
Author: Ell <ell_se yahoo com>
Date:   Tue Mar 26 04:54:59 2019 -0400

    app: preserve projection priority rect across structure/bounds changes
    
    In GimpProjection, store the priority rect in image coordinates,
    and only convert it to projectable coordinates when initializing
    the chunk-iterator's priority rect.  This allows us to preserve the
    priority rect across projectable structure/bounds changes.

 app/core/gimpprojection.c | 80 +++++++++++++++++++----------------------------
 1 file changed, 33 insertions(+), 47 deletions(-)
---
diff --git a/app/core/gimpprojection.c b/app/core/gimpprojection.c
index 873393ede7..f74321210c 100644
--- a/app/core/gimpprojection.c
+++ b/app/core/gimpprojection.c
@@ -135,6 +135,7 @@ static void        gimp_projection_add_update_area       (GimpProjection  *proj,
 static void        gimp_projection_flush_whenever        (GimpProjection  *proj,
                                                           gboolean         now,
                                                           gboolean         direct);
+static void        gimp_projection_update_priority_rect  (GimpProjection  *proj);
 static void        gimp_projection_chunk_render_start    (GimpProjection  *proj);
 static void        gimp_projection_chunk_render_stop     (GimpProjection  *proj,
                                                           gboolean         merge);
@@ -505,30 +506,11 @@ gimp_projection_set_priority_rect (GimpProjection *proj,
                                    gint            w,
                                    gint            h)
 {
-  gint off_x, off_y;
-  gint width, height;
-
   g_return_if_fail (GIMP_IS_PROJECTION (proj));
 
-  gimp_projectable_get_offset (proj->priv->projectable, &off_x, &off_y);
-  gimp_projectable_get_size   (proj->priv->projectable, &width, &height);
+  proj->priv->priority_rect = *GEGL_RECTANGLE (x, y, w, h);
 
-  /*  subtract the projectable's offsets because the list of update
-   *  areas is in tile-pyramid coordinates, but our external API is
-   *  always in terms of image coordinates.
-   */
-  x -= off_x;
-  y -= off_y;
-
-  gegl_rectangle_intersect (&proj->priv->priority_rect,
-                            GEGL_RECTANGLE (x, y, w, h),
-                            GEGL_RECTANGLE (0, 0, width, height));
-
-  if (proj->priv->iter)
-    {
-      gimp_chunk_iterator_set_priority_rect (proj->priv->iter,
-                                             &proj->priv->priority_rect);
-    }
+  gimp_projection_update_priority_rect (proj);
 }
 
 void
@@ -707,6 +689,35 @@ gimp_projection_flush_whenever (GimpProjection *proj,
     }
 }
 
+static void
+gimp_projection_update_priority_rect (GimpProjection *proj)
+{
+  if (proj->priv->iter)
+    {
+      GeglRectangle rect;
+      gint          off_x, off_y;
+      gint          width, height;
+
+      rect = proj->priv->priority_rect;
+
+      gimp_projectable_get_offset (proj->priv->projectable, &off_x, &off_y);
+      gimp_projectable_get_size   (proj->priv->projectable, &width, &height);
+
+      /*  subtract the projectable's offsets because the list of update
+       *  areas is in tile-pyramid coordinates, but our external API is
+       *  always in terms of image coordinates.
+       */
+      rect.x -= off_x;
+      rect.y -= off_y;
+
+      gegl_rectangle_intersect (&rect,
+                                &rect,
+                                GEGL_RECTANGLE (0, 0, width, height));
+
+      gimp_chunk_iterator_set_priority_rect (proj->priv->iter, &rect);
+    }
+}
+
 static void
 gimp_projection_chunk_render_start (GimpProjection *proj)
 {
@@ -736,8 +747,7 @@ gimp_projection_chunk_render_start (GimpProjection *proj)
     {
       proj->priv->iter = gimp_chunk_iterator_new (region);
 
-      gimp_chunk_iterator_set_priority_rect (proj->priv->iter,
-                                             &proj->priv->priority_rect);
+      gimp_projection_update_priority_rect (proj);
 
       if (! proj->priv->idle_id)
         {
@@ -955,11 +965,6 @@ gimp_projection_projectable_structure_changed (GimpProjectable *projectable,
   gimp_projectable_get_size (projectable, &width, &height);
 
   gimp_projection_add_update_area (proj, 0, 0, width, height);
-
-  proj->priv->priority_rect.x      = 0;
-  proj->priv->priority_rect.y      = 0;
-  proj->priv->priority_rect.width  = width;
-  proj->priv->priority_rect.height = height;
 }
 
 static void
@@ -1054,25 +1059,6 @@ gimp_projection_projectable_bounds_changed (GimpProjectable *projectable,
       cairo_region_intersect_rectangle (proj->priv->update_region, &bounds);
     }
 
-  if (proj->priv->priority_rect.width  > 0 &&
-      proj->priv->priority_rect.height > 0)
-    {
-      proj->priv->priority_rect.x += dx;
-      proj->priv->priority_rect.y += dy;
-
-      gimp_rectangle_intersect (proj->priv->priority_rect.x,
-                                proj->priv->priority_rect.y,
-                                proj->priv->priority_rect.width,
-                                proj->priv->priority_rect.height,
-
-                                0, 0, w, h,
-
-                                &proj->priv->priority_rect.x,
-                                &proj->priv->priority_rect.y,
-                                &proj->priv->priority_rect.width,
-                                &proj->priv->priority_rect.height);
-    }
-
   if (dx > 0)
     gimp_projection_add_update_area (proj, 0, 0, dx, h);
   if (dy > 0)


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