1#include <string.h>
2#include <locale.h>
3
4#include <pango/pango.h>
5#include <pango/pangocairo-fc.h>
6#include <pango/pangofc-fontmap.h>
7#include "test-common.h"
8
9static void
10install_fonts (const char *dir)
11{
12 FcConfig *config;
13 PangoFontMap *map;
14 char *path;
15 gsize len;
16 char *conf;
17
18 map = g_object_new (PANGO_TYPE_CAIRO_FC_FONT_MAP, NULL);
19
20 config = FcConfigCreate ();
21
22 path = g_build_filename (first_element: dir, "fonts.conf", NULL);
23 g_file_get_contents (filename: path, contents: &conf, length: &len, NULL);
24
25 if (!FcConfigParseAndLoadFromMemory (config, buffer: (const FcChar8 *) conf, TRUE))
26 g_error ("Failed to parse fontconfig configuration");
27
28 g_free (mem: conf);
29 g_free (mem: path);
30
31 FcConfigAppFontAddDir (config, dir: (const FcChar8 *) dir);
32 pango_fc_font_map_set_config (PANGO_FC_FONT_MAP (map), fcconfig: config);
33 FcConfigDestroy (config);
34
35 pango_cairo_font_map_set_default (PANGO_CAIRO_FONT_MAP (map));
36
37 g_object_unref (object: map);
38}
39
40static gboolean
41append_one (PangoFontset *fonts,
42 PangoFont *font,
43 gpointer data)
44{
45 PangoFontDescription *desc;
46 GString *str = data;
47 char *s;
48
49 desc = pango_font_describe (font);
50 s = pango_font_description_to_string (desc);
51
52 g_string_append_printf (string: str, format: "%s\n", s);
53
54 g_free (mem: s);
55 pango_font_description_free (desc);
56
57 return FALSE;
58}
59
60static char *
61list_fonts (const char *contents)
62{
63 char *p, *s;
64 PangoFontDescription *desc;
65 PangoContext *context;
66 PangoFontset *fonts;
67 GString *str;
68
69 p = strchr (s: contents, c: '\n');
70 if (p)
71 s = g_strndup (str: contents, n: p - contents);
72 else
73 s = g_strdup (str: contents);
74
75 desc = pango_font_description_from_string (str: s);
76
77 context = pango_font_map_create_context (fontmap: pango_cairo_font_map_get_default ());
78 fonts = pango_context_load_fontset (context, desc, language: pango_language_get_default ());
79
80 str = g_string_new (init: s);
81 g_string_append (string: str, val: "\n\n");
82
83 pango_fontset_foreach (fontset: fonts, func: append_one, data: str);
84
85 g_object_unref (object: fonts);
86 g_object_unref (object: context);
87 pango_font_description_free (desc);
88
89 g_free (mem: s);
90
91 return g_string_free (string: str, FALSE);
92}
93
94static void
95test_fontset (gconstpointer d)
96{
97 const char *filename = d;
98 GError *error = NULL;
99 char *diff;
100 GBytes *bytes;
101 char *contents;
102 gsize length;
103 char *s;
104 GBytes *orig;
105
106 if (!PANGO_IS_FC_FONT_MAP (pango_cairo_font_map_get_default ()))
107 {
108 g_test_skip (msg: "Not an fc fontmap. Skipping...");
109 return;
110 }
111
112 char *old_locale = g_strdup (str: setlocale (LC_ALL, NULL));
113 setlocale (LC_ALL, locale: "en_US.UTF-8");
114 if (strstr (haystack: setlocale (LC_ALL, NULL), needle: "en_US") == NULL)
115 {
116 char *msg = g_strdup_printf (format: "Locale en_US.UTF-8 not available, skipping layout %s", filename);
117 g_test_skip (msg);
118 g_free (mem: msg);
119 g_free (mem: old_locale);
120 return;
121 }
122
123 g_file_get_contents (filename, contents: &contents, length: &length, error: &error);
124 g_assert_no_error (error);
125
126 s = list_fonts (contents);
127
128 orig = g_bytes_new_take (data: contents, size: length);
129 bytes = g_bytes_new_take (data: s, size: strlen (s: s));
130
131 diff = diff_bytes (b1: orig, b2: bytes, error: &error);
132 g_assert_no_error (error);
133
134 g_bytes_unref (bytes);
135 g_bytes_unref (bytes: orig);
136
137 setlocale (LC_ALL, locale: old_locale);
138 g_free (mem: old_locale);
139
140 if (diff && diff[0])
141 {
142 char **lines = g_strsplit (string: diff, delimiter: "\n", max_tokens: -1);
143 const char *line;
144 int i = 0;
145
146 g_test_message (format: "Contents don't match expected contents");
147
148 for (line = lines[0]; line != NULL; line = lines[++i])
149 g_test_message (format: "%s", line);
150
151 g_test_fail ();
152 g_strfreev (str_array: lines);
153 }
154
155 g_free (mem: diff);
156}
157
158int
159main (int argc, char *argv[])
160{
161 GDir *dir;
162 GError *error = NULL;
163 char *opt_fonts = NULL;
164 const gchar *name;
165 char *path;
166 GOptionContext *option_context;
167 GOptionEntry entries[] = {
168 { "fonts", 0, 0, G_OPTION_ARG_FILENAME, &opt_fonts, "Fonts to use", "DIR" },
169 { NULL, 0 },
170 };
171
172 setlocale (LC_ALL, locale: "");
173 option_context = g_option_context_new (parameter_string: "");
174 g_option_context_add_main_entries (context: option_context, entries, NULL);
175 g_option_context_set_ignore_unknown_options (context: option_context, TRUE);
176 if (!g_option_context_parse (context: option_context, argc: &argc, argv: &argv, error: &error))
177 {
178 g_error ("failed to parse options: %s", error->message);
179 return 1;
180 }
181 g_option_context_free (context: option_context);
182
183 if (opt_fonts)
184 {
185 install_fonts (dir: opt_fonts);
186 g_free (mem: opt_fonts);
187 }
188
189 /* allow to easily generate expected output for new test cases */
190 if (argc > 1 && argv[1][0] != '-')
191 {
192 char *contents;
193 gsize length;
194 GError *error = NULL;
195 char *s;
196
197 g_file_get_contents (filename: argv[1], contents: &contents, length: &length, error: &error);
198 g_assert_no_error (error);
199
200 s = list_fonts (contents);
201
202 g_print (format: "%s", s);
203
204 g_free (mem: s);
205 g_free (mem: contents);
206
207 return 0;
208 }
209
210 g_test_init (argc: &argc, argv: &argv, NULL);
211
212 if (!opt_fonts)
213 {
214 path = g_test_build_filename (file_type: G_TEST_DIST, first_path: "fonts", NULL);
215 install_fonts (dir: path);
216 g_free (mem: path);
217 }
218
219 path = g_test_build_filename (file_type: G_TEST_DIST, first_path: "fontsets", NULL);
220 dir = g_dir_open (path, flags: 0, error: &error);
221 g_free (mem: path);
222 g_assert_no_error (error);
223 while ((name = g_dir_read_name (dir)) != NULL)
224 {
225 path = g_strdup_printf (format: "/fontsets/%s", name);
226 g_test_add_data_func_full (testpath: path, test_data: g_test_build_filename (file_type: G_TEST_DIST, first_path: "fontsets", name, NULL),
227 test_func: test_fontset, data_free_func: g_free);
228 g_free (mem: path);
229 }
230 g_dir_close (dir);
231
232 return g_test_run ();
233}
234

source code of gtk/subprojects/pango/tests/test-fonts.c