- GtkImage *image;
- GtkMisc *misc;
- GtkImagePrivate *priv;
- GdkRectangle area, image_bound;
- gfloat xalign;
- gint x, y, mask_x, mask_y;
- GdkBitmap *mask;
- GdkPixbuf *pixbuf;
- gboolean needs_state_transform;
-
- image = GTK_IMAGE (widget);
- misc = GTK_MISC (widget);
- priv = GTK_IMAGE_GET_PRIVATE (image);
-
- 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 (priv->need_calc_size)
- gtk_image_calc_size (image);
-
- if (!gdk_rectangle_intersect (&area, &widget->allocation, &area))
- return FALSE;
-
- if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
- xalign = misc->xalign;
- else
- xalign = 1.0 - misc->xalign;
-
- x = floor (widget->allocation.x + misc->xpad
- + ((widget->allocation.width - widget->requisition.width) * xalign));
- y = floor (widget->allocation.y + misc->ypad
- + ((widget->allocation.height - widget->requisition.height) * misc->yalign));
- mask_x = x;
- mask_y = y;
-
- image_bound.x = x;
- image_bound.y = y;
- image_bound.width = 0;
- image_bound.height = 0;
-
- mask = NULL;
- pixbuf = NULL;
- needs_state_transform = GTK_WIDGET_STATE (widget) != GTK_STATE_NORMAL;
-
- switch (image->storage_type)
- {
- case GTK_IMAGE_PIXMAP:
- mask = image->mask;
- gdk_drawable_get_size (image->data.pixmap.pixmap,
- &image_bound.width,
- &image_bound.height);
- 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 - x, image_bound.y - y,
- 0, 0,
- image_bound.width,
- image_bound.height);
-
- x = image_bound.x;
- y = image_bound.y;
- }
-
- break;
-
- case GTK_IMAGE_IMAGE:
- mask = image->mask;
- image_bound.width = image->data.image.image->width;
- image_bound.height = image->data.image.image->height;
-
- if (rectangle_intersect_even (&area, &image_bound) &&
- needs_state_transform)
- {
- pixbuf = gdk_pixbuf_get_from_image (NULL,
- image->data.image.image,
- gtk_widget_get_colormap (widget),
- image_bound.x - x, image_bound.y - y,
- 0, 0,
- image_bound.width,
- image_bound.height);
-
- x = image_bound.x;
- y = image_bound.y;
- }
- break;
-
- 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 (rectangle_intersect_even (&area, &image_bound) &&
- needs_state_transform)
- {
- pixbuf = gdk_pixbuf_new_subpixbuf (image->data.pixbuf.pixbuf,
- image_bound.x - x, image_bound.y - y,
- image_bound.width, image_bound.height);
-
- x = image_bound.x;
- y = image_bound.y;
- }
- else
- {
- pixbuf = image->data.pixbuf.pixbuf;
- g_object_ref (pixbuf);
- }
- break;
-
- case GTK_IMAGE_STOCK:
- pixbuf = gtk_widget_render_icon (widget,
- image->data.stock.stock_id,
- image->icon_size,
- NULL);
- if (pixbuf)
- {
- image_bound.width = gdk_pixbuf_get_width (pixbuf);
- image_bound.height = gdk_pixbuf_get_height (pixbuf);
- }
-
- /* already done */
- needs_state_transform = FALSE;
- break;
-
- case GTK_IMAGE_ICON_SET:
- pixbuf =
- gtk_icon_set_render_icon (image->data.icon_set.icon_set,
- widget->style,
- gtk_widget_get_direction (widget),
- GTK_WIDGET_STATE (widget),
- image->icon_size,
- widget,
- NULL);
-
- if (pixbuf)
- {
- image_bound.width = gdk_pixbuf_get_width (pixbuf);
- image_bound.height = gdk_pixbuf_get_height (pixbuf);
- }
-
- /* already done */
- needs_state_transform = FALSE;
- break;
-
- case GTK_IMAGE_ANIMATION:
- {
- if (image->data.anim.iter == NULL)
- {
- image->data.anim.iter = gdk_pixbuf_animation_get_iter (image->data.anim.anim, NULL);
-
- if (gdk_pixbuf_animation_iter_get_delay_time (image->data.anim.iter) >= 0)
- image->data.anim.frame_timeout =
- gdk_threads_add_timeout (gdk_pixbuf_animation_iter_get_delay_time (image->data.anim.iter),
- animation_timeout,
- image);
- }
-
- image_bound.width = gdk_pixbuf_animation_get_width (image->data.anim.anim);
- image_bound.height = gdk_pixbuf_animation_get_height (image->data.anim.anim);
-
- /* don't advance the anim iter here, or we could get frame changes between two
- * exposes of different areas.
- */
-
- pixbuf = gdk_pixbuf_animation_iter_get_pixbuf (image->data.anim.iter);
- g_object_ref (pixbuf);
- }
- break;
-
- case GTK_IMAGE_ICON_NAME:
- ensure_pixbuf_for_icon_name (image);
- pixbuf = image->data.name.pixbuf;
- if (pixbuf)
- {
- g_object_ref (pixbuf);
- image_bound.width = gdk_pixbuf_get_width (pixbuf);
- image_bound.height = gdk_pixbuf_get_height (pixbuf);
- }
- break;
-
- case GTK_IMAGE_GICON:
- ensure_pixbuf_for_gicon (image);
- pixbuf = image->data.gicon.pixbuf;
- if (pixbuf)
- {
- g_object_ref (pixbuf);
- image_bound.width = gdk_pixbuf_get_width (pixbuf);
- image_bound.height = gdk_pixbuf_get_height (pixbuf);
- }
- break;
-
- case GTK_IMAGE_EMPTY:
- g_assert_not_reached ();
- break;
- }
-
- if (mask)
- {
- gdk_gc_set_clip_mask (widget->style->black_gc, mask);
- gdk_gc_set_clip_origin (widget->style->black_gc, mask_x, mask_y);
- }
-
- if (rectangle_intersect_even (&area, &image_bound))
- {
- if (pixbuf)
- {
- if (needs_state_transform)
- {
- GtkIconSource *source;
- GdkPixbuf *rendered;
-
- source = gtk_icon_source_new ();
- gtk_icon_source_set_pixbuf (source, pixbuf);
- /* The size here is arbitrary; since size isn't
- * wildcarded in the souce, it isn't supposed to be
- * scaled by the engine function
- */
- gtk_icon_source_set_size (source,
- GTK_ICON_SIZE_SMALL_TOOLBAR);
- gtk_icon_source_set_size_wildcarded (source, FALSE);
-
- rendered = gtk_style_render_icon (widget->style,
- source,
- gtk_widget_get_direction (widget),
- GTK_WIDGET_STATE (widget),
- /* arbitrary */
- (GtkIconSize)-1,
- widget,
- "gtk-image");
-
- gtk_icon_source_free (source);
-
- g_object_unref (pixbuf);
- pixbuf = rendered;
- }
-
- if (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);
- }
- }
- else
- {
- switch (image->storage_type)
- {
- case GTK_IMAGE_PIXMAP:
- gdk_draw_drawable (widget->window,
- widget->style->black_gc,
- image->data.pixmap.pixmap,
- image_bound.x - x, image_bound.y - y,
- image_bound.x, image_bound.y,
- image_bound.width, image_bound.height);
- break;
-
- case GTK_IMAGE_IMAGE:
- gdk_draw_image (widget->window,
- widget->style->black_gc,
- image->data.image.image,
- image_bound.x - x, image_bound.y - y,
- image_bound.x, image_bound.y,
- image_bound.width, image_bound.height);
- break;
-
- case GTK_IMAGE_PIXBUF:
- case GTK_IMAGE_STOCK:
- case GTK_IMAGE_ICON_SET:
- case GTK_IMAGE_ANIMATION:
- case GTK_IMAGE_ICON_NAME:
- case GTK_IMAGE_EMPTY:
- case GTK_IMAGE_GICON:
- g_assert_not_reached ();
- break;
- }
- }
- } /* if rectangle intersects */
-
- if (mask)
- {
- gdk_gc_set_clip_mask (widget->style->black_gc, NULL);
- gdk_gc_set_clip_origin (widget->style->black_gc, 0, 0);
- }
-
- if (pixbuf)
- g_object_unref (pixbuf);
-
- } /* if widget is drawable */