]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkimage.c
Make it possible to specify additional modules to load via a setting.
[~andy/gtk] / gtk / gtkimage.c
index 280a8d772073e55105091a19fd4f585c5b8c7df2..8d8b54ad3a104e95be5a81f5ede93ef7ce39ce5f 100644 (file)
@@ -24,7 +24,9 @@
  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  */
 
+#include <config.h>
 #include <math.h>
+#include "gtkalias.h"
 #include "gtkcontainer.h"
 #include "gtkimage.h"
 #include "gtkiconfactory.h"
@@ -32,6 +34,8 @@
 #include "gtkintl.h"
 #include <string.h>
 
+
+
 #define DEFAULT_ICON_SIZE GTK_ICON_SIZE_BUTTON
 
 static void gtk_image_class_init   (GtkImageClass  *klass);
@@ -39,11 +43,14 @@ static void gtk_image_init         (GtkImage       *image);
 static gint gtk_image_expose       (GtkWidget      *widget,
                                     GdkEventExpose *event);
 static void gtk_image_unmap        (GtkWidget      *widget);
+static void gtk_image_unrealize    (GtkWidget      *widget);
 static void gtk_image_size_request (GtkWidget      *widget,
                                     GtkRequisition *requisition);
 static void gtk_image_destroy      (GtkObject      *object);
 static void gtk_image_clear        (GtkImage       *image);
 static void gtk_image_reset        (GtkImage       *image);
+static void gtk_image_calc_size    (GtkImage       *image);
+
 static void gtk_image_update_size  (GtkImage       *image,
                                     gint            image_width,
                                     gint            image_height);
@@ -74,26 +81,28 @@ enum
   PROP_STORAGE_TYPE
 };
 
-GtkType
+GType
 gtk_image_get_type (void)
 {
-  static GtkType image_type = 0;
+  static GType image_type = 0;
 
   if (!image_type)
     {
-      static const GtkTypeInfo image_info =
+      static const GTypeInfo image_info =
       {
-       "GtkImage",
-       sizeof (GtkImage),
        sizeof (GtkImageClass),
-       (GtkClassInitFunc) gtk_image_class_init,
-       (GtkObjectInitFunc) gtk_image_init,
-       /* reserved_1 */ NULL,
-        /* reserved_2 */ NULL,
-        (GtkClassInitFunc) NULL,
+       NULL,           /* base_init */
+       NULL,           /* base_finalize */
+       (GClassInitFunc) gtk_image_class_init,
+       NULL,           /* class_finalize */
+       NULL,           /* class_data */
+       sizeof (GtkImage),
+       0,              /* n_preallocs */
+       (GInstanceInitFunc) gtk_image_init,
       };
 
-      image_type = gtk_type_unique (GTK_TYPE_MISC, &image_info);
+      image_type = g_type_register_static (GTK_TYPE_MISC, "GtkImage",
+                                          &image_info, 0);
     }
 
   return image_type;
@@ -122,44 +131,45 @@ gtk_image_class_init (GtkImageClass *class)
   widget_class->expose_event = gtk_image_expose;
   widget_class->size_request = gtk_image_size_request;
   widget_class->unmap = gtk_image_unmap;
+  widget_class->unrealize = gtk_image_unrealize;
   
   g_object_class_install_property (gobject_class,
                                    PROP_PIXBUF,
                                    g_param_spec_object ("pixbuf",
-                                                        _("Pixbuf"),
-                                                        _("A GdkPixbuf to display."),
+                                                        P_("Pixbuf"),
+                                                        P_("A GdkPixbuf to display"),
                                                         GDK_TYPE_PIXBUF,
                                                         G_PARAM_READWRITE));
 
   g_object_class_install_property (gobject_class,
                                    PROP_PIXMAP,
                                    g_param_spec_object ("pixmap",
-                                                        _("Pixmap"),
-                                                        _("A GdkPixmap to display."),
+                                                        P_("Pixmap"),
+                                                        P_("A GdkPixmap to display"),
                                                         GDK_TYPE_PIXMAP,
                                                         G_PARAM_READWRITE));
 
   g_object_class_install_property (gobject_class,
                                    PROP_IMAGE,
                                    g_param_spec_object ("image",
-                                                        _("Image"),
-                                                        _("A GdkImage to display."),
+                                                        P_("Image"),
+                                                        P_("A GdkImage to display"),
                                                         GDK_TYPE_IMAGE,
                                                         G_PARAM_READWRITE));
 
   g_object_class_install_property (gobject_class,
                                    PROP_MASK,
                                    g_param_spec_object ("mask",
-                                                        _("Mask"),
-                                                        _("Mask bitmap to use with GdkImage or GdkPixmap"),
+                                                        P_("Mask"),
+                                                        P_("Mask bitmap to use with GdkImage or GdkPixmap"),
                                                         GDK_TYPE_PIXMAP,
                                                         G_PARAM_READWRITE));
   
   g_object_class_install_property (gobject_class,
                                    PROP_FILE,
                                    g_param_spec_string ("file",
-                                                        _("Filename"),
-                                                        _("Filename to load and siplay."),
+                                                        P_("Filename"),
+                                                        P_("Filename to load and display"),
                                                         NULL,
                                                         G_PARAM_WRITABLE));
   
@@ -167,24 +177,24 @@ gtk_image_class_init (GtkImageClass *class)
   g_object_class_install_property (gobject_class,
                                    PROP_STOCK,
                                    g_param_spec_string ("stock",
-                                                        _("Stock ID"),
-                                                        _("Stock ID for a stock image to display."),
+                                                        P_("Stock ID"),
+                                                        P_("Stock ID for a stock image to display"),
                                                         NULL,
                                                         G_PARAM_READWRITE));
   
   g_object_class_install_property (gobject_class,
                                    PROP_ICON_SET,
                                    g_param_spec_boxed ("icon_set",
-                                                       _("Icon set"),
-                                                       _("Icon set to display."),
+                                                       P_("Icon set"),
+                                                       P_("Icon set to display"),
                                                        GTK_TYPE_ICON_SET,
                                                        G_PARAM_READWRITE));
   
   g_object_class_install_property (gobject_class,
                                    PROP_ICON_SIZE,
                                    g_param_spec_int ("icon_size",
-                                                     _("Icon size"),
-                                                     _("Size to use for stock icon or icon set."),
+                                                     P_("Icon size"),
+                                                     P_("Size to use for stock icon or icon set"),
                                                      0, G_MAXINT,
                                                      DEFAULT_ICON_SIZE,
                                                      G_PARAM_READWRITE));
@@ -192,16 +202,16 @@ gtk_image_class_init (GtkImageClass *class)
   g_object_class_install_property (gobject_class,
                                    PROP_PIXBUF_ANIMATION,
                                    g_param_spec_object ("pixbuf_animation",
-                                                        _("Animation"),
-                                                        _("GdkPixbufAnimation to display."),
+                                                        P_("Animation"),
+                                                        P_("GdkPixbufAnimation to display"),
                                                         GDK_TYPE_PIXBUF_ANIMATION,
                                                         G_PARAM_READWRITE));
   
   g_object_class_install_property (gobject_class,
                                    PROP_STORAGE_TYPE,
                                    g_param_spec_enum ("storage_type",
-                                                      _("Storage type"),
-                                                      _("The representation being used for image data."),
+                                                      P_("Storage type"),
+                                                      P_("The representation being used for image data"),
                                                       GTK_TYPE_IMAGE_TYPE,
                                                       GTK_IMAGE_EMPTY,
                                                       G_PARAM_READABLE));
@@ -269,7 +279,7 @@ gtk_image_set_property (GObject      *object,
           mask = g_value_get_object (value);
 
           if (mask)
-            g_object_ref (G_OBJECT (mask));
+            g_object_ref (mask);
           
           gtk_image_reset (image);
 
@@ -395,7 +405,7 @@ gtk_image_get_property (GObject     *object,
  * @mask: a #GdkBitmap, or %NULL
  * 
  * Creates a #GtkImage widget displaying @pixmap with a @mask.
- * A #GdkImage is a server-side image buffer in the pixel format of the
+ * A #GdkPixmap is a server-side image buffer in the pixel format of the
  * current display. The #GtkImage does not assume a reference to the
  * pixmap or mask; you still need to unref them if you own references.
  * #GtkImage will add its own reference rather than adopting yours.
@@ -408,7 +418,7 @@ gtk_image_new_from_pixmap (GdkPixmap *pixmap,
 {
   GtkImage *image;
 
-  image = gtk_type_new (GTK_TYPE_IMAGE);
+  image = g_object_new (GTK_TYPE_IMAGE, NULL);
 
   gtk_image_set_from_pixmap (image, pixmap, mask);
 
@@ -435,7 +445,7 @@ gtk_image_new_from_image  (GdkImage  *gdk_image,
 {
   GtkImage *image;
 
-  image = gtk_type_new (GTK_TYPE_IMAGE);
+  image = g_object_new (GTK_TYPE_IMAGE, NULL);
 
   gtk_image_set_from_image (image, gdk_image, mask);
 
@@ -470,7 +480,7 @@ gtk_image_new_from_file   (const gchar *filename)
 {
   GtkImage *image;
 
-  image = gtk_type_new (GTK_TYPE_IMAGE);
+  image = g_object_new (GTK_TYPE_IMAGE, NULL);
 
   gtk_image_set_from_file (image, filename);
 
@@ -497,7 +507,7 @@ gtk_image_new_from_pixbuf (GdkPixbuf *pixbuf)
 {
   GtkImage *image;
 
-  image = gtk_type_new (GTK_TYPE_IMAGE);
+  image = g_object_new (GTK_TYPE_IMAGE, NULL);
 
   gtk_image_set_from_pixbuf (image, pixbuf);
 
@@ -524,7 +534,7 @@ gtk_image_new_from_stock (const gchar    *stock_id,
 {
   GtkImage *image;
 
-  image = gtk_type_new (GTK_TYPE_IMAGE);
+  image = g_object_new (GTK_TYPE_IMAGE, NULL);
 
   gtk_image_set_from_stock (image, stock_id, size);
 
@@ -557,7 +567,7 @@ gtk_image_new_from_icon_set (GtkIconSet     *icon_set,
 {
   GtkImage *image;
 
-  image = gtk_type_new (GTK_TYPE_IMAGE);
+  image = g_object_new (GTK_TYPE_IMAGE, NULL);
 
   gtk_image_set_from_icon_set (image, icon_set, size);
 
@@ -582,7 +592,7 @@ gtk_image_new_from_animation (GdkPixbufAnimation *animation)
 
   g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION (animation), NULL);
   
-  image = gtk_type_new (GTK_TYPE_IMAGE);
+  image = g_object_new (GTK_TYPE_IMAGE, NULL);
 
   gtk_image_set_from_animation (image, animation);
 
@@ -612,10 +622,10 @@ gtk_image_set_from_pixmap (GtkImage  *image,
   g_object_freeze_notify (G_OBJECT (image));
   
   if (pixmap)
-    g_object_ref (G_OBJECT (pixmap));
+    g_object_ref (pixmap);
 
   if (mask)
-    g_object_ref (G_OBJECT (mask));
+    g_object_ref (mask);
 
   gtk_image_reset (image);
 
@@ -664,10 +674,10 @@ gtk_image_set_from_image  (GtkImage  *image,
   g_object_freeze_notify (G_OBJECT (image));
   
   if (gdk_image)
-    g_object_ref (G_OBJECT (gdk_image));
+    g_object_ref (gdk_image);
 
   if (mask)
-    g_object_ref (G_OBJECT (mask));
+    g_object_ref (mask);
 
   gtk_image_reset (image);
 
@@ -684,7 +694,7 @@ gtk_image_set_from_image  (GtkImage  *image,
     {
       /* Clean up the mask if gdk_image was NULL */
       if (mask)
-        g_object_unref (G_OBJECT (mask));
+        g_object_unref (mask);
     }
 
   g_object_notify (G_OBJECT (image), "image");
@@ -708,7 +718,6 @@ gtk_image_set_from_file   (GtkImage    *image,
   GdkPixbufAnimation *anim;
   
   g_return_if_fail (GTK_IS_IMAGE (image));
-  g_return_if_fail (filename != NULL);
 
   g_object_freeze_notify (G_OBJECT (image));
   
@@ -746,7 +755,7 @@ gtk_image_set_from_file   (GtkImage    *image,
       gtk_image_set_from_animation (image, anim);
     }
 
-  g_object_unref (G_OBJECT (anim));
+  g_object_unref (anim);
 
   g_object_thaw_notify (G_OBJECT (image));
 }
@@ -770,7 +779,7 @@ gtk_image_set_from_pixbuf (GtkImage  *image,
   g_object_freeze_notify (G_OBJECT (image));
   
   if (pixbuf)
-    g_object_ref (G_OBJECT (pixbuf));
+    g_object_ref (pixbuf);
 
   gtk_image_reset (image);
 
@@ -894,7 +903,7 @@ gtk_image_set_from_animation (GtkImage           *image,
   g_object_freeze_notify (G_OBJECT (image));
   
   if (animation)
-    g_object_ref (G_OBJECT (animation));
+    g_object_ref (animation);
 
   gtk_image_reset (image);
 
@@ -1137,12 +1146,8 @@ gtk_image_get (GtkImage   *image,
 }
 
 static void
-gtk_image_unmap (GtkWidget *widget)
+gtk_image_reset_anim_iter (GtkImage *image)
 {
-  GtkImage *image;
-
-  image = GTK_IMAGE (widget);
-
   if (image->storage_type == GTK_IMAGE_ANIMATION)
     {
       /* Reset the animation */
@@ -1155,16 +1160,31 @@ gtk_image_unmap (GtkWidget *widget)
 
       if (image->data.anim.iter)
         {
-          g_object_unref (G_OBJECT (image->data.anim.iter));
+          g_object_unref (image->data.anim.iter);
           image->data.anim.iter = NULL;
         }
     }
+}
+
+static void
+gtk_image_unmap (GtkWidget *widget)
+{
+  gtk_image_reset_anim_iter (GTK_IMAGE (widget));
 
   if (GTK_WIDGET_CLASS (parent_class)->unmap)
     GTK_WIDGET_CLASS (parent_class)->unmap (widget);
 }
 
-gint
+static void
+gtk_image_unrealize (GtkWidget *widget)
+{
+  gtk_image_reset_anim_iter (GTK_IMAGE (widget));
+
+  if (GTK_WIDGET_CLASS (parent_class)->unrealize)
+    GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
+}
+
+static gint
 animation_timeout (gpointer data)
 {
   GtkImage *image;
@@ -1190,6 +1210,44 @@ animation_timeout (gpointer data)
   return FALSE;
 }
 
+/*
+ * Like gdk_rectangle_intersect (dest, src, dest), but make 
+ * sure that the origin of dest is moved by an "even" offset. 
+ * If necessary grow the intersection by one row or column 
+ * to achieve this.
+ *
+ * This is necessary since we can't pass alignment information
+ * for the pixelation pattern down to gdk_pixbuf_saturate_and_pixelate(), 
+ * thus we have to makesure that the subimages are properly aligned.
+ */
+static gboolean
+rectangle_intersect_even (GdkRectangle *src, 
+                         GdkRectangle *dest)
+{
+  gboolean isect;
+  gint x, y;
+
+  x = dest->x;
+  y = dest->y;
+  isect = gdk_rectangle_intersect (dest, src, dest);
+
+  if ((dest->x - x + dest->y - y) % 2 != 0)
+    {
+      if (dest->x > x)
+       {
+         dest->x--;
+         dest->width++;
+       }
+      else
+       {
+         dest->y--;
+         dest->height++;
+       }
+    }
+  
+  return isect;
+}
+
 static gint
 gtk_image_expose (GtkWidget      *widget,
                  GdkEventExpose *event)
@@ -1204,7 +1262,7 @@ gtk_image_expose (GtkWidget      *widget,
       GtkMisc *misc;
       GdkRectangle area, image_bound;
       gfloat xalign;
-      gint x, y;
+      gint x, y, mask_x, mask_y;
       GdkBitmap *mask;
       GdkPixbuf *pixbuf;
       gboolean needs_state_transform;
@@ -1213,6 +1271,14 @@ gtk_image_expose (GtkWidget      *widget,
       misc = GTK_MISC (widget);
 
       area = event->area;
+
+      /* For stock items and icon sets, we lazily calculate
+       * the size; we might get here between a queue_resize()
+       * and size_request() if something explicitely forces
+       * a redraw.
+       */
+      if (widget->requisition.width == 0 && widget->requisition.height == 0)
+       gtk_image_calc_size (image);
       
       if (!gdk_rectangle_intersect (&area, &widget->allocation, &area))
        return FALSE;
@@ -1228,6 +1294,8 @@ gtk_image_expose (GtkWidget      *widget,
       y = floor (widget->allocation.y + misc->ypad 
                 + ((widget->allocation.height - widget->requisition.height) * misc->yalign)
                 + 0.5);
+      mask_x = x;
+      mask_y = y;
       
       image_bound.x = x;
       image_bound.y = y;      
@@ -1245,14 +1313,13 @@ gtk_image_expose (GtkWidget      *widget,
           gdk_drawable_get_size (image->data.pixmap.pixmap,
                                  &image_bound.width,
                                  &image_bound.height);
-
-         if (gdk_rectangle_intersect (&image_bound, &area, &image_bound) &&
+         if (rectangle_intersect_even (&area, &image_bound) &&
              needs_state_transform)
             {
               pixbuf = gdk_pixbuf_get_from_drawable (NULL,
                                                      image->data.pixmap.pixmap,
                                                      gtk_widget_get_colormap (widget),
-                                                     image_bound.x, image_bound.y,
+                                                     image_bound.x - x, image_bound.y - y,
                                                     0, 0,
                                                      image_bound.width,
                                                      image_bound.height);
@@ -1268,7 +1335,7 @@ gtk_image_expose (GtkWidget      *widget,
           image_bound.width = image->data.image.image->width;
           image_bound.height = image->data.image.image->height;
 
-         if (gdk_rectangle_intersect (&image_bound, &area, &image_bound) &&
+         if (rectangle_intersect_even (&area, &image_bound) &&
              needs_state_transform)
             {
               pixbuf = gdk_pixbuf_get_from_image (NULL,
@@ -1287,8 +1354,9 @@ gtk_image_expose (GtkWidget      *widget,
         case GTK_IMAGE_PIXBUF:
           image_bound.width = gdk_pixbuf_get_width (image->data.pixbuf.pixbuf);
           image_bound.height = gdk_pixbuf_get_height (image->data.pixbuf.pixbuf);          
+         
 
-         if (gdk_rectangle_intersect (&image_bound, &area, &image_bound) &&
+         if (rectangle_intersect_even (&area, &image_bound) &&
              needs_state_transform)
            {
              pixbuf = gdk_pixbuf_new_subpixbuf (image->data.pixbuf.pixbuf,
@@ -1301,7 +1369,7 @@ gtk_image_expose (GtkWidget      *widget,
          else
            {
              pixbuf = image->data.pixbuf.pixbuf;
-             g_object_ref (G_OBJECT (pixbuf));
+             g_object_ref (pixbuf);
            }
           break;
 
@@ -1361,7 +1429,7 @@ gtk_image_expose (GtkWidget      *widget,
              */
             
             pixbuf = gdk_pixbuf_animation_iter_get_pixbuf (image->data.anim.iter);
-            g_object_ref (G_OBJECT (pixbuf));
+            g_object_ref (pixbuf);
           }
           break;
 
@@ -1373,10 +1441,10 @@ gtk_image_expose (GtkWidget      *widget,
       if (mask)
        {
          gdk_gc_set_clip_mask (widget->style->black_gc, mask);
-         gdk_gc_set_clip_origin (widget->style->black_gc, x, y);
+         gdk_gc_set_clip_origin (widget->style->black_gc, mask_x, mask_y);
        }
 
-      if (gdk_rectangle_intersect (&image_bound, &area, &image_bound))
+      if (rectangle_intersect_even (&area, &image_bound))
         {
           if (pixbuf)
             {
@@ -1406,25 +1474,25 @@ gtk_image_expose (GtkWidget      *widget,
 
                   gtk_icon_source_free (source);
 
-                  g_object_unref (G_OBJECT (pixbuf));
+                  g_object_unref (pixbuf);
                   pixbuf = rendered;
                 }
 
               if (pixbuf)
                 {
-                  gdk_pixbuf_render_to_drawable (pixbuf,
-                                                widget->window,
-                                                widget->style->black_gc,                                                
-                                                image_bound.x - x,
-                                                image_bound.y - y,
-                                                image_bound.x,
-                                                image_bound.y,
-                                                image_bound.width,
-                                                image_bound.height,
-                                                GDK_RGB_DITHER_NORMAL,
-                                                0, 0);
-
-                  g_object_unref (G_OBJECT (pixbuf));
+                  gdk_draw_pixbuf (widget->window,
+                                  widget->style->black_gc,
+                                  pixbuf,
+                                  image_bound.x - x,
+                                  image_bound.y - y,
+                                  image_bound.x,
+                                  image_bound.y,
+                                  image_bound.width,
+                                  image_bound.height,
+                                  GDK_RGB_DITHER_NORMAL,
+                                  0, 0);
+
+                  g_object_unref (pixbuf);
                   pixbuf = NULL;
                 }
             }
@@ -1482,7 +1550,7 @@ gtk_image_clear (GtkImage *image)
 
   if (image->mask)
     {
-      g_object_unref (G_OBJECT (image->mask));
+      g_object_unref (image->mask);
       image->mask = NULL;
       g_object_notify (G_OBJECT (image), "mask");
     }
@@ -1498,7 +1566,7 @@ gtk_image_clear (GtkImage *image)
     case GTK_IMAGE_PIXMAP:
 
       if (image->data.pixmap.pixmap)
-        g_object_unref (G_OBJECT (image->data.pixmap.pixmap));
+        g_object_unref (image->data.pixmap.pixmap);
       image->data.pixmap.pixmap = NULL;
       
       g_object_notify (G_OBJECT (image), "pixmap");
@@ -1508,7 +1576,7 @@ gtk_image_clear (GtkImage *image)
     case GTK_IMAGE_IMAGE:
 
       if (image->data.image.image)
-        g_object_unref (G_OBJECT (image->data.image.image));
+        g_object_unref (image->data.image.image);
       image->data.image.image = NULL;
       
       g_object_notify (G_OBJECT (image), "image");
@@ -1518,7 +1586,7 @@ gtk_image_clear (GtkImage *image)
     case GTK_IMAGE_PIXBUF:
 
       if (image->data.pixbuf.pixbuf)
-        g_object_unref (G_OBJECT (image->data.pixbuf.pixbuf));
+        g_object_unref (image->data.pixbuf.pixbuf);
 
       g_object_notify (G_OBJECT (image), "pixbuf");
       
@@ -1542,13 +1610,10 @@ gtk_image_clear (GtkImage *image)
       break;
 
     case GTK_IMAGE_ANIMATION:
-      if (image->data.anim.frame_timeout)
-        g_source_remove (image->data.anim.frame_timeout);
+      gtk_image_reset_anim_iter (image);
       
       if (image->data.anim.anim)
-        g_object_unref (G_OBJECT (image->data.anim.anim));
-
-      image->data.anim.frame_timeout = 0;
+        g_object_unref (image->data.anim.anim);
       image->data.anim.anim = NULL;
       
       g_object_notify (G_OBJECT (image), "pixbuf_animation");
@@ -1577,29 +1642,25 @@ gtk_image_reset (GtkImage *image)
 }
 
 static void
-gtk_image_size_request (GtkWidget      *widget,
-                        GtkRequisition *requisition)
+gtk_image_calc_size (GtkImage *image)
 {
-  GtkImage *image;
+  GtkWidget *widget = GTK_WIDGET (image);
   GdkPixbuf *pixbuf = NULL;
   
-  image = GTK_IMAGE (widget);
-
   /* We update stock/icon set on every size request, because
    * the theme could have affected the size; for other kinds of
    * image, we just update the requisition when the image data
    * is set.
    */
-  
   switch (image->storage_type)
     {
     case GTK_IMAGE_STOCK:
-      pixbuf = gtk_widget_render_icon (GTK_WIDGET (image),
+      pixbuf = gtk_widget_render_icon (widget,
                                        image->data.stock.stock_id,
                                        image->icon_size,
                                        NULL);
       break;
-
+      
     case GTK_IMAGE_ICON_SET:
       pixbuf = gtk_icon_set_render_icon (image->data.icon_set.icon_set,
                                          widget->style,
@@ -1616,11 +1677,22 @@ gtk_image_size_request (GtkWidget      *widget,
 
   if (pixbuf)
     {
-      GTK_WIDGET (image)->requisition.width = gdk_pixbuf_get_width (pixbuf) + GTK_MISC (image)->xpad * 2;
-      GTK_WIDGET (image)->requisition.height = gdk_pixbuf_get_height (pixbuf) + GTK_MISC (image)->ypad * 2;
+      widget->requisition.width = gdk_pixbuf_get_width (pixbuf) + GTK_MISC (image)->xpad * 2;
+      widget->requisition.height = gdk_pixbuf_get_height (pixbuf) + GTK_MISC (image)->ypad * 2;
 
-      g_object_unref (G_OBJECT (pixbuf));
+      g_object_unref (pixbuf);
     }
+}
+
+static void
+gtk_image_size_request (GtkWidget      *widget,
+                        GtkRequisition *requisition)
+{
+  GtkImage *image;
+  
+  image = GTK_IMAGE (widget);
+
+  gtk_image_calc_size (image);
 
   /* Chain up to default that simply reads current requisition */
   GTK_WIDGET_CLASS (parent_class)->size_request (widget, requisition);
@@ -1637,5 +1709,3 @@ gtk_image_update_size (GtkImage *image,
   if (GTK_WIDGET_VISIBLE (image))
     gtk_widget_queue_resize (GTK_WIDGET (image));
 }
-
-