From e9dfba023f756801f8931a08644c23809cb38412 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 12 Feb 2013 13:59:09 +0100 Subject: [PATCH 56/68] iconfactory: Add _scaled() variants These functions can be used to deal with stock icons at sizes that are suitable for gdk_window_get_scale_factor() --- gtk/gtkiconfactory.c | 173 +++++++++++++++++++++++++++++++++++++++----------- gtk/gtkiconfactory.h | 14 +++- 2 files changed, 150 insertions(+), 37 deletions(-) diff --git a/gtk/gtkiconfactory.c b/gtk/gtkiconfactory.c index c4b6c9c..0dc31e6 100644 --- a/gtk/gtkiconfactory.c +++ b/gtk/gtkiconfactory.c @@ -801,6 +801,7 @@ icon_sizes_init_for_settings (GtkSettings *settings) static gboolean icon_size_lookup_intern (GtkSettings *settings, GtkIconSize size, + gdouble scale, gint *widthp, gint *heightp) { @@ -840,10 +841,16 @@ icon_size_lookup_intern (GtkSettings *settings, } if (widthp) - *widthp = width_for_settings >= 0 ? width_for_settings : icon_sizes[size].width; + { + *widthp = width_for_settings >= 0 ? width_for_settings : icon_sizes[size].width; + (*widthp) *= scale; + } if (heightp) - *heightp = height_for_settings >= 0 ? height_for_settings : icon_sizes[size].height; + { + *heightp = height_for_settings >= 0 ? height_for_settings : icon_sizes[size].height; + (*heightp) *= scale; + } return TRUE; } @@ -879,7 +886,7 @@ gtk_icon_size_lookup_for_settings (GtkSettings *settings, { g_return_val_if_fail (GTK_IS_SETTINGS (settings), FALSE); - return icon_size_lookup_intern (settings, size, width, height); + return icon_size_lookup_intern (settings, size, 1, width, height); } /** @@ -914,6 +921,18 @@ gtk_icon_size_lookup (GtkIconSize size, size, widthp, heightp); } +gboolean +gtk_icon_size_lookup_scaled (GtkSettings *settings, + GtkIconSize size, + gdouble scale, + gint *width, + gint *height) +{ + g_return_val_if_fail (GTK_IS_SETTINGS (settings), FALSE); + + return icon_size_lookup_intern (settings, size, scale, width, height); +} + static GtkIconSize icon_size_register_intern (const gchar *name, gint width, @@ -1000,7 +1019,7 @@ gtk_icon_size_register_alias (const gchar *alias, init_icon_sizes (); - if (!icon_size_lookup_intern (NULL, target, NULL, NULL)) + if (!icon_size_lookup_intern (NULL, target, 1, NULL, NULL)) g_warning ("gtk_icon_size_register_alias: Icon size %u does not exist", target); ia = g_hash_table_lookup (icon_aliases, alias); @@ -1288,8 +1307,8 @@ sizes_equivalent (GtkIconSize lhs, gint r_w, r_h, l_w, l_h; - icon_size_lookup_intern (NULL, rhs, &r_w, &r_h); - icon_size_lookup_intern (NULL, lhs, &l_w, &l_h); + icon_size_lookup_intern (NULL, rhs, 1, &r_w, &r_h); + icon_size_lookup_intern (NULL, lhs, 1, &l_w, &l_h); return r_w == l_w && r_h == l_h; #endif @@ -1372,7 +1391,8 @@ render_icon_name_pixbuf (GtkIconSource *icon_source, GtkStateType state, GtkIconSize size, GtkWidget *widget, - const char *detail) + const char *detail, + gboolean scale_requested) { GdkPixbuf *pixbuf; GdkPixbuf *tmp_pixbuf; @@ -1383,6 +1403,7 @@ render_icon_name_pixbuf (GtkIconSource *icon_source, gint width, height, pixel_size; gint *sizes, *s, dist; GError *error = NULL; + gdouble scale = 1; if (widget && gtk_widget_has_screen (widget)) screen = gtk_widget_get_screen (widget); @@ -1398,6 +1419,14 @@ render_icon_name_pixbuf (GtkIconSource *icon_source, icon_theme = gtk_icon_theme_get_for_screen (screen); settings = gtk_settings_get_for_screen (screen); + if (scale_requested && widget) + { + if (!widget->window) + gtk_widget_realize (widget); + + scale = gdk_window_get_scale_factor (widget->window); + } + if (!gtk_icon_size_lookup_for_settings (settings, size, &width, &height)) { if (size == (GtkIconSize)-1) @@ -1440,7 +1469,7 @@ render_icon_name_pixbuf (GtkIconSource *icon_source, } } - pixel_size = MIN (width, height); + pixel_size = MIN (width, height) * scale; if (icon_source->direction != GTK_TEXT_DIR_NONE) { @@ -1504,7 +1533,8 @@ find_and_render_icon_source (GtkIconSet *icon_set, GtkStateType state, GtkIconSize size, GtkWidget *widget, - const char *detail) + const char *detail, + gboolean scale_requested) { GSList *failed = NULL; GdkPixbuf *pixbuf = NULL; @@ -1546,7 +1576,7 @@ find_and_render_icon_source (GtkIconSet *icon_set, case GTK_ICON_SOURCE_STATIC_ICON_NAME: pixbuf = render_icon_name_pixbuf (source, style, direction, state, size, - widget, detail); + widget, detail, scale_requested); if (!pixbuf) failed = g_slist_prepend (failed, source); break; @@ -1598,6 +1628,84 @@ render_fallback_image (GtkStyle *style, detail); } +static gdouble +_get_real_scale (GtkWidget *widget, + GtkStyle *style, + GtkIconSize size, + GdkPixbuf *icon) +{ + GtkSettings *settings; + GdkScreen *screen; + gint icon_width; + + if (widget && gtk_widget_has_screen (widget)) + screen = gtk_widget_get_screen (widget); + else if (style && style->colormap) + screen = gdk_colormap_get_screen (style->colormap); + else + { + screen = gdk_screen_get_default (); + GTK_NOTE (MULTIHEAD, + g_warning ("Using the default screen for gtk_icon_set_render_icon()")); + } + + settings = gtk_settings_get_for_screen (screen); + gtk_icon_size_lookup_for_settings (settings, size, &icon_width, NULL); + + return (gdouble) gdk_pixbuf_get_width (icon) / icon_width; +} + +GdkPixbuf* +gtk_icon_set_render_icon_internal (GtkIconSet *icon_set, + GtkStyle *style, + GtkTextDirection direction, + GtkStateType state, + GtkIconSize size, + GtkWidget *widget, + const char *detail, + gboolean scale_requested, + gdouble *real_scale) +{ + GdkPixbuf *icon; + + if (real_scale) + *real_scale = 1; + + if (icon_set->sources == NULL) + return render_fallback_image (style, direction, state, size, widget, detail); + + if (detail == NULL) + { + icon = find_in_cache (icon_set, style, direction, + state, size); + + if (icon) + { + g_object_ref (icon); + + if (scale_requested && real_scale) + *real_scale = _get_real_scale (widget, style, size, icon); + + return icon; + } + } + + + icon = find_and_render_icon_source (icon_set, style, direction, state, size, + widget, detail, scale_requested); + + if (icon == NULL) + icon = render_fallback_image (style, direction, state, size, widget, detail); + + if (detail == NULL) + add_to_cache (icon_set, style, direction, state, size, icon); + + if (scale_requested && real_scale) + *real_scale = _get_real_scale (widget, style, size, icon); + + return icon; +} + /** * gtk_icon_set_render_icon: * @icon_set: a #GtkIconSet @@ -1631,37 +1739,30 @@ gtk_icon_set_render_icon (GtkIconSet *icon_set, GtkWidget *widget, const char *detail) { - GdkPixbuf *icon; - g_return_val_if_fail (icon_set != NULL, NULL); g_return_val_if_fail (style == NULL || GTK_IS_STYLE (style), NULL); - if (icon_set->sources == NULL) - return render_fallback_image (style, direction, state, size, widget, detail); - - if (detail == NULL) - { - icon = find_in_cache (icon_set, style, direction, - state, size); - - if (icon) - { - g_object_ref (icon); - return icon; - } - } - - - icon = find_and_render_icon_source (icon_set, style, direction, state, size, - widget, detail); - - if (icon == NULL) - icon = render_fallback_image (style, direction, state, size, widget, detail); + return gtk_icon_set_render_icon_internal (icon_set, style, direction, + state, size, widget, detail, + FALSE, NULL); +} - if (detail == NULL) - add_to_cache (icon_set, style, direction, state, size, icon); +GdkPixbuf* +gtk_icon_set_render_icon_scaled (GtkIconSet *icon_set, + GtkStyle *style, + GtkTextDirection direction, + GtkStateType state, + GtkIconSize size, + GtkWidget *widget, + const char *detail, + gdouble *real_scale) +{ + g_return_val_if_fail (icon_set != NULL, NULL); + g_return_val_if_fail (style == NULL || GTK_IS_STYLE (style), NULL); - return icon; + return gtk_icon_set_render_icon_internal (icon_set, style, direction, + state, size, widget, detail, + TRUE, real_scale); } /* Order sources by their "wildness", so that "wilder" sources are diff --git a/gtk/gtkiconfactory.h b/gtk/gtkiconfactory.h index ea97123..e38f8e6 100644 --- a/gtk/gtkiconfactory.h +++ b/gtk/gtkiconfactory.h @@ -105,6 +105,11 @@ gboolean gtk_icon_size_lookup_for_settings (GtkSettings *settings, GtkIconSize size, gint *width, gint *height); +gboolean gtk_icon_size_lookup_scaled (GtkSettings *settings, + GtkIconSize size, + gdouble scale, + gint *width, + gint *height); GtkIconSize gtk_icon_size_register (const gchar *name, gint width, @@ -134,7 +139,14 @@ GdkPixbuf* gtk_icon_set_render_icon (GtkIconSet *icon_set, GtkIconSize size, GtkWidget *widget, const char *detail); - +GdkPixbuf* gtk_icon_set_render_icon_scaled (GtkIconSet *icon_set, + GtkStyle *style, + GtkTextDirection direction, + GtkStateType state, + GtkIconSize size, + GtkWidget *widget, + const char *detail, + gdouble *real_scale); void gtk_icon_set_add_source (GtkIconSet *icon_set, const GtkIconSource *source); -- 1.7.10.2 (Apple Git-33)