1 | /* Pango |
2 | * test-layout.c: Test Pango Layout |
3 | * |
4 | * Copyright (C) 2014 Red Hat, Inc |
5 | * |
6 | * This library is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Library General Public |
8 | * License as published by the Free Software Foundation; either |
9 | * version 2 of the License, or (at your option) any later version. |
10 | * |
11 | * This library is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * Library General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Library General Public |
17 | * License along with this library; if not, write to the |
18 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
19 | * Boston, MA 02111-1307, USA. |
20 | */ |
21 | |
22 | #include <glib.h> |
23 | #include <string.h> |
24 | #include <locale.h> |
25 | |
26 | #ifndef G_OS_WIN32 |
27 | #include <unistd.h> |
28 | #endif |
29 | |
30 | #include "config.h" |
31 | #include <pango/pangocairo.h> |
32 | #include <pango/pangocairo-fc.h> |
33 | #include <pango/pangofc-fontmap.h> |
34 | #include "test-common.h" |
35 | |
36 | |
37 | static void |
38 | test_layout (gconstpointer d) |
39 | { |
40 | const char *filename = d; |
41 | GError *error = NULL; |
42 | char *diff; |
43 | GBytes *bytes; |
44 | char *contents; |
45 | gsize length; |
46 | GBytes *orig; |
47 | PangoContext *context; |
48 | PangoLayout *layout; |
49 | |
50 | if (!PANGO_IS_FC_FONT_MAP (pango_cairo_font_map_get_default ())) |
51 | { |
52 | g_test_skip (msg: "Not an fc fontmap. Skipping..." ); |
53 | return; |
54 | } |
55 | |
56 | char *old_locale = g_strdup (str: setlocale (LC_ALL, NULL)); |
57 | setlocale (LC_ALL, locale: "en_US.UTF-8" ); |
58 | if (strstr (haystack: setlocale (LC_ALL, NULL), needle: "en_US" ) == NULL) |
59 | { |
60 | char *msg = g_strdup_printf (format: "Locale en_US.UTF-8 not available, skipping layout %s" , filename); |
61 | g_test_skip (msg); |
62 | g_free (mem: msg); |
63 | g_free (mem: old_locale); |
64 | return; |
65 | } |
66 | |
67 | g_file_get_contents (filename, contents: &contents, length: &length, error: &error); |
68 | g_assert_no_error (error); |
69 | orig = g_bytes_new_take (data: contents, size: length); |
70 | |
71 | context = pango_font_map_create_context (fontmap: pango_cairo_font_map_get_default ()); |
72 | layout = pango_layout_deserialize (context, bytes: orig, flags: PANGO_LAYOUT_DESERIALIZE_CONTEXT, error: &error); |
73 | g_assert_no_error (error); |
74 | |
75 | bytes = pango_layout_serialize (layout, flags: PANGO_LAYOUT_SERIALIZE_CONTEXT | PANGO_LAYOUT_SERIALIZE_OUTPUT); |
76 | |
77 | g_object_unref (object: layout); |
78 | g_object_unref (object: context); |
79 | |
80 | diff = diff_bytes (b1: orig, b2: bytes, error: &error); |
81 | g_assert_no_error (error); |
82 | |
83 | g_bytes_unref (bytes); |
84 | g_bytes_unref (bytes: orig); |
85 | |
86 | setlocale (LC_ALL, locale: old_locale); |
87 | g_free (mem: old_locale); |
88 | |
89 | if (diff && diff[0]) |
90 | { |
91 | char **lines = g_strsplit (string: diff, delimiter: "\n" , max_tokens: -1); |
92 | const char *line; |
93 | int i = 0; |
94 | |
95 | g_test_message (format: "Contents don't match expected contents" ); |
96 | |
97 | for (line = lines[0]; line != NULL; line = lines[++i]) |
98 | g_test_message (format: "%s" , line); |
99 | |
100 | g_test_fail (); |
101 | g_strfreev (str_array: lines); |
102 | } |
103 | |
104 | g_free (mem: diff); |
105 | } |
106 | |
107 | static void |
108 | install_fonts (const char *dir) |
109 | { |
110 | FcConfig *config; |
111 | PangoFontMap *map; |
112 | char *path; |
113 | gsize len; |
114 | char *conf; |
115 | |
116 | map = g_object_new (PANGO_TYPE_CAIRO_FC_FONT_MAP, NULL); |
117 | |
118 | config = FcConfigCreate (); |
119 | |
120 | path = g_build_filename (first_element: dir, "fonts.conf" , NULL); |
121 | g_file_get_contents (filename: path, contents: &conf, length: &len, NULL); |
122 | |
123 | if (!FcConfigParseAndLoadFromMemory (config, buffer: (const FcChar8 *) conf, TRUE)) |
124 | g_error ("Failed to parse fontconfig configuration" ); |
125 | |
126 | g_free (mem: conf); |
127 | g_free (mem: path); |
128 | |
129 | FcConfigAppFontAddDir (config, dir: (const FcChar8 *) dir); |
130 | pango_fc_font_map_set_config (PANGO_FC_FONT_MAP (map), fcconfig: config); |
131 | FcConfigDestroy (config); |
132 | |
133 | pango_cairo_font_map_set_default (PANGO_CAIRO_FONT_MAP (map)); |
134 | |
135 | g_object_unref (object: map); |
136 | } |
137 | |
138 | int |
139 | main (int argc, char *argv[]) |
140 | { |
141 | GDir *dir; |
142 | GError *error = NULL; |
143 | char *opt_fonts = NULL; |
144 | const gchar *name; |
145 | char *path; |
146 | GOptionContext *option_context; |
147 | GOptionEntry entries[] = { |
148 | { "fonts" , 0, 0, G_OPTION_ARG_FILENAME, &opt_fonts, "Fonts to use" , "DIR" }, |
149 | { NULL, 0 }, |
150 | }; |
151 | |
152 | setlocale (LC_ALL, locale: "" ); |
153 | option_context = g_option_context_new (parameter_string: "" ); |
154 | g_option_context_add_main_entries (context: option_context, entries, NULL); |
155 | g_option_context_set_ignore_unknown_options (context: option_context, TRUE); |
156 | if (!g_option_context_parse (context: option_context, argc: &argc, argv: &argv, error: &error)) |
157 | { |
158 | g_error ("failed to parse options: %s" , error->message); |
159 | return 1; |
160 | } |
161 | g_option_context_free (context: option_context); |
162 | |
163 | if (opt_fonts) |
164 | { |
165 | install_fonts (dir: opt_fonts); |
166 | g_free (mem: opt_fonts); |
167 | } |
168 | |
169 | /* allow to easily generate expected output for new test cases */ |
170 | if (argc > 1 && argv[1][0] != '-') |
171 | { |
172 | char *contents; |
173 | gsize length; |
174 | GError *error = NULL; |
175 | GBytes *orig; |
176 | GBytes *bytes; |
177 | PangoContext *context; |
178 | PangoLayout *layout; |
179 | |
180 | g_file_get_contents (filename: argv[1], contents: &contents, length: &length, error: &error); |
181 | g_assert_no_error (error); |
182 | orig = g_bytes_new_take (data: contents, size: length); |
183 | context = pango_font_map_create_context (fontmap: pango_cairo_font_map_get_default ()); |
184 | layout = pango_layout_deserialize (context, bytes: orig, flags: PANGO_LAYOUT_DESERIALIZE_CONTEXT, error: &error); |
185 | g_assert_no_error (error); |
186 | |
187 | bytes = pango_layout_serialize (layout, flags: PANGO_LAYOUT_SERIALIZE_CONTEXT | PANGO_LAYOUT_SERIALIZE_OUTPUT); |
188 | |
189 | g_object_unref (object: layout); |
190 | g_object_unref (object: context); |
191 | |
192 | g_print (format: "%s" , (const char *)g_bytes_get_data (bytes, NULL)); |
193 | |
194 | g_bytes_unref (bytes); |
195 | g_bytes_unref (bytes: orig); |
196 | |
197 | return 0; |
198 | } |
199 | |
200 | g_test_init (argc: &argc, argv: &argv, NULL); |
201 | |
202 | if (!opt_fonts) |
203 | { |
204 | path = g_test_build_filename (file_type: G_TEST_DIST, first_path: "fonts" , NULL); |
205 | install_fonts (dir: path); |
206 | g_free (mem: path); |
207 | } |
208 | |
209 | path = g_test_build_filename (file_type: G_TEST_DIST, first_path: "layouts" , NULL); |
210 | dir = g_dir_open (path, flags: 0, error: &error); |
211 | g_free (mem: path); |
212 | g_assert_no_error (error); |
213 | while ((name = g_dir_read_name (dir)) != NULL) |
214 | { |
215 | if (!g_str_has_suffix (str: name, suffix: ".layout" )) |
216 | continue; |
217 | |
218 | path = g_strdup_printf (format: "/layout/%s" , name); |
219 | g_test_add_data_func_full (testpath: path, test_data: g_test_build_filename (file_type: G_TEST_DIST, first_path: "layouts" , name, NULL), |
220 | test_func: test_layout, data_free_func: g_free); |
221 | g_free (mem: path); |
222 | } |
223 | g_dir_close (dir); |
224 | |
225 | return g_test_run (); |
226 | } |
227 | |