1 #include <gtk/gtk.h>
2 
3 #include <string.h>
4 
5 #define SCALABLE_IMAGE_SIZE (128)
6 
7 static GtkIconTheme *
get_test_icontheme(gboolean force_reload)8 get_test_icontheme (gboolean force_reload)
9 {
10   static GtkIconTheme *icon_theme = NULL;
11   const char *current_dir[2];
12 
13   if (force_reload)
14     g_clear_object (&icon_theme);
15 
16   if (icon_theme)
17     return icon_theme;
18 
19   icon_theme = gtk_icon_theme_new ();
20   gtk_icon_theme_set_theme_name (icon_theme, "icons");
21   current_dir[0] = g_test_get_dir (G_TEST_DIST);
22   current_dir[1] = NULL;
23   gtk_icon_theme_set_search_path (icon_theme, current_dir);
24 
25   return icon_theme;
26 }
27 
28 static char *
lookup_flags_to_string(GtkIconLookupFlags flags)29 lookup_flags_to_string (GtkIconLookupFlags flags)
30 {
31   GValue flags_value = { 0, }, string_value = { 0, };
32   char *result;
33 
34   g_value_init (&flags_value, GTK_TYPE_ICON_LOOKUP_FLAGS);
35   g_value_init (&string_value, G_TYPE_STRING);
36 
37   g_value_set_flags (&flags_value, flags);
38   if (!g_value_transform (&flags_value, &string_value))
39     {
40       g_assert_not_reached ();
41     }
42 
43   result = g_value_dup_string (&string_value);
44 
45   g_value_unset (&flags_value);
46   g_value_unset (&string_value);
47 
48   return result;
49 }
50 
51 static void
assert_icon_lookup_size(const char * icon_name,int size,GtkTextDirection direction,GtkIconLookupFlags flags,gboolean fallbacks,const char * filename,int pixbuf_size)52 assert_icon_lookup_size (const char         *icon_name,
53                          int                 size,
54                          GtkTextDirection    direction,
55                          GtkIconLookupFlags  flags,
56                          gboolean            fallbacks,
57                          const char         *filename,
58                          int                 pixbuf_size)
59 {
60   GtkIconPaintable *info;
61   GFile *file;
62   char *path = NULL;
63 
64   if (fallbacks)
65     {
66       GThemedIcon *fallback_icons = G_THEMED_ICON (g_themed_icon_new_with_default_fallbacks (icon_name));
67       const char **fallback_names = (const char **) g_themed_icon_get_names (fallback_icons);
68       info = gtk_icon_theme_lookup_icon (get_test_icontheme (FALSE), icon_name, &fallback_names[1], size, 1, direction, flags);
69       g_object_unref (fallback_icons);
70     }
71   else
72     {
73       info = gtk_icon_theme_lookup_icon (get_test_icontheme (FALSE), icon_name, NULL, size, 1, direction, flags);
74     }
75 
76   if (info == NULL)
77     {
78       g_error ("Could not look up an icon for \"%s\" with flags %s at size %d",
79                icon_name, lookup_flags_to_string (flags), size);
80       return;
81     }
82 
83   file = gtk_icon_paintable_get_file (info);
84   if (file)
85     {
86       path = g_file_get_path (file);
87       g_object_unref (file);
88     }
89 
90   if (filename)
91     {
92       if (path == NULL || !g_str_has_suffix (path, filename))
93         {
94           g_error ("Icon for \"%s\" with flags %s at size %d should be \"...%s\" but is \"...%s\"",
95                    icon_name, lookup_flags_to_string (flags), size,
96                    filename, path);
97           return;
98         }
99     }
100   else
101     {
102       g_assert_null (path);
103     }
104 
105   g_free (path);
106 
107   g_assert_cmpint (gdk_paintable_get_intrinsic_width (GDK_PAINTABLE (info)), ==, size);
108 
109   g_object_unref (info);
110 }
111 
112 static void
assert_icon_lookup(const char * icon_name,int size,GtkTextDirection direction,GtkIconLookupFlags flags,gboolean fallbacks,const char * filename)113 assert_icon_lookup (const char         *icon_name,
114                     int                 size,
115                     GtkTextDirection    direction,
116                     GtkIconLookupFlags  flags,
117                     gboolean            fallbacks,
118                     const char         *filename)
119 {
120   assert_icon_lookup_size (icon_name, size, direction, flags, fallbacks, filename, -1);
121 }
122 
123 static void
assert_icon_lookup_fails(const char * icon_name,int size,GtkTextDirection direction,GtkIconLookupFlags flags)124 assert_icon_lookup_fails (const char         *icon_name,
125                           int                 size,
126                           GtkTextDirection    direction,
127                           GtkIconLookupFlags  flags)
128 {
129   GtkIconPaintable *info;
130 
131   info = gtk_icon_theme_lookup_icon (get_test_icontheme (FALSE), icon_name, NULL, size, 1, direction, flags);
132 
133   /* We never truly *fail*, but check that we got the image-missing fallback */
134   g_assert_nonnull (info);
135   g_assert_cmpstr (gtk_icon_paintable_get_icon_name (info), ==, "image-missing");
136 }
137 
138 static GList *lookups = NULL;
139 
140 static GLogWriterOutput
log_writer(GLogLevelFlags log_level,const GLogField * fields,gsize n_fields,gpointer user_data)141 log_writer (GLogLevelFlags   log_level,
142             const GLogField *fields,
143             gsize            n_fields,
144             gpointer         user_data)
145 {
146   const char *domain = NULL;
147   const char *msg = NULL;
148   int i;
149 
150   for (i = 0; i < n_fields; i++)
151     {
152       if (strcmp (fields[i].key, "GLIB_DOMAIN") == 0)
153         domain = fields[i].value;
154       if (strcmp (fields[i].key, "MESSAGE") == 0)
155         msg = fields[i].value;
156     }
157 
158   if (log_level != G_LOG_LEVEL_MESSAGE || g_strcmp0 (domain, "Gtk") != 0)
159     return g_log_writer_default (log_level, fields, n_fields, user_data);
160 
161   if (g_str_has_prefix (msg, "\tlookup name: "))
162     {
163       char *s;
164       s = g_strchomp (g_strdup (msg + strlen ("\tlookup name: ")));
165       lookups = g_list_append (lookups, s);
166     }
167 
168   return G_LOG_WRITER_HANDLED;
169 }
170 
171 static void
assert_lookup_order(const char * icon_name,int size,GtkTextDirection direction,GtkIconLookupFlags flags,gboolean fallbacks,const char * first,...)172 assert_lookup_order (const char         *icon_name,
173                      int                 size,
174                      GtkTextDirection    direction,
175                      GtkIconLookupFlags  flags,
176                      gboolean            fallbacks,
177                      const char         *first,
178                      ...)
179 {
180   guint debug_flags;
181   va_list args;
182   const char *s;
183   GtkIconPaintable *info;
184   GList *l;
185 
186 /* this hack is only usable in debug builds */
187 #ifndef G_ENABLE_DEBUG
188   g_assert_not_reached ();
189 #endif
190 
191   debug_flags = gtk_get_debug_flags ();
192   gtk_set_debug_flags (debug_flags | GTK_DEBUG_ICONTHEME);
193   g_log_set_writer_func (log_writer, NULL, NULL);
194 
195   g_assert_null (lookups);
196 
197   if (fallbacks)
198     {
199       GThemedIcon *fallback_icons = G_THEMED_ICON (g_themed_icon_new_with_default_fallbacks (icon_name));
200       const char **fallback_names = (const char **) g_themed_icon_get_names (fallback_icons);
201       info = gtk_icon_theme_lookup_icon (get_test_icontheme (FALSE), icon_name, &fallback_names[1], size, 1, direction, flags);
202       g_object_unref (fallback_icons);
203     }
204   else
205     {
206       info = gtk_icon_theme_lookup_icon (get_test_icontheme (FALSE), icon_name, NULL, size, 1, direction, flags);
207     }
208 
209   if (info)
210     g_object_unref (info);
211 
212   va_start (args, first);
213   s = first;
214   l = lookups;
215   while (s != NULL)
216     {
217       g_assert_nonnull (l);
218       g_assert_cmpstr (s, ==, l->data);
219       s = va_arg (args, char *);
220       l = l->next;
221     }
222   g_assert_null (l);
223   va_end (args);
224 
225   g_list_free_full (lookups, g_free);
226   lookups = NULL;
227 
228   g_log_set_writer_func (g_log_writer_default, NULL, NULL);
229   gtk_set_debug_flags (debug_flags);
230 }
231 
232 #ifdef G_ENABLE_DEBUG
233 #define require_debug()
234 #else
235 #define require_debug() \
236   g_test_skip ("requires G_ENABLE_DEBUG"); \
237   return;
238 #endif
239 
240 
241 static void
test_basics(void)242 test_basics (void)
243 {
244   /* just a basic boring lookup so we know everything works */
245   assert_icon_lookup ("simple", 16, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/16x16/simple.png");
246 }
247 
248 static void
test_lookup_order(void)249 test_lookup_order (void)
250 {
251   require_debug ();
252 
253   assert_lookup_order ("foo-bar-baz", 16, GTK_TEXT_DIR_NONE, 0, TRUE,
254                        "foo-bar-baz",
255                        "foo-bar",
256                        "foo",
257                        "foo-bar-baz-symbolic",
258                        "foo-bar-symbolic",
259                        "foo-symbolic",
260                        NULL);
261   assert_lookup_order ("foo-bar-baz", 16, GTK_TEXT_DIR_RTL, 0, TRUE,
262                        "foo-bar-baz-rtl",
263                        "foo-bar-baz",
264                        "foo-bar-rtl",
265                        "foo-bar",
266                        "foo-rtl",
267                        "foo",
268                        "foo-bar-baz-symbolic-rtl",
269                        "foo-bar-baz-symbolic",
270                        "foo-bar-symbolic-rtl",
271                        "foo-bar-symbolic",
272                        "foo-symbolic-rtl",
273                        "foo-symbolic",
274                        NULL);
275   assert_lookup_order ("foo-bar-baz", 16, GTK_TEXT_DIR_RTL, 0, FALSE,
276                        "foo-bar-baz-rtl",
277                        "foo-bar-baz",
278                        NULL);
279   assert_lookup_order ("foo-bar-baz-symbolic", 16, GTK_TEXT_DIR_NONE, 0, TRUE,
280                        "foo-bar-baz-symbolic",
281                        "foo-bar-symbolic",
282                        "foo-symbolic",
283                        "foo-bar-baz",
284                        "foo-bar",
285                        "foo",
286                        NULL);
287 
288   assert_lookup_order ("bla-bla", 16, GTK_TEXT_DIR_NONE, GTK_ICON_LOOKUP_FORCE_SYMBOLIC, TRUE,
289                        "bla-bla-symbolic",
290                        "bla-symbolic",
291                        "bla-bla-symbolic", /* awkward */
292                        "bla-symbolic", /* awkward */
293                        "bla-bla",
294                        "bla",
295                        NULL);
296   assert_lookup_order ("bla-bla-symbolic", 16, GTK_TEXT_DIR_NONE, GTK_ICON_LOOKUP_FORCE_SYMBOLIC, TRUE,
297                        "bla-bla-symbolic",
298                        "bla-symbolic",
299                        "bla-bla-symbolic", /* awkward */
300                        "bla-symbolic", /* awkward */
301                        "bla-bla",
302                        "bla",
303                        NULL);
304 
305   assert_lookup_order ("bar-baz", 16, GTK_TEXT_DIR_RTL, GTK_ICON_LOOKUP_FORCE_SYMBOLIC, TRUE,
306                        "bar-baz-symbolic-rtl",
307                        "bar-baz-symbolic",
308                        "bar-symbolic-rtl",
309                        "bar-symbolic",
310                        "bar-baz-symbolic-rtl", /* awkward */
311                        "bar-baz-symbolic", /* awkward */
312                        "bar-symbolic-rtl", /* awkward */
313                        "bar-symbolic", /* awkward */
314                        "bar-baz-rtl",
315                        "bar-baz",
316                        "bar-rtl",
317                        "bar",
318                        NULL);
319   assert_lookup_order ("bar-baz-symbolic", 16, GTK_TEXT_DIR_RTL, GTK_ICON_LOOKUP_FORCE_SYMBOLIC, TRUE,
320                        "bar-baz-symbolic-rtl",
321                        "bar-baz-symbolic",
322                        "bar-symbolic-rtl",
323                        "bar-symbolic",
324                        "bar-baz-symbolic-rtl", /* awkward */
325                        "bar-baz-symbolic", /* awkward */
326                        "bar-symbolic-rtl", /* awkward */
327                        "bar-symbolic", /* awkward */
328                        "bar-baz-rtl",
329                        "bar-baz",
330                        "bar-rtl",
331                        "bar",
332                        NULL);
333 
334   assert_lookup_order ("bar-baz", 16, GTK_TEXT_DIR_LTR, GTK_ICON_LOOKUP_FORCE_SYMBOLIC, TRUE,
335                        "bar-baz-symbolic-ltr",
336                        "bar-baz-symbolic",
337                        "bar-symbolic-ltr",
338                        "bar-symbolic",
339                        "bar-baz-symbolic-ltr", /* awkward */
340                        "bar-baz-symbolic", /* awkward */
341                        "bar-symbolic-ltr", /* awkward */
342                        "bar-symbolic", /* awkward */
343                        "bar-baz-ltr",
344                        "bar-baz",
345                        "bar-ltr",
346                        "bar",
347                        NULL);
348   assert_lookup_order ("bar-baz-symbolic", 16, GTK_TEXT_DIR_LTR, GTK_ICON_LOOKUP_FORCE_SYMBOLIC, TRUE,
349                        "bar-baz-symbolic-ltr",
350                        "bar-baz-symbolic",
351                        "bar-symbolic-ltr",
352                        "bar-symbolic",
353                        "bar-baz-symbolic-ltr", /* awkward */
354                        "bar-baz-symbolic", /* awkward */
355                        "bar-symbolic-ltr", /* awkward */
356                        "bar-symbolic", /* awkward */
357                        "bar-baz-ltr",
358                        "bar-baz",
359                        "bar-ltr",
360                        "bar",
361                        NULL);
362 }
363 
364 static void
test_generic_fallback(void)365 test_generic_fallback (void)
366 {
367   /* simple test for generic fallback */
368   assert_icon_lookup ("simple-foo-bar",
369                       16,
370                       GTK_TEXT_DIR_NONE,
371                       0,
372                       TRUE,
373                       "/icons/16x16/simple.png");
374 
375   /* Check generic fallback also works for symbolics falling back to regular items */
376   assert_icon_lookup ("simple-foo-bar-symbolic",
377                       16,
378                       GTK_TEXT_DIR_NONE,
379                       0,
380                       TRUE,
381                       "/icons/16x16/simple.png");
382 
383   /* Check we fall back to more generic symbolic icons before falling back to
384    * non-symbolics */
385   assert_icon_lookup ("everything-justregular-symbolic",
386                       SCALABLE_IMAGE_SIZE,
387                       GTK_TEXT_DIR_NONE,
388                       0,
389                       TRUE,
390                       "/icons/scalable/everything-symbolic.svg");
391 }
392 
393 static void
test_force_symbolic(void)394 test_force_symbolic (void)
395 {
396   /* check forcing symbolic works */
397   assert_icon_lookup ("everything",
398                       SCALABLE_IMAGE_SIZE,
399                       GTK_TEXT_DIR_NONE,
400                       GTK_ICON_LOOKUP_FORCE_SYMBOLIC,
401                       FALSE,
402                       "/icons/scalable/everything-symbolic.svg");
403   /* check forcing symbolic also works for symbolic icons (d'oh) */
404   assert_icon_lookup ("everything-symbolic",
405                       SCALABLE_IMAGE_SIZE,
406                       GTK_TEXT_DIR_NONE,
407                       GTK_ICON_LOOKUP_FORCE_SYMBOLIC,
408                       FALSE,
409                       "/icons/scalable/everything-symbolic.svg");
410 
411   /* check all the combos for fallbacks on an icon that only exists as symbolic */
412   assert_icon_lookup ("everything-justsymbolic",
413                       SCALABLE_IMAGE_SIZE,
414                       GTK_TEXT_DIR_NONE,
415                       GTK_ICON_LOOKUP_FORCE_SYMBOLIC,
416                       FALSE,
417                       "/icons/scalable/everything-justsymbolic-symbolic.svg");
418   assert_icon_lookup ("everything-justsymbolic",
419                       SCALABLE_IMAGE_SIZE,
420                       GTK_TEXT_DIR_NONE,
421                       GTK_ICON_LOOKUP_FORCE_SYMBOLIC,
422                       TRUE,
423                       "/icons/scalable/everything-justsymbolic-symbolic.svg");
424   assert_icon_lookup ("everything-justsymbolic-symbolic",
425                       SCALABLE_IMAGE_SIZE,
426                       GTK_TEXT_DIR_NONE,
427                       GTK_ICON_LOOKUP_FORCE_SYMBOLIC,
428                       FALSE,
429                       "/icons/scalable/everything-justsymbolic-symbolic.svg");
430   assert_icon_lookup ("everything-justsymbolic-symbolic",
431                       SCALABLE_IMAGE_SIZE,
432                       GTK_TEXT_DIR_NONE,
433                       GTK_ICON_LOOKUP_FORCE_SYMBOLIC,
434                       TRUE,
435                       "/icons/scalable/everything-justsymbolic-symbolic.svg");
436 
437   /* check all the combos for fallbacks, this time for an icon that only exists as regular */
438   assert_icon_lookup ("everything-justregular",
439                       SCALABLE_IMAGE_SIZE,
440                       GTK_TEXT_DIR_NONE,
441                       GTK_ICON_LOOKUP_FORCE_SYMBOLIC,
442                       FALSE,
443                       "/icons/scalable/everything-justregular.svg");
444   assert_icon_lookup ("everything-justregular",
445                       SCALABLE_IMAGE_SIZE,
446                       GTK_TEXT_DIR_NONE,
447                       GTK_ICON_LOOKUP_FORCE_SYMBOLIC,
448                       TRUE,
449                       "/icons/scalable/everything-symbolic.svg");
450   assert_icon_lookup_fails ("everything-justregular-symbolic",
451                             SCALABLE_IMAGE_SIZE,
452                             GTK_TEXT_DIR_NONE,
453                             GTK_ICON_LOOKUP_FORCE_SYMBOLIC);
454   assert_icon_lookup ("everything-justregular-symbolic",
455                       SCALABLE_IMAGE_SIZE,
456                       GTK_TEXT_DIR_NONE,
457                       GTK_ICON_LOOKUP_FORCE_SYMBOLIC,
458                       TRUE,
459                       "/icons/scalable/everything-symbolic.svg");
460 }
461 
462 static void
test_force_regular(void)463 test_force_regular (void)
464 {
465   /* check forcing regular works (d'oh) */
466   assert_icon_lookup ("everything",
467                       SCALABLE_IMAGE_SIZE,
468                       GTK_TEXT_DIR_NONE,
469                       GTK_ICON_LOOKUP_FORCE_REGULAR,
470                       FALSE,
471                       "/icons/scalable/everything.svg");
472   /* check forcing regular also works for symbolic icons ) */
473   assert_icon_lookup ("everything-symbolic",
474                       SCALABLE_IMAGE_SIZE,
475                       GTK_TEXT_DIR_NONE,
476                       GTK_ICON_LOOKUP_FORCE_REGULAR,
477                       FALSE,
478                       "/icons/scalable/everything.svg");
479 
480   /* check all the combos for fallbacks on an icon that only exists as regular */
481   assert_icon_lookup ("everything-justregular",
482                       SCALABLE_IMAGE_SIZE,
483                       GTK_TEXT_DIR_NONE,
484                       GTK_ICON_LOOKUP_FORCE_REGULAR,
485                       FALSE,
486                       "/icons/scalable/everything-justregular.svg");
487   assert_icon_lookup ("everything-justregular",
488                       SCALABLE_IMAGE_SIZE,
489                       GTK_TEXT_DIR_NONE,
490                       GTK_ICON_LOOKUP_FORCE_REGULAR,
491                       TRUE,
492                       "/icons/scalable/everything-justregular.svg");
493   assert_icon_lookup ("everything-justregular-symbolic",
494                       SCALABLE_IMAGE_SIZE,
495                       GTK_TEXT_DIR_NONE,
496                       GTK_ICON_LOOKUP_FORCE_REGULAR,
497                       FALSE,
498                       "/icons/scalable/everything-justregular.svg");
499   assert_icon_lookup ("everything-justregular-symbolic",
500                       SCALABLE_IMAGE_SIZE,
501                       GTK_TEXT_DIR_NONE,
502                       GTK_ICON_LOOKUP_FORCE_REGULAR,
503                       TRUE,
504                       "/icons/scalable/everything-justregular.svg");
505 
506   /* check all the combos for fallbacks, this time for an icon that only exists as symbolic */
507   assert_icon_lookup_fails ("everything-justsymbolic",
508                             SCALABLE_IMAGE_SIZE,
509                             GTK_TEXT_DIR_NONE,
510                             GTK_ICON_LOOKUP_FORCE_REGULAR);
511   assert_icon_lookup ("everything-justsymbolic",
512                       SCALABLE_IMAGE_SIZE,
513                       GTK_TEXT_DIR_NONE,
514                       GTK_ICON_LOOKUP_FORCE_REGULAR,
515                       TRUE,
516                       "/icons/scalable/everything.svg");
517   assert_icon_lookup ("everything-justsymbolic-symbolic",
518                       SCALABLE_IMAGE_SIZE,
519                       GTK_TEXT_DIR_NONE,
520                       GTK_ICON_LOOKUP_FORCE_REGULAR,
521                       FALSE,
522                       "/icons/scalable/everything-justsymbolic-symbolic.svg");
523   assert_icon_lookup ("everything-justsymbolic-symbolic",
524                       SCALABLE_IMAGE_SIZE,
525                       GTK_TEXT_DIR_NONE,
526                       GTK_ICON_LOOKUP_FORCE_REGULAR,
527                       TRUE,
528                       "/icons/scalable/everything.svg");
529 }
530 
531 static void
test_rtl(void)532 test_rtl (void)
533 {
534   assert_icon_lookup ("everything",
535                       SCALABLE_IMAGE_SIZE,
536                       GTK_TEXT_DIR_RTL,
537                       0,
538                       FALSE,
539                       "/icons/scalable/everything-rtl.svg");
540   assert_icon_lookup ("everything-symbolic",
541                       SCALABLE_IMAGE_SIZE,
542                       GTK_TEXT_DIR_RTL,
543                       0,
544                       FALSE,
545                       "/icons/scalable/everything-symbolic-rtl.svg");
546 
547   assert_icon_lookup_fails ("everything-justrtl",
548                             SCALABLE_IMAGE_SIZE,
549                             GTK_TEXT_DIR_NONE,
550                             0);
551   assert_icon_lookup_fails ("everything-justrtl",
552                             SCALABLE_IMAGE_SIZE,
553                             GTK_TEXT_DIR_LTR,
554                             0);
555   assert_icon_lookup ("everything-justrtl",
556                       SCALABLE_IMAGE_SIZE,
557                       GTK_TEXT_DIR_RTL,
558                       0,
559                       FALSE,
560                       "/icons/scalable/everything-justrtl-rtl.svg");
561 
562   assert_icon_lookup ("everything-justrtl",
563                       SCALABLE_IMAGE_SIZE,
564                       GTK_TEXT_DIR_NONE,
565                       0,
566                       TRUE,
567                       "/icons/scalable/everything.svg");
568   assert_icon_lookup ("everything-justrtl",
569                       SCALABLE_IMAGE_SIZE,
570                       GTK_TEXT_DIR_LTR,
571                       0,
572                       TRUE,
573                       "/icons/scalable/everything.svg");
574   assert_icon_lookup ("everything-justrtl",
575                       SCALABLE_IMAGE_SIZE,
576                       GTK_TEXT_DIR_RTL,
577                       0,
578                       TRUE,
579                       "/icons/scalable/everything-justrtl-rtl.svg");
580 }
581 
582 static void
test_symbolic_single_size(void)583 test_symbolic_single_size (void)
584 {
585   /* Check we properly load a symbolic icon from a sized directory */
586   assert_icon_lookup ("only32-symbolic",
587                       32,
588                       GTK_TEXT_DIR_NONE,
589                       0,
590                       FALSE,
591                       "/icons/32x32/only32-symbolic.svg");
592   /* Check that we still properly load it even if a different size is requested */
593   assert_icon_lookup ("only32-symbolic",
594                       16,
595                       GTK_TEXT_DIR_NONE,
596                       0,
597                       FALSE,
598                       "/icons/32x32/only32-symbolic.svg");
599   assert_icon_lookup ("only32-symbolic",
600                       128,
601                       GTK_TEXT_DIR_NONE,
602                       0,
603                       FALSE,
604                       "/icons/32x32/only32-symbolic.svg");
605 }
606 
607 static void
test_svg_size(void)608 test_svg_size (void)
609 {
610   /* Check we properly load a svg icon from a sized directory */
611   assert_icon_lookup_size ("twosize-fixed", 48, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/32x32/twosize-fixed.svg", 48);
612   assert_icon_lookup_size ("twosize-fixed", 32, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/32x32/twosize-fixed.svg", 32);
613   assert_icon_lookup_size ("twosize-fixed", 20, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/32x32/twosize-fixed.svg", 20);
614   assert_icon_lookup_size ("twosize-fixed", 16, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/16x16/twosize-fixed.svg", 16);
615 
616   /* Check that we still properly load it even if a different size is requested */
617   assert_icon_lookup_size ("twosize", 64, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/32x32s/twosize.svg", 64);
618   assert_icon_lookup_size ("twosize", 48, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/32x32s/twosize.svg", 48);
619   assert_icon_lookup_size ("twosize", 32, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/32x32s/twosize.svg", 32);
620   assert_icon_lookup_size ("twosize", 24, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/32x32s/twosize.svg", 24);
621   assert_icon_lookup_size ("twosize", 16, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/16x16s/twosize.svg", 16);
622   assert_icon_lookup_size ("twosize", 12, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/16x16s/twosize.svg", 12);
623   assert_icon_lookup_size ("twosize",  8, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/16x16s/twosize.svg", 8);
624 }
625 
626 static void
test_size(void)627 test_size (void)
628 {
629   assert_icon_lookup_size ("size-test", 12, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/15/size-test.png", 15);
630   assert_icon_lookup_size ("size-test", 13, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/15/size-test.png", 15);
631   assert_icon_lookup_size ("size-test", 14, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/15/size-test.png", 15);
632   assert_icon_lookup_size ("size-test", 15, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/15/size-test.png", 15);
633   assert_icon_lookup_size ("size-test", 16, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/16-22/size-test.png", 19);
634   assert_icon_lookup_size ("size-test", 17, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/16-22/size-test.png", 19);
635   assert_icon_lookup_size ("size-test", 18, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/16-22/size-test.png", 19);
636   assert_icon_lookup_size ("size-test", 19, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/16-22/size-test.png", 19);
637   /* the next 3 are because we never scale up */
638   assert_icon_lookup_size ("size-test", 20, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/25+/size-test.svg", 20);
639   assert_icon_lookup_size ("size-test", 21, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/25+/size-test.svg", 21);
640   assert_icon_lookup_size ("size-test", 22, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/25+/size-test.svg", 22);
641 
642   assert_icon_lookup_size ("size-test", 23, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/25+/size-test.svg", 23);
643   assert_icon_lookup_size ("size-test", 23, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/25+/size-test.svg", 23);
644   assert_icon_lookup_size ("size-test", 25, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/25+/size-test.svg", 25);
645   assert_icon_lookup_size ("size-test", 28, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/25+/size-test.svg", 28);
646   /* the next 2 are because we never scale up */
647   assert_icon_lookup_size ("size-test", 31, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/35+/size-test.svg", 31);
648   assert_icon_lookup_size ("size-test", 34, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/35+/size-test.svg", 34);
649 
650   assert_icon_lookup_size ("size-test", 37, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/35+/size-test.svg", 37);
651   assert_icon_lookup_size ("size-test", 40, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/35+/size-test.svg", 40);
652   assert_icon_lookup_size ("size-test", 45, GTK_TEXT_DIR_NONE, 0, FALSE, "/icons/35+/size-test.svg", 45);
653 }
654 
655 static void
test_list(void)656 test_list (void)
657 {
658   GtkIconTheme *theme;
659   char **icons;
660 
661   theme = get_test_icontheme (TRUE);
662   icons = gtk_icon_theme_get_icon_names (theme);
663 
664   g_assert_true (g_strv_contains ((const char * const *)icons, "size-test"));
665   g_assert_true (g_strv_contains ((const char * const *)icons, "simple"));
666   g_assert_true (g_strv_contains ((const char * const *)icons, "twosize-fixed"));
667   g_assert_true (g_strv_contains ((const char * const *)icons, "twosize"));
668   g_assert_true (g_strv_contains ((const char * const *)icons, "only32-symbolic"));
669   g_assert_true (g_strv_contains ((const char * const *)icons, "everything"));
670   g_assert_true (g_strv_contains ((const char * const *)icons, "everything-rtl"));
671   g_assert_true (g_strv_contains ((const char * const *)icons, "everything-symbolic"));
672   g_assert_true (g_strv_contains ((const char * const *)icons, "everything-justregular"));
673   g_assert_true (g_strv_contains ((const char * const *)icons, "everything-justrtl-rtl"));
674   g_assert_true (g_strv_contains ((const char * const *)icons, "everything-symbolic-rtl"));
675   g_assert_true (g_strv_contains ((const char * const *)icons, "everything-justsymbolic-symbolic"));
676 
677   g_assert_true (gtk_icon_theme_has_icon (theme, "size-test"));
678   g_assert_true (gtk_icon_theme_has_icon (theme, "simple"));
679   g_assert_true (gtk_icon_theme_has_icon (theme, "twosize-fixed"));
680   g_assert_true (gtk_icon_theme_has_icon (theme, "twosize"));
681   g_assert_true (gtk_icon_theme_has_icon (theme, "only32-symbolic"));
682   g_assert_true (gtk_icon_theme_has_icon (theme, "everything"));
683   g_assert_true (gtk_icon_theme_has_icon (theme, "everything-rtl"));
684   g_assert_true (gtk_icon_theme_has_icon (theme, "everything-symbolic"));
685   g_assert_true (gtk_icon_theme_has_icon (theme, "everything-justregular"));
686   g_assert_true (gtk_icon_theme_has_icon (theme, "everything-justrtl-rtl"));
687   g_assert_true (gtk_icon_theme_has_icon (theme, "everything-symbolic-rtl"));
688   g_assert_true (gtk_icon_theme_has_icon (theme, "everything-justsymbolic-symbolic"));
689 
690   g_strfreev (icons);
691 }
692 
693 static void
test_inherit(void)694 test_inherit (void)
695 {
696   assert_icon_lookup ("one-two-three",
697                       SCALABLE_IMAGE_SIZE,
698                       GTK_TEXT_DIR_NONE,
699                       0,
700                       TRUE,
701                       "/icons/scalable/one-two.svg");
702   assert_icon_lookup ("one-two-three",
703                       SCALABLE_IMAGE_SIZE,
704                       GTK_TEXT_DIR_RTL,
705                       0,
706                       TRUE,
707                       "/icons/scalable/one-two-rtl.svg");
708   assert_icon_lookup ("one-two-three-symbolic",
709                       SCALABLE_IMAGE_SIZE,
710                       GTK_TEXT_DIR_NONE,
711                       0,
712                       TRUE,
713                       "/icons2/scalable/one-two-three-symbolic.svg");
714   assert_icon_lookup ("one-two-three-symbolic",
715                       SCALABLE_IMAGE_SIZE,
716                       GTK_TEXT_DIR_RTL,
717                       0,
718                       TRUE,
719                       "/icons2/scalable/one-two-three-symbolic.svg");
720   assert_icon_lookup ("one-two-symbolic",
721                       SCALABLE_IMAGE_SIZE,
722                       GTK_TEXT_DIR_NONE,
723                       0,
724                       TRUE,
725                       "/icons2/scalable/one-two-symbolic.svg");
726   assert_icon_lookup ("one-two-symbolic",
727                       SCALABLE_IMAGE_SIZE,
728                       GTK_TEXT_DIR_RTL,
729                       0,
730                       TRUE,
731                       "/icons2/scalable/one-two-symbolic-rtl.svg");
732 }
733 
734 static void
test_nonsquare_symbolic(void)735 test_nonsquare_symbolic (void)
736 {
737   int width, height, size;
738   GtkIconTheme *icon_theme;
739   GtkIconPaintable *info;
740   GFile *file;
741   GIcon *icon;
742   GError *error = NULL;
743   GdkPixbuf *pixbuf;
744   GtkSnapshot *snapshot;
745   GskRenderNode *node;
746   graphene_rect_t bounds;
747 
748   char *path = g_build_filename (g_test_get_dir (G_TEST_DIST),
749                                   "icons",
750                                   "scalable",
751                                   "nonsquare-symbolic.svg",
752                                   NULL);
753 
754   /* load the original image for reference */
755   pixbuf = gdk_pixbuf_new_from_file (path, &error);
756 
757   g_assert_no_error (error);
758   g_assert_nonnull (pixbuf);
759 
760   width = gdk_pixbuf_get_width (pixbuf);
761   height = gdk_pixbuf_get_height (pixbuf);
762   size = MAX (width, height);
763   g_object_unref (pixbuf);
764 
765   g_assert_cmpint (width, !=, height);
766 
767   /* now load it through GtkIconTheme */
768   icon_theme = gtk_icon_theme_get_for_display (gdk_display_get_default ());
769   file = g_file_new_for_path (path);
770   icon = g_file_icon_new (file);
771   info = gtk_icon_theme_lookup_by_gicon (icon_theme, icon,
772                                          height, 1, GTK_TEXT_DIR_NONE, 0);
773   g_assert_nonnull (info);
774 
775   snapshot = gtk_snapshot_new ();
776   gdk_paintable_snapshot (GDK_PAINTABLE (info), snapshot, size, size);
777   node = gtk_snapshot_free_to_node (snapshot);
778 
779   /* the original dimensions have been preserved */
780 
781   gsk_render_node_get_bounds (node, &bounds);
782   g_assert_cmpint (bounds.size.width, ==, width);
783   g_assert_cmpint (bounds.size.height, ==, height);
784 
785   gsk_render_node_unref (node);
786   g_free (path);
787   g_object_unref (file);
788   g_object_unref (icon);
789   g_object_unref (info);
790 }
791 
792 static void
require_env(const char * var)793 require_env (const char *var)
794 {
795   if (g_getenv (var) == NULL)
796     g_warning ("Some tests require %s to be set", var);
797 }
798 
799 int
main(int argc,char * argv[])800 main (int argc, char *argv[])
801 {
802   require_env ("G_TEST_SRCDIR");
803 
804   gtk_test_init (&argc, &argv);
805 
806   g_test_add_func ("/icontheme/basics", test_basics);
807   g_test_add_func ("/icontheme/lookup-order", test_lookup_order);
808   g_test_add_func ("/icontheme/generic-fallback", test_generic_fallback);
809   g_test_add_func ("/icontheme/force-symbolic", test_force_symbolic);
810   g_test_add_func ("/icontheme/force-regular", test_force_regular);
811   g_test_add_func ("/icontheme/rtl", test_rtl);
812   g_test_add_func ("/icontheme/symbolic-single-size", test_symbolic_single_size);
813   g_test_add_func ("/icontheme/svg-size", test_svg_size);
814   g_test_add_func ("/icontheme/size", test_size);
815   g_test_add_func ("/icontheme/list", test_list);
816   g_test_add_func ("/icontheme/inherit", test_inherit);
817   g_test_add_func ("/icontheme/nonsquare-symbolic", test_nonsquare_symbolic);
818 
819   return g_test_run();
820 }
821