static void ensure_surface_from_pixbuf (GtkIconHelper *self, GtkStyleContext *context) { gint width, height; GdkPixbuf *pixbuf, *stated; int scale; if (!check_invalidate_surface (self, context)) return; if (self->priv->rendered_surface) return; if (get_pixbuf_size (self, context, &width, &height, &scale)) pixbuf = gdk_pixbuf_scale_simple (self->priv->orig_pixbuf, width, height, GDK_INTERP_BILINEAR); else pixbuf = g_object_ref (self->priv->orig_pixbuf); stated = ensure_stated_pixbuf_from_pixbuf (self, context, pixbuf); g_object_unref (pixbuf); pixbuf = stated; self->priv->rendered_surface_width = (width + scale - 1) / scale; self->priv->rendered_surface_height = (height + scale - 1) / scale; self->priv->rendered_surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, self->priv->window); g_object_unref (pixbuf); }
static cairo_surface_t * ensure_surface_from_pixbuf (GtkIconHelper *self, GtkCssStyle *style, gint scale, GdkPixbuf *orig_pixbuf, gint orig_scale) { gint width, height; cairo_surface_t *surface; GdkPixbuf *pixbuf; GtkCssIconEffect icon_effect; if (get_pixbuf_size (self, scale, orig_pixbuf, orig_scale, &width, &height, &scale)) pixbuf = gdk_pixbuf_scale_simple (orig_pixbuf, width, height, GDK_INTERP_BILINEAR); else pixbuf = g_object_ref (orig_pixbuf); surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, gtk_widget_get_window (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self)))); icon_effect = _gtk_css_icon_effect_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_EFFECT)); gtk_css_icon_effect_apply (icon_effect, surface); g_object_unref (pixbuf); return surface; }
void _gtk_icon_helper_get_size (GtkIconHelper *self, GtkStyleContext *context, gint *width_out, gint *height_out) { cairo_surface_t *surface; gint width, height, scale; width = height = 0; /* Certain kinds of images are easy to calculate the size for, these we do immediately to avoid having to potentially load the image data for something that may not yet be visible */ switch (self->priv->storage_type) { case GTK_IMAGE_SURFACE: get_surface_size (self, context, self->priv->orig_surface, &width, &height); break; case GTK_IMAGE_PIXBUF: get_pixbuf_size (self, context, &width, &height, &scale); width = (width + scale - 1) / scale; height = (height + scale - 1) / scale; break; case GTK_IMAGE_ICON_NAME: case GTK_IMAGE_GICON: if (self->priv->pixel_size != -1 || self->priv->force_scale_pixbuf) ensure_icon_size (self, context, &width, &height); break; case GTK_IMAGE_STOCK: case GTK_IMAGE_ICON_SET: case GTK_IMAGE_ANIMATION: case GTK_IMAGE_EMPTY: default: break; } /* Otherwise we load the surface to guarantee we get a size */ if (width == 0) { surface = _gtk_icon_helper_ensure_surface (self, context); if (surface != NULL) { width = self->priv->rendered_surface_width; height = self->priv->rendered_surface_height; cairo_surface_destroy (surface); } else if (self->priv->storage_type == GTK_IMAGE_ANIMATION) { width = gdk_pixbuf_animation_get_width (self->priv->animation); height = gdk_pixbuf_animation_get_height (self->priv->animation); } else if (self->priv->icon_size != GTK_ICON_SIZE_INVALID) { ensure_icon_size (self, context, &width, &height); } } if (width_out) *width_out = width; if (height_out) *height_out = height; }
void _gtk_icon_helper_get_size (GtkIconHelper *self, gint *width_out, gint *height_out) { gint width, height, scale; width = height = 0; /* Certain kinds of images are easy to calculate the size for, these we do immediately to avoid having to potentially load the image data for something that may not yet be visible */ switch (gtk_image_definition_get_storage_type (self->priv->def)) { case GTK_IMAGE_SURFACE: get_surface_size (self, gtk_image_definition_get_surface (self->priv->def), &width, &height); break; case GTK_IMAGE_PIXBUF: get_pixbuf_size (self, gtk_widget_get_scale_factor (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self))), gtk_image_definition_get_pixbuf (self->priv->def), gtk_image_definition_get_scale (self->priv->def), &width, &height, &scale); width = (width + scale - 1) / scale; height = (height + scale - 1) / scale; break; case GTK_IMAGE_ANIMATION: { GdkPixbufAnimation *animation = gtk_image_definition_get_animation (self->priv->def); width = gdk_pixbuf_animation_get_width (animation); height = gdk_pixbuf_animation_get_height (animation); break; } case GTK_IMAGE_ICON_NAME: case GTK_IMAGE_GICON: if (self->priv->pixel_size != -1 || self->priv->force_scale_pixbuf) ensure_icon_size (self, &width, &height); break; case GTK_IMAGE_STOCK: case GTK_IMAGE_ICON_SET: case GTK_IMAGE_EMPTY: default: break; } /* Otherwise we load the surface to guarantee we get a size */ if (width == 0) { gtk_icon_helper_ensure_surface (self); if (self->priv->rendered_surface != NULL) { get_surface_size (self, self->priv->rendered_surface, &width, &height); } else if (self->priv->icon_size != GTK_ICON_SIZE_INVALID) { ensure_icon_size (self, &width, &height); } } if (width_out) *width_out = width; if (height_out) *height_out = height; }