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, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "config.h"
19
20#include "gtkcellrendererpixbuf.h"
21
22#include "gtkiconhelperprivate.h"
23#include "gtkicontheme.h"
24#include "gtkintl.h"
25#include "gtkprivate.h"
26#include "gtksnapshot.h"
27#include "gtkstylecontextprivate.h"
28#include "gtktypebuiltins.h"
29
30#include <cairo-gobject.h>
31#include <stdlib.h>
32
33/**
34 * GtkCellRendererPixbuf:
35 *
36 * Renders a pixbuf in a cell
37 *
38 * A `GtkCellRendererPixbuf` can be used to render an image in a cell. It allows
39 * to render either a given `GdkPixbuf` (set via the
40 * `GtkCellRendererPixbuf:pixbuf` property) or a named icon (set via the
41 * `GtkCellRendererPixbuf:icon-name` property).
42 *
43 * To support the tree view, `GtkCellRendererPixbuf` also supports rendering two
44 * alternative pixbufs, when the `GtkCellRenderer:is-expander` property is %TRUE.
45 * If the `GtkCellRenderer:is-expanded property` is %TRUE and the
46 * `GtkCellRendererPixbuf:pixbuf-expander-open` property is set to a pixbuf, it
47 * renders that pixbuf, if the `GtkCellRenderer:is-expanded` property is %FALSE
48 * and the `GtkCellRendererPixbuf:pixbuf-expander-closed` property is set to a
49 * pixbuf, it renders that one.
50 */
51
52
53static void gtk_cell_renderer_pixbuf_get_property (GObject *object,
54 guint param_id,
55 GValue *value,
56 GParamSpec *pspec);
57static void gtk_cell_renderer_pixbuf_set_property (GObject *object,
58 guint param_id,
59 const GValue *value,
60 GParamSpec *pspec);
61static void gtk_cell_renderer_pixbuf_get_size (GtkCellRendererPixbuf *self,
62 GtkWidget *widget,
63 const GdkRectangle *rectangle,
64 int *x_offset,
65 int *y_offset,
66 int *width,
67 int *height);
68static void gtk_cell_renderer_pixbuf_snapshot (GtkCellRenderer *cell,
69 GtkSnapshot *snapshot,
70 GtkWidget *widget,
71 const GdkRectangle *background_area,
72 const GdkRectangle *cell_area,
73 GtkCellRendererState flags);
74
75
76enum {
77 PROP_0,
78 PROP_PIXBUF,
79 PROP_PIXBUF_EXPANDER_OPEN,
80 PROP_PIXBUF_EXPANDER_CLOSED,
81 PROP_TEXTURE,
82 PROP_ICON_SIZE,
83 PROP_ICON_NAME,
84 PROP_GICON
85};
86
87typedef struct _GtkCellRendererPixbufPrivate GtkCellRendererPixbufPrivate;
88typedef struct _GtkCellRendererPixbufClass GtkCellRendererPixbufClass;
89
90struct _GtkCellRendererPixbuf
91{
92 GtkCellRenderer parent;
93};
94
95struct _GtkCellRendererPixbufClass
96{
97 GtkCellRendererClass parent_class;
98};
99
100struct _GtkCellRendererPixbufPrivate
101{
102 GtkImageDefinition *image_def;
103 GtkIconSize icon_size;
104
105 GdkPixbuf *pixbuf_expander_open;
106 GdkPixbuf *pixbuf_expander_closed;
107 GdkTexture *texture_expander_open;
108 GdkTexture *texture_expander_closed;
109};
110
111G_DEFINE_TYPE_WITH_PRIVATE (GtkCellRendererPixbuf, gtk_cell_renderer_pixbuf, GTK_TYPE_CELL_RENDERER)
112
113static void
114gtk_cell_renderer_pixbuf_init (GtkCellRendererPixbuf *cellpixbuf)
115{
116 GtkCellRendererPixbufPrivate *priv = gtk_cell_renderer_pixbuf_get_instance_private (self: cellpixbuf);
117
118 priv->image_def = gtk_image_definition_new_empty ();
119}
120
121static void
122gtk_cell_renderer_pixbuf_finalize (GObject *object)
123{
124 GtkCellRendererPixbuf *cellpixbuf = GTK_CELL_RENDERER_PIXBUF (object);
125 GtkCellRendererPixbufPrivate *priv = gtk_cell_renderer_pixbuf_get_instance_private (self: cellpixbuf);
126
127 gtk_image_definition_unref (def: priv->image_def);
128
129 g_clear_object (&priv->pixbuf_expander_open);
130 g_clear_object (&priv->pixbuf_expander_closed);
131 g_clear_object (&priv->texture_expander_open);
132 g_clear_object (&priv->texture_expander_closed);
133
134 G_OBJECT_CLASS (gtk_cell_renderer_pixbuf_parent_class)->finalize (object);
135}
136
137static GtkSizeRequestMode
138gtk_cell_renderer_pixbuf_get_request_mode (GtkCellRenderer *cell)
139{
140 return GTK_SIZE_REQUEST_CONSTANT_SIZE;
141}
142
143static void
144gtk_cell_renderer_pixbuf_get_preferred_width (GtkCellRenderer *cell,
145 GtkWidget *widget,
146 int *minimum,
147 int *natural)
148{
149 int size = 0;
150
151 gtk_cell_renderer_pixbuf_get_size (GTK_CELL_RENDERER_PIXBUF (cell), widget, NULL,
152 NULL, NULL, width: &size, NULL);
153
154 if (minimum != NULL)
155 *minimum = size;
156
157 if (natural != NULL)
158 *natural = size;
159}
160
161static void
162gtk_cell_renderer_pixbuf_get_preferred_height (GtkCellRenderer *cell,
163 GtkWidget *widget,
164 int *minimum,
165 int *natural)
166{
167 int size = 0;
168
169 gtk_cell_renderer_pixbuf_get_size (GTK_CELL_RENDERER_PIXBUF (cell), widget, NULL,
170 NULL, NULL, NULL, height: &size);
171
172 if (minimum != NULL)
173 *minimum = size;
174
175 if (natural != NULL)
176 *natural = size;
177}
178
179static void
180gtk_cell_renderer_pixbuf_class_init (GtkCellRendererPixbufClass *class)
181{
182 GObjectClass *object_class = G_OBJECT_CLASS (class);
183 GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (class);
184
185 object_class->finalize = gtk_cell_renderer_pixbuf_finalize;
186
187 object_class->get_property = gtk_cell_renderer_pixbuf_get_property;
188 object_class->set_property = gtk_cell_renderer_pixbuf_set_property;
189
190 cell_class->get_request_mode = gtk_cell_renderer_pixbuf_get_request_mode;
191 cell_class->get_preferred_width = gtk_cell_renderer_pixbuf_get_preferred_width;
192 cell_class->get_preferred_height = gtk_cell_renderer_pixbuf_get_preferred_height;
193 cell_class->snapshot = gtk_cell_renderer_pixbuf_snapshot;
194
195 g_object_class_install_property (oclass: object_class,
196 property_id: PROP_PIXBUF,
197 pspec: g_param_spec_object (name: "pixbuf",
198 P_("Pixbuf Object"),
199 P_("The pixbuf to render"),
200 GDK_TYPE_PIXBUF,
201 GTK_PARAM_WRITABLE));
202
203 g_object_class_install_property (oclass: object_class,
204 property_id: PROP_PIXBUF_EXPANDER_OPEN,
205 pspec: g_param_spec_object (name: "pixbuf-expander-open",
206 P_("Pixbuf Expander Open"),
207 P_("Pixbuf for open expander"),
208 GDK_TYPE_PIXBUF,
209 GTK_PARAM_READWRITE));
210
211 g_object_class_install_property (oclass: object_class,
212 property_id: PROP_PIXBUF_EXPANDER_CLOSED,
213 pspec: g_param_spec_object (name: "pixbuf-expander-closed",
214 P_("Pixbuf Expander Closed"),
215 P_("Pixbuf for closed expander"),
216 GDK_TYPE_PIXBUF,
217 GTK_PARAM_READWRITE));
218
219 /**
220 * GtkCellRendererPixbuf:texture:
221 */
222 g_object_class_install_property (oclass: object_class,
223 property_id: PROP_TEXTURE,
224 pspec: g_param_spec_object (name: "texture",
225 P_("Texture"),
226 P_("The texture to render"),
227 GDK_TYPE_TEXTURE,
228 GTK_PARAM_READWRITE));
229
230 /**
231 * GtkCellRendererPixbuf:icon-size:
232 *
233 * The `GtkIconSize` value that specifies the size of the rendered icon.
234 */
235 g_object_class_install_property (oclass: object_class,
236 property_id: PROP_ICON_SIZE,
237 pspec: g_param_spec_enum (name: "icon-size",
238 P_("Icon Size"),
239 P_("The GtkIconSize value that specifies the size of the rendered icon"),
240 enum_type: GTK_TYPE_ICON_SIZE,
241 default_value: GTK_ICON_SIZE_INHERIT,
242 GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY));
243
244 /**
245 * GtkCellRendererPixbuf:icon-name:
246 *
247 * The name of the themed icon to display.
248 * This property only has an effect if not overridden by the "pixbuf" property.
249 */
250 g_object_class_install_property (oclass: object_class,
251 property_id: PROP_ICON_NAME,
252 pspec: g_param_spec_string (name: "icon-name",
253 P_("Icon Name"),
254 P_("The name of the icon from the icon theme"),
255 NULL,
256 GTK_PARAM_READWRITE));
257
258 /**
259 * GtkCellRendererPixbuf:gicon:
260 *
261 * The GIcon representing the icon to display.
262 * If the icon theme is changed, the image will be updated
263 * automatically.
264 */
265 g_object_class_install_property (oclass: object_class,
266 property_id: PROP_GICON,
267 pspec: g_param_spec_object (name: "gicon",
268 P_("Icon"),
269 P_("The GIcon being displayed"),
270 G_TYPE_ICON,
271 GTK_PARAM_READWRITE));
272}
273
274static void
275gtk_cell_renderer_pixbuf_get_property (GObject *object,
276 guint param_id,
277 GValue *value,
278 GParamSpec *pspec)
279{
280 GtkCellRendererPixbuf *cellpixbuf = GTK_CELL_RENDERER_PIXBUF (object);
281 GtkCellRendererPixbufPrivate *priv = gtk_cell_renderer_pixbuf_get_instance_private (self: cellpixbuf);
282
283 switch (param_id)
284 {
285 case PROP_PIXBUF_EXPANDER_OPEN:
286 g_value_set_object (value, v_object: priv->pixbuf_expander_open);
287 break;
288 case PROP_PIXBUF_EXPANDER_CLOSED:
289 g_value_set_object (value, v_object: priv->pixbuf_expander_closed);
290 break;
291 case PROP_TEXTURE:
292 g_value_set_object (value, v_object: gtk_image_definition_get_paintable (def: priv->image_def));
293 break;
294 case PROP_ICON_SIZE:
295 g_value_set_enum (value, v_enum: priv->icon_size);
296 break;
297 case PROP_ICON_NAME:
298 g_value_set_string (value, v_string: gtk_image_definition_get_icon_name (def: priv->image_def));
299 break;
300 case PROP_GICON:
301 g_value_set_object (value, v_object: gtk_image_definition_get_gicon (def: priv->image_def));
302 break;
303 default:
304 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
305 break;
306 }
307}
308
309static void
310notify_storage_type (GtkCellRendererPixbuf *cellpixbuf,
311 GtkImageType storage_type)
312{
313 switch (storage_type)
314 {
315 case GTK_IMAGE_PAINTABLE:
316 g_object_notify (G_OBJECT (cellpixbuf), property_name: "texture");
317 break;
318 case GTK_IMAGE_ICON_NAME:
319 g_object_notify (G_OBJECT (cellpixbuf), property_name: "icon-name");
320 break;
321 case GTK_IMAGE_GICON:
322 g_object_notify (G_OBJECT (cellpixbuf), property_name: "gicon");
323 break;
324 default:
325 g_assert_not_reached ();
326 case GTK_IMAGE_EMPTY:
327 break;
328 }
329}
330
331static void
332take_image_definition (GtkCellRendererPixbuf *cellpixbuf,
333 GtkImageDefinition *def)
334{
335 GtkCellRendererPixbufPrivate *priv = gtk_cell_renderer_pixbuf_get_instance_private (self: cellpixbuf);
336 GtkImageType old_storage_type, new_storage_type;
337
338 if (def == NULL)
339 def = gtk_image_definition_new_empty ();
340
341 old_storage_type = gtk_image_definition_get_storage_type (def: priv->image_def);
342 new_storage_type = gtk_image_definition_get_storage_type (def);
343
344 if (new_storage_type != old_storage_type)
345 notify_storage_type (cellpixbuf, storage_type: old_storage_type);
346
347 gtk_image_definition_unref (def: priv->image_def);
348 priv->image_def = def;
349}
350
351static void
352gtk_cell_renderer_pixbuf_set_icon_size (GtkCellRendererPixbuf *cellpixbuf,
353 GtkIconSize icon_size)
354{
355 GtkCellRendererPixbufPrivate *priv = gtk_cell_renderer_pixbuf_get_instance_private (self: cellpixbuf);
356
357 if (priv->icon_size == icon_size)
358 return;
359
360 priv->icon_size = icon_size;
361 g_object_notify (G_OBJECT (cellpixbuf), property_name: "icon-size");
362}
363
364static void
365gtk_cell_renderer_pixbuf_set_property (GObject *object,
366 guint param_id,
367 const GValue *value,
368 GParamSpec *pspec)
369{
370 GtkCellRendererPixbuf *cellpixbuf = GTK_CELL_RENDERER_PIXBUF (object);
371 GtkCellRendererPixbufPrivate *priv = gtk_cell_renderer_pixbuf_get_instance_private (self: cellpixbuf);
372 GdkTexture *texture;
373 GdkPixbuf *pixbuf;
374
375 switch (param_id)
376 {
377 case PROP_PIXBUF:
378 pixbuf = g_value_get_object (value);
379 if (pixbuf)
380 texture = gdk_texture_new_for_pixbuf (pixbuf);
381 else
382 texture = NULL;
383 take_image_definition (cellpixbuf, def: gtk_image_definition_new_paintable (paintable: GDK_PAINTABLE (ptr: texture)));
384 break;
385 case PROP_PIXBUF_EXPANDER_OPEN:
386 g_clear_object (&priv->pixbuf_expander_open);
387 g_clear_object (&priv->texture_expander_open);
388 priv->pixbuf_expander_open = (GdkPixbuf*) g_value_dup_object (value);
389 priv->texture_expander_open = gdk_texture_new_for_pixbuf (pixbuf: priv->pixbuf_expander_open);
390 break;
391 case PROP_PIXBUF_EXPANDER_CLOSED:
392 g_clear_object (&priv->pixbuf_expander_closed);
393 g_clear_object (&priv->texture_expander_closed);
394 priv->pixbuf_expander_closed = (GdkPixbuf*) g_value_dup_object (value);
395 priv->texture_expander_closed = gdk_texture_new_for_pixbuf (pixbuf: priv->pixbuf_expander_open);
396 break;
397 case PROP_TEXTURE:
398 take_image_definition (cellpixbuf, def: gtk_image_definition_new_paintable (paintable: g_value_get_object (value)));
399 break;
400 case PROP_ICON_SIZE:
401 gtk_cell_renderer_pixbuf_set_icon_size (cellpixbuf, icon_size: g_value_get_enum (value));
402 break;
403 case PROP_ICON_NAME:
404 take_image_definition (cellpixbuf, def: gtk_image_definition_new_icon_name (icon_name: g_value_get_string (value)));
405 break;
406 case PROP_GICON:
407 take_image_definition (cellpixbuf, def: gtk_image_definition_new_gicon (gicon: g_value_get_object (value)));
408 break;
409 default:
410 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
411 break;
412 }
413}
414
415/**
416 * gtk_cell_renderer_pixbuf_new:
417 *
418 * Creates a new `GtkCellRendererPixbuf`. Adjust rendering
419 * parameters using object properties. Object properties can be set
420 * globally (with g_object_set()). Also, with `GtkTreeViewColumn`, you
421 * can bind a property to a value in a `GtkTreeModel`. For example, you
422 * can bind the “pixbuf” property on the cell renderer to a pixbuf value
423 * in the model, thus rendering a different image in each row of the
424 * `GtkTreeView`.
425 *
426 * Returns: the new cell renderer
427 **/
428GtkCellRenderer *
429gtk_cell_renderer_pixbuf_new (void)
430{
431 return g_object_new (GTK_TYPE_CELL_RENDERER_PIXBUF, NULL);
432}
433
434static GtkIconHelper *
435create_icon_helper (GtkCellRendererPixbuf *cellpixbuf,
436 GtkWidget *widget)
437{
438 GtkCellRendererPixbufPrivate *priv = gtk_cell_renderer_pixbuf_get_instance_private (self: cellpixbuf);
439 GtkIconHelper *icon_helper;
440
441 icon_helper = gtk_icon_helper_new (css_node: gtk_style_context_get_node (context: gtk_widget_get_style_context (widget)),
442 owner: widget);
443 _gtk_icon_helper_set_use_fallback (self: icon_helper, TRUE);
444 _gtk_icon_helper_set_definition (self: icon_helper, def: priv->image_def);
445
446 return icon_helper;
447}
448
449static void
450gtk_cell_renderer_pixbuf_get_size (GtkCellRendererPixbuf *self,
451 GtkWidget *widget,
452 const GdkRectangle *cell_area,
453 int *x_offset,
454 int *y_offset,
455 int *width,
456 int *height)
457{
458 GtkCellRendererPixbufPrivate *priv = gtk_cell_renderer_pixbuf_get_instance_private (self);
459 GtkCellRenderer *cell = GTK_CELL_RENDERER (self);
460 int pixbuf_width;
461 int pixbuf_height;
462 int calc_width;
463 int calc_height;
464 int xpad, ypad;
465 GtkStyleContext *context;
466 GtkIconHelper *icon_helper;
467
468 context = gtk_widget_get_style_context (widget);
469 gtk_style_context_save (context);
470 gtk_style_context_add_class (context, class_name: "image");
471 gtk_icon_size_set_style_classes (cssnode: gtk_style_context_get_node (context), icon_size: priv->icon_size);
472 icon_helper = create_icon_helper (cellpixbuf: self, widget);
473
474 if (_gtk_icon_helper_get_is_empty (self: icon_helper))
475 pixbuf_width = pixbuf_height = 0;
476 else if (gtk_image_definition_get_paintable (def: priv->image_def))
477 {
478 GdkPaintable *paintable = gtk_image_definition_get_paintable (def: priv->image_def);
479 pixbuf_width = gdk_paintable_get_intrinsic_width (paintable);
480 pixbuf_height = gdk_paintable_get_intrinsic_height (paintable);
481 }
482 else
483 pixbuf_width = pixbuf_height = gtk_icon_helper_get_size (self: icon_helper);
484
485 g_object_unref (object: icon_helper);
486 gtk_style_context_restore (context);
487
488 if (priv->pixbuf_expander_open)
489 {
490 pixbuf_width = MAX (pixbuf_width, gdk_pixbuf_get_width (priv->pixbuf_expander_open));
491 pixbuf_height = MAX (pixbuf_height, gdk_pixbuf_get_height (priv->pixbuf_expander_open));
492 }
493 if (priv->pixbuf_expander_closed)
494 {
495 pixbuf_width = MAX (pixbuf_width, gdk_pixbuf_get_width (priv->pixbuf_expander_closed));
496 pixbuf_height = MAX (pixbuf_height, gdk_pixbuf_get_height (priv->pixbuf_expander_closed));
497 }
498
499 gtk_cell_renderer_get_padding (cell, xpad: &xpad, ypad: &ypad);
500 calc_width = (int) xpad * 2 + pixbuf_width;
501 calc_height = (int) ypad * 2 + pixbuf_height;
502
503 if (cell_area && pixbuf_width > 0 && pixbuf_height > 0)
504 {
505 float xalign, yalign;
506
507 gtk_cell_renderer_get_alignment (cell, xalign: &xalign, yalign: &yalign);
508 if (x_offset)
509 {
510 *x_offset = (((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ?
511 (1.0 - xalign) : xalign) *
512 (cell_area->width - calc_width));
513 *x_offset = MAX (*x_offset, 0);
514 }
515 if (y_offset)
516 {
517 *y_offset = (yalign *
518 (cell_area->height - calc_height));
519 *y_offset = MAX (*y_offset, 0);
520 }
521 }
522 else
523 {
524 if (x_offset) *x_offset = 0;
525 if (y_offset) *y_offset = 0;
526 }
527
528 if (width)
529 *width = calc_width;
530
531 if (height)
532 *height = calc_height;
533}
534
535static void
536gtk_cell_renderer_pixbuf_snapshot (GtkCellRenderer *cell,
537 GtkSnapshot *snapshot,
538 GtkWidget *widget,
539 const GdkRectangle *background_area,
540 const GdkRectangle *cell_area,
541 GtkCellRendererState flags)
542
543{
544 GtkCellRendererPixbuf *cellpixbuf = GTK_CELL_RENDERER_PIXBUF (cell);
545 GtkCellRendererPixbufPrivate *priv = gtk_cell_renderer_pixbuf_get_instance_private (self: cellpixbuf);
546 GtkStyleContext *context;
547 GdkRectangle pix_rect;
548 gboolean is_expander;
549 int xpad, ypad;
550 GtkIconHelper *icon_helper;
551
552 gtk_cell_renderer_pixbuf_get_size (self: cellpixbuf, widget,
553 cell_area,
554 x_offset: &pix_rect.x,
555 y_offset: &pix_rect.y,
556 width: &pix_rect.width,
557 height: &pix_rect.height);
558
559 gtk_cell_renderer_get_padding (cell, xpad: &xpad, ypad: &ypad);
560 pix_rect.x += cell_area->x + xpad;
561 pix_rect.y += cell_area->y + ypad;
562 pix_rect.width -= xpad * 2;
563 pix_rect.height -= ypad * 2;
564
565 if (!gdk_rectangle_intersect (src1: cell_area, src2: &pix_rect, NULL))
566 return;
567
568 context = gtk_widget_get_style_context (widget);
569 gtk_style_context_save (context);
570
571 gtk_style_context_add_class (context, class_name: "image");
572 gtk_icon_size_set_style_classes (cssnode: gtk_style_context_get_node (context), icon_size: priv->icon_size);
573
574 is_expander = gtk_cell_renderer_get_is_expander (cell);
575 if (is_expander)
576 {
577 gboolean is_expanded = gtk_cell_renderer_get_is_expanded (cell);;
578
579 if (is_expanded && priv->pixbuf_expander_open != NULL)
580 {
581 icon_helper = gtk_icon_helper_new (css_node: gtk_style_context_get_node (context), owner: widget);
582 _gtk_icon_helper_set_paintable (self: icon_helper, paintable: GDK_PAINTABLE (ptr: priv->texture_expander_open));
583 }
584 else if (!is_expanded && priv->pixbuf_expander_closed != NULL)
585 {
586 icon_helper = gtk_icon_helper_new (css_node: gtk_style_context_get_node (context), owner: widget);
587 _gtk_icon_helper_set_paintable (self: icon_helper, paintable: GDK_PAINTABLE (ptr: priv->texture_expander_closed));
588 }
589 else
590 {
591 icon_helper = create_icon_helper (cellpixbuf, widget);
592 }
593 }
594 else
595 {
596 icon_helper = create_icon_helper (cellpixbuf, widget);
597 }
598
599 gtk_snapshot_save (snapshot);
600 gtk_snapshot_translate (snapshot, point: &GRAPHENE_POINT_INIT (pix_rect.x, pix_rect.y));
601 gdk_paintable_snapshot (paintable: GDK_PAINTABLE (ptr: icon_helper), snapshot, width: pix_rect.width, height: pix_rect.height);
602 gtk_snapshot_restore (snapshot);
603
604 g_object_unref (object: icon_helper);
605 gtk_style_context_restore (context);
606}
607

source code of gtk/gtk/gtkcellrendererpixbuf.c