nsresult nsIconChannel::InitWithGIO(nsIMozIconURI *aIconURI) { nsresult rv; GIcon *icon = NULL; nsCOMPtr<nsIURL> fileURI; // Read icon content aIconURI->GetIconURL(getter_AddRefs(fileURI)); // Get icon for file specified by URI if (fileURI) { bool isFile; nsCAutoString spec; fileURI->GetAsciiSpec(spec); if (NS_SUCCEEDED(fileURI->SchemeIs("file", &isFile)) && isFile) { GFile *file = g_file_new_for_uri(spec.get()); GFileInfo *fileInfo = g_file_query_info(file, G_FILE_ATTRIBUTE_STANDARD_ICON, G_FILE_QUERY_INFO_NONE, NULL, NULL); g_object_unref(file); if (fileInfo) { // icon from g_content_type_get_icon doesn't need unref icon = g_file_info_get_icon(fileInfo); if (icon) g_object_ref(icon); g_object_unref(fileInfo); } } } // Try to get icon by using MIME type if (!icon) { nsCAutoString type; aIconURI->GetContentType(type); // Try to get MIME type from file extension by using nsIMIMEService if (type.IsEmpty()) { nsCOMPtr<nsIMIMEService> ms(do_GetService("@mozilla.org/mime;1")); if (ms) { nsCAutoString fileExt; aIconURI->GetFileExtension(fileExt); ms->GetTypeFromExtension(fileExt, type); } } char *ctype = NULL; // character representation of content type if (!type.IsEmpty()) { ctype = g_content_type_from_mime_type(type.get()); } if (ctype) { icon = g_content_type_get_icon(ctype); g_free(ctype); } } // Get default icon theme GtkIconTheme *iconTheme = gtk_icon_theme_get_default(); GtkIconInfo *iconInfo = NULL; // Get icon size PRInt32 iconSize = GetIconSize(aIconURI); if (icon) { NS_SUCCEEDED(rv); // Use icon and theme to get GtkIconInfo iconInfo = gtk_icon_theme_lookup_by_gicon(iconTheme, icon, iconSize, (GtkIconLookupFlags)0); g_object_unref(icon); } if (!iconInfo) { // Mozilla's mimetype lookup failed. Try the "unknown" icon. iconInfo = gtk_icon_theme_lookup_icon(iconTheme, "unknown", iconSize, (GtkIconLookupFlags)0); if (!iconInfo) { return NS_ERROR_NOT_AVAILABLE; } } // Create a GdkPixbuf buffer containing icon and scale it GdkPixbuf* buf = gtk_icon_info_load_icon(iconInfo, NULL); gtk_icon_info_free(iconInfo); if (!buf) { return NS_ERROR_UNEXPECTED; } rv = ScaleIconBuf(&buf, iconSize); NS_ENSURE_SUCCESS(rv, rv); rv = moz_gdk_pixbuf_to_channel(buf, aIconURI, getter_AddRefs(mRealChannel)); g_object_unref(buf); return rv; }
static void exo_cell_renderer_icon_render (GtkCellRenderer *renderer, GdkWindow *window, GtkWidget *widget, GdkRectangle *background_area, GdkRectangle *cell_area, GdkRectangle *expose_area, GtkCellRendererState flags) { const ExoCellRendererIconPrivate *priv = EXO_CELL_RENDERER_ICON_GET_PRIVATE (renderer); GtkIconSource *icon_source; GtkIconTheme *icon_theme; GdkRectangle icon_area; GdkRectangle draw_area; GtkStateType state; const gchar *filename; GtkIconInfo *icon_info = NULL; GdkPixbuf *icon = NULL; GdkPixbuf *temp; GError *err = NULL; gchar *display_name = NULL; gint *icon_sizes; gint icon_size; gint n; /* verify that we have an icon */ if (G_UNLIKELY (priv->icon == NULL && priv->gicon == NULL)) return; /* icon may be either an image file or a named icon */ if (priv->icon != NULL && g_path_is_absolute (priv->icon)) { /* load the icon via the thumbnail database */ icon = _exo_thumbnail_get_for_file (priv->icon, (priv->size > 128) ? EXO_THUMBNAIL_SIZE_LARGE : EXO_THUMBNAIL_SIZE_NORMAL, &err); } else if (priv->icon != NULL || priv->gicon != NULL) { /* determine the best icon size (GtkIconTheme is somewhat messy scaling up small icons) */ icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget)); if (priv->icon != NULL) { icon_sizes = gtk_icon_theme_get_icon_sizes (icon_theme, priv->icon); for (icon_size = -1, n = 0; icon_sizes[n] != 0; ++n) { /* we can use any size if scalable, because we load the file directly */ if (icon_sizes[n] == -1) icon_size = priv->size; else if (icon_sizes[n] > icon_size && icon_sizes[n] <= priv->size) icon_size = icon_sizes[n]; } g_free (icon_sizes); /* if we don't know any icon sizes at all, the icon is probably not present */ if (G_UNLIKELY (icon_size < 0)) icon_size = priv->size; /* lookup the icon in the icon theme */ icon_info = gtk_icon_theme_lookup_icon (icon_theme, priv->icon, icon_size, 0); } else if (priv->gicon != NULL) { icon_info = gtk_icon_theme_lookup_by_gicon (icon_theme, priv->gicon, priv->size, GTK_ICON_LOOKUP_USE_BUILTIN); } if (G_UNLIKELY (icon_info == NULL)) return; /* check if we have an SVG icon here */ filename = gtk_icon_info_get_filename (icon_info); if (filename != NULL && g_str_has_suffix (filename, ".svg")) { /* loading SVG icons is terribly slow, so we try to use thumbnail instead, and we use the * real available cell area directly here, because loading thumbnails involves scaling anyway * and this way we need to the thumbnail pixbuf scale only once. */ icon = _exo_thumbnail_get_for_file (filename, (priv->size > 128) ? EXO_THUMBNAIL_SIZE_LARGE : EXO_THUMBNAIL_SIZE_NORMAL, &err); } else { /* regularly load the icon from the theme */ icon = gtk_icon_info_load_icon (icon_info, &err); } gtk_icon_info_free (icon_info); } /* check if we failed */ if (G_UNLIKELY (icon == NULL)) { /* better let the user know whats going on, might be surprising otherwise */ if (G_LIKELY (priv->icon != NULL)) { display_name = g_filename_display_name (priv->icon); } else if (G_UNLIKELY (priv->gicon != NULL && g_object_class_find_property (G_OBJECT_GET_CLASS (priv->gicon), "name"))) { g_object_get (priv->gicon, "name", &display_name, NULL); } if (display_name != NULL) { g_warning ("Failed to load \"%s\": %s", display_name, err->message); g_free (display_name); } g_error_free (err); return; } /* determine the real icon size */ icon_area.width = gdk_pixbuf_get_width (icon); icon_area.height = gdk_pixbuf_get_height (icon); /* scale down the icon on-demand */ if (G_UNLIKELY (icon_area.width > cell_area->width || icon_area.height > cell_area->height)) { /* scale down to fit */ temp = exo_gdk_pixbuf_scale_down (icon, TRUE, cell_area->width, cell_area->height); g_object_unref (G_OBJECT (icon)); icon = temp; /* determine the icon dimensions again */ icon_area.width = gdk_pixbuf_get_width (icon); icon_area.height = gdk_pixbuf_get_height (icon); } icon_area.x = cell_area->x + (cell_area->width - icon_area.width) / 2; icon_area.y = cell_area->y + (cell_area->height - icon_area.height) / 2; /* check whether the icon is affected by the expose event */ if (gdk_rectangle_intersect (expose_area, &icon_area, &draw_area)) { /* colorize the icon if we should follow the selection state */ if ((flags & (GTK_CELL_RENDERER_SELECTED | GTK_CELL_RENDERER_PRELIT)) != 0 && priv->follow_state) { if ((flags & GTK_CELL_RENDERER_SELECTED) != 0) { state = GTK_WIDGET_HAS_FOCUS (widget) ? GTK_STATE_SELECTED : GTK_STATE_ACTIVE; temp = exo_gdk_pixbuf_colorize (icon, &widget->style->base[state]); g_object_unref (G_OBJECT (icon)); icon = temp; } if ((flags & GTK_CELL_RENDERER_PRELIT) != 0) { temp = exo_gdk_pixbuf_spotlight (icon); g_object_unref (G_OBJECT (icon)); icon = temp; } } /* check if we should render an insensitive icon */ if (G_UNLIKELY (GTK_WIDGET_STATE (widget) == GTK_STATE_INSENSITIVE || !renderer->sensitive)) { /* allocate an icon source */ icon_source = gtk_icon_source_new (); gtk_icon_source_set_pixbuf (icon_source, icon); gtk_icon_source_set_size_wildcarded (icon_source, FALSE); gtk_icon_source_set_size (icon_source, GTK_ICON_SIZE_SMALL_TOOLBAR); /* render the insensitive icon */ temp = gtk_style_render_icon (widget->style, icon_source, gtk_widget_get_direction (widget), GTK_STATE_INSENSITIVE, -1, widget, "gtkcellrendererpixbuf"); g_object_unref (G_OBJECT (icon)); icon = temp; /* release the icon source */ gtk_icon_source_free (icon_source); } /* render the invalid parts of the icon */ gdk_draw_pixbuf (window, widget->style->black_gc, icon, draw_area.x - icon_area.x, draw_area.y - icon_area.y, draw_area.x, draw_area.y, draw_area.width, draw_area.height, GDK_RGB_DITHER_NORMAL, 0, 0); } /* release the file's icon */ g_object_unref (G_OBJECT (icon)); }
static GitgSpinnerImages * gitg_spinner_images_load (GdkScreen *screen, GtkIconTheme *icon_theme, GtkIconSize icon_size) { GitgSpinnerImages *images; GdkPixbuf *icon_pixbuf, *pixbuf; GtkIconInfo *icon_info = NULL; int grid_width, grid_height, x, y, requested_size, size, isw, ish, n; const char *icon; GSList *list = NULL, *l; /* LOG ("GitgSpinnerCacheData loading for screen %p at size %d", screen, icon_size); */ /* START_PROFILER ("loading spinner animation") */ if (screen == NULL) screen = gdk_screen_get_default (); if (!gtk_icon_size_lookup_for_settings (gtk_settings_get_for_screen (screen), icon_size, &isw, &ish)) goto loser; requested_size = MAX (ish, isw); /* Load the animation. The 'rest icon' is the 0th frame */ icon_info = gtk_icon_theme_lookup_icon (icon_theme, SPINNER_ICON_NAME, requested_size, 0); if (icon_info == NULL) { g_warning ("Throbber animation not found"); /* If the icon naming spec compliant name wasn't found, try the old name */ icon_info = gtk_icon_theme_lookup_icon (icon_theme, SPINNER_FALLBACK_ICON_NAME, requested_size, 0); if (icon_info == NULL) { g_warning ("Throbber fallback animation not found either"); goto loser; } } g_assert (icon_info != NULL); size = gtk_icon_info_get_base_size (icon_info); icon = gtk_icon_info_get_filename (icon_info); if (icon == NULL) goto loser; icon_pixbuf = gdk_pixbuf_new_from_file (icon, NULL); gtk_icon_info_free (icon_info); icon_info = NULL; if (icon_pixbuf == NULL) { g_warning ("Could not load the spinner file"); goto loser; } grid_width = gdk_pixbuf_get_width (icon_pixbuf); grid_height = gdk_pixbuf_get_height (icon_pixbuf); n = 0; for (y = 0; y < grid_height; y += size) { for (x = 0; x < grid_width ; x += size) { pixbuf = extract_frame (icon_pixbuf, x, y, size); if (pixbuf) { list = g_slist_prepend (list, pixbuf); ++n; } else { g_warning ("Cannot extract frame (%d, %d) from the grid\n", x, y); } } } g_object_unref (icon_pixbuf); if (list == NULL) goto loser; /* g_assert (n > 0); */ if (size > requested_size) { for (l = list; l != NULL; l = l->next) { l->data = scale_to_size (l->data, isw, ish); } } /* Now we've successfully got all the data */ images = g_new (GitgSpinnerImages, 1); images->ref_count = 1; images->size = icon_size; images->width = images->height = requested_size; images->n_animation_pixbufs = n; images->animation_pixbufs = g_new (GdkPixbuf *, n); for (l = list; l != NULL; l = l->next) { g_assert (l->data != NULL); images->animation_pixbufs[--n] = l->data; } g_assert (n == 0); g_slist_free (list); /* STOP_PROFILER ("loading spinner animation") */ return images; loser: if (icon_info) { gtk_icon_info_free (icon_info); } g_slist_foreach (list, (GFunc) g_object_unref, NULL); /* STOP_PROFILER ("loading spinner animation") */ return NULL; }
nsresult nsIconChannel::Init(nsIURI* aURI) { nsCOMPtr<nsIMozIconURI> iconURI = do_QueryInterface(aURI); NS_ASSERTION(iconURI, "URI is not an nsIMozIconURI"); nsCAutoString stockIcon; iconURI->GetStockIcon(stockIcon); if (stockIcon.IsEmpty()) { #ifdef MOZ_ENABLE_GNOMEUI return InitWithGnome(iconURI); #else return NS_ERROR_NOT_AVAILABLE; #endif } nsCAutoString iconSizeString; iconURI->GetIconSize(iconSizeString); nsCAutoString iconStateString; iconURI->GetIconState(iconStateString); GtkIconSize icon_size = moz_gtk_icon_size(iconSizeString.get()); GtkStateType state = iconStateString.EqualsLiteral("disabled") ? GTK_STATE_INSENSITIVE : GTK_STATE_NORMAL; // First lookup the icon by stock id and text direction. GtkTextDirection direction = GTK_TEXT_DIR_NONE; if (StringEndsWith(stockIcon, NS_LITERAL_CSTRING("-ltr"))) { direction = GTK_TEXT_DIR_LTR; } else if (StringEndsWith(stockIcon, NS_LITERAL_CSTRING("-rtl"))) { direction = GTK_TEXT_DIR_RTL; } PRBool forceDirection = direction != GTK_TEXT_DIR_NONE; nsCAutoString stockID; PRBool useIconName = PR_FALSE; if (!forceDirection) { direction = gtk_widget_get_default_direction(); stockID = stockIcon; } else { // GTK versions < 2.22 use icon names from concatenating stock id with // -(rtl|ltr), which is how the moz-icon stock name is interpreted here. stockID = Substring(stockIcon, 0, stockIcon.Length() - 4); // However, if we lookup bidi icons by the stock name, then GTK versions // >= 2.22 will use a bidi lookup convention that most icon themes do not // yet follow. Therefore, we first check to see if the theme supports the // old icon name as this will have bidi support (if found). GtkIconTheme *icon_theme = gtk_icon_theme_get_default(); // Micking what gtk_icon_set_render_icon does with sizes, though it's not // critical as icons will be scaled to suit size. It just means we follow // the same pathes and so share caches. gint width, height; if (gtk_icon_size_lookup(icon_size, &width, &height)) { gint size = NS_MIN(width, height); // We use gtk_icon_theme_lookup_icon() without // GTK_ICON_LOOKUP_USE_BUILTIN instead of gtk_icon_theme_has_icon() so // we don't pick up fallback icons added by distributions for backward // compatibility. GtkIconInfo *icon = gtk_icon_theme_lookup_icon(icon_theme, stockIcon.get(), size, (GtkIconLookupFlags)0); if (icon) { useIconName = PR_TRUE; gtk_icon_info_free(icon); } } } ensure_stock_image_widget(); GtkStyle *style = gtk_widget_get_style(gStockImageWidget); GtkIconSet *icon_set = NULL; if (!useIconName) { icon_set = gtk_style_lookup_icon_set(style, stockID.get()); } if (!icon_set) { // Either we have choosen icon-name lookup for a bidi icon, or stockIcon is // not a stock id so we assume it is an icon name. useIconName = PR_TRUE; // Creating a GtkIconSet is a convenient way to allow the style to // render the icon, possibly with variations suitable for insensitive // states. icon_set = gtk_icon_set_new(); GtkIconSource *icon_source = gtk_icon_source_new(); gtk_icon_source_set_icon_name(icon_source, stockIcon.get()); gtk_icon_set_add_source(icon_set, icon_source); gtk_icon_source_free(icon_source); } GdkPixbuf *icon = gtk_icon_set_render_icon (icon_set, style, direction, state, icon_size, gStockImageWidget, NULL); if (useIconName) { gtk_icon_set_unref(icon_set); } // According to documentation, gtk_icon_set_render_icon() never returns // NULL, but it does return NULL when we have the problem reported here: // https://bugzilla.gnome.org/show_bug.cgi?id=629878#c13 if (!icon) return NS_ERROR_NOT_AVAILABLE; nsresult rv = moz_gdk_pixbuf_to_channel(icon, iconURI, getter_AddRefs(mRealChannel)); g_object_unref(icon); return rv; }
/* Load image from file */ static void _xfdashboard_image_content_load_from_file(XfdashboardImageContent *self) { XfdashboardImageContentPrivate *priv; gchar *lookupFilename; gchar *filename; g_return_if_fail(XFDASHBOARD_IS_IMAGE_CONTENT(self)); priv=self->priv; filename=NULL; /* Check if type of image is valid and all needed parameters are set */ g_return_if_fail(priv->type==XFDASHBOARD_IMAGE_TYPE_FILE); g_return_if_fail(priv->iconName); g_return_if_fail(priv->iconSize>0); /* If path of icon filename is relative build absolute path by prefixing theme path ... */ if(!g_path_is_absolute(priv->iconName)) { XfdashboardTheme *theme; const gchar *themePath; /* Get theme path */ theme=xfdashboard_application_get_theme(); g_object_ref(theme); themePath=xfdashboard_theme_get_path(theme); /* Build absolute path from theme path and given relative path to icon */ lookupFilename=g_build_filename(themePath, priv->iconName, NULL); /* Release allocated resources */ g_object_unref(theme); } /* ... otherwise it is an absolute path already so just copy it */ else lookupFilename=g_strdup(priv->iconName); /* If file does not exists then load fallback icon */ if(!g_file_test(lookupFilename, G_FILE_TEST_EXISTS)) { GtkIconInfo *iconInfo; g_warning(_("Icon file '%s' does not exist - trying fallback icon '%s'"), priv->iconName, priv->missingIconName); iconInfo=gtk_icon_theme_lookup_icon(priv->iconTheme, priv->missingIconName, priv->iconSize, #ifdef USE_GTK_BUILTIN_ICONS GTK_ICON_LOOKUP_USE_BUILTIN); #else 0); #endif if(!iconInfo) { g_error(_("Could not load fallback icon for file '%s'"), priv->iconName); _xfdashboard_image_content_set_empty_image(self); g_free(lookupFilename); return; } /* Check if have to use built-in GdkPixbuf for icon ... */ filename=g_strdup(gtk_icon_info_get_filename(iconInfo)); #ifdef USE_GTK_BUILTIN_ICONS if(!filename) { GdkPixbuf *iconPixbuf; GError *error=NULL; iconPixbuf=gtk_icon_info_get_builtin_pixbuf(iconInfo); if(!clutter_image_set_data(CLUTTER_IMAGE(self), gdk_pixbuf_get_pixels(iconPixbuf), gdk_pixbuf_get_has_alpha(iconPixbuf) ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888, gdk_pixbuf_get_width(iconPixbuf), gdk_pixbuf_get_height(iconPixbuf), gdk_pixbuf_get_rowstride(iconPixbuf), &error)) { g_warning(_("Failed to load image data into content for icon '%s': %s"), priv->iconName, error ? error->message : _("Unknown error")); if(error) { g_error_free(error); error=NULL; } } else g_debug("Loaded fallback icon for file '%s' from built-in pixbuf", priv->iconName); g_object_unref(iconPixbuf); } #endif /* Release allocated resources */ g_object_unref(iconInfo); }
static gboolean swatch_draw (GtkWidget *widget, cairo_t *cr) { GtkColorSwatch *swatch = (GtkColorSwatch*)widget; GtkThemingBackground background; gdouble width, height; GtkStyleContext *context; GtkStateFlags state; GtkIconTheme *theme; GtkIconInfo *icon_info = NULL; theme = gtk_icon_theme_get_default (); context = gtk_widget_get_style_context (widget); state = gtk_widget_get_state_flags (widget); width = gtk_widget_get_allocated_width (widget); height = gtk_widget_get_allocated_height (widget); cairo_save (cr); gtk_style_context_save (context); gtk_style_context_set_state (context, state); _gtk_theming_background_init_from_context (&background, context, 0, 0, width, height, GTK_JUNCTION_NONE); if (swatch->priv->has_color) { cairo_pattern_t *pattern; cairo_matrix_t matrix; if (swatch->priv->use_alpha) { cairo_save (cr); _gtk_rounded_box_path (&background.padding_box, 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); background.bg_color = swatch->priv->color; } else { background.bg_color = swatch->priv->color; background.bg_color.alpha = 1.0; } _gtk_theming_background_render (&background, cr); } else _gtk_theming_background_render (&background, cr); gtk_render_frame (context, cr, 0, 0, width, height); if (gtk_widget_has_visible_focus (widget)) { cairo_set_line_width (cr, 2); if (swatch->priv->has_color && INTENSITY (swatch->priv->color.red, swatch->priv->color.green, swatch->priv->color.blue) < 0.5) cairo_set_source_rgba (cr, 1., 1., 1., 0.4); else cairo_set_source_rgba (cr, 0., 0., 0., 0.4); _gtk_rounded_box_shrink (&background.padding_box, 3, 3, 3, 3); _gtk_rounded_box_path (&background.padding_box, cr); cairo_stroke (cr); } if (swatch->priv->icon) { icon_info = gtk_icon_theme_lookup_icon (theme, swatch->priv->icon, 16, GTK_ICON_LOOKUP_GENERIC_FALLBACK | GTK_ICON_LOOKUP_USE_BUILTIN); } else if ((state & GTK_STATE_FLAG_SELECTED) != 0) { GdkRGBA bg, border; GtkBorder border_width; GIcon *gicon; gtk_style_context_add_class (context, "color-active-badge"); _gtk_theming_background_init_from_context (&background, context, (width - 2 * ACTIVE_BADGE_RADIUS) / 2, (height - 2 * ACTIVE_BADGE_RADIUS) / 2, 2 * ACTIVE_BADGE_RADIUS, 2* ACTIVE_BADGE_RADIUS, GTK_JUNCTION_NONE); if (_gtk_theming_background_has_background_image (&background)) { _gtk_theming_background_render (&background, cr); } else { gtk_style_context_get_background_color (context, state, &bg); gtk_style_context_get_border_color (context, state, &border); gtk_style_context_get_border (context, state, &border_width); cairo_new_sub_path (cr); cairo_arc (cr, width / 2, height / 2, ACTIVE_BADGE_RADIUS, 0, 2 * G_PI); cairo_close_path (cr); gdk_cairo_set_source_rgba (cr, &bg); cairo_fill_preserve (cr); gdk_cairo_set_source_rgba (cr, &border); cairo_set_line_width (cr, border_width.left); cairo_stroke (cr); 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 (theme, gicon, 16, GTK_ICON_LOOKUP_GENERIC_FALLBACK | GTK_ICON_LOOKUP_USE_BUILTIN); g_object_unref (gicon); } } if (icon_info != NULL) { GdkPixbuf *pixbuf; pixbuf = gtk_icon_info_load_symbolic_for_context (icon_info, context, NULL, NULL); if (pixbuf != NULL) { gtk_render_icon (context, cr, pixbuf, (width - gdk_pixbuf_get_width (pixbuf)) / 2, (height - gdk_pixbuf_get_height (pixbuf)) / 2); g_object_unref (pixbuf); } g_object_unref (icon_info); } cairo_restore (cr); gtk_style_context_restore (context); return FALSE; }