d696b4592e77bb96f7c89d1f61de0f2a30c24889
[mono.git] / bockbuild / mac-sdk / patches / gtk / 0059-iconfactory-Add-scale-info-to-GtkIconSource.patch
1 From 431d1225b153c1a1389686920aed1d26ff3218b2 Mon Sep 17 00:00:00 2001
2 From: Carlos Garnacho <carlos@lanedo.com>
3 Date: Fri, 10 May 2013 18:24:26 +0200
4 Subject: [PATCH 59/68] iconfactory: Add scale info to GtkIconSource
5
6 GtkIconSource now has notions knows about scale, so it can correctly
7 fetch the icon at the right scale for ICON_NAME source types.
8
9 All default stock icons have been made to have a wildcarded scale,
10 so 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
16 diff --git a/gtk/gtkiconfactory.c b/gtk/gtkiconfactory.c
17 index 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)
449 diff --git a/gtk/gtkiconfactory.h b/gtk/gtkiconfactory.h
450 index 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 --
480 1.7.10.2 (Apple Git-33)