static GdkPixbuf * photos_base_item_create_placeholder_icon (const gchar *icon_name) { GApplication *app; GdkPixbuf *centered_pixbuf = NULL; GdkPixbuf *pixbuf = NULL; GdkPixbuf *ret_val = NULL; GError *error; GIcon *icon = NULL; GList *windows; GtkIconInfo *info = NULL; GtkIconTheme *theme; GtkStyleContext *context; gint icon_size; gint scale; app = g_application_get_default (); windows = gtk_application_get_windows (GTK_APPLICATION (app)); if (windows == NULL) goto out; icon = g_themed_icon_new (icon_name); scale = photos_application_get_scale_factor (PHOTOS_APPLICATION (app)); theme = gtk_icon_theme_get_default (); info = gtk_icon_theme_lookup_by_gicon_for_scale (theme, icon, 16, scale, GTK_ICON_LOOKUP_FORCE_SIZE | GTK_ICON_LOOKUP_FORCE_SYMBOLIC); if (info == NULL) goto out; context = gtk_widget_get_style_context (GTK_WIDGET (windows->data)); error = NULL; pixbuf = gtk_icon_info_load_symbolic_for_context (info, context, NULL, &error); if (error != NULL) { g_warning ("Unable to load icon '%s': %s", icon_name, error->message); g_error_free (error); goto out; } icon_size = photos_utils_get_icon_size (); centered_pixbuf = photos_utils_center_pixbuf (pixbuf, icon_size); photos_utils_border_pixbuf (centered_pixbuf); ret_val = centered_pixbuf; centered_pixbuf = NULL; out: g_clear_object (¢ered_pixbuf); g_clear_object (&pixbuf); g_clear_object (&info); g_clear_object (&icon); return ret_val; }
GdkPixbuf * photos_utils_create_placeholder_icon_for_scale (const gchar *name, gint size, gint scale) { GApplication *app; g_autoptr (GdkPixbuf) centered_pixbuf = NULL; g_autoptr (GdkPixbuf) pixbuf = NULL; GdkPixbuf *ret_val = NULL; g_autoptr (GIcon) icon = NULL; GList *windows; g_autoptr (GtkIconInfo) info = NULL; GtkIconTheme *theme; GtkStyleContext *context; gint size_scaled; app = g_application_get_default (); windows = gtk_application_get_windows (GTK_APPLICATION (app)); if (windows == NULL) goto out; icon = g_themed_icon_new (name); theme = gtk_icon_theme_get_default (); info = gtk_icon_theme_lookup_by_gicon_for_scale (theme, icon, 16, scale, GTK_ICON_LOOKUP_FORCE_SIZE | GTK_ICON_LOOKUP_FORCE_SYMBOLIC); if (info == NULL) goto out; context = gtk_widget_get_style_context (GTK_WIDGET (windows->data)); { g_autoptr (GError) error = NULL; pixbuf = gtk_icon_info_load_symbolic_for_context (info, context, NULL, &error); if (error != NULL) { g_warning ("Unable to load icon '%s': %s", name, error->message); goto out; } } size_scaled = size * scale; centered_pixbuf = photos_utils_center_pixbuf (pixbuf, size_scaled); ret_val = centered_pixbuf; centered_pixbuf = NULL; out: return ret_val; }
static void ensure_surface_for_icon_name_or_gicon (GtkIconHelper *self, GtkStyleContext *context) { GtkIconTheme *icon_theme; gint width, height, scale; GtkIconInfo *info; GtkIconLookupFlags flags; if (!check_invalidate_surface (self, context)) return; icon_theme = gtk_icon_theme_get_default (); flags = get_icon_lookup_flags (self); ensure_icon_size (self, context, &width, &height); scale = get_scale_factor (self, context); if (self->priv->storage_type == GTK_IMAGE_ICON_NAME && self->priv->icon_name != NULL) { info = gtk_icon_theme_lookup_icon_for_scale (icon_theme, self->priv->icon_name, MIN (width, height), scale, flags); } else if (self->priv->storage_type == GTK_IMAGE_GICON && self->priv->gicon != NULL) { info = gtk_icon_theme_lookup_by_gicon_for_scale (icon_theme, self->priv->gicon, MIN (width, height), scale, flags); } else { g_assert_not_reached (); return; } ensure_stated_surface_from_info (self, context, info, scale); if (info) g_object_unref (info); }
static GdkPaintable * ensure_paintable_for_gicon (GtkIconHelper *self, GtkCssStyle *style, GtkTextDirection dir, gint scale, GIcon *gicon, gboolean *symbolic) { GtkIconTheme *icon_theme; gint width, height; GtkIconInfo *info; GtkIconLookupFlags flags; GdkPaintable *paintable; icon_theme = gtk_css_icon_theme_value_get_icon_theme (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_THEME)); flags = get_icon_lookup_flags (self, style, dir); width = height = gtk_icon_helper_get_size (self); info = gtk_icon_theme_lookup_by_gicon_for_scale (icon_theme, gicon, MIN (width, height), scale, flags); if (info == NULL) info = gtk_icon_theme_lookup_icon (icon_theme, "image-missing", width, flags | GTK_ICON_LOOKUP_USE_BUILTIN | GTK_ICON_LOOKUP_GENERIC_FALLBACK); *symbolic = gtk_icon_info_is_symbolic (info); paintable = GDK_PAINTABLE (gtk_icon_info_load_texture (info)); g_object_unref (info); if (paintable && scale != 1) { GdkPaintable *orig = paintable; paintable = gtk_scaler_new (orig, scale); g_object_unref (orig); } return paintable; }
/** * st_texture_cache_load_gicon: * @cache: The texture cache instance * @theme_node: (nullable): The #StThemeNode to use for colors, or NULL * if the icon must not be recolored * @icon: the #GIcon to load * @size: Size of themed * @scale: Scale factor of display * * This method returns a new #ClutterActor for a given #GIcon. If the * icon isn't loaded already, the texture will be filled * asynchronously. * * Return Value: (transfer none): A new #ClutterActor for the icon, or %NULL if not found */ ClutterActor * st_texture_cache_load_gicon (StTextureCache *cache, StThemeNode *theme_node, GIcon *icon, gint size, gint scale) { AsyncTextureLoadData *request; ClutterActor *texture; char *gicon_string; char *key; GtkIconTheme *theme; GtkIconInfo *info; StTextureCachePolicy policy; StIconColors *colors = NULL; StIconStyle icon_style = ST_ICON_STYLE_REQUESTED; GtkIconLookupFlags lookup_flags; if (theme_node) { colors = st_theme_node_get_icon_colors (theme_node); icon_style = st_theme_node_get_icon_style (theme_node); } /* Do theme lookups in the main thread to avoid thread-unsafety */ theme = cache->priv->icon_theme; lookup_flags = GTK_ICON_LOOKUP_USE_BUILTIN; if (icon_style == ST_ICON_STYLE_REGULAR) lookup_flags |= GTK_ICON_LOOKUP_FORCE_REGULAR; else if (icon_style == ST_ICON_STYLE_SYMBOLIC) lookup_flags |= GTK_ICON_LOOKUP_FORCE_SYMBOLIC; if (clutter_get_default_text_direction () == CLUTTER_TEXT_DIRECTION_RTL) lookup_flags |= GTK_ICON_LOOKUP_DIR_RTL; else lookup_flags |= GTK_ICON_LOOKUP_DIR_LTR; info = gtk_icon_theme_lookup_by_gicon_for_scale (theme, icon, size, scale, lookup_flags); if (info == NULL) return NULL; gicon_string = g_icon_to_string (icon); /* A return value of NULL indicates that the icon can not be serialized, * so don't have a unique identifier for it as a cache key, and thus can't * be cached. If it is cachable, we hardcode a policy of FOREVER here for * now; we should actually blow this away on icon theme changes probably */ policy = gicon_string != NULL ? ST_TEXTURE_CACHE_POLICY_FOREVER : ST_TEXTURE_CACHE_POLICY_NONE; if (colors) { /* This raises some doubts about the practice of using string keys */ key = g_strdup_printf (CACHE_PREFIX_ICON "%s,size=%d,scale=%d,style=%d,colors=%2x%2x%2x%2x,%2x%2x%2x%2x,%2x%2x%2x%2x,%2x%2x%2x%2x", gicon_string, size, scale, icon_style, colors->foreground.red, colors->foreground.blue, colors->foreground.green, colors->foreground.alpha, colors->warning.red, colors->warning.blue, colors->warning.green, colors->warning.alpha, colors->error.red, colors->error.blue, colors->error.green, colors->error.alpha, colors->success.red, colors->success.blue, colors->success.green, colors->success.alpha); } else { key = g_strdup_printf (CACHE_PREFIX_ICON "%s,size=%d,scale=%d,style=%d", gicon_string, size, scale, icon_style); } g_free (gicon_string); texture = (ClutterActor *) create_default_texture (); clutter_actor_set_size (texture, size * scale, size * scale); if (ensure_request (cache, key, policy, &request, texture)) { /* If there's an outstanding request, we've just added ourselves to it */ g_object_unref (info); g_free (key); } else { /* Else, make a new request */ request->cache = cache; /* Transfer ownership of key */ request->key = key; request->policy = policy; request->colors = colors ? st_icon_colors_ref (colors) : NULL; request->icon_info = info; request->width = request->height = size; request->scale = scale; load_texture_async (cache, request); } return CLUTTER_ACTOR (texture); }
static CoglHandle cinnamon_app_create_faded_icon_cpu (StTextureCache *cache, const char *key, void *datap, GError **error) { CreateFadedIconData *data = datap; CinnamonApp *app; GdkPixbuf *pixbuf; int size; int scale; CoglHandle texture; gint width, height, rowstride; guint8 n_channels; gboolean have_alpha; gint fade_start; gint fade_range; guint i, j; guint pixbuf_byte_size; guint8 *orig_pixels; guint8 *pixels; GIcon *icon; GtkIconInfo *info; app = data->app; size = data->size; scale = data->scale; info = NULL; icon = g_app_info_get_icon (G_APP_INFO (gmenu_tree_entry_get_app_info (app->entry))); if (icon != NULL) { info = gtk_icon_theme_lookup_by_gicon_for_scale (gtk_icon_theme_get_default (), icon, size, scale, GTK_ICON_LOOKUP_FORCE_SIZE); } if (info == NULL) { icon = g_themed_icon_new ("application-x-executable"); info = gtk_icon_theme_lookup_by_gicon_for_scale (gtk_icon_theme_get_default (), icon, size, scale, GTK_ICON_LOOKUP_FORCE_SIZE); g_object_unref (icon); } if (info == NULL) return COGL_INVALID_HANDLE; pixbuf = gtk_icon_info_load_icon (info, NULL); g_object_unref (info); if (pixbuf == NULL) return COGL_INVALID_HANDLE; width = gdk_pixbuf_get_width (pixbuf); height = gdk_pixbuf_get_height (pixbuf); rowstride = gdk_pixbuf_get_rowstride (pixbuf); n_channels = gdk_pixbuf_get_n_channels (pixbuf); orig_pixels = gdk_pixbuf_get_pixels (pixbuf); have_alpha = gdk_pixbuf_get_has_alpha (pixbuf); pixbuf_byte_size = (height - 1) * rowstride + + width * ((n_channels * gdk_pixbuf_get_bits_per_sample (pixbuf) + 7) / 8); pixels = g_malloc0 (rowstride * height); memcpy (pixels, orig_pixels, pixbuf_byte_size); fade_start = width / 2; fade_range = width - fade_start; for (i = fade_start; i < width; i++) { for (j = 0; j < height; j++) { guchar *pixel = &pixels[j * rowstride + i * n_channels]; float fade = 1.0 - ((float) i - fade_start) / fade_range; pixel[0] = 0.5 + pixel[0] * fade; pixel[1] = 0.5 + pixel[1] * fade; pixel[2] = 0.5 + pixel[2] * fade; if (have_alpha) pixel[3] = 0.5 + pixel[3] * fade; } } texture = st_cogl_texture_new_from_data_wrapper (width, height, COGL_TEXTURE_NONE, have_alpha ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888, COGL_PIXEL_FORMAT_ANY, rowstride, pixels); g_free (pixels); g_object_unref (pixbuf); return texture; }
static gboolean gtk_color_swatch_render_overlay (GtkCssGadget *gadget, cairo_t *cr, int x, int y, int width, int height, gpointer data) { GtkWidget *widget; GtkColorSwatch *swatch; GtkStyleContext *context; GtkStateFlags state; GtkIconTheme *theme; GtkIconInfo *icon_info = NULL; gint scale; widget = gtk_css_gadget_get_owner (gadget); swatch = GTK_COLOR_SWATCH (widget); theme = gtk_icon_theme_get_default (); context = gtk_widget_get_style_context (widget); state = gtk_style_context_get_state (context); scale = gtk_widget_get_scale_factor (widget); if (swatch->priv->icon) { icon_info = gtk_icon_theme_lookup_icon_for_scale (theme, swatch->priv->icon, PIXBUF_SIZE, scale, GTK_ICON_LOOKUP_GENERIC_FALLBACK | GTK_ICON_LOOKUP_USE_BUILTIN); } else if ((state & GTK_STATE_FLAG_SELECTED) != 0) { GIcon *gicon; gicon = g_themed_icon_new ("object-select-symbolic"); /* fallback for themes that don't have object-select-symbolic */ g_themed_icon_append_name (G_THEMED_ICON (gicon), "gtk-apply"); icon_info = gtk_icon_theme_lookup_by_gicon_for_scale (theme, gicon, PIXBUF_SIZE, scale, GTK_ICON_LOOKUP_USE_BUILTIN); g_object_unref (gicon); } /* now draw the overlay image */ if (icon_info != NULL) { GdkPixbuf *pixbuf; pixbuf = gtk_icon_info_load_symbolic_for_context (icon_info, context, NULL, NULL); if (pixbuf != NULL) { cairo_surface_t *surface; surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, gtk_widget_get_window (widget)); gtk_render_icon_surface (context, cr, surface, x, y); cairo_surface_destroy (surface); g_object_unref (pixbuf); } g_object_unref (icon_info); } return FALSE; }
static gboolean swatch_draw (GtkWidget *widget, cairo_t *cr) { GtkColorSwatch *swatch = (GtkColorSwatch*)widget; gdouble width, height; GtkStyleContext *context; GtkStateFlags state; GtkIconTheme *theme; GtkBorder border, padding; GdkRectangle rect; GtkIconInfo *icon_info = NULL; gint scale; theme = gtk_icon_theme_get_default (); context = gtk_widget_get_style_context (widget); state = gtk_style_context_get_state (context); width = gtk_widget_get_allocated_width (widget); height = gtk_widget_get_allocated_height (widget); gtk_render_background (context, cr, 0, 0, width, height); if (swatch->priv->has_color) { cairo_pattern_t *pattern; cairo_matrix_t matrix; gtk_render_content_path (context, cr, 0, 0, width, height); if (swatch->priv->use_alpha) { cairo_save (cr); cairo_clip_preserve (cr); cairo_set_source_rgb (cr, 0.33, 0.33, 0.33); cairo_fill_preserve (cr); pattern = _gtk_color_chooser_get_checkered_pattern (); cairo_matrix_init_scale (&matrix, 0.125, 0.125); cairo_pattern_set_matrix (pattern, &matrix); cairo_set_source_rgb (cr, 0.66, 0.66, 0.66); cairo_mask (cr, pattern); cairo_pattern_destroy (pattern); cairo_restore (cr); gdk_cairo_set_source_rgba (cr, &swatch->priv->color); } else { cairo_set_source_rgb (cr, swatch->priv->color.red, swatch->priv->color.green, swatch->priv->color.blue); } cairo_fill (cr); } gtk_render_frame (context, cr, 0, 0, width, height); scale = gtk_widget_get_scale_factor (widget); if (swatch->priv->icon) { icon_info = gtk_icon_theme_lookup_icon_for_scale (theme, swatch->priv->icon, PIXBUF_SIZE, scale, GTK_ICON_LOOKUP_GENERIC_FALLBACK | GTK_ICON_LOOKUP_USE_BUILTIN); } else if ((state & GTK_STATE_FLAG_SELECTED) != 0) { GIcon *gicon; gicon = g_themed_icon_new ("object-select-symbolic"); /* fallback for themes that don't have object-select-symbolic */ g_themed_icon_append_name (G_THEMED_ICON (gicon), "gtk-apply"); icon_info = gtk_icon_theme_lookup_by_gicon_for_scale (theme, gicon, PIXBUF_SIZE, scale, GTK_ICON_LOOKUP_GENERIC_FALLBACK | GTK_ICON_LOOKUP_USE_BUILTIN); g_object_unref (gicon); } /* now draw the overlay image */ gtk_style_context_get_border (context, state, &border); gtk_style_context_get_padding (context, state, &padding); rect.width = width - (border.left + border.right + padding.left + padding.right); rect.height = height - (border.top + border.bottom + padding.top + padding.bottom); rect.x = border.left + padding.left; rect.y = border.top + padding.top; gtk_style_context_save_to_node (context, swatch->priv->overlay_node); gtk_render_background (context, cr, rect.x, rect.y, rect.width, rect.height); gtk_render_frame (context, cr, rect.x, rect.y, rect.width, rect.height); if (icon_info != NULL) { GdkPixbuf *pixbuf; pixbuf = gtk_icon_info_load_symbolic_for_context (icon_info, context, NULL, NULL); if (pixbuf != NULL) { cairo_surface_t *surface; surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, gtk_widget_get_window (widget)); gtk_render_icon_surface (context, cr, surface, rect.x + (rect.width - (gdk_pixbuf_get_width (pixbuf) / scale)) / 2, rect.y + (rect.height - (gdk_pixbuf_get_height (pixbuf) / scale)) / 2); cairo_surface_destroy (surface); g_object_unref (pixbuf); } g_object_unref (icon_info); } if (gtk_widget_has_visible_focus (widget)) gtk_render_focus (context, cr, 0, 0, width, height); gtk_style_context_restore (context); return FALSE; }
static cairo_surface_t * ensure_surface_for_gicon (GtkIconHelper *self, GtkCssStyle *style, GtkTextDirection dir, gint scale, GIcon *gicon) { GtkIconHelperPrivate *priv = self->priv; GtkIconTheme *icon_theme; gint width, height; GtkIconInfo *info; GtkIconLookupFlags flags; cairo_surface_t *surface; GdkPixbuf *destination; gboolean symbolic; icon_theme = gtk_css_icon_theme_value_get_icon_theme (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_THEME)); flags = get_icon_lookup_flags (self, style, dir); ensure_icon_size (self, &width, &height); info = gtk_icon_theme_lookup_by_gicon_for_scale (icon_theme, gicon, MIN (width, height), scale, flags); if (info) { symbolic = gtk_icon_info_is_symbolic (info); if (symbolic) { GdkRGBA fg, success_color, warning_color, error_color; gtk_icon_theme_lookup_symbolic_colors (style, &fg, &success_color, &warning_color, &error_color); destination = gtk_icon_info_load_symbolic (info, &fg, &success_color, &warning_color, &error_color, NULL, NULL); } else { destination = gtk_icon_info_load_icon (info, NULL); } g_object_unref (info); } else { destination = NULL; } if (destination == NULL) { destination = gtk_icon_theme_load_icon (icon_theme, "image-missing", width, flags | GTK_ICON_LOOKUP_USE_BUILTIN | GTK_ICON_LOOKUP_GENERIC_FALLBACK, NULL); /* We include this image as resource, so we always have it available or * the icontheme code is broken */ g_assert (destination); symbolic = FALSE; } surface = gdk_cairo_surface_create_from_pixbuf (destination, scale, gtk_widget_get_window (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self)))); if (!symbolic) { GtkCssIconEffect icon_effect; 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); } else { priv->rendered_surface_is_symbolic = TRUE; } g_object_unref (destination); return surface; }
GIcon * photos_utils_create_symbolic_icon_for_scale (const gchar *name, gint base_size, gint scale) { g_autoptr (GIcon) icon = NULL; GIcon *ret_val = NULL; g_autoptr (GdkPixbuf) pixbuf = NULL; g_autoptr (GtkIconInfo) info = NULL; GtkIconTheme *theme; g_autoptr (GtkStyleContext) style = NULL; g_autoptr (GtkWidgetPath) path = NULL; cairo_surface_t *icon_surface = NULL; /* TODO: use g_autoptr */ cairo_surface_t *surface; /* TODO: use g_autoptr */ cairo_t *cr; /* TODO: use g_autoptr */ g_autofree gchar *symbolic_name = NULL; const gint bg_size = 24; const gint emblem_margin = 4; gint emblem_pos; gint emblem_size; gint total_size; gint total_size_scaled; total_size = base_size / 2; total_size_scaled = total_size * scale; emblem_size = bg_size - emblem_margin * 2; surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, total_size_scaled, total_size_scaled); cairo_surface_set_device_scale (surface, (gdouble) scale, (gdouble) scale); cr = cairo_create (surface); style = gtk_style_context_new (); path = gtk_widget_path_new (); gtk_widget_path_append_type (path, GTK_TYPE_ICON_VIEW); gtk_style_context_set_path (style, path); gtk_style_context_add_class (style, "photos-icon-bg"); gtk_render_background (style, cr, total_size - bg_size, total_size - bg_size, bg_size, bg_size); symbolic_name = g_strconcat (name, "-symbolic", NULL); icon = g_themed_icon_new_with_default_fallbacks (symbolic_name); theme = gtk_icon_theme_get_default(); info = gtk_icon_theme_lookup_by_gicon_for_scale (theme, icon, emblem_size, scale, GTK_ICON_LOOKUP_FORCE_SIZE); if (info == NULL) goto out; pixbuf = gtk_icon_info_load_symbolic_for_context (info, style, NULL, NULL); if (pixbuf == NULL) goto out; icon_surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, NULL); emblem_pos = total_size - emblem_size - emblem_margin; gtk_render_icon_surface (style, cr, icon_surface, emblem_pos, emblem_pos); ret_val = G_ICON (gdk_pixbuf_get_from_surface (surface, 0, 0, total_size_scaled, total_size_scaled)); out: cairo_surface_destroy (icon_surface); cairo_surface_destroy (surface); cairo_destroy (cr); return ret_val; }
/** * gd_create_symbolic_icon_for_scale: * @name: * @base_size: * @scale: * * Returns: (transfer full): */ GIcon * gd_create_symbolic_icon_for_scale (const gchar *name, gint base_size, gint scale) { gchar *symbolic_name; GIcon *icon, *retval = NULL; cairo_surface_t *icon_surface; cairo_surface_t *surface; cairo_t *cr; GtkStyleContext *style; GtkWidgetPath *path; GdkPixbuf *pixbuf; GtkIconTheme *theme; GtkIconInfo *info; gint bg_size; gint emblem_size; gint total_size; gint total_size_scaled; total_size = base_size / 2; total_size_scaled = total_size * scale; bg_size = MAX (total_size / 2, _BG_MIN_SIZE); emblem_size = MAX (bg_size - 8, _EMBLEM_MIN_SIZE); surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, total_size_scaled, total_size_scaled); cairo_surface_set_device_scale (surface, (gdouble) scale, (gdouble) scale); cr = cairo_create (surface); style = gtk_style_context_new (); path = gtk_widget_path_new (); gtk_widget_path_append_type (path, GTK_TYPE_ICON_VIEW); gtk_style_context_set_path (style, path); gtk_widget_path_unref (path); gtk_style_context_add_class (style, "documents-icon-bg"); gtk_render_background (style, cr, (total_size - bg_size) / 2, (total_size - bg_size) / 2, bg_size, bg_size); symbolic_name = g_strconcat (name, "-symbolic", NULL); icon = g_themed_icon_new_with_default_fallbacks (symbolic_name); g_free (symbolic_name); theme = gtk_icon_theme_get_default(); info = gtk_icon_theme_lookup_by_gicon_for_scale (theme, icon, emblem_size, scale, GTK_ICON_LOOKUP_FORCE_SIZE); g_object_unref (icon); if (info == NULL) goto out; pixbuf = gtk_icon_info_load_symbolic_for_context (info, style, NULL, NULL); g_object_unref (info); if (pixbuf == NULL) goto out; icon_surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, NULL); g_object_unref (pixbuf); gtk_render_icon_surface (style, cr, icon_surface, (total_size - emblem_size) / 2, (total_size - emblem_size) / 2); cairo_surface_destroy (icon_surface); retval = G_ICON (gdk_pixbuf_get_from_surface (surface, 0, 0, total_size_scaled, total_size_scaled)); out: g_object_unref (style); cairo_surface_destroy (surface); cairo_destroy (cr); return retval; }
NautilusIconInfo * nautilus_icon_info_lookup (GIcon *icon, int size, int scale) { NautilusIconInfo *icon_info; GdkPixbuf *pixbuf; if (G_IS_LOADABLE_ICON (icon)) { LoadableIconKey lookup_key; LoadableIconKey *key; GInputStream *stream; if (loadable_icon_cache == NULL) { loadable_icon_cache = g_hash_table_new_full ((GHashFunc)loadable_icon_key_hash, (GEqualFunc)loadable_icon_key_equal, (GDestroyNotify) loadable_icon_key_free, (GDestroyNotify) g_object_unref); } lookup_key.icon = icon; lookup_key.size = size; icon_info = g_hash_table_lookup (loadable_icon_cache, &lookup_key); if (icon_info) { return g_object_ref (icon_info); } pixbuf = NULL; stream = g_loadable_icon_load (G_LOADABLE_ICON (icon), size * scale, NULL, NULL, NULL); if (stream) { pixbuf = gdk_pixbuf_new_from_stream_at_scale (stream, size * scale, size * scale, TRUE, NULL, NULL); g_input_stream_close (stream, NULL, NULL); g_object_unref (stream); } icon_info = nautilus_icon_info_new_for_pixbuf (pixbuf, scale); key = loadable_icon_key_new (icon, size); g_hash_table_insert (loadable_icon_cache, key, icon_info); return g_object_ref (icon_info); } else if (G_IS_THEMED_ICON (icon)) { const char * const *names; ThemedIconKey lookup_key; ThemedIconKey *key; GtkIconTheme *icon_theme; GtkIconInfo *gtkicon_info; const char *filename; if (themed_icon_cache == NULL) { themed_icon_cache = g_hash_table_new_full ((GHashFunc)themed_icon_key_hash, (GEqualFunc)themed_icon_key_equal, (GDestroyNotify) themed_icon_key_free, (GDestroyNotify) g_object_unref); } names = g_themed_icon_get_names (G_THEMED_ICON (icon)); icon_theme = gtk_icon_theme_get_default (); gtkicon_info = gtk_icon_theme_choose_icon_for_scale (icon_theme, (const char **)names, size, scale, GTK_ICON_LOOKUP_FORCE_SIZE); if (gtkicon_info == NULL) { return nautilus_icon_info_new_for_pixbuf (NULL, scale); } filename = gtk_icon_info_get_filename (gtkicon_info); if (filename == NULL) { g_object_unref (gtkicon_info); return nautilus_icon_info_new_for_pixbuf (NULL, scale); } lookup_key.filename = (char *)filename; lookup_key.size = size; icon_info = g_hash_table_lookup (themed_icon_cache, &lookup_key); if (icon_info) { g_object_unref (gtkicon_info); return g_object_ref (icon_info); } icon_info = nautilus_icon_info_new_for_icon_info (gtkicon_info, scale); key = themed_icon_key_new (filename, size); g_hash_table_insert (themed_icon_cache, key, icon_info); g_object_unref (gtkicon_info); return g_object_ref (icon_info); } else { GdkPixbuf *pixbuf; GtkIconInfo *gtk_icon_info; gtk_icon_info = gtk_icon_theme_lookup_by_gicon_for_scale (gtk_icon_theme_get_default (), icon, size, scale, GTK_ICON_LOOKUP_FORCE_SIZE); if (gtk_icon_info != NULL) { pixbuf = gtk_icon_info_load_icon (gtk_icon_info, NULL); g_object_unref (gtk_icon_info); } else { pixbuf = NULL; } icon_info = nautilus_icon_info_new_for_pixbuf (pixbuf, scale); if (pixbuf != NULL) { g_object_unref (pixbuf); } return icon_info; } }