From: Carl Worth <cworth@cworth.org>
Date: Thu, 15 Mar 2007 16:25:54 +0000 (-0700)
Subject: Use the expose event's region to avoid drawing tiles that don't need to be redrawn.
X-Git-Url: https://git.cworth.org/git?a=commitdiff_plain;h=83a1595786b01a55be5b26516473253886c54b0c;p=kub

Use the expose event's region to avoid drawing tiles that don't need to be redrawn.

The reason that dragging was so slow before is that the program
was redrawing every single tile every time the mouse moved. Now
we only redraw tiles that are actually affected by the movement.

This is fast enough now that we probably don't even need to add
caches for pre-rendered tiles, (though of course, if we did that
it would be even faster).
---

diff --git a/kub.c b/kub.c
index 1e508b7..52e8b8e 100644
--- a/kub.c
+++ b/kub.c
@@ -114,10 +114,18 @@ static void tile_print(tile_t tile)
     printf("%6s %2d\n", colors[tile.color], tile.number + 1);
 }
 
-static void tile_draw(game_t *game, tile_t *tile, cairo_t *cr)
+static void tile_draw(game_t *game, tile_t *tile, cairo_t *cr, GdkRegion *region)
 {
     char number_string[3];
     int len;
+    GdkRectangle rectangle;
+
+    rectangle.x = tile->x - 1;
+    rectangle.y = tile->y - 1;
+    rectangle.width = TILE_WIDTH + 2;
+    rectangle.height = TILE_HEIGHT + 2;
+    if (gdk_region_rect_in (region, &rectangle) == GDK_OVERLAP_RECTANGLE_OUT)
+	return;
 
     len = snprintf (number_string, 3, "%d", tile->number + 1);
     if (len < 0 || len >= 3)
@@ -378,12 +386,12 @@ static void deck_spread(deck_t *deck)
     }
 }
 
-static void deck_draw(game_t *game, cairo_t *cr)
+static void deck_draw(game_t *game, cairo_t *cr, GdkRegion *region)
 {
     int i;
     for (i = 0; i < game->deck.num_tiles; i++)
     {
-	    tile_draw(game, &game->deck.tiles[i], cr);
+	    tile_draw(game, &game->deck.tiles[i], cr, region);
     }
 }   
 
@@ -396,7 +404,7 @@ static void hand_print(game_t *game, int player)
     }
 }
 
-static void hand_draw(game_t *game, int player, cairo_t *cr)
+static void hand_draw(game_t *game, int player, cairo_t *cr, GdkRegion *region)
 {
     int i;
     int gwdw = GAME_WINDOW_DEFAULT_WIDTH;
@@ -409,7 +417,7 @@ static void hand_draw(game_t *game, int player, cairo_t *cr)
     }
     for (i = 0; i < game->players[player].hand.num_tiles; i++)
     {
-	tile_draw(game, &game->players[player].hand.tiles[i], cr);
+	tile_draw(game, &game->players[player].hand.tiles[i], cr, region);
     }
 }
 
@@ -444,9 +452,9 @@ static gboolean on_expose_event (GtkWidget *widget, GdkEventExpose *event, game_
 
     cr = gdk_cairo_create (widget->window);
 
-    deck_draw(game, cr);
+    deck_draw(game, cr, event->region);
 
-    hand_draw(game, 0, cr);
+    hand_draw(game, 0, cr, event->region);
 
     cairo_destroy (cr);