]> Pileus Git - ~andy/gtk/blob - gtk/gtkcellrendererpixbuf.c
1575b4cd707ae6d1db2106f36a6ce56a2ae574e0
[~andy/gtk] / gtk / gtkcellrendererpixbuf.c
1 /* gtkcellrendererpixbuf.c
2  * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #include <config.h>
21 #include <stdlib.h>
22 #include "gtkcellrendererpixbuf.h"
23 #include "gtkiconfactory.h"
24 #include "gtkicontheme.h"
25 #include "gtkintl.h"
26 #include "gtkprivate.h"
27 #include "gtkalias.h"
28
29 static void gtk_cell_renderer_pixbuf_get_property  (GObject                    *object,
30                                                     guint                       param_id,
31                                                     GValue                     *value,
32                                                     GParamSpec                 *pspec);
33 static void gtk_cell_renderer_pixbuf_set_property  (GObject                    *object,
34                                                     guint                       param_id,
35                                                     const GValue               *value,
36                                                     GParamSpec                 *pspec);
37 static void gtk_cell_renderer_pixbuf_finalize   (GObject                    *object);
38 static void gtk_cell_renderer_pixbuf_create_stock_pixbuf (GtkCellRendererPixbuf *cellpixbuf,
39                                                           GtkWidget             *widget);
40 static void gtk_cell_renderer_pixbuf_create_named_icon_pixbuf (GtkCellRendererPixbuf *cellpixbuf,
41                                                                GtkWidget             *widget);
42 static void gtk_cell_renderer_pixbuf_get_size   (GtkCellRenderer            *cell,
43                                                  GtkWidget                  *widget,
44                                                  GdkRectangle               *rectangle,
45                                                  gint                       *x_offset,
46                                                  gint                       *y_offset,
47                                                  gint                       *width,
48                                                  gint                       *height);
49 static void gtk_cell_renderer_pixbuf_render     (GtkCellRenderer            *cell,
50                                                  GdkDrawable                *window,
51                                                  GtkWidget                  *widget,
52                                                  GdkRectangle               *background_area,
53                                                  GdkRectangle               *cell_area,
54                                                  GdkRectangle               *expose_area,
55                                                  GtkCellRendererState        flags);
56
57
58 enum {
59         PROP_ZERO,
60         PROP_PIXBUF,
61         PROP_PIXBUF_EXPANDER_OPEN,
62         PROP_PIXBUF_EXPANDER_CLOSED,
63         PROP_STOCK_ID,
64         PROP_STOCK_SIZE,
65         PROP_STOCK_DETAIL,
66         PROP_FOLLOW_STATE,
67         PROP_ICON_NAME
68 };
69
70
71 #define GTK_CELL_RENDERER_PIXBUF_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_CELL_RENDERER_PIXBUF, GtkCellRendererPixbufPrivate))
72
73 typedef struct _GtkCellRendererPixbufPrivate GtkCellRendererPixbufPrivate;
74 struct _GtkCellRendererPixbufPrivate
75 {
76   gchar *stock_id;
77   GtkIconSize stock_size;
78   gchar *stock_detail;
79   gboolean follow_state;
80
81   gchar *icon_name;
82 };
83
84 G_DEFINE_TYPE (GtkCellRendererPixbuf, gtk_cell_renderer_pixbuf, GTK_TYPE_CELL_RENDERER)
85
86 static void
87 gtk_cell_renderer_pixbuf_init (GtkCellRendererPixbuf *cellpixbuf)
88 {
89   GtkCellRendererPixbufPrivate *priv;
90
91   priv = GTK_CELL_RENDERER_PIXBUF_GET_PRIVATE (cellpixbuf);
92   priv->stock_size = GTK_ICON_SIZE_MENU;
93 }
94
95 static void
96 gtk_cell_renderer_pixbuf_class_init (GtkCellRendererPixbufClass *class)
97 {
98   GObjectClass *object_class = G_OBJECT_CLASS (class);
99   GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (class);
100
101   object_class->finalize = gtk_cell_renderer_pixbuf_finalize;
102
103   object_class->get_property = gtk_cell_renderer_pixbuf_get_property;
104   object_class->set_property = gtk_cell_renderer_pixbuf_set_property;
105
106   cell_class->get_size = gtk_cell_renderer_pixbuf_get_size;
107   cell_class->render = gtk_cell_renderer_pixbuf_render;
108
109   g_object_class_install_property (object_class,
110                                    PROP_PIXBUF,
111                                    g_param_spec_object ("pixbuf",
112                                                         P_("Pixbuf Object"),
113                                                         P_("The pixbuf to render"),
114                                                         GDK_TYPE_PIXBUF,
115                                                         GTK_PARAM_READWRITE));
116
117   g_object_class_install_property (object_class,
118                                    PROP_PIXBUF_EXPANDER_OPEN,
119                                    g_param_spec_object ("pixbuf-expander-open",
120                                                         P_("Pixbuf Expander Open"),
121                                                         P_("Pixbuf for open expander"),
122                                                         GDK_TYPE_PIXBUF,
123                                                         GTK_PARAM_READWRITE));
124
125   g_object_class_install_property (object_class,
126                                    PROP_PIXBUF_EXPANDER_CLOSED,
127                                    g_param_spec_object ("pixbuf-expander-closed",
128                                                         P_("Pixbuf Expander Closed"),
129                                                         P_("Pixbuf for closed expander"),
130                                                         GDK_TYPE_PIXBUF,
131                                                         GTK_PARAM_READWRITE));
132
133   g_object_class_install_property (object_class,
134                                    PROP_STOCK_ID,
135                                    g_param_spec_string ("stock-id",
136                                                         P_("Stock ID"),
137                                                         P_("The stock ID of the stock icon to render"),
138                                                         NULL,
139                                                         GTK_PARAM_READWRITE));
140
141   g_object_class_install_property (object_class,
142                                    PROP_STOCK_SIZE,
143                                    g_param_spec_uint ("stock-size",
144                                                       P_("Size"),
145                                                       P_("The GtkIconSize value that specifies the size of the rendered icon"),
146                                                       0,
147                                                       G_MAXUINT,
148                                                       GTK_ICON_SIZE_MENU,
149                                                       GTK_PARAM_READWRITE));
150
151   g_object_class_install_property (object_class,
152                                    PROP_STOCK_DETAIL,
153                                    g_param_spec_string ("stock-detail",
154                                                         P_("Detail"),
155                                                         P_("Render detail to pass to the theme engine"),
156                                                         NULL,
157                                                         GTK_PARAM_READWRITE));
158
159   
160   /**
161    * GtkCellRendererPixbuf:icon-name:
162    *
163    * The name of the themed icon to display.
164    * This property only has an effect if not overridden by "stock_id" 
165    * or "pixbuf" properties.
166    *
167    * Since: 2.8 
168    */
169   g_object_class_install_property (object_class,
170                                    PROP_ICON_NAME,
171                                    g_param_spec_string ("icon-name",
172                                                         P_("Icon Name"),
173                                                         P_("The name of the icon from the icon theme"),
174                                                         NULL,
175                                                         GTK_PARAM_READWRITE));
176
177   /**
178    * GtkCellRendererPixbuf:follow-state:
179    *
180    * Specifies whether the rendered pixbuf should be colorized
181    * according to the #GtkCellRendererState.
182    *
183    * Since: 2.8
184    */
185   g_object_class_install_property (object_class,
186                                    PROP_FOLLOW_STATE,
187                                    g_param_spec_boolean ("follow-state",
188                                                          P_("Follow State"),
189                                                          P_("Whether the rendered pixbuf should be "
190                                                             "colorized according to the state"),
191                                                          FALSE,
192                                                          GTK_PARAM_READWRITE));
193
194
195   g_type_class_add_private (object_class, sizeof (GtkCellRendererPixbufPrivate));
196 }
197
198 static void
199 gtk_cell_renderer_pixbuf_finalize (GObject *object)
200 {
201   GtkCellRendererPixbuf *cellpixbuf = GTK_CELL_RENDERER_PIXBUF (object);
202   GtkCellRendererPixbufPrivate *priv;
203
204   priv = GTK_CELL_RENDERER_PIXBUF_GET_PRIVATE (object);
205   
206   if (cellpixbuf->pixbuf)
207     g_object_unref (cellpixbuf->pixbuf);
208   if (cellpixbuf->pixbuf_expander_open)
209     g_object_unref (cellpixbuf->pixbuf_expander_open);
210   if (cellpixbuf->pixbuf_expander_closed)
211     g_object_unref (cellpixbuf->pixbuf_expander_closed);
212
213   g_free (priv->stock_id);
214   g_free (priv->stock_detail);
215   g_free (priv->icon_name);
216
217   (* G_OBJECT_CLASS (gtk_cell_renderer_pixbuf_parent_class)->finalize) (object);
218 }
219
220 static void
221 gtk_cell_renderer_pixbuf_get_property (GObject        *object,
222                                        guint           param_id,
223                                        GValue         *value,
224                                        GParamSpec     *pspec)
225 {
226   GtkCellRendererPixbuf *cellpixbuf = GTK_CELL_RENDERER_PIXBUF (object);
227   GtkCellRendererPixbufPrivate *priv;
228
229   priv = GTK_CELL_RENDERER_PIXBUF_GET_PRIVATE (object);
230   
231   switch (param_id)
232     {
233     case PROP_PIXBUF:
234       g_value_set_object (value, G_OBJECT (cellpixbuf->pixbuf));
235       break;
236     case PROP_PIXBUF_EXPANDER_OPEN:
237       g_value_set_object (value, G_OBJECT (cellpixbuf->pixbuf_expander_open));
238       break;
239     case PROP_PIXBUF_EXPANDER_CLOSED:
240       g_value_set_object (value, G_OBJECT (cellpixbuf->pixbuf_expander_closed));
241       break;
242     case PROP_STOCK_ID:
243       g_value_set_string (value, priv->stock_id);
244       break;
245     case PROP_STOCK_SIZE:
246       g_value_set_uint (value, priv->stock_size);
247       break;
248     case PROP_STOCK_DETAIL:
249       g_value_set_string (value, priv->stock_detail);
250       break;
251     case PROP_FOLLOW_STATE:
252       g_value_set_boolean (value, priv->follow_state);
253       break;
254     case PROP_ICON_NAME:
255       g_value_set_string (value, priv->icon_name);
256       break;
257     default:
258       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
259       break;
260     }
261 }
262
263
264 static void
265 gtk_cell_renderer_pixbuf_set_property (GObject      *object,
266                                        guint         param_id,
267                                        const GValue *value,
268                                        GParamSpec   *pspec)
269 {
270   GtkCellRendererPixbuf *cellpixbuf = GTK_CELL_RENDERER_PIXBUF (object);
271   GtkCellRendererPixbufPrivate *priv;
272
273   priv = GTK_CELL_RENDERER_PIXBUF_GET_PRIVATE (object);
274   
275   switch (param_id)
276     {
277     case PROP_PIXBUF:
278       if (cellpixbuf->pixbuf)
279         g_object_unref (cellpixbuf->pixbuf);
280       cellpixbuf->pixbuf = (GdkPixbuf*) g_value_dup_object (value);
281       if (cellpixbuf->pixbuf)
282         {
283           if (priv->stock_id)
284             {
285               g_free (priv->stock_id);
286               priv->stock_id = NULL;
287               g_object_notify (object, "stock-id");
288             }
289           if (priv->icon_name)
290             {
291               g_free (priv->icon_name);
292               priv->icon_name = NULL;
293               g_object_notify (object, "icon-name");
294             }
295         }
296       break;
297     case PROP_PIXBUF_EXPANDER_OPEN:
298       if (cellpixbuf->pixbuf_expander_open)
299         g_object_unref (cellpixbuf->pixbuf_expander_open);
300       cellpixbuf->pixbuf_expander_open = (GdkPixbuf*) g_value_dup_object (value);
301       break;
302     case PROP_PIXBUF_EXPANDER_CLOSED:
303       if (cellpixbuf->pixbuf_expander_closed)
304         g_object_unref (cellpixbuf->pixbuf_expander_closed);
305       cellpixbuf->pixbuf_expander_closed = (GdkPixbuf*) g_value_dup_object (value);
306       break;
307     case PROP_STOCK_ID:
308       if (priv->stock_id)
309         {
310           if (cellpixbuf->pixbuf)
311             {
312               g_object_unref (cellpixbuf->pixbuf);
313               cellpixbuf->pixbuf = NULL;
314               g_object_notify (object, "pixbuf");
315             }
316           g_free (priv->stock_id);
317         }
318       priv->stock_id = g_value_dup_string (value);
319       if (priv->stock_id)
320         {
321           if (cellpixbuf->pixbuf)
322             {
323               g_object_unref (cellpixbuf->pixbuf);
324               cellpixbuf->pixbuf = NULL;
325               g_object_notify (object, "pixbuf");
326             }
327           if (priv->icon_name)
328             {
329               g_free (priv->icon_name);
330               priv->icon_name = NULL;
331               g_object_notify (object, "icon-name");
332             }
333         }
334       break;
335     case PROP_STOCK_SIZE:
336       priv->stock_size = g_value_get_uint (value);
337       break;
338     case PROP_STOCK_DETAIL:
339       if (priv->stock_detail)
340         g_free (priv->stock_detail);
341       priv->stock_detail = g_value_dup_string (value);
342       break;
343     case PROP_ICON_NAME:
344       if (priv->icon_name)
345         {
346           if (cellpixbuf->pixbuf)
347             {
348               g_object_unref (cellpixbuf->pixbuf);
349               cellpixbuf->pixbuf = NULL;
350               g_object_notify (object, "pixbuf");
351             }
352           g_free (priv->icon_name);
353         }
354       priv->icon_name = g_value_dup_string (value);
355       if (priv->icon_name)
356         {
357           if (cellpixbuf->pixbuf)
358             {
359               g_object_unref (cellpixbuf->pixbuf);
360               cellpixbuf->pixbuf = NULL;
361               g_object_notify (object, "pixbuf");
362             }
363           if (priv->stock_id)
364             {
365               g_free (priv->stock_id);
366               priv->stock_id = NULL;
367               g_object_notify (object, "stock-id");
368             }
369         }
370       break;
371     case PROP_FOLLOW_STATE:
372       priv->follow_state = g_value_get_boolean (value);
373       break;
374     default:
375       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
376       break;
377     }
378 }
379
380 /**
381  * gtk_cell_renderer_pixbuf_new:
382  * 
383  * Creates a new #GtkCellRendererPixbuf. Adjust rendering
384  * parameters using object properties. Object properties can be set
385  * globally (with g_object_set()). Also, with #GtkTreeViewColumn, you
386  * can bind a property to a value in a #GtkTreeModel. For example, you
387  * can bind the "pixbuf" property on the cell renderer to a pixbuf value
388  * in the model, thus rendering a different image in each row of the
389  * #GtkTreeView.
390  * 
391  * Return value: the new cell renderer
392  **/
393 GtkCellRenderer *
394 gtk_cell_renderer_pixbuf_new (void)
395 {
396   return g_object_new (GTK_TYPE_CELL_RENDERER_PIXBUF, NULL);
397 }
398
399 static void
400 gtk_cell_renderer_pixbuf_create_stock_pixbuf (GtkCellRendererPixbuf *cellpixbuf,
401                                               GtkWidget             *widget)
402 {
403   GtkCellRendererPixbufPrivate *priv;
404
405   priv = GTK_CELL_RENDERER_PIXBUF_GET_PRIVATE (cellpixbuf);
406
407   if (cellpixbuf->pixbuf)
408     g_object_unref (cellpixbuf->pixbuf);
409
410   cellpixbuf->pixbuf = gtk_widget_render_icon (widget,
411                                                priv->stock_id,
412                                                priv->stock_size,
413                                                priv->stock_detail);
414
415   g_object_notify (G_OBJECT (cellpixbuf), "pixbuf");
416 }
417
418 static void 
419 gtk_cell_renderer_pixbuf_create_named_icon_pixbuf (GtkCellRendererPixbuf *cellpixbuf,
420                                                    GtkWidget             *widget)
421 {
422   GtkCellRendererPixbufPrivate *priv;
423   GdkScreen *screen;
424   GtkIconTheme *icon_theme;
425   GtkSettings *settings;
426   gint width, height;
427   GError *error = NULL;
428
429   priv = GTK_CELL_RENDERER_PIXBUF_GET_PRIVATE (cellpixbuf);
430
431   if (cellpixbuf->pixbuf)
432     g_object_unref (cellpixbuf->pixbuf);
433
434   screen = gtk_widget_get_screen (GTK_WIDGET (widget));
435   icon_theme = gtk_icon_theme_get_for_screen (screen);
436   settings = gtk_settings_get_for_screen (screen);
437
438   if (!gtk_icon_size_lookup_for_settings (settings,
439                                           priv->stock_size,
440                                           &width, &height))
441     {
442       g_warning ("Invalid icon size %u\n", priv->stock_size);
443       width = height = 24;
444     }
445
446   cellpixbuf->pixbuf =
447     gtk_icon_theme_load_icon (icon_theme,
448                               priv->icon_name,
449                               MIN (width, height), 0, &error);
450   if (!cellpixbuf->pixbuf) 
451     {
452       g_warning ("could not load image: %s\n", error->message);
453       g_error_free (error);
454     }
455
456   g_object_notify (G_OBJECT (cellpixbuf), "pixbuf");
457 }
458
459 static GdkPixbuf *
460 create_colorized_pixbuf (GdkPixbuf *src, 
461                          GdkColor  *new_color)
462 {
463   gint i, j;
464   gint width, height, has_alpha, src_row_stride, dst_row_stride;
465   gint red_value, green_value, blue_value;
466   guchar *target_pixels;
467   guchar *original_pixels;
468   guchar *pixsrc;
469   guchar *pixdest;
470   GdkPixbuf *dest;
471   
472   red_value = new_color->red / 255.0;
473   green_value = new_color->green / 255.0;
474   blue_value = new_color->blue / 255.0;
475   
476   dest = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (src),
477                          gdk_pixbuf_get_has_alpha (src),
478                          gdk_pixbuf_get_bits_per_sample (src),
479                          gdk_pixbuf_get_width (src),
480                          gdk_pixbuf_get_height (src));
481   
482   has_alpha = gdk_pixbuf_get_has_alpha (src);
483   width = gdk_pixbuf_get_width (src);
484   height = gdk_pixbuf_get_height (src);
485   src_row_stride = gdk_pixbuf_get_rowstride (src);
486   dst_row_stride = gdk_pixbuf_get_rowstride (dest);
487   target_pixels = gdk_pixbuf_get_pixels (dest);
488   original_pixels = gdk_pixbuf_get_pixels (src);
489   
490   for (i = 0; i < height; i++) {
491     pixdest = target_pixels + i*dst_row_stride;
492     pixsrc = original_pixels + i*src_row_stride;
493     for (j = 0; j < width; j++) {               
494       *pixdest++ = (*pixsrc++ * red_value) >> 8;
495       *pixdest++ = (*pixsrc++ * green_value) >> 8;
496       *pixdest++ = (*pixsrc++ * blue_value) >> 8;
497       if (has_alpha) {
498         *pixdest++ = *pixsrc++;
499       }
500     }
501   }
502   return dest;
503 }
504
505
506 static void
507 gtk_cell_renderer_pixbuf_get_size (GtkCellRenderer *cell,
508                                    GtkWidget       *widget,
509                                    GdkRectangle    *cell_area,
510                                    gint            *x_offset,
511                                    gint            *y_offset,
512                                    gint            *width,
513                                    gint            *height)
514 {
515   GtkCellRendererPixbuf *cellpixbuf = (GtkCellRendererPixbuf *) cell;
516   GtkCellRendererPixbufPrivate *priv;
517   gint pixbuf_width  = 0;
518   gint pixbuf_height = 0;
519   gint calc_width;
520   gint calc_height;
521
522   priv = GTK_CELL_RENDERER_PIXBUF_GET_PRIVATE (cell);
523
524   if (!cellpixbuf->pixbuf)
525     {
526       if (priv->stock_id)
527         gtk_cell_renderer_pixbuf_create_stock_pixbuf (cellpixbuf, widget);
528       else if (priv->icon_name)
529         gtk_cell_renderer_pixbuf_create_named_icon_pixbuf (cellpixbuf, widget);
530     }
531   
532   if (cellpixbuf->pixbuf)
533     {
534       pixbuf_width  = gdk_pixbuf_get_width (cellpixbuf->pixbuf);
535       pixbuf_height = gdk_pixbuf_get_height (cellpixbuf->pixbuf);
536     }
537   if (cellpixbuf->pixbuf_expander_open)
538     {
539       pixbuf_width  = MAX (pixbuf_width, gdk_pixbuf_get_width (cellpixbuf->pixbuf_expander_open));
540       pixbuf_height = MAX (pixbuf_height, gdk_pixbuf_get_height (cellpixbuf->pixbuf_expander_open));
541     }
542   if (cellpixbuf->pixbuf_expander_closed)
543     {
544       pixbuf_width  = MAX (pixbuf_width, gdk_pixbuf_get_width (cellpixbuf->pixbuf_expander_closed));
545       pixbuf_height = MAX (pixbuf_height, gdk_pixbuf_get_height (cellpixbuf->pixbuf_expander_closed));
546     }
547   
548   calc_width  = (gint) cell->xpad * 2 + pixbuf_width;
549   calc_height = (gint) cell->ypad * 2 + pixbuf_height;
550   
551   if (cell_area && pixbuf_width > 0 && pixbuf_height > 0)
552     {
553       if (x_offset)
554         {
555           *x_offset = (((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ?
556                         (1.0 - cell->xalign) : cell->xalign) * 
557                        (cell_area->width - calc_width));
558           *x_offset = MAX (*x_offset, 0);
559         }
560       if (y_offset)
561         {
562           *y_offset = (cell->yalign *
563                        (cell_area->height - calc_height));
564           *y_offset = MAX (*y_offset, 0);
565         }
566     }
567   else
568     {
569       if (x_offset) *x_offset = 0;
570       if (y_offset) *y_offset = 0;
571     }
572
573   if (width)
574     *width = calc_width;
575   
576   if (height)
577     *height = calc_height;
578 }
579
580 static void
581 gtk_cell_renderer_pixbuf_render (GtkCellRenderer      *cell,
582                                  GdkWindow            *window,
583                                  GtkWidget            *widget,
584                                  GdkRectangle         *background_area,
585                                  GdkRectangle         *cell_area,
586                                  GdkRectangle         *expose_area,
587                                  GtkCellRendererState  flags)
588
589 {
590   GtkCellRendererPixbuf *cellpixbuf = (GtkCellRendererPixbuf *) cell;
591   GtkCellRendererPixbufPrivate *priv;
592   GdkPixbuf *pixbuf;
593   GdkPixbuf *invisible = NULL;
594   GdkPixbuf *colorized = NULL;
595   GdkRectangle pix_rect;
596   GdkRectangle draw_rect;
597   cairo_t *cr;
598
599   priv = GTK_CELL_RENDERER_PIXBUF_GET_PRIVATE (cell);
600
601   gtk_cell_renderer_pixbuf_get_size (cell, widget, cell_area,
602                                      &pix_rect.x,
603                                      &pix_rect.y,
604                                      &pix_rect.width,
605                                      &pix_rect.height);
606
607   pix_rect.x += cell_area->x + cell->xpad;
608   pix_rect.y += cell_area->y + cell->ypad;
609   pix_rect.width  -= cell->xpad * 2;
610   pix_rect.height -= cell->ypad * 2;
611
612   if (!gdk_rectangle_intersect (cell_area, &pix_rect, &draw_rect) ||
613       !gdk_rectangle_intersect (expose_area, &draw_rect, &draw_rect))
614     return;
615
616   pixbuf = cellpixbuf->pixbuf;
617
618   if (cell->is_expander)
619     {
620       if (cell->is_expanded &&
621           cellpixbuf->pixbuf_expander_open != NULL)
622         pixbuf = cellpixbuf->pixbuf_expander_open;
623       else if (!cell->is_expanded &&
624                cellpixbuf->pixbuf_expander_closed != NULL)
625         pixbuf = cellpixbuf->pixbuf_expander_closed;
626     }
627
628   if (!pixbuf)
629     return;
630
631   if (GTK_WIDGET_STATE (widget) == GTK_STATE_INSENSITIVE || !cell->sensitive)
632     {
633       GtkIconSource *source;
634       
635       source = gtk_icon_source_new ();
636       gtk_icon_source_set_pixbuf (source, pixbuf);
637       /* The size here is arbitrary; since size isn't
638        * wildcarded in the source, it isn't supposed to be
639        * scaled by the engine function
640        */
641       gtk_icon_source_set_size (source, GTK_ICON_SIZE_SMALL_TOOLBAR);
642       gtk_icon_source_set_size_wildcarded (source, FALSE);
643       
644      invisible = gtk_style_render_icon (widget->style,
645                                         source,
646                                         gtk_widget_get_direction (widget),
647                                         GTK_STATE_INSENSITIVE,
648                                         /* arbitrary */
649                                         (GtkIconSize)-1,
650                                         widget,
651                                         "gtkcellrendererpixbuf");
652      
653      gtk_icon_source_free (source);
654      
655      pixbuf = invisible;
656     }
657   else if (priv->follow_state && 
658            (flags & (GTK_CELL_RENDERER_SELECTED|GTK_CELL_RENDERER_PRELIT)) != 0)
659     {
660       GtkStateType state;
661
662       if ((flags & GTK_CELL_RENDERER_SELECTED) != 0)
663         {
664           if (GTK_WIDGET_HAS_FOCUS (widget))
665             state = GTK_STATE_SELECTED;
666           else
667             state = GTK_STATE_ACTIVE;
668         }
669       else
670         state = GTK_STATE_PRELIGHT;
671
672       colorized = create_colorized_pixbuf (pixbuf,
673                                            &widget->style->base[state]);
674
675       pixbuf = colorized;
676     }
677
678   cr = gdk_cairo_create (window);
679   
680   gdk_cairo_set_source_pixbuf (cr, pixbuf, pix_rect.x, pix_rect.y);
681   gdk_cairo_rectangle (cr, &draw_rect);
682   cairo_fill (cr);
683
684   cairo_destroy (cr);
685   
686   if (invisible)
687     g_object_unref (invisible);
688
689   if (colorized)
690     g_object_unref (colorized);
691 }
692
693 #define __GTK_CELL_RENDERER_PIXBUF_C__
694 #include "gtkaliasdef.c"