GtkImage bug+patch



Hi all,

While doing some stuff at work, I found bug 67472: I did an evil fix @
work and a nice patch this week-end @ home (patch is attached both in
the bug report and here). I hope this will get into the next release.

Mathieu
-- 
Mathieu Lacage <mathieu gnu org>
? patch
Index: gtkimage.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkimage.c,v
retrieving revision 1.30
diff -u -r1.30 gtkimage.c
--- gtkimage.c	2001/09/08 06:24:46	1.30
+++ gtkimage.c	2001/12/24 08:34:27
@@ -1195,6 +1195,64 @@
 {
   g_return_val_if_fail (GTK_IS_IMAGE (widget), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);
+
+  /*****
+    This expose handler works on a relatively simple principle which
+    is not easy to grasp from the code so, here is a quick explanation:
+    
+    If you want to render an image within a GtkImage, you have four
+    parameters to take into account:
+     - the x and y padding.
+     - the x and y alignment.
+     - the assigned drawing area (stored in widget->allocation).
+     - the event's area.
+
+     A------------------------
+     |                       |
+     |  ---------------------+-----------------------     <--- Allocation area top border
+     |  |                    |                            <--- Y padding
+     |  |                    |  
+     |  |  B-----------------+-----------------------     <--- Allocation area with y padding.
+     |  |  |                 |
+     |  |  |    X <----------+---- Image center
+     |  |  |                 |
+     |  |  |                 |
+     |  |  |                 |
+     |  |  |        C--------+----
+     |  |  |        |        |   |
+     |  |  |        |        |   |
+     ---+--+--------+---------   |
+        |  |        |            |
+        |  |        --------------
+        |  |
+        |  |
+        
+          ^
+	  |
+	  X padding
+
+
+	  Each window is identified by its top-left-corner letter:
+	  window A represents the image shifted to accomodate the alignment parameter
+	    (ie: its center's position is shifted from the allocation area's center
+	         by the alignment factor)
+	  window B represents the allocation area with padding taken into account.
+	  window C represents the event window (the window where painting needs
+	    to be redone).
+
+	  In the code below, the variable area will be used to store a description
+	  of the window B, image_bounds will be used to store a description of 
+	  window A. Window C is stored in event->area.
+
+
+	  The function is split in three parts:
+	  - first part gets the image width and height and stores them in the
+	  image_bounds variable.
+	  - second part calculates the top-left-coordinate of window A and
+	  window B.
+	  - third part calculates the intersection between all three rectangles
+	  and does the actual drawing.
+   *****/
   
   if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget) &&
       GTK_IMAGE (widget)->storage_type != GTK_IMAGE_EMPTY)
@@ -1209,18 +1267,6 @@
       image = GTK_IMAGE (widget);
       misc = GTK_MISC (widget);
 
-      x = (widget->allocation.x * (1.0 - misc->xalign) +
-	   (widget->allocation.x + widget->allocation.width
-	    - (widget->requisition.width - misc->xpad * 2)) *
-	   misc->xalign) + 0.5;
-      y = (widget->allocation.y * (1.0 - misc->yalign) +
-	   (widget->allocation.y + widget->allocation.height
-	    - (widget->requisition.height - misc->ypad * 2)) *
-	   misc->yalign) + 0.5;
-
-      image_bound.x = x;
-      image_bound.y = y;      
-
       switch (image->storage_type)
         {
         case GTK_IMAGE_PIXMAP:
@@ -1292,15 +1338,27 @@
           break;
         }
 
+      x = widget->allocation.x + misc->xpad + 0.5 +
+	(widget->allocation.width - 2 * misc->xpad - image_bound.width) * misc->xalign;
+      y = widget->allocation.y + misc->ypad + 0.5 +
+	(widget->allocation.height - 2 * misc->ypad - image_bound.height) * misc->yalign;
+
+      image_bound.x = x;
+      image_bound.y = y;      
+
       if (mask)
 	{
 	  gdk_gc_set_clip_mask (widget->style->black_gc, mask);
 	  gdk_gc_set_clip_origin (widget->style->black_gc, x, y);
 	}
 
-      area = event->area;
+      area = widget->allocation;
+      area.x += misc->xpad;
+      area.y += misc->ypad;
+      area.width  -= 2 * misc->xpad;
+      area.height -= 2 * misc->ypad;
       
-      if (gdk_rectangle_intersect (&area, &widget->allocation, &area) &&
+      if (gdk_rectangle_intersect (&area, &event->area, &area) &&
           gdk_rectangle_intersect (&image_bound, &area, &image_bound))
         {
           switch (image->storage_type)


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