void _gtk_icon_helper_clear (GtkIconHelper *self) { g_clear_object (&self->paintable); self->texture_is_symbolic = FALSE; if (gtk_image_definition_get_storage_type (self->def) != GTK_IMAGE_EMPTY) { gtk_image_definition_unref (self->def); self->def = gtk_image_definition_new_empty (); gtk_icon_helper_invalidate (self); } }
static GdkPaintable * gtk_icon_helper_load_paintable (GtkIconHelper *self, gboolean *out_symbolic) { GdkPaintable *paintable; GIcon *gicon; gboolean symbolic; switch (gtk_image_definition_get_storage_type (self->def)) { case GTK_IMAGE_PAINTABLE: paintable = g_object_ref (gtk_image_definition_get_paintable (self->def)); symbolic = FALSE; break; case GTK_IMAGE_ICON_NAME: if (self->use_fallback) gicon = g_themed_icon_new_with_default_fallbacks (gtk_image_definition_get_icon_name (self->def)); else gicon = g_themed_icon_new (gtk_image_definition_get_icon_name (self->def)); paintable = ensure_paintable_for_gicon (self, gtk_css_node_get_style (self->node), gtk_widget_get_direction (self->owner), gtk_widget_get_scale_factor (self->owner), gicon, &symbolic); g_object_unref (gicon); break; case GTK_IMAGE_GICON: paintable = ensure_paintable_for_gicon (self, gtk_css_node_get_style (self->node), gtk_widget_get_direction (self->owner), gtk_widget_get_scale_factor (self->owner), gtk_image_definition_get_gicon (self->def), &symbolic); break; case GTK_IMAGE_EMPTY: default: paintable = NULL; symbolic = FALSE; break; } *out_symbolic = symbolic; return paintable; }
void _gtk_icon_helper_set_pixbuf_scale (GtkIconHelper *self, int scale) { switch (gtk_image_definition_get_storage_type (self->priv->def)) { case GTK_IMAGE_PIXBUF: gtk_icon_helper_take_definition (self, gtk_image_definition_new_pixbuf (gtk_image_definition_get_pixbuf (self->priv->def), scale)); break; case GTK_IMAGE_ANIMATION: gtk_icon_helper_take_definition (self, gtk_image_definition_new_animation (gtk_image_definition_get_animation (self->priv->def), scale)); break; default: break; } }
gboolean _gtk_icon_helper_get_is_empty (GtkIconHelper *self) { return gtk_image_definition_get_storage_type (self->def) == GTK_IMAGE_EMPTY; }
GtkImageType _gtk_icon_helper_get_storage_type (GtkIconHelper *self) { return gtk_image_definition_get_storage_type (self->def); }
static void gtk_icon_helper_paintable_snapshot (GdkPaintable *paintable, GdkSnapshot *snapshot, double width, double height) { GtkIconHelper *self = GTK_ICON_HELPER (paintable); GtkCssStyle *style; style = gtk_css_node_get_style (self->node); gtk_icon_helper_ensure_paintable (self); if (self->paintable == NULL) return; switch (gtk_image_definition_get_storage_type (self->def)) { case GTK_IMAGE_ICON_NAME: case GTK_IMAGE_GICON: { double x, y, w, h; /* Never scale up icons. */ w = gdk_paintable_get_intrinsic_width (self->paintable); h = gdk_paintable_get_intrinsic_height (self->paintable); w = MIN (w, width); h = MIN (h, height); x = (width - w) / 2; y = (height - h) / 2; gtk_snapshot_offset (snapshot, x, y); gtk_css_style_snapshot_icon_paintable (style, snapshot, self->paintable, w, h, self->texture_is_symbolic); gtk_snapshot_offset (snapshot, -x, -y); } break; case GTK_IMAGE_PAINTABLE: case GTK_IMAGE_EMPTY: default: { double image_ratio = (double) width / height; double ratio; double x, y, w, h; if (self->paintable == NULL) break; ratio = gdk_paintable_get_intrinsic_aspect_ratio (self->paintable); if (ratio == 0) { w = width; h = height; } else if (ratio > image_ratio) { w = width; h = width / ratio; } else { w = height * ratio; h = height; } x = floor (width - ceil (w)) / 2; y = floor (height - ceil (h)) / 2; gtk_snapshot_offset (snapshot, x, y); gtk_css_style_snapshot_icon_paintable (style, snapshot, self->paintable, w, h, self->texture_is_symbolic); gtk_snapshot_offset (snapshot, -x, -y); } break; } }
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; }
cairo_surface_t * gtk_icon_helper_load_surface (GtkIconHelper *self, int scale) { cairo_surface_t *surface; GtkIconSet *icon_set; GIcon *gicon; switch (gtk_image_definition_get_storage_type (self->priv->def)) { case GTK_IMAGE_SURFACE: surface = ensure_surface_from_surface (self, gtk_image_definition_get_surface (self->priv->def)); break; case GTK_IMAGE_PIXBUF: surface = ensure_surface_from_pixbuf (self, gtk_css_node_get_style (gtk_css_gadget_get_node (GTK_CSS_GADGET (self))), scale, gtk_image_definition_get_pixbuf (self->priv->def), gtk_image_definition_get_scale (self->priv->def)); break; case GTK_IMAGE_STOCK: G_GNUC_BEGIN_IGNORE_DEPRECATIONS; icon_set = gtk_icon_factory_lookup_default (gtk_image_definition_get_stock (self->priv->def)); G_GNUC_END_IGNORE_DEPRECATIONS; if (icon_set != NULL) surface = ensure_surface_for_icon_set (self, gtk_css_node_get_style (gtk_css_gadget_get_node (GTK_CSS_GADGET (self))), gtk_widget_get_direction (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self))), scale, icon_set); else surface = NULL; break; case GTK_IMAGE_ICON_SET: icon_set = gtk_image_definition_get_icon_set (self->priv->def); surface = ensure_surface_for_icon_set (self, gtk_css_node_get_style (gtk_css_gadget_get_node (GTK_CSS_GADGET (self))), gtk_widget_get_direction (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self))), scale, icon_set); break; case GTK_IMAGE_ICON_NAME: if (self->priv->use_fallback) gicon = g_themed_icon_new_with_default_fallbacks (gtk_image_definition_get_icon_name (self->priv->def)); else gicon = g_themed_icon_new (gtk_image_definition_get_icon_name (self->priv->def)); surface = ensure_surface_for_gicon (self, gtk_css_node_get_style (gtk_css_gadget_get_node (GTK_CSS_GADGET (self))), gtk_widget_get_direction (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self))), scale, gicon); g_object_unref (gicon); break; case GTK_IMAGE_GICON: surface = ensure_surface_for_gicon (self, gtk_css_node_get_style (gtk_css_gadget_get_node (GTK_CSS_GADGET (self))), gtk_widget_get_direction (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self))), scale, gtk_image_definition_get_gicon (self->priv->def)); break; case GTK_IMAGE_ANIMATION: case GTK_IMAGE_EMPTY: default: surface = NULL; break; } return surface; }