1From 431d1225b153c1a1389686920aed1d26ff3218b2 Mon Sep 17 00:00:00 2001 2From: Carlos Garnacho <carlos@lanedo.com> 3Date: Fri, 10 May 2013 18:24:26 +0200 4Subject: [PATCH 59/68] iconfactory: Add scale info to GtkIconSource 5 6GtkIconSource now has notions knows about scale, so it can correctly 7fetch the icon at the right scale for ICON_NAME source types. 8 9All default stock icons have been made to have a wildcarded scale, 10so it's up to the GtkIconTheme to do the scaling business. 11--- 12 gtk/gtkiconfactory.c | 140 ++++++++++++++++++++++++++++++++------------------ 13 gtk/gtkiconfactory.h | 7 ++- 14 2 files changed, 97 insertions(+), 50 deletions(-) 15 16diff --git a/gtk/gtkiconfactory.c b/gtk/gtkiconfactory.c 17index 0dc31e6..41d1ee7 100644 18--- a/gtk/gtkiconfactory.c 19+++ b/gtk/gtkiconfactory.c 20@@ -66,6 +66,7 @@ struct _GtkIconSource 21 GtkTextDirection direction; 22 GtkStateType state; 23 GtkIconSize size; 24+ gdouble scale; 25 26 /* If TRUE, then the parameter is wildcarded, and the above 27 * fields should be ignored. If FALSE, the parameter is 28@@ -74,6 +75,7 @@ struct _GtkIconSource 29 guint any_direction : 1; 30 guint any_state : 1; 31 guint any_size : 1; 32+ guint any_scale : 1; 33 34 #if defined (G_OS_WIN32) && !defined (_WIN64) 35 /* System codepage version of filename, for DLL ABI backward 36@@ -106,10 +108,10 @@ static GtkIconSize icon_size_register_intern (const gchar *name, 37 gint width, 38 gint height); 39 40-#define GTK_ICON_SOURCE_INIT(any_direction, any_state, any_size) \ 41+#define GTK_ICON_SOURCE_INIT(any_direction, any_state, any_size, any_scale) \ 42 { GTK_ICON_SOURCE_EMPTY, { NULL }, NULL, \ 43- 0, 0, 0, \ 44- any_direction, any_state, any_size } 45+ 0, 0, 0, 1, \ 46+ any_direction, any_state, any_size, any_scale } 47 48 G_DEFINE_TYPE_WITH_CODE (GtkIconFactory, gtk_icon_factory, G_TYPE_OBJECT, 49 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, 50@@ -349,7 +351,7 @@ register_stock_icon (GtkIconFactory *factory, 51 const gchar *icon_name) 52 { 53 GtkIconSet *set = gtk_icon_set_new (); 54- GtkIconSource source = GTK_ICON_SOURCE_INIT (TRUE, TRUE, TRUE); 55+ GtkIconSource source = GTK_ICON_SOURCE_INIT (TRUE, TRUE, TRUE, TRUE); 56 57 source.type = GTK_ICON_SOURCE_STATIC_ICON_NAME; 58 source.source.icon_name = (gchar *)icon_name; 59@@ -366,7 +368,7 @@ register_bidi_stock_icon (GtkIconFactory *factory, 60 const gchar *icon_name) 61 { 62 GtkIconSet *set = gtk_icon_set_new (); 63- GtkIconSource source = GTK_ICON_SOURCE_INIT (FALSE, TRUE, TRUE); 64+ GtkIconSource source = GTK_ICON_SOURCE_INIT (FALSE, TRUE, TRUE, TRUE); 65 66 source.type = GTK_ICON_SOURCE_STATIC_ICON_NAME; 67 source.source.icon_name = (gchar *)icon_name; 68@@ -1094,12 +1096,14 @@ static GdkPixbuf *find_in_cache (GtkIconSet *icon_set, 69 GtkStyle *style, 70 GtkTextDirection direction, 71 GtkStateType state, 72- GtkIconSize size); 73+ GtkIconSize size, 74+ gdouble scale); 75 static void add_to_cache (GtkIconSet *icon_set, 76 GtkStyle *style, 77 GtkTextDirection direction, 78 GtkStateType state, 79 GtkIconSize size, 80+ gdouble scale, 81 GdkPixbuf *pixbuf); 82 /* Clear icon set contents, drop references to all contained 83 * GdkPixbuf objects and forget all GtkIconSources. Used to 84@@ -1179,7 +1183,7 @@ gtk_icon_set_new_from_pixbuf (GdkPixbuf *pixbuf) 85 { 86 GtkIconSet *set; 87 88- GtkIconSource source = GTK_ICON_SOURCE_INIT (TRUE, TRUE, TRUE); 89+ GtkIconSource source = GTK_ICON_SOURCE_INIT (TRUE, TRUE, TRUE, TRUE); 90 91 g_return_val_if_fail (pixbuf != NULL, NULL); 92 93@@ -1319,6 +1323,7 @@ find_best_matching_source (GtkIconSet *icon_set, 94 GtkTextDirection direction, 95 GtkStateType state, 96 GtkIconSize size, 97+ gdouble scale, 98 GSList *failed) 99 { 100 GtkIconSource *source; 101@@ -1340,7 +1345,8 @@ find_best_matching_source (GtkIconSet *icon_set, 102 103 if ((s->any_direction || (s->direction == direction)) && 104 (s->any_state || (s->state == state)) && 105- (s->any_size || size == (GtkIconSize)-1 || (sizes_equivalent (size, s->size)))) 106+ (s->any_size || size == (GtkIconSize)-1 || (sizes_equivalent (size, s->size))) && 107+ (s->any_scale || (s->scale == scale))) 108 { 109 if (!g_slist_find (failed, s)) 110 { 111@@ -1392,7 +1398,7 @@ render_icon_name_pixbuf (GtkIconSource *icon_source, 112 GtkIconSize size, 113 GtkWidget *widget, 114 const char *detail, 115- gboolean scale_requested) 116+ gdouble scale) 117 { 118 GdkPixbuf *pixbuf; 119 GdkPixbuf *tmp_pixbuf; 120@@ -1403,7 +1409,6 @@ render_icon_name_pixbuf (GtkIconSource *icon_source, 121 gint width, height, pixel_size; 122 gint *sizes, *s, dist; 123 GError *error = NULL; 124- gdouble scale = 1; 125 126 if (widget && gtk_widget_has_screen (widget)) 127 screen = gtk_widget_get_screen (widget); 128@@ -1419,14 +1424,6 @@ render_icon_name_pixbuf (GtkIconSource *icon_source, 129 icon_theme = gtk_icon_theme_get_for_screen (screen); 130 settings = gtk_settings_get_for_screen (screen); 131 132- if (scale_requested && widget) 133- { 134- if (!widget->window) 135- gtk_widget_realize (widget); 136- 137- scale = gdk_window_get_scale_factor (widget->window); 138- } 139- 140 if (!gtk_icon_size_lookup_for_settings (settings, size, &width, &height)) 141 { 142 if (size == (GtkIconSize)-1) 143@@ -1469,7 +1466,7 @@ render_icon_name_pixbuf (GtkIconSource *icon_source, 144 } 145 } 146 147- pixel_size = MIN (width, height) * scale; 148+ pixel_size = MIN (width, height); 149 150 if (icon_source->direction != GTK_TEXT_DIR_NONE) 151 { 152@@ -1483,9 +1480,10 @@ render_icon_name_pixbuf (GtkIconSource *icon_source, 153 names[1] = icon_source->source.icon_name; 154 names[2] = NULL; 155 156- info = gtk_icon_theme_choose_icon (icon_theme, 157- names, 158- pixel_size, GTK_ICON_LOOKUP_USE_BUILTIN); 159+ info = gtk_icon_theme_choose_icon_for_scale (icon_theme, 160+ names, 161+ pixel_size, scale, 162+ GTK_ICON_LOOKUP_USE_BUILTIN); 163 g_free (name_with_dir); 164 if (info) 165 { 166@@ -1495,10 +1493,10 @@ render_icon_name_pixbuf (GtkIconSource *icon_source, 167 } 168 else 169 { 170- tmp_pixbuf = gtk_icon_theme_load_icon (icon_theme, 171- icon_source->source.icon_name, 172- pixel_size, 0, 173- &error); 174+ tmp_pixbuf = gtk_icon_theme_load_icon_for_scale (icon_theme, 175+ icon_source->source.icon_name, 176+ pixel_size, scale, 0, 177+ &error); 178 } 179 180 if (!tmp_pixbuf) 181@@ -1534,7 +1532,7 @@ find_and_render_icon_source (GtkIconSet *icon_set, 182 GtkIconSize size, 183 GtkWidget *widget, 184 const char *detail, 185- gboolean scale_requested) 186+ gdouble scale) 187 { 188 GSList *failed = NULL; 189 GdkPixbuf *pixbuf = NULL; 190@@ -1551,7 +1549,7 @@ find_and_render_icon_source (GtkIconSet *icon_set, 191 */ 192 while (pixbuf == NULL) 193 { 194- GtkIconSource *source = find_best_matching_source (icon_set, direction, state, size, failed); 195+ GtkIconSource *source = find_best_matching_source (icon_set, direction, state, size, scale, failed); 196 197 if (source == NULL) 198 break; 199@@ -1576,7 +1574,7 @@ find_and_render_icon_source (GtkIconSet *icon_set, 200 case GTK_ICON_SOURCE_STATIC_ICON_NAME: 201 pixbuf = render_icon_name_pixbuf (source, style, 202 direction, state, size, 203- widget, detail, scale_requested); 204+ widget, detail, scale); 205 if (!pixbuf) 206 failed = g_slist_prepend (failed, source); 207 break; 208@@ -1601,7 +1599,7 @@ render_fallback_image (GtkStyle *style, 209 const char *detail) 210 { 211 /* This icon can be used for any direction/state/size */ 212- static GtkIconSource fallback_source = GTK_ICON_SOURCE_INIT (TRUE, TRUE, TRUE); 213+ static GtkIconSource fallback_source = GTK_ICON_SOURCE_INIT (TRUE, TRUE, TRUE, TRUE); 214 215 if (fallback_source.type == GTK_ICON_SOURCE_EMPTY) 216 { 217@@ -1652,7 +1650,7 @@ _get_real_scale (GtkWidget *widget, 218 settings = gtk_settings_get_for_screen (screen); 219 gtk_icon_size_lookup_for_settings (settings, size, &icon_width, NULL); 220 221- return (gdouble) gdk_pixbuf_get_width (icon) / icon_width; 222+ return round ((gdouble) gdk_pixbuf_get_width (icon) / icon_width); 223 } 224 225 GdkPixbuf* 226@@ -1663,28 +1661,23 @@ gtk_icon_set_render_icon_internal (GtkIconSet *icon_set, 227 GtkIconSize size, 228 GtkWidget *widget, 229 const char *detail, 230- gboolean scale_requested, 231- gdouble *real_scale) 232+ gdouble *scale) 233 { 234 GdkPixbuf *icon; 235 236- if (real_scale) 237- *real_scale = 1; 238- 239 if (icon_set->sources == NULL) 240 return render_fallback_image (style, direction, state, size, widget, detail); 241 242 if (detail == NULL) 243 { 244 icon = find_in_cache (icon_set, style, direction, 245- state, size); 246+ state, size, *scale); 247 248 if (icon) 249 { 250 g_object_ref (icon); 251 252- if (scale_requested && real_scale) 253- *real_scale = _get_real_scale (widget, style, size, icon); 254+ *scale = _get_real_scale (widget, style, size, icon); 255 256 return icon; 257 } 258@@ -1692,16 +1685,15 @@ gtk_icon_set_render_icon_internal (GtkIconSet *icon_set, 259 260 261 icon = find_and_render_icon_source (icon_set, style, direction, state, size, 262- widget, detail, scale_requested); 263+ widget, detail, *scale); 264 265 if (icon == NULL) 266 icon = render_fallback_image (style, direction, state, size, widget, detail); 267 268- if (detail == NULL) 269- add_to_cache (icon_set, style, direction, state, size, icon); 270+ *scale = _get_real_scale (widget, style, size, icon); 271 272- if (scale_requested && real_scale) 273- *real_scale = _get_real_scale (widget, style, size, icon); 274+ if (detail == NULL) 275+ add_to_cache (icon_set, style, direction, state, size, *scale, icon); 276 277 return icon; 278 } 279@@ -1739,12 +1731,14 @@ gtk_icon_set_render_icon (GtkIconSet *icon_set, 280 GtkWidget *widget, 281 const char *detail) 282 { 283+ gdouble scale = 1; 284+ 285 g_return_val_if_fail (icon_set != NULL, NULL); 286 g_return_val_if_fail (style == NULL || GTK_IS_STYLE (style), NULL); 287 288 return gtk_icon_set_render_icon_internal (icon_set, style, direction, 289 state, size, widget, detail, 290- FALSE, NULL); 291+ &scale); 292 } 293 294 GdkPixbuf* 295@@ -1755,19 +1749,22 @@ gtk_icon_set_render_icon_scaled (GtkIconSet *icon_set, 296 GtkIconSize size, 297 GtkWidget *widget, 298 const char *detail, 299- gdouble *real_scale) 300+ gdouble *scale) 301 { 302 g_return_val_if_fail (icon_set != NULL, NULL); 303 g_return_val_if_fail (style == NULL || GTK_IS_STYLE (style), NULL); 304+ g_return_val_if_fail (scale != NULL, NULL); 305+ 306+ *scale = MAX (*scale, 1); 307 308 return gtk_icon_set_render_icon_internal (icon_set, style, direction, 309 state, size, widget, detail, 310- TRUE, real_scale); 311+ scale); 312 } 313 314 /* Order sources by their "wildness", so that "wilder" sources are 315 * greater than "specific" sources; for determining ordering, 316- * direction beats state beats size. 317+ * direction beats state beats size beats scale. 318 */ 319 320 static int 321@@ -1788,6 +1785,10 @@ icon_source_compare (gconstpointer ap, gconstpointer bp) 322 return -1; 323 else if (a->any_size && !b->any_size) 324 return 1; 325+ else if (!a->any_scale && b->any_scale) 326+ return -1; 327+ else if (a->any_scale && !b->any_scale) 328+ return 1; 329 else 330 return 0; 331 } 332@@ -1965,10 +1966,12 @@ gtk_icon_source_new (void) 333 src->direction = GTK_TEXT_DIR_NONE; 334 src->size = GTK_ICON_SIZE_INVALID; 335 src->state = GTK_STATE_NORMAL; 336+ src->scale = 1; 337 338 src->any_direction = TRUE; 339 src->any_state = TRUE; 340 src->any_size = TRUE; 341+ src->any_scale = TRUE; 342 343 return src; 344 } 345@@ -2319,6 +2322,15 @@ gtk_icon_source_set_size_wildcarded (GtkIconSource *source, 346 source->any_size = setting != FALSE; 347 } 348 349+void 350+gtk_icon_source_set_scale_wildcarded (GtkIconSource *source, 351+ gboolean setting) 352+{ 353+ g_return_if_fail (source != NULL); 354+ 355+ source->any_scale = setting != FALSE; 356+} 357+ 358 /** 359 * gtk_icon_source_get_size_wildcarded: 360 * @source: a #GtkIconSource 361@@ -2367,6 +2379,14 @@ gtk_icon_source_get_direction_wildcarded (const GtkIconSource *source) 362 return source->any_direction; 363 } 364 365+gboolean 366+gtk_icon_source_get_scale_wildcarded (const GtkIconSource *source) 367+{ 368+ g_return_val_if_fail (source != NULL, TRUE); 369+ 370+ return source->any_scale; 371+} 372+ 373 /** 374 * gtk_icon_source_set_direction: 375 * @source: a #GtkIconSource 376@@ -2433,6 +2453,15 @@ gtk_icon_source_set_size (GtkIconSource *source, 377 source->size = size; 378 } 379 380+void 381+gtk_icon_source_set_scale (GtkIconSource *source, 382+ gdouble scale) 383+{ 384+ g_return_if_fail (source != NULL); 385+ 386+ source->scale = scale; 387+} 388+ 389 /** 390 * gtk_icon_source_get_direction: 391 * @source: a #GtkIconSource 392@@ -2486,6 +2515,14 @@ gtk_icon_source_get_size (const GtkIconSource *source) 393 return source->size; 394 } 395 396+gdouble 397+gtk_icon_source_get_scale (const GtkIconSource *source) 398+{ 399+ g_return_val_if_fail (source != NULL, 0); 400+ 401+ return source->scale; 402+} 403+ 404 #define NUM_CACHED_ICONS 8 405 406 typedef struct _CachedIcon CachedIcon; 407@@ -2499,6 +2536,7 @@ struct _CachedIcon 408 GtkTextDirection direction; 409 GtkStateType state; 410 GtkIconSize size; 411+ gdouble scale; 412 413 GdkPixbuf *pixbuf; 414 }; 415@@ -2529,7 +2567,8 @@ find_in_cache (GtkIconSet *icon_set, 416 GtkStyle *style, 417 GtkTextDirection direction, 418 GtkStateType state, 419- GtkIconSize size) 420+ GtkIconSize size, 421+ gdouble scale) 422 { 423 GSList *tmp_list; 424 GSList *prev; 425@@ -2545,6 +2584,7 @@ find_in_cache (GtkIconSet *icon_set, 426 if (icon->style == style && 427 icon->direction == direction && 428 icon->state == state && 429+ icon->scale == scale && 430 (size == (GtkIconSize)-1 || icon->size == size)) 431 { 432 if (prev) 433@@ -2571,6 +2611,7 @@ add_to_cache (GtkIconSet *icon_set, 434 GtkTextDirection direction, 435 GtkStateType state, 436 GtkIconSize size, 437+ gdouble scale, 438 GdkPixbuf *pixbuf) 439 { 440 CachedIcon *icon; 441@@ -2595,6 +2636,7 @@ add_to_cache (GtkIconSet *icon_set, 442 icon->direction = direction; 443 icon->state = state; 444 icon->size = size; 445+ icon->scale = scale; 446 icon->pixbuf = pixbuf; 447 448 if (icon->style) 449diff --git a/gtk/gtkiconfactory.h b/gtk/gtkiconfactory.h 450index e38f8e6..d646ed9 100644 451--- a/gtk/gtkiconfactory.h 452+++ b/gtk/gtkiconfactory.h 453@@ -177,19 +177,24 @@ void gtk_icon_source_set_state_wildcarded (GtkIconSource * 454 gboolean setting); 455 void gtk_icon_source_set_size_wildcarded (GtkIconSource *source, 456 gboolean setting); 457+void gtk_icon_source_set_scale_wildcarded (GtkIconSource *source, 458+ gboolean setting); 459 gboolean gtk_icon_source_get_size_wildcarded (const GtkIconSource *source); 460 gboolean gtk_icon_source_get_state_wildcarded (const GtkIconSource *source); 461 gboolean gtk_icon_source_get_direction_wildcarded (const GtkIconSource *source); 462+gboolean gtk_icon_source_get_scale_wildcarded (const GtkIconSource *source); 463 void gtk_icon_source_set_direction (GtkIconSource *source, 464 GtkTextDirection direction); 465 void gtk_icon_source_set_state (GtkIconSource *source, 466 GtkStateType state); 467 void gtk_icon_source_set_size (GtkIconSource *source, 468 GtkIconSize size); 469+void gtk_icon_source_set_scale (GtkIconSource *source, 470+ gdouble scale); 471 GtkTextDirection gtk_icon_source_get_direction (const GtkIconSource *source); 472 GtkStateType gtk_icon_source_get_state (const GtkIconSource *source); 473 GtkIconSize gtk_icon_source_get_size (const GtkIconSource *source); 474- 475+gdouble gtk_icon_source_get_scale (const GtkIconSource *source); 476 477 /* ignore this */ 478 void _gtk_icon_set_invalidate_caches (void); 479-- 4801.7.10.2 (Apple Git-33) 481