From 06968d9bf993dde529b4bef679c9711c01ac323e Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Sat, 30 Mar 2013 17:44:59 +0100 Subject: [PATCH] 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 2e553929f8..ca60885f9c 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 13e79af618..07eac37c1a 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 eec9980248..3df269afcf 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,