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
37static void
38test_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
107static void
108install_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
138int
139main (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

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