[gimp] Bug 690325 - Image Display broken: a rectangle undrawn to the top left



commit 06968d9bf993dde529b4bef679c9711c01ac323e
Author: Michael Natterer <mitch gimp org>
Date:   Sat Mar 30 17:44:59 2013 +0100

    Bug 690325 - Image Display broken: a rectangle undrawn to the top left
    
    Let GimpTileHandlerProjection know how large the projection is so it
    can calculate the number of levels in the pyramid, and always
    invalidate all levels.

 app/core/gimpprojection.c            |    3 +-
 app/gegl/gimptilehandlerprojection.c |   53 +++++++++++++++++++++------------
 app/gegl/gimptilehandlerprojection.h |    6 +++-
 3 files changed, 41 insertions(+), 21 deletions(-)
---
diff --git a/app/core/gimpprojection.c b/app/core/gimpprojection.c
index 2e55392..ca60885 100644
--- a/app/core/gimpprojection.c
+++ b/app/core/gimpprojection.c
@@ -281,7 +281,8 @@ gimp_projection_get_buffer (GimpPickable *pickable)
       proj->buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0, width, height),
                                       format);
 
-      proj->validate_handler = gimp_tile_handler_projection_new (graph);
+      proj->validate_handler = gimp_tile_handler_projection_new (graph,
+                                                                 width, height);
       gegl_buffer_add_handler (proj->buffer, proj->validate_handler);
 
       /*  This used to call gimp_tile_handler_projection_invalidate()
diff --git a/app/gegl/gimptilehandlerprojection.c b/app/gegl/gimptilehandlerprojection.c
index 13e79af..07eac37 100644
--- a/app/gegl/gimptilehandlerprojection.c
+++ b/app/gegl/gimptilehandlerprojection.c
@@ -265,7 +265,9 @@ gimp_tile_handler_projection_command (GeglTileSource  *source,
 }
 
 GeglTileHandler *
-gimp_tile_handler_projection_new (GeglNode *graph)
+gimp_tile_handler_projection_new (GeglNode *graph,
+                                  gint      proj_width,
+                                  gint      proj_height)
 {
   GimpTileHandlerProjection *projection;
 
@@ -273,7 +275,9 @@ gimp_tile_handler_projection_new (GeglNode *graph)
 
   projection = g_object_new (GIMP_TYPE_TILE_HANDLER_PROJECTION, NULL);
 
-  projection->graph = g_object_ref (graph);
+  projection->graph       = g_object_ref (graph);
+  projection->proj_width  = proj_width;
+  projection->proj_height = proj_height;
 
   return GEGL_TILE_HANDLER (projection);
 }
@@ -282,12 +286,14 @@ static void
 gimp_tile_handler_projection_void_pyramid (GeglTileSource *source,
                                            gint            x,
                                            gint            y,
-                                           gint            z)
+                                           gint            z,
+                                           gint            max_z)
 {
   gegl_tile_source_void (source, x, y, z);
 
-  if (x / 2 != x || y / 2 != y)
-    gimp_tile_handler_projection_void_pyramid (source, x / 2, y / 2, z + 1);
+  if (z < max_z)
+    gimp_tile_handler_projection_void_pyramid (source, x / 2, y / 2, z + 1,
+                                               max_z);
 }
 
 void
@@ -298,28 +304,37 @@ gimp_tile_handler_projection_invalidate (GimpTileHandlerProjection *projection,
                                          gint                       height)
 {
   cairo_rectangle_int_t rect = { x, y, width, height };
-  gint                  tile_x1;
-  gint                  tile_y1;
-  gint                  tile_x2;
-  gint                  tile_y2;
-  gint                  tile_x;
-  gint                  tile_y;
+  gint                  n_tiles;
+  gint                  max_z = 0;
 
   g_return_if_fail (GIMP_IS_TILE_HANDLER_PROJECTION (projection));
 
   cairo_region_union_rectangle (projection->dirty_region, &rect);
 
-  tile_x1 = x / projection->tile_width;
-  tile_y1 = y / projection->tile_height;
-  tile_x2 = (x + width  - 1) / projection->tile_width;
-  tile_y2 = (y + height - 1) / projection->tile_height;
+  n_tiles = MAX (projection->proj_width  / projection->tile_width,
+                 projection->proj_height / projection->tile_height) + 1;
 
-  for (tile_y = tile_y1; tile_y <= tile_y2; tile_y++)
+  while (n_tiles >>= 1)
+    max_z++;
+
+  if (max_z > 0)
     {
-      for (tile_x = tile_x1; tile_x <= tile_x2; tile_x++)
+      gint tile_x1 = x / projection->tile_width;
+      gint tile_y1 = y / projection->tile_height;
+      gint tile_x2 = (x + width  - 1) / projection->tile_width;
+      gint tile_y2 = (y + height - 1) / projection->tile_height;
+      gint tile_x;
+      gint tile_y;
+
+      for (tile_y = tile_y1; tile_y <= tile_y2; tile_y++)
         {
-          gimp_tile_handler_projection_void_pyramid (GEGL_TILE_SOURCE (projection),
-                                                     tile_x / 2,  tile_y / 2, 1);
+          for (tile_x = tile_x1; tile_x <= tile_x2; tile_x++)
+            {
+              gimp_tile_handler_projection_void_pyramid (GEGL_TILE_SOURCE (projection),
+                                                         tile_x / 2,
+                                                         tile_y / 2,
+                                                         1, max_z);
+            }
         }
     }
 }
diff --git a/app/gegl/gimptilehandlerprojection.h b/app/gegl/gimptilehandlerprojection.h
index eec9980..3df269a 100644
--- a/app/gegl/gimptilehandlerprojection.h
+++ b/app/gegl/gimptilehandlerprojection.h
@@ -47,6 +47,8 @@ struct _GimpTileHandlerProjection
   const Babl      *format;
   gint             tile_width;
   gint             tile_height;
+  gint             proj_width;
+  gint             proj_height;
 };
 
 struct _GimpTileHandlerProjectionClass
@@ -56,7 +58,9 @@ struct _GimpTileHandlerProjectionClass
 
 
 GType             gimp_tile_handler_projection_get_type   (void) G_GNUC_CONST;
-GeglTileHandler * gimp_tile_handler_projection_new        (GeglNode                  *graph);
+GeglTileHandler * gimp_tile_handler_projection_new        (GeglNode                  *graph,
+                                                           gint                       proj_width,
+                                                           gint                       proj_height);
 
 void              gimp_tile_handler_projection_invalidate (GimpTileHandlerProjection *projection,
                                                            gint                       x,


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