1*2d1272b8SAndroid Build Coastguard Worker /*
2*2d1272b8SAndroid Build Coastguard Worker * Copyright © 2011 Google, Inc.
3*2d1272b8SAndroid Build Coastguard Worker *
4*2d1272b8SAndroid Build Coastguard Worker * This is part of HarfBuzz, a text shaping library.
5*2d1272b8SAndroid Build Coastguard Worker *
6*2d1272b8SAndroid Build Coastguard Worker * Permission is hereby granted, without written agreement and without
7*2d1272b8SAndroid Build Coastguard Worker * license or royalty fees, to use, copy, modify, and distribute this
8*2d1272b8SAndroid Build Coastguard Worker * software and its documentation for any purpose, provided that the
9*2d1272b8SAndroid Build Coastguard Worker * above copyright notice and the following two paragraphs appear in
10*2d1272b8SAndroid Build Coastguard Worker * all copies of this software.
11*2d1272b8SAndroid Build Coastguard Worker *
12*2d1272b8SAndroid Build Coastguard Worker * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13*2d1272b8SAndroid Build Coastguard Worker * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14*2d1272b8SAndroid Build Coastguard Worker * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15*2d1272b8SAndroid Build Coastguard Worker * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16*2d1272b8SAndroid Build Coastguard Worker * DAMAGE.
17*2d1272b8SAndroid Build Coastguard Worker *
18*2d1272b8SAndroid Build Coastguard Worker * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19*2d1272b8SAndroid Build Coastguard Worker * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20*2d1272b8SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21*2d1272b8SAndroid Build Coastguard Worker * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22*2d1272b8SAndroid Build Coastguard Worker * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23*2d1272b8SAndroid Build Coastguard Worker *
24*2d1272b8SAndroid Build Coastguard Worker * Google Author(s): Behdad Esfahbod
25*2d1272b8SAndroid Build Coastguard Worker */
26*2d1272b8SAndroid Build Coastguard Worker
27*2d1272b8SAndroid Build Coastguard Worker #include "hb-test.h"
28*2d1272b8SAndroid Build Coastguard Worker
29*2d1272b8SAndroid Build Coastguard Worker /* Unit tests for hb-buffer.h */
30*2d1272b8SAndroid Build Coastguard Worker
31*2d1272b8SAndroid Build Coastguard Worker
32*2d1272b8SAndroid Build Coastguard Worker static const char utf8[10] = "ab\360\240\200\200defg";
33*2d1272b8SAndroid Build Coastguard Worker static const uint16_t utf16[8] = {'a', 'b', 0xD840, 0xDC00, 'd', 'e', 'f', 'g'};
34*2d1272b8SAndroid Build Coastguard Worker static const uint32_t utf32[7] = {'a', 'b', 0x20000, 'd', 'e', 'f', 'g'};
35*2d1272b8SAndroid Build Coastguard Worker
36*2d1272b8SAndroid Build Coastguard Worker
37*2d1272b8SAndroid Build Coastguard Worker typedef enum {
38*2d1272b8SAndroid Build Coastguard Worker BUFFER_EMPTY,
39*2d1272b8SAndroid Build Coastguard Worker BUFFER_ONE_BY_ONE,
40*2d1272b8SAndroid Build Coastguard Worker BUFFER_UTF32,
41*2d1272b8SAndroid Build Coastguard Worker BUFFER_UTF16,
42*2d1272b8SAndroid Build Coastguard Worker BUFFER_UTF8,
43*2d1272b8SAndroid Build Coastguard Worker BUFFER_NUM_TYPES,
44*2d1272b8SAndroid Build Coastguard Worker } buffer_type_t;
45*2d1272b8SAndroid Build Coastguard Worker
46*2d1272b8SAndroid Build Coastguard Worker static const char *buffer_names[] = {
47*2d1272b8SAndroid Build Coastguard Worker "empty",
48*2d1272b8SAndroid Build Coastguard Worker "one-by-one",
49*2d1272b8SAndroid Build Coastguard Worker "utf32",
50*2d1272b8SAndroid Build Coastguard Worker "utf16",
51*2d1272b8SAndroid Build Coastguard Worker "utf8"
52*2d1272b8SAndroid Build Coastguard Worker };
53*2d1272b8SAndroid Build Coastguard Worker
54*2d1272b8SAndroid Build Coastguard Worker typedef struct
55*2d1272b8SAndroid Build Coastguard Worker {
56*2d1272b8SAndroid Build Coastguard Worker hb_buffer_t *buffer;
57*2d1272b8SAndroid Build Coastguard Worker } fixture_t;
58*2d1272b8SAndroid Build Coastguard Worker
59*2d1272b8SAndroid Build Coastguard Worker static void
fixture_init(fixture_t * fixture,gconstpointer user_data)60*2d1272b8SAndroid Build Coastguard Worker fixture_init (fixture_t *fixture, gconstpointer user_data)
61*2d1272b8SAndroid Build Coastguard Worker {
62*2d1272b8SAndroid Build Coastguard Worker hb_buffer_t *b;
63*2d1272b8SAndroid Build Coastguard Worker unsigned int i;
64*2d1272b8SAndroid Build Coastguard Worker
65*2d1272b8SAndroid Build Coastguard Worker b = fixture->buffer = hb_buffer_create ();
66*2d1272b8SAndroid Build Coastguard Worker
67*2d1272b8SAndroid Build Coastguard Worker switch (GPOINTER_TO_INT (user_data))
68*2d1272b8SAndroid Build Coastguard Worker {
69*2d1272b8SAndroid Build Coastguard Worker case BUFFER_EMPTY:
70*2d1272b8SAndroid Build Coastguard Worker break;
71*2d1272b8SAndroid Build Coastguard Worker
72*2d1272b8SAndroid Build Coastguard Worker case BUFFER_ONE_BY_ONE:
73*2d1272b8SAndroid Build Coastguard Worker for (i = 1; i < G_N_ELEMENTS (utf32) - 1; i++)
74*2d1272b8SAndroid Build Coastguard Worker hb_buffer_add (b, utf32[i], i);
75*2d1272b8SAndroid Build Coastguard Worker break;
76*2d1272b8SAndroid Build Coastguard Worker
77*2d1272b8SAndroid Build Coastguard Worker case BUFFER_UTF32:
78*2d1272b8SAndroid Build Coastguard Worker hb_buffer_add_utf32 (b, utf32, G_N_ELEMENTS (utf32), 1, G_N_ELEMENTS (utf32) - 2);
79*2d1272b8SAndroid Build Coastguard Worker break;
80*2d1272b8SAndroid Build Coastguard Worker
81*2d1272b8SAndroid Build Coastguard Worker case BUFFER_UTF16:
82*2d1272b8SAndroid Build Coastguard Worker hb_buffer_add_utf16 (b, utf16, G_N_ELEMENTS (utf16), 1, G_N_ELEMENTS (utf16) - 2);
83*2d1272b8SAndroid Build Coastguard Worker break;
84*2d1272b8SAndroid Build Coastguard Worker
85*2d1272b8SAndroid Build Coastguard Worker case BUFFER_UTF8:
86*2d1272b8SAndroid Build Coastguard Worker hb_buffer_add_utf8 (b, utf8, G_N_ELEMENTS (utf8), 1, G_N_ELEMENTS (utf8) - 2);
87*2d1272b8SAndroid Build Coastguard Worker break;
88*2d1272b8SAndroid Build Coastguard Worker
89*2d1272b8SAndroid Build Coastguard Worker default:
90*2d1272b8SAndroid Build Coastguard Worker g_assert_not_reached ();
91*2d1272b8SAndroid Build Coastguard Worker }
92*2d1272b8SAndroid Build Coastguard Worker }
93*2d1272b8SAndroid Build Coastguard Worker
94*2d1272b8SAndroid Build Coastguard Worker static void
fixture_finish(fixture_t * fixture,gconstpointer user_data HB_UNUSED)95*2d1272b8SAndroid Build Coastguard Worker fixture_finish (fixture_t *fixture, gconstpointer user_data HB_UNUSED)
96*2d1272b8SAndroid Build Coastguard Worker {
97*2d1272b8SAndroid Build Coastguard Worker hb_buffer_destroy (fixture->buffer);
98*2d1272b8SAndroid Build Coastguard Worker }
99*2d1272b8SAndroid Build Coastguard Worker
100*2d1272b8SAndroid Build Coastguard Worker
101*2d1272b8SAndroid Build Coastguard Worker static void
test_buffer_properties(fixture_t * fixture,gconstpointer user_data HB_UNUSED)102*2d1272b8SAndroid Build Coastguard Worker test_buffer_properties (fixture_t *fixture, gconstpointer user_data HB_UNUSED)
103*2d1272b8SAndroid Build Coastguard Worker {
104*2d1272b8SAndroid Build Coastguard Worker hb_buffer_t *b = fixture->buffer;
105*2d1272b8SAndroid Build Coastguard Worker hb_unicode_funcs_t *ufuncs;
106*2d1272b8SAndroid Build Coastguard Worker
107*2d1272b8SAndroid Build Coastguard Worker /* test default properties */
108*2d1272b8SAndroid Build Coastguard Worker
109*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_unicode_funcs (b) == hb_unicode_funcs_get_default ());
110*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_INVALID);
111*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_script (b) == HB_SCRIPT_INVALID);
112*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_language (b) == NULL);
113*2d1272b8SAndroid Build Coastguard Worker
114*2d1272b8SAndroid Build Coastguard Worker
115*2d1272b8SAndroid Build Coastguard Worker /* test property changes are retained */
116*2d1272b8SAndroid Build Coastguard Worker ufuncs = hb_unicode_funcs_create (NULL);
117*2d1272b8SAndroid Build Coastguard Worker hb_buffer_set_unicode_funcs (b, ufuncs);
118*2d1272b8SAndroid Build Coastguard Worker hb_unicode_funcs_destroy (ufuncs);
119*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_unicode_funcs (b) == ufuncs);
120*2d1272b8SAndroid Build Coastguard Worker
121*2d1272b8SAndroid Build Coastguard Worker hb_buffer_set_direction (b, HB_DIRECTION_RTL);
122*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_RTL);
123*2d1272b8SAndroid Build Coastguard Worker
124*2d1272b8SAndroid Build Coastguard Worker hb_buffer_set_script (b, HB_SCRIPT_ARABIC);
125*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_script (b) == HB_SCRIPT_ARABIC);
126*2d1272b8SAndroid Build Coastguard Worker
127*2d1272b8SAndroid Build Coastguard Worker hb_buffer_set_language (b, hb_language_from_string ("fa", -1));
128*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_language (b) == hb_language_from_string ("Fa", -1));
129*2d1272b8SAndroid Build Coastguard Worker
130*2d1272b8SAndroid Build Coastguard Worker hb_buffer_set_flags (b, HB_BUFFER_FLAG_BOT);
131*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_flags (b) == HB_BUFFER_FLAG_BOT);
132*2d1272b8SAndroid Build Coastguard Worker
133*2d1272b8SAndroid Build Coastguard Worker hb_buffer_set_replacement_codepoint (b, (unsigned int) -1);
134*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_replacement_codepoint (b) == (unsigned int) -1);
135*2d1272b8SAndroid Build Coastguard Worker
136*2d1272b8SAndroid Build Coastguard Worker
137*2d1272b8SAndroid Build Coastguard Worker /* test clear_contents clears all these properties: */
138*2d1272b8SAndroid Build Coastguard Worker
139*2d1272b8SAndroid Build Coastguard Worker hb_buffer_clear_contents (b);
140*2d1272b8SAndroid Build Coastguard Worker
141*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_unicode_funcs (b) == ufuncs);
142*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_INVALID);
143*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_script (b) == HB_SCRIPT_INVALID);
144*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_language (b) == NULL);
145*2d1272b8SAndroid Build Coastguard Worker
146*2d1272b8SAndroid Build Coastguard Worker /* but not these: */
147*2d1272b8SAndroid Build Coastguard Worker
148*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_flags (b) != HB_BUFFER_FLAG_DEFAULT);
149*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_replacement_codepoint (b) != HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT);
150*2d1272b8SAndroid Build Coastguard Worker
151*2d1272b8SAndroid Build Coastguard Worker
152*2d1272b8SAndroid Build Coastguard Worker /* test reset clears all properties */
153*2d1272b8SAndroid Build Coastguard Worker
154*2d1272b8SAndroid Build Coastguard Worker hb_buffer_set_direction (b, HB_DIRECTION_RTL);
155*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_RTL);
156*2d1272b8SAndroid Build Coastguard Worker
157*2d1272b8SAndroid Build Coastguard Worker hb_buffer_set_script (b, HB_SCRIPT_ARABIC);
158*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_script (b) == HB_SCRIPT_ARABIC);
159*2d1272b8SAndroid Build Coastguard Worker
160*2d1272b8SAndroid Build Coastguard Worker hb_buffer_set_language (b, hb_language_from_string ("fa", -1));
161*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_language (b) == hb_language_from_string ("Fa", -1));
162*2d1272b8SAndroid Build Coastguard Worker
163*2d1272b8SAndroid Build Coastguard Worker hb_buffer_set_flags (b, HB_BUFFER_FLAG_BOT);
164*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_flags (b) == HB_BUFFER_FLAG_BOT);
165*2d1272b8SAndroid Build Coastguard Worker
166*2d1272b8SAndroid Build Coastguard Worker hb_buffer_set_replacement_codepoint (b, (unsigned int) -1);
167*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_replacement_codepoint (b) == (unsigned int) -1);
168*2d1272b8SAndroid Build Coastguard Worker
169*2d1272b8SAndroid Build Coastguard Worker hb_buffer_reset (b);
170*2d1272b8SAndroid Build Coastguard Worker
171*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_unicode_funcs (b) == hb_unicode_funcs_get_default ());
172*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_INVALID);
173*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_script (b) == HB_SCRIPT_INVALID);
174*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_language (b) == NULL);
175*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_flags (b) == HB_BUFFER_FLAG_DEFAULT);
176*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_replacement_codepoint (b) == HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT);
177*2d1272b8SAndroid Build Coastguard Worker }
178*2d1272b8SAndroid Build Coastguard Worker
179*2d1272b8SAndroid Build Coastguard Worker static void
test_buffer_contents(fixture_t * fixture,gconstpointer user_data)180*2d1272b8SAndroid Build Coastguard Worker test_buffer_contents (fixture_t *fixture, gconstpointer user_data)
181*2d1272b8SAndroid Build Coastguard Worker {
182*2d1272b8SAndroid Build Coastguard Worker hb_buffer_t *b = fixture->buffer;
183*2d1272b8SAndroid Build Coastguard Worker unsigned int i, len, len2;
184*2d1272b8SAndroid Build Coastguard Worker buffer_type_t buffer_type = GPOINTER_TO_INT (user_data);
185*2d1272b8SAndroid Build Coastguard Worker hb_glyph_info_t *glyphs;
186*2d1272b8SAndroid Build Coastguard Worker
187*2d1272b8SAndroid Build Coastguard Worker if (buffer_type == BUFFER_EMPTY) {
188*2d1272b8SAndroid Build Coastguard Worker g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
189*2d1272b8SAndroid Build Coastguard Worker return;
190*2d1272b8SAndroid Build Coastguard Worker }
191*2d1272b8SAndroid Build Coastguard Worker
192*2d1272b8SAndroid Build Coastguard Worker len = hb_buffer_get_length (b);
193*2d1272b8SAndroid Build Coastguard Worker hb_buffer_get_glyph_infos (b, NULL); /* test NULL */
194*2d1272b8SAndroid Build Coastguard Worker glyphs = hb_buffer_get_glyph_infos (b, &len2);
195*2d1272b8SAndroid Build Coastguard Worker g_assert_cmpint (len, ==, len2);
196*2d1272b8SAndroid Build Coastguard Worker g_assert_cmpint (len, ==, 5);
197*2d1272b8SAndroid Build Coastguard Worker
198*2d1272b8SAndroid Build Coastguard Worker for (i = 0; i < len; i++) {
199*2d1272b8SAndroid Build Coastguard Worker g_assert_cmphex (glyphs[i].mask, ==, 0);
200*2d1272b8SAndroid Build Coastguard Worker g_assert_cmphex (glyphs[i].var1.u32, ==, 0);
201*2d1272b8SAndroid Build Coastguard Worker g_assert_cmphex (glyphs[i].var2.u32, ==, 0);
202*2d1272b8SAndroid Build Coastguard Worker }
203*2d1272b8SAndroid Build Coastguard Worker
204*2d1272b8SAndroid Build Coastguard Worker for (i = 0; i < len; i++) {
205*2d1272b8SAndroid Build Coastguard Worker unsigned int cluster;
206*2d1272b8SAndroid Build Coastguard Worker cluster = 1+i;
207*2d1272b8SAndroid Build Coastguard Worker if (i >= 2) {
208*2d1272b8SAndroid Build Coastguard Worker if (buffer_type == BUFFER_UTF16)
209*2d1272b8SAndroid Build Coastguard Worker cluster++;
210*2d1272b8SAndroid Build Coastguard Worker else if (buffer_type == BUFFER_UTF8)
211*2d1272b8SAndroid Build Coastguard Worker cluster += 3;
212*2d1272b8SAndroid Build Coastguard Worker }
213*2d1272b8SAndroid Build Coastguard Worker g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
214*2d1272b8SAndroid Build Coastguard Worker g_assert_cmphex (glyphs[i].cluster, ==, cluster);
215*2d1272b8SAndroid Build Coastguard Worker }
216*2d1272b8SAndroid Build Coastguard Worker
217*2d1272b8SAndroid Build Coastguard Worker /* reverse, test, and reverse back */
218*2d1272b8SAndroid Build Coastguard Worker
219*2d1272b8SAndroid Build Coastguard Worker hb_buffer_reverse (b);
220*2d1272b8SAndroid Build Coastguard Worker for (i = 0; i < len; i++)
221*2d1272b8SAndroid Build Coastguard Worker g_assert_cmphex (glyphs[i].codepoint, ==, utf32[len-i]);
222*2d1272b8SAndroid Build Coastguard Worker
223*2d1272b8SAndroid Build Coastguard Worker hb_buffer_reverse (b);
224*2d1272b8SAndroid Build Coastguard Worker for (i = 0; i < len; i++)
225*2d1272b8SAndroid Build Coastguard Worker g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
226*2d1272b8SAndroid Build Coastguard Worker
227*2d1272b8SAndroid Build Coastguard Worker /* reverse_clusters works same as reverse for now since each codepoint is
228*2d1272b8SAndroid Build Coastguard Worker * in its own cluster */
229*2d1272b8SAndroid Build Coastguard Worker
230*2d1272b8SAndroid Build Coastguard Worker hb_buffer_reverse_clusters (b);
231*2d1272b8SAndroid Build Coastguard Worker for (i = 0; i < len; i++)
232*2d1272b8SAndroid Build Coastguard Worker g_assert_cmphex (glyphs[i].codepoint, ==, utf32[len-i]);
233*2d1272b8SAndroid Build Coastguard Worker
234*2d1272b8SAndroid Build Coastguard Worker hb_buffer_reverse_clusters (b);
235*2d1272b8SAndroid Build Coastguard Worker for (i = 0; i < len; i++)
236*2d1272b8SAndroid Build Coastguard Worker g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
237*2d1272b8SAndroid Build Coastguard Worker
238*2d1272b8SAndroid Build Coastguard Worker /* now form a cluster and test again */
239*2d1272b8SAndroid Build Coastguard Worker glyphs[2].cluster = glyphs[1].cluster;
240*2d1272b8SAndroid Build Coastguard Worker
241*2d1272b8SAndroid Build Coastguard Worker /* reverse, test, and reverse back */
242*2d1272b8SAndroid Build Coastguard Worker
243*2d1272b8SAndroid Build Coastguard Worker hb_buffer_reverse (b);
244*2d1272b8SAndroid Build Coastguard Worker for (i = 0; i < len; i++)
245*2d1272b8SAndroid Build Coastguard Worker g_assert_cmphex (glyphs[i].codepoint, ==, utf32[len-i]);
246*2d1272b8SAndroid Build Coastguard Worker
247*2d1272b8SAndroid Build Coastguard Worker hb_buffer_reverse (b);
248*2d1272b8SAndroid Build Coastguard Worker for (i = 0; i < len; i++)
249*2d1272b8SAndroid Build Coastguard Worker g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
250*2d1272b8SAndroid Build Coastguard Worker
251*2d1272b8SAndroid Build Coastguard Worker /* reverse_clusters twice still should return the original string,
252*2d1272b8SAndroid Build Coastguard Worker * but when applied once, the 1-2 cluster should be retained. */
253*2d1272b8SAndroid Build Coastguard Worker
254*2d1272b8SAndroid Build Coastguard Worker hb_buffer_reverse_clusters (b);
255*2d1272b8SAndroid Build Coastguard Worker for (i = 0; i < len; i++) {
256*2d1272b8SAndroid Build Coastguard Worker unsigned int j = len-1-i;
257*2d1272b8SAndroid Build Coastguard Worker if (j == 1)
258*2d1272b8SAndroid Build Coastguard Worker j = 2;
259*2d1272b8SAndroid Build Coastguard Worker else if (j == 2)
260*2d1272b8SAndroid Build Coastguard Worker j = 1;
261*2d1272b8SAndroid Build Coastguard Worker g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+j]);
262*2d1272b8SAndroid Build Coastguard Worker }
263*2d1272b8SAndroid Build Coastguard Worker
264*2d1272b8SAndroid Build Coastguard Worker hb_buffer_reverse_clusters (b);
265*2d1272b8SAndroid Build Coastguard Worker for (i = 0; i < len; i++)
266*2d1272b8SAndroid Build Coastguard Worker g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
267*2d1272b8SAndroid Build Coastguard Worker
268*2d1272b8SAndroid Build Coastguard Worker
269*2d1272b8SAndroid Build Coastguard Worker /* test setting length */
270*2d1272b8SAndroid Build Coastguard Worker
271*2d1272b8SAndroid Build Coastguard Worker /* enlarge */
272*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_set_length (b, 10));
273*2d1272b8SAndroid Build Coastguard Worker glyphs = hb_buffer_get_glyph_infos (b, NULL);
274*2d1272b8SAndroid Build Coastguard Worker g_assert_cmpint (hb_buffer_get_length (b), ==, 10);
275*2d1272b8SAndroid Build Coastguard Worker for (i = 0; i < 5; i++)
276*2d1272b8SAndroid Build Coastguard Worker g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
277*2d1272b8SAndroid Build Coastguard Worker for (i = 5; i < 10; i++)
278*2d1272b8SAndroid Build Coastguard Worker g_assert_cmphex (glyphs[i].codepoint, ==, 0);
279*2d1272b8SAndroid Build Coastguard Worker /* shrink */
280*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_set_length (b, 3));
281*2d1272b8SAndroid Build Coastguard Worker glyphs = hb_buffer_get_glyph_infos (b, NULL);
282*2d1272b8SAndroid Build Coastguard Worker g_assert_cmpint (hb_buffer_get_length (b), ==, 3);
283*2d1272b8SAndroid Build Coastguard Worker for (i = 0; i < 3; i++)
284*2d1272b8SAndroid Build Coastguard Worker g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
285*2d1272b8SAndroid Build Coastguard Worker
286*2d1272b8SAndroid Build Coastguard Worker
287*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_allocation_successful (b));
288*2d1272b8SAndroid Build Coastguard Worker
289*2d1272b8SAndroid Build Coastguard Worker
290*2d1272b8SAndroid Build Coastguard Worker /* test reset clears content */
291*2d1272b8SAndroid Build Coastguard Worker
292*2d1272b8SAndroid Build Coastguard Worker hb_buffer_reset (b);
293*2d1272b8SAndroid Build Coastguard Worker g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
294*2d1272b8SAndroid Build Coastguard Worker }
295*2d1272b8SAndroid Build Coastguard Worker
296*2d1272b8SAndroid Build Coastguard Worker static void
test_buffer_positions(fixture_t * fixture,gconstpointer user_data HB_UNUSED)297*2d1272b8SAndroid Build Coastguard Worker test_buffer_positions (fixture_t *fixture, gconstpointer user_data HB_UNUSED)
298*2d1272b8SAndroid Build Coastguard Worker {
299*2d1272b8SAndroid Build Coastguard Worker hb_buffer_t *b = fixture->buffer;
300*2d1272b8SAndroid Build Coastguard Worker unsigned int i, len, len2;
301*2d1272b8SAndroid Build Coastguard Worker hb_glyph_position_t *positions;
302*2d1272b8SAndroid Build Coastguard Worker
303*2d1272b8SAndroid Build Coastguard Worker /* Without shaping, positions should all be zero */
304*2d1272b8SAndroid Build Coastguard Worker len = hb_buffer_get_length (b);
305*2d1272b8SAndroid Build Coastguard Worker hb_buffer_get_glyph_positions (b, NULL); /* test NULL */
306*2d1272b8SAndroid Build Coastguard Worker positions = hb_buffer_get_glyph_positions (b, &len2);
307*2d1272b8SAndroid Build Coastguard Worker g_assert_cmpint (len, ==, len2);
308*2d1272b8SAndroid Build Coastguard Worker for (i = 0; i < len; i++) {
309*2d1272b8SAndroid Build Coastguard Worker g_assert_cmpint (0, ==, positions[i].x_advance);
310*2d1272b8SAndroid Build Coastguard Worker g_assert_cmpint (0, ==, positions[i].y_advance);
311*2d1272b8SAndroid Build Coastguard Worker g_assert_cmpint (0, ==, positions[i].x_offset);
312*2d1272b8SAndroid Build Coastguard Worker g_assert_cmpint (0, ==, positions[i].y_offset);
313*2d1272b8SAndroid Build Coastguard Worker g_assert_cmpint (0, ==, positions[i].var.i32);
314*2d1272b8SAndroid Build Coastguard Worker }
315*2d1272b8SAndroid Build Coastguard Worker
316*2d1272b8SAndroid Build Coastguard Worker /* test reset clears content */
317*2d1272b8SAndroid Build Coastguard Worker hb_buffer_reset (b);
318*2d1272b8SAndroid Build Coastguard Worker g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
319*2d1272b8SAndroid Build Coastguard Worker }
320*2d1272b8SAndroid Build Coastguard Worker
321*2d1272b8SAndroid Build Coastguard Worker static void
test_buffer_allocation(fixture_t * fixture,gconstpointer user_data HB_UNUSED)322*2d1272b8SAndroid Build Coastguard Worker test_buffer_allocation (fixture_t *fixture, gconstpointer user_data HB_UNUSED)
323*2d1272b8SAndroid Build Coastguard Worker {
324*2d1272b8SAndroid Build Coastguard Worker hb_buffer_t *b = fixture->buffer;
325*2d1272b8SAndroid Build Coastguard Worker
326*2d1272b8SAndroid Build Coastguard Worker g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
327*2d1272b8SAndroid Build Coastguard Worker
328*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_pre_allocate (b, 100));
329*2d1272b8SAndroid Build Coastguard Worker g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
330*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_allocation_successful (b));
331*2d1272b8SAndroid Build Coastguard Worker
332*2d1272b8SAndroid Build Coastguard Worker /* lets try a huge allocation, make sure it fails */
333*2d1272b8SAndroid Build Coastguard Worker g_assert (!hb_buffer_pre_allocate (b, (unsigned int) -1));
334*2d1272b8SAndroid Build Coastguard Worker g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
335*2d1272b8SAndroid Build Coastguard Worker g_assert (!hb_buffer_allocation_successful (b));
336*2d1272b8SAndroid Build Coastguard Worker
337*2d1272b8SAndroid Build Coastguard Worker /* small one again */
338*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_pre_allocate (b, 50));
339*2d1272b8SAndroid Build Coastguard Worker g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
340*2d1272b8SAndroid Build Coastguard Worker g_assert (!hb_buffer_allocation_successful (b));
341*2d1272b8SAndroid Build Coastguard Worker
342*2d1272b8SAndroid Build Coastguard Worker hb_buffer_reset (b);
343*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_allocation_successful (b));
344*2d1272b8SAndroid Build Coastguard Worker
345*2d1272b8SAndroid Build Coastguard Worker /* all allocation and size */
346*2d1272b8SAndroid Build Coastguard Worker g_assert (!hb_buffer_pre_allocate (b, ((unsigned int) -1) / 20 + 1));
347*2d1272b8SAndroid Build Coastguard Worker g_assert (!hb_buffer_allocation_successful (b));
348*2d1272b8SAndroid Build Coastguard Worker
349*2d1272b8SAndroid Build Coastguard Worker hb_buffer_reset (b);
350*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_allocation_successful (b));
351*2d1272b8SAndroid Build Coastguard Worker
352*2d1272b8SAndroid Build Coastguard Worker /* technically, this one can actually pass on 64bit machines, but
353*2d1272b8SAndroid Build Coastguard Worker * I'm doubtful that any malloc allows 4GB allocations at a time.
354*2d1272b8SAndroid Build Coastguard Worker * But let's only enable it on a 32-bit machine. */
355*2d1272b8SAndroid Build Coastguard Worker if (sizeof (long) == 4) {
356*2d1272b8SAndroid Build Coastguard Worker g_assert (!hb_buffer_pre_allocate (b, ((unsigned int) -1) / 20 - 1));
357*2d1272b8SAndroid Build Coastguard Worker g_assert (!hb_buffer_allocation_successful (b));
358*2d1272b8SAndroid Build Coastguard Worker }
359*2d1272b8SAndroid Build Coastguard Worker
360*2d1272b8SAndroid Build Coastguard Worker hb_buffer_reset (b);
361*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_allocation_successful (b));
362*2d1272b8SAndroid Build Coastguard Worker }
363*2d1272b8SAndroid Build Coastguard Worker
364*2d1272b8SAndroid Build Coastguard Worker
365*2d1272b8SAndroid Build Coastguard Worker typedef struct {
366*2d1272b8SAndroid Build Coastguard Worker const char utf8[8];
367*2d1272b8SAndroid Build Coastguard Worker const uint32_t codepoints[8];
368*2d1272b8SAndroid Build Coastguard Worker } utf8_conversion_test_t;
369*2d1272b8SAndroid Build Coastguard Worker
370*2d1272b8SAndroid Build Coastguard Worker /* note: we skip the first and last byte when adding to buffer */
371*2d1272b8SAndroid Build Coastguard Worker static const utf8_conversion_test_t utf8_conversion_tests[] = {
372*2d1272b8SAndroid Build Coastguard Worker {"a\303\207", {(hb_codepoint_t) -1}},
373*2d1272b8SAndroid Build Coastguard Worker {"a\303\207b", {0xC7}},
374*2d1272b8SAndroid Build Coastguard Worker {"ab\303cd", {'b', (hb_codepoint_t) -1, 'c'}},
375*2d1272b8SAndroid Build Coastguard Worker {"ab\303\302\301cd", {'b', (hb_codepoint_t) -1, (hb_codepoint_t) -1, (hb_codepoint_t) -1, 'c'}}
376*2d1272b8SAndroid Build Coastguard Worker };
377*2d1272b8SAndroid Build Coastguard Worker
378*2d1272b8SAndroid Build Coastguard Worker static void
test_buffer_utf8_conversion(void)379*2d1272b8SAndroid Build Coastguard Worker test_buffer_utf8_conversion (void)
380*2d1272b8SAndroid Build Coastguard Worker {
381*2d1272b8SAndroid Build Coastguard Worker hb_buffer_t *b;
382*2d1272b8SAndroid Build Coastguard Worker unsigned int chars, i, j, len;
383*2d1272b8SAndroid Build Coastguard Worker
384*2d1272b8SAndroid Build Coastguard Worker b = hb_buffer_create ();
385*2d1272b8SAndroid Build Coastguard Worker hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -1);
386*2d1272b8SAndroid Build Coastguard Worker
387*2d1272b8SAndroid Build Coastguard Worker for (i = 0; i < G_N_ELEMENTS (utf8_conversion_tests); i++)
388*2d1272b8SAndroid Build Coastguard Worker {
389*2d1272b8SAndroid Build Coastguard Worker unsigned int bytes;
390*2d1272b8SAndroid Build Coastguard Worker hb_glyph_info_t *glyphs;
391*2d1272b8SAndroid Build Coastguard Worker const utf8_conversion_test_t *test = &utf8_conversion_tests[i];
392*2d1272b8SAndroid Build Coastguard Worker char *escaped;
393*2d1272b8SAndroid Build Coastguard Worker
394*2d1272b8SAndroid Build Coastguard Worker escaped = g_strescape (test->utf8, NULL);
395*2d1272b8SAndroid Build Coastguard Worker g_test_message ("UTF-8 test #%d: %s", i, escaped);
396*2d1272b8SAndroid Build Coastguard Worker g_free (escaped);
397*2d1272b8SAndroid Build Coastguard Worker
398*2d1272b8SAndroid Build Coastguard Worker bytes = strlen (test->utf8);
399*2d1272b8SAndroid Build Coastguard Worker for (chars = 0; test->codepoints[chars]; chars++)
400*2d1272b8SAndroid Build Coastguard Worker ;
401*2d1272b8SAndroid Build Coastguard Worker
402*2d1272b8SAndroid Build Coastguard Worker hb_buffer_clear_contents (b);
403*2d1272b8SAndroid Build Coastguard Worker hb_buffer_add_utf8 (b, test->utf8, bytes, 1, bytes - 2);
404*2d1272b8SAndroid Build Coastguard Worker
405*2d1272b8SAndroid Build Coastguard Worker glyphs = hb_buffer_get_glyph_infos (b, &len);
406*2d1272b8SAndroid Build Coastguard Worker g_assert_cmpint (len, ==, chars);
407*2d1272b8SAndroid Build Coastguard Worker for (j = 0; j < chars; j++)
408*2d1272b8SAndroid Build Coastguard Worker g_assert_cmphex (glyphs[j].codepoint, ==, test->codepoints[j]);
409*2d1272b8SAndroid Build Coastguard Worker }
410*2d1272b8SAndroid Build Coastguard Worker
411*2d1272b8SAndroid Build Coastguard Worker hb_buffer_destroy (b);
412*2d1272b8SAndroid Build Coastguard Worker }
413*2d1272b8SAndroid Build Coastguard Worker
414*2d1272b8SAndroid Build Coastguard Worker
415*2d1272b8SAndroid Build Coastguard Worker
416*2d1272b8SAndroid Build Coastguard Worker /* Following test table is adapted from glib/glib/tests/utf8-validate.c
417*2d1272b8SAndroid Build Coastguard Worker * with relicensing permission from Matthias Clasen. */
418*2d1272b8SAndroid Build Coastguard Worker
419*2d1272b8SAndroid Build Coastguard Worker typedef struct {
420*2d1272b8SAndroid Build Coastguard Worker const char *utf8;
421*2d1272b8SAndroid Build Coastguard Worker int max_len;
422*2d1272b8SAndroid Build Coastguard Worker unsigned int offset;
423*2d1272b8SAndroid Build Coastguard Worker gboolean valid;
424*2d1272b8SAndroid Build Coastguard Worker } utf8_validity_test_t;
425*2d1272b8SAndroid Build Coastguard Worker
426*2d1272b8SAndroid Build Coastguard Worker static const utf8_validity_test_t utf8_validity_tests[] = {
427*2d1272b8SAndroid Build Coastguard Worker /* some tests to check max_len handling */
428*2d1272b8SAndroid Build Coastguard Worker /* length 1 */
429*2d1272b8SAndroid Build Coastguard Worker { "abcde", -1, 5, TRUE },
430*2d1272b8SAndroid Build Coastguard Worker { "abcde", 3, 3, TRUE },
431*2d1272b8SAndroid Build Coastguard Worker { "abcde", 5, 5, TRUE },
432*2d1272b8SAndroid Build Coastguard Worker /* length 2 */
433*2d1272b8SAndroid Build Coastguard Worker { "\xc2\xa9\xc2\xa9\xc2\xa9", -1, 6, TRUE },
434*2d1272b8SAndroid Build Coastguard Worker { "\xc2\xa9\xc2\xa9\xc2\xa9", 1, 0, FALSE },
435*2d1272b8SAndroid Build Coastguard Worker { "\xc2\xa9\xc2\xa9\xc2\xa9", 2, 2, TRUE },
436*2d1272b8SAndroid Build Coastguard Worker { "\xc2\xa9\xc2\xa9\xc2\xa9", 3, 2, FALSE },
437*2d1272b8SAndroid Build Coastguard Worker { "\xc2\xa9\xc2\xa9\xc2\xa9", 4, 4, TRUE },
438*2d1272b8SAndroid Build Coastguard Worker { "\xc2\xa9\xc2\xa9\xc2\xa9", 5, 4, FALSE },
439*2d1272b8SAndroid Build Coastguard Worker { "\xc2\xa9\xc2\xa9\xc2\xa9", 6, 6, TRUE },
440*2d1272b8SAndroid Build Coastguard Worker /* length 3 */
441*2d1272b8SAndroid Build Coastguard Worker { "\xe2\x89\xa0\xe2\x89\xa0", -1, 6, TRUE },
442*2d1272b8SAndroid Build Coastguard Worker { "\xe2\x89\xa0\xe2\x89\xa0", 1, 0, FALSE },
443*2d1272b8SAndroid Build Coastguard Worker { "\xe2\x89\xa0\xe2\x89\xa0", 2, 0, FALSE },
444*2d1272b8SAndroid Build Coastguard Worker { "\xe2\x89\xa0\xe2\x89\xa0", 3, 3, TRUE },
445*2d1272b8SAndroid Build Coastguard Worker { "\xe2\x89\xa0\xe2\x89\xa0", 4, 3, FALSE },
446*2d1272b8SAndroid Build Coastguard Worker { "\xe2\x89\xa0\xe2\x89\xa0", 5, 3, FALSE },
447*2d1272b8SAndroid Build Coastguard Worker { "\xe2\x89\xa0\xe2\x89\xa0", 6, 6, TRUE },
448*2d1272b8SAndroid Build Coastguard Worker
449*2d1272b8SAndroid Build Coastguard Worker /* examples from https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt */
450*2d1272b8SAndroid Build Coastguard Worker /* greek 'kosme' */
451*2d1272b8SAndroid Build Coastguard Worker { "\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce\xb5", -1, 11, TRUE },
452*2d1272b8SAndroid Build Coastguard Worker /* first sequence of each length */
453*2d1272b8SAndroid Build Coastguard Worker { "\x00", -1, 0, TRUE },
454*2d1272b8SAndroid Build Coastguard Worker { "\xc2\x80", -1, 2, TRUE },
455*2d1272b8SAndroid Build Coastguard Worker { "\xe0\xa0\x80", -1, 3, TRUE },
456*2d1272b8SAndroid Build Coastguard Worker { "\xf0\x90\x80\x80", -1, 4, TRUE },
457*2d1272b8SAndroid Build Coastguard Worker { "\xf8\x88\x80\x80\x80", -1, 0, FALSE },
458*2d1272b8SAndroid Build Coastguard Worker { "\xfc\x84\x80\x80\x80\x80", -1, 0, FALSE },
459*2d1272b8SAndroid Build Coastguard Worker /* last sequence of each length */
460*2d1272b8SAndroid Build Coastguard Worker { "\x7f", -1, 1, TRUE },
461*2d1272b8SAndroid Build Coastguard Worker { "\xdf\xbf", -1, 2, TRUE },
462*2d1272b8SAndroid Build Coastguard Worker { "\xef\xbf\xbf", -1, 0, TRUE },
463*2d1272b8SAndroid Build Coastguard Worker { "\xf4\x8f\xbf\xbf", -1, 0, TRUE },
464*2d1272b8SAndroid Build Coastguard Worker { "\xf4\x90\xbf\xbf", -1, 0, FALSE },
465*2d1272b8SAndroid Build Coastguard Worker { "\xf7\xbf\xbf\xbf", -1, 0, FALSE },
466*2d1272b8SAndroid Build Coastguard Worker { "\xfb\xbf\xbf\xbf\xbf", -1, 0, FALSE },
467*2d1272b8SAndroid Build Coastguard Worker { "\xfd\xbf\xbf\xbf\xbf\xbf", -1, 0, FALSE },
468*2d1272b8SAndroid Build Coastguard Worker /* other boundary conditions */
469*2d1272b8SAndroid Build Coastguard Worker { "\xed\x9f\xbf", -1, 3, TRUE },
470*2d1272b8SAndroid Build Coastguard Worker { "\xed\xa0\x80", -1, 0, FALSE },
471*2d1272b8SAndroid Build Coastguard Worker { "\xed\xbf\xbf", -1, 0, FALSE },
472*2d1272b8SAndroid Build Coastguard Worker { "\xee\x80\x80", -1, 3, TRUE },
473*2d1272b8SAndroid Build Coastguard Worker { "\xef\xbf\xbd", -1, 3, TRUE },
474*2d1272b8SAndroid Build Coastguard Worker { "\xf4\x8f\xbf\xbf", -1, 0, TRUE },
475*2d1272b8SAndroid Build Coastguard Worker /* malformed sequences */
476*2d1272b8SAndroid Build Coastguard Worker /* continuation bytes */
477*2d1272b8SAndroid Build Coastguard Worker { "\x80", -1, 0, FALSE },
478*2d1272b8SAndroid Build Coastguard Worker { "\xbf", -1, 0, FALSE },
479*2d1272b8SAndroid Build Coastguard Worker { "\x80\xbf", -1, 0, FALSE },
480*2d1272b8SAndroid Build Coastguard Worker { "\x80\xbf\x80", -1, 0, FALSE },
481*2d1272b8SAndroid Build Coastguard Worker { "\x80\xbf\x80\xbf", -1, 0, FALSE },
482*2d1272b8SAndroid Build Coastguard Worker { "\x80\xbf\x80\xbf\x80", -1, 0, FALSE },
483*2d1272b8SAndroid Build Coastguard Worker { "\x80\xbf\x80\xbf\x80\xbf", -1, 0, FALSE },
484*2d1272b8SAndroid Build Coastguard Worker { "\x80\xbf\x80\xbf\x80\xbf\x80", -1, 0, FALSE },
485*2d1272b8SAndroid Build Coastguard Worker
486*2d1272b8SAndroid Build Coastguard Worker /* all possible continuation byte */
487*2d1272b8SAndroid Build Coastguard Worker { "\x80", -1, 0, FALSE },
488*2d1272b8SAndroid Build Coastguard Worker { "\x81", -1, 0, FALSE },
489*2d1272b8SAndroid Build Coastguard Worker { "\x82", -1, 0, FALSE },
490*2d1272b8SAndroid Build Coastguard Worker { "\x83", -1, 0, FALSE },
491*2d1272b8SAndroid Build Coastguard Worker { "\x84", -1, 0, FALSE },
492*2d1272b8SAndroid Build Coastguard Worker { "\x85", -1, 0, FALSE },
493*2d1272b8SAndroid Build Coastguard Worker { "\x86", -1, 0, FALSE },
494*2d1272b8SAndroid Build Coastguard Worker { "\x87", -1, 0, FALSE },
495*2d1272b8SAndroid Build Coastguard Worker { "\x88", -1, 0, FALSE },
496*2d1272b8SAndroid Build Coastguard Worker { "\x89", -1, 0, FALSE },
497*2d1272b8SAndroid Build Coastguard Worker { "\x8a", -1, 0, FALSE },
498*2d1272b8SAndroid Build Coastguard Worker { "\x8b", -1, 0, FALSE },
499*2d1272b8SAndroid Build Coastguard Worker { "\x8c", -1, 0, FALSE },
500*2d1272b8SAndroid Build Coastguard Worker { "\x8d", -1, 0, FALSE },
501*2d1272b8SAndroid Build Coastguard Worker { "\x8e", -1, 0, FALSE },
502*2d1272b8SAndroid Build Coastguard Worker { "\x8f", -1, 0, FALSE },
503*2d1272b8SAndroid Build Coastguard Worker { "\x90", -1, 0, FALSE },
504*2d1272b8SAndroid Build Coastguard Worker { "\x91", -1, 0, FALSE },
505*2d1272b8SAndroid Build Coastguard Worker { "\x92", -1, 0, FALSE },
506*2d1272b8SAndroid Build Coastguard Worker { "\x93", -1, 0, FALSE },
507*2d1272b8SAndroid Build Coastguard Worker { "\x94", -1, 0, FALSE },
508*2d1272b8SAndroid Build Coastguard Worker { "\x95", -1, 0, FALSE },
509*2d1272b8SAndroid Build Coastguard Worker { "\x96", -1, 0, FALSE },
510*2d1272b8SAndroid Build Coastguard Worker { "\x97", -1, 0, FALSE },
511*2d1272b8SAndroid Build Coastguard Worker { "\x98", -1, 0, FALSE },
512*2d1272b8SAndroid Build Coastguard Worker { "\x99", -1, 0, FALSE },
513*2d1272b8SAndroid Build Coastguard Worker { "\x9a", -1, 0, FALSE },
514*2d1272b8SAndroid Build Coastguard Worker { "\x9b", -1, 0, FALSE },
515*2d1272b8SAndroid Build Coastguard Worker { "\x9c", -1, 0, FALSE },
516*2d1272b8SAndroid Build Coastguard Worker { "\x9d", -1, 0, FALSE },
517*2d1272b8SAndroid Build Coastguard Worker { "\x9e", -1, 0, FALSE },
518*2d1272b8SAndroid Build Coastguard Worker { "\x9f", -1, 0, FALSE },
519*2d1272b8SAndroid Build Coastguard Worker { "\xa0", -1, 0, FALSE },
520*2d1272b8SAndroid Build Coastguard Worker { "\xa1", -1, 0, FALSE },
521*2d1272b8SAndroid Build Coastguard Worker { "\xa2", -1, 0, FALSE },
522*2d1272b8SAndroid Build Coastguard Worker { "\xa3", -1, 0, FALSE },
523*2d1272b8SAndroid Build Coastguard Worker { "\xa4", -1, 0, FALSE },
524*2d1272b8SAndroid Build Coastguard Worker { "\xa5", -1, 0, FALSE },
525*2d1272b8SAndroid Build Coastguard Worker { "\xa6", -1, 0, FALSE },
526*2d1272b8SAndroid Build Coastguard Worker { "\xa7", -1, 0, FALSE },
527*2d1272b8SAndroid Build Coastguard Worker { "\xa8", -1, 0, FALSE },
528*2d1272b8SAndroid Build Coastguard Worker { "\xa9", -1, 0, FALSE },
529*2d1272b8SAndroid Build Coastguard Worker { "\xaa", -1, 0, FALSE },
530*2d1272b8SAndroid Build Coastguard Worker { "\xab", -1, 0, FALSE },
531*2d1272b8SAndroid Build Coastguard Worker { "\xac", -1, 0, FALSE },
532*2d1272b8SAndroid Build Coastguard Worker { "\xad", -1, 0, FALSE },
533*2d1272b8SAndroid Build Coastguard Worker { "\xae", -1, 0, FALSE },
534*2d1272b8SAndroid Build Coastguard Worker { "\xaf", -1, 0, FALSE },
535*2d1272b8SAndroid Build Coastguard Worker { "\xb0", -1, 0, FALSE },
536*2d1272b8SAndroid Build Coastguard Worker { "\xb1", -1, 0, FALSE },
537*2d1272b8SAndroid Build Coastguard Worker { "\xb2", -1, 0, FALSE },
538*2d1272b8SAndroid Build Coastguard Worker { "\xb3", -1, 0, FALSE },
539*2d1272b8SAndroid Build Coastguard Worker { "\xb4", -1, 0, FALSE },
540*2d1272b8SAndroid Build Coastguard Worker { "\xb5", -1, 0, FALSE },
541*2d1272b8SAndroid Build Coastguard Worker { "\xb6", -1, 0, FALSE },
542*2d1272b8SAndroid Build Coastguard Worker { "\xb7", -1, 0, FALSE },
543*2d1272b8SAndroid Build Coastguard Worker { "\xb8", -1, 0, FALSE },
544*2d1272b8SAndroid Build Coastguard Worker { "\xb9", -1, 0, FALSE },
545*2d1272b8SAndroid Build Coastguard Worker { "\xba", -1, 0, FALSE },
546*2d1272b8SAndroid Build Coastguard Worker { "\xbb", -1, 0, FALSE },
547*2d1272b8SAndroid Build Coastguard Worker { "\xbc", -1, 0, FALSE },
548*2d1272b8SAndroid Build Coastguard Worker { "\xbd", -1, 0, FALSE },
549*2d1272b8SAndroid Build Coastguard Worker { "\xbe", -1, 0, FALSE },
550*2d1272b8SAndroid Build Coastguard Worker { "\xbf", -1, 0, FALSE },
551*2d1272b8SAndroid Build Coastguard Worker /* lone start characters */
552*2d1272b8SAndroid Build Coastguard Worker { "\xc0\x20", -1, 0, FALSE },
553*2d1272b8SAndroid Build Coastguard Worker { "\xc1\x20", -1, 0, FALSE },
554*2d1272b8SAndroid Build Coastguard Worker { "\xc2\x20", -1, 0, FALSE },
555*2d1272b8SAndroid Build Coastguard Worker { "\xc3\x20", -1, 0, FALSE },
556*2d1272b8SAndroid Build Coastguard Worker { "\xc4\x20", -1, 0, FALSE },
557*2d1272b8SAndroid Build Coastguard Worker { "\xc5\x20", -1, 0, FALSE },
558*2d1272b8SAndroid Build Coastguard Worker { "\xc6\x20", -1, 0, FALSE },
559*2d1272b8SAndroid Build Coastguard Worker { "\xc7\x20", -1, 0, FALSE },
560*2d1272b8SAndroid Build Coastguard Worker { "\xc8\x20", -1, 0, FALSE },
561*2d1272b8SAndroid Build Coastguard Worker { "\xc9\x20", -1, 0, FALSE },
562*2d1272b8SAndroid Build Coastguard Worker { "\xca\x20", -1, 0, FALSE },
563*2d1272b8SAndroid Build Coastguard Worker { "\xcb\x20", -1, 0, FALSE },
564*2d1272b8SAndroid Build Coastguard Worker { "\xcc\x20", -1, 0, FALSE },
565*2d1272b8SAndroid Build Coastguard Worker { "\xcd\x20", -1, 0, FALSE },
566*2d1272b8SAndroid Build Coastguard Worker { "\xce\x20", -1, 0, FALSE },
567*2d1272b8SAndroid Build Coastguard Worker { "\xcf\x20", -1, 0, FALSE },
568*2d1272b8SAndroid Build Coastguard Worker { "\xd0\x20", -1, 0, FALSE },
569*2d1272b8SAndroid Build Coastguard Worker { "\xd1\x20", -1, 0, FALSE },
570*2d1272b8SAndroid Build Coastguard Worker { "\xd2\x20", -1, 0, FALSE },
571*2d1272b8SAndroid Build Coastguard Worker { "\xd3\x20", -1, 0, FALSE },
572*2d1272b8SAndroid Build Coastguard Worker { "\xd4\x20", -1, 0, FALSE },
573*2d1272b8SAndroid Build Coastguard Worker { "\xd5\x20", -1, 0, FALSE },
574*2d1272b8SAndroid Build Coastguard Worker { "\xd6\x20", -1, 0, FALSE },
575*2d1272b8SAndroid Build Coastguard Worker { "\xd7\x20", -1, 0, FALSE },
576*2d1272b8SAndroid Build Coastguard Worker { "\xd8\x20", -1, 0, FALSE },
577*2d1272b8SAndroid Build Coastguard Worker { "\xd9\x20", -1, 0, FALSE },
578*2d1272b8SAndroid Build Coastguard Worker { "\xda\x20", -1, 0, FALSE },
579*2d1272b8SAndroid Build Coastguard Worker { "\xdb\x20", -1, 0, FALSE },
580*2d1272b8SAndroid Build Coastguard Worker { "\xdc\x20", -1, 0, FALSE },
581*2d1272b8SAndroid Build Coastguard Worker { "\xdd\x20", -1, 0, FALSE },
582*2d1272b8SAndroid Build Coastguard Worker { "\xde\x20", -1, 0, FALSE },
583*2d1272b8SAndroid Build Coastguard Worker { "\xdf\x20", -1, 0, FALSE },
584*2d1272b8SAndroid Build Coastguard Worker { "\xe0\x20", -1, 0, FALSE },
585*2d1272b8SAndroid Build Coastguard Worker { "\xe1\x20", -1, 0, FALSE },
586*2d1272b8SAndroid Build Coastguard Worker { "\xe2\x20", -1, 0, FALSE },
587*2d1272b8SAndroid Build Coastguard Worker { "\xe3\x20", -1, 0, FALSE },
588*2d1272b8SAndroid Build Coastguard Worker { "\xe4\x20", -1, 0, FALSE },
589*2d1272b8SAndroid Build Coastguard Worker { "\xe5\x20", -1, 0, FALSE },
590*2d1272b8SAndroid Build Coastguard Worker { "\xe6\x20", -1, 0, FALSE },
591*2d1272b8SAndroid Build Coastguard Worker { "\xe7\x20", -1, 0, FALSE },
592*2d1272b8SAndroid Build Coastguard Worker { "\xe8\x20", -1, 0, FALSE },
593*2d1272b8SAndroid Build Coastguard Worker { "\xe9\x20", -1, 0, FALSE },
594*2d1272b8SAndroid Build Coastguard Worker { "\xea\x20", -1, 0, FALSE },
595*2d1272b8SAndroid Build Coastguard Worker { "\xeb\x20", -1, 0, FALSE },
596*2d1272b8SAndroid Build Coastguard Worker { "\xec\x20", -1, 0, FALSE },
597*2d1272b8SAndroid Build Coastguard Worker { "\xed\x20", -1, 0, FALSE },
598*2d1272b8SAndroid Build Coastguard Worker { "\xee\x20", -1, 0, FALSE },
599*2d1272b8SAndroid Build Coastguard Worker { "\xef\x20", -1, 0, FALSE },
600*2d1272b8SAndroid Build Coastguard Worker { "\xf0\x20", -1, 0, FALSE },
601*2d1272b8SAndroid Build Coastguard Worker { "\xf1\x20", -1, 0, FALSE },
602*2d1272b8SAndroid Build Coastguard Worker { "\xf2\x20", -1, 0, FALSE },
603*2d1272b8SAndroid Build Coastguard Worker { "\xf3\x20", -1, 0, FALSE },
604*2d1272b8SAndroid Build Coastguard Worker { "\xf4\x20", -1, 0, FALSE },
605*2d1272b8SAndroid Build Coastguard Worker { "\xf5\x20", -1, 0, FALSE },
606*2d1272b8SAndroid Build Coastguard Worker { "\xf6\x20", -1, 0, FALSE },
607*2d1272b8SAndroid Build Coastguard Worker { "\xf7\x20", -1, 0, FALSE },
608*2d1272b8SAndroid Build Coastguard Worker { "\xf8\x20", -1, 0, FALSE },
609*2d1272b8SAndroid Build Coastguard Worker { "\xf9\x20", -1, 0, FALSE },
610*2d1272b8SAndroid Build Coastguard Worker { "\xfa\x20", -1, 0, FALSE },
611*2d1272b8SAndroid Build Coastguard Worker { "\xfb\x20", -1, 0, FALSE },
612*2d1272b8SAndroid Build Coastguard Worker { "\xfc\x20", -1, 0, FALSE },
613*2d1272b8SAndroid Build Coastguard Worker { "\xfd\x20", -1, 0, FALSE },
614*2d1272b8SAndroid Build Coastguard Worker /* missing continuation bytes */
615*2d1272b8SAndroid Build Coastguard Worker { "\x20\xc0", -1, 1, FALSE },
616*2d1272b8SAndroid Build Coastguard Worker { "\x20\xe0\x80", -1, 1, FALSE },
617*2d1272b8SAndroid Build Coastguard Worker { "\x20\xf0\x80\x80", -1, 1, FALSE },
618*2d1272b8SAndroid Build Coastguard Worker { "\x20\xf8\x80\x80\x80", -1, 1, FALSE },
619*2d1272b8SAndroid Build Coastguard Worker { "\x20\xfc\x80\x80\x80\x80", -1, 1, FALSE },
620*2d1272b8SAndroid Build Coastguard Worker { "\x20\xdf", -1, 1, FALSE },
621*2d1272b8SAndroid Build Coastguard Worker { "\x20\xef\xbf", -1, 1, FALSE },
622*2d1272b8SAndroid Build Coastguard Worker { "\x20\xf7\xbf\xbf", -1, 1, FALSE },
623*2d1272b8SAndroid Build Coastguard Worker { "\x20\xfb\xbf\xbf\xbf", -1, 1, FALSE },
624*2d1272b8SAndroid Build Coastguard Worker { "\x20\xfd\xbf\xbf\xbf\xbf", -1, 1, FALSE },
625*2d1272b8SAndroid Build Coastguard Worker /* impossible bytes */
626*2d1272b8SAndroid Build Coastguard Worker { "\x20\xfe\x20", -1, 1, FALSE },
627*2d1272b8SAndroid Build Coastguard Worker { "\x20\xff\x20", -1, 1, FALSE },
628*2d1272b8SAndroid Build Coastguard Worker /* overlong sequences */
629*2d1272b8SAndroid Build Coastguard Worker { "\x20\xc0\xaf\x20", -1, 1, FALSE },
630*2d1272b8SAndroid Build Coastguard Worker { "\x20\xe0\x80\xaf\x20", -1, 1, FALSE },
631*2d1272b8SAndroid Build Coastguard Worker { "\x20\xf0\x80\x80\xaf\x20", -1, 1, FALSE },
632*2d1272b8SAndroid Build Coastguard Worker { "\x20\xf8\x80\x80\x80\xaf\x20", -1, 1, FALSE },
633*2d1272b8SAndroid Build Coastguard Worker { "\x20\xfc\x80\x80\x80\x80\xaf\x20", -1, 1, FALSE },
634*2d1272b8SAndroid Build Coastguard Worker { "\x20\xc1\xbf\x20", -1, 1, FALSE },
635*2d1272b8SAndroid Build Coastguard Worker { "\x20\xe0\x9f\xbf\x20", -1, 1, FALSE },
636*2d1272b8SAndroid Build Coastguard Worker { "\x20\xf0\x8f\xbf\xbf\x20", -1, 1, FALSE },
637*2d1272b8SAndroid Build Coastguard Worker { "\x20\xf8\x87\xbf\xbf\xbf\x20", -1, 1, FALSE },
638*2d1272b8SAndroid Build Coastguard Worker { "\x20\xfc\x83\xbf\xbf\xbf\xbf\x20", -1, 1, FALSE },
639*2d1272b8SAndroid Build Coastguard Worker { "\x20\xc0\x80\x20", -1, 1, FALSE },
640*2d1272b8SAndroid Build Coastguard Worker { "\x20\xe0\x80\x80\x20", -1, 1, FALSE },
641*2d1272b8SAndroid Build Coastguard Worker { "\x20\xf0\x80\x80\x80\x20", -1, 1, FALSE },
642*2d1272b8SAndroid Build Coastguard Worker { "\x20\xf8\x80\x80\x80\x80\x20", -1, 1, FALSE },
643*2d1272b8SAndroid Build Coastguard Worker { "\x20\xfc\x80\x80\x80\x80\x80\x20", -1, 1, FALSE },
644*2d1272b8SAndroid Build Coastguard Worker /* illegal code positions */
645*2d1272b8SAndroid Build Coastguard Worker { "\x20\xed\xa0\x80\x20", -1, 1, FALSE },
646*2d1272b8SAndroid Build Coastguard Worker { "\x20\xed\xad\xbf\x20", -1, 1, FALSE },
647*2d1272b8SAndroid Build Coastguard Worker { "\x20\xed\xae\x80\x20", -1, 1, FALSE },
648*2d1272b8SAndroid Build Coastguard Worker { "\x20\xed\xaf\xbf\x20", -1, 1, FALSE },
649*2d1272b8SAndroid Build Coastguard Worker { "\x20\xed\xb0\x80\x20", -1, 1, FALSE },
650*2d1272b8SAndroid Build Coastguard Worker { "\x20\xed\xbe\x80\x20", -1, 1, FALSE },
651*2d1272b8SAndroid Build Coastguard Worker { "\x20\xed\xbf\xbf\x20", -1, 1, FALSE },
652*2d1272b8SAndroid Build Coastguard Worker { "\x20\xed\xa0\x80\xed\xb0\x80\x20", -1, 1, FALSE },
653*2d1272b8SAndroid Build Coastguard Worker { "\x20\xed\xa0\x80\xed\xbf\xbf\x20", -1, 1, FALSE },
654*2d1272b8SAndroid Build Coastguard Worker { "\x20\xed\xad\xbf\xed\xb0\x80\x20", -1, 1, FALSE },
655*2d1272b8SAndroid Build Coastguard Worker { "\x20\xed\xad\xbf\xed\xbf\xbf\x20", -1, 1, FALSE },
656*2d1272b8SAndroid Build Coastguard Worker { "\x20\xed\xae\x80\xed\xb0\x80\x20", -1, 1, FALSE },
657*2d1272b8SAndroid Build Coastguard Worker { "\x20\xed\xae\x80\xed\xbf\xbf\x20", -1, 1, FALSE },
658*2d1272b8SAndroid Build Coastguard Worker { "\x20\xed\xaf\xbf\xed\xb0\x80\x20", -1, 1, FALSE },
659*2d1272b8SAndroid Build Coastguard Worker { "\x20\xed\xaf\xbf\xed\xbf\xbf\x20", -1, 1, FALSE },
660*2d1272b8SAndroid Build Coastguard Worker #if 0 /* We don't consider U+FFFE / U+FFFF and similar invalid. */
661*2d1272b8SAndroid Build Coastguard Worker { "\x20\xef\xbf\xbe\x20", -1, 1, FALSE },
662*2d1272b8SAndroid Build Coastguard Worker { "\x20\xef\xbf\xbf\x20", -1, 1, FALSE },
663*2d1272b8SAndroid Build Coastguard Worker #endif
664*2d1272b8SAndroid Build Coastguard Worker { "", -1, 0, TRUE }
665*2d1272b8SAndroid Build Coastguard Worker };
666*2d1272b8SAndroid Build Coastguard Worker
667*2d1272b8SAndroid Build Coastguard Worker static void
test_buffer_utf8_validity(void)668*2d1272b8SAndroid Build Coastguard Worker test_buffer_utf8_validity (void)
669*2d1272b8SAndroid Build Coastguard Worker {
670*2d1272b8SAndroid Build Coastguard Worker hb_buffer_t *b;
671*2d1272b8SAndroid Build Coastguard Worker unsigned int i;
672*2d1272b8SAndroid Build Coastguard Worker
673*2d1272b8SAndroid Build Coastguard Worker b = hb_buffer_create ();
674*2d1272b8SAndroid Build Coastguard Worker hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -1);
675*2d1272b8SAndroid Build Coastguard Worker
676*2d1272b8SAndroid Build Coastguard Worker for (i = 0; i < G_N_ELEMENTS (utf8_validity_tests); i++)
677*2d1272b8SAndroid Build Coastguard Worker {
678*2d1272b8SAndroid Build Coastguard Worker const utf8_validity_test_t *test = &utf8_validity_tests[i];
679*2d1272b8SAndroid Build Coastguard Worker unsigned int text_bytes, segment_bytes, j, len;
680*2d1272b8SAndroid Build Coastguard Worker hb_glyph_info_t *glyphs;
681*2d1272b8SAndroid Build Coastguard Worker char *escaped;
682*2d1272b8SAndroid Build Coastguard Worker
683*2d1272b8SAndroid Build Coastguard Worker escaped = g_strescape (test->utf8, NULL);
684*2d1272b8SAndroid Build Coastguard Worker g_test_message ("UTF-8 test #%d: %s", i, escaped);
685*2d1272b8SAndroid Build Coastguard Worker g_free (escaped);
686*2d1272b8SAndroid Build Coastguard Worker
687*2d1272b8SAndroid Build Coastguard Worker text_bytes = strlen (test->utf8);
688*2d1272b8SAndroid Build Coastguard Worker if (test->max_len == -1)
689*2d1272b8SAndroid Build Coastguard Worker segment_bytes = text_bytes;
690*2d1272b8SAndroid Build Coastguard Worker else
691*2d1272b8SAndroid Build Coastguard Worker segment_bytes = test->max_len;
692*2d1272b8SAndroid Build Coastguard Worker
693*2d1272b8SAndroid Build Coastguard Worker hb_buffer_clear_contents (b);
694*2d1272b8SAndroid Build Coastguard Worker hb_buffer_add_utf8 (b, test->utf8, text_bytes, 0, segment_bytes);
695*2d1272b8SAndroid Build Coastguard Worker
696*2d1272b8SAndroid Build Coastguard Worker glyphs = hb_buffer_get_glyph_infos (b, &len);
697*2d1272b8SAndroid Build Coastguard Worker for (j = 0; j < len; j++)
698*2d1272b8SAndroid Build Coastguard Worker if (glyphs[j].codepoint == (hb_codepoint_t) -1)
699*2d1272b8SAndroid Build Coastguard Worker break;
700*2d1272b8SAndroid Build Coastguard Worker
701*2d1272b8SAndroid Build Coastguard Worker g_assert (test->valid ? j == len : j < len);
702*2d1272b8SAndroid Build Coastguard Worker if (!test->valid)
703*2d1272b8SAndroid Build Coastguard Worker g_assert (glyphs[j].cluster == test->offset);
704*2d1272b8SAndroid Build Coastguard Worker }
705*2d1272b8SAndroid Build Coastguard Worker
706*2d1272b8SAndroid Build Coastguard Worker hb_buffer_destroy (b);
707*2d1272b8SAndroid Build Coastguard Worker }
708*2d1272b8SAndroid Build Coastguard Worker
709*2d1272b8SAndroid Build Coastguard Worker
710*2d1272b8SAndroid Build Coastguard Worker typedef struct {
711*2d1272b8SAndroid Build Coastguard Worker const uint16_t utf16[8];
712*2d1272b8SAndroid Build Coastguard Worker const uint32_t codepoints[8];
713*2d1272b8SAndroid Build Coastguard Worker } utf16_conversion_test_t;
714*2d1272b8SAndroid Build Coastguard Worker
715*2d1272b8SAndroid Build Coastguard Worker /* note: we skip the first and last item from utf16 when adding to buffer */
716*2d1272b8SAndroid Build Coastguard Worker static const utf16_conversion_test_t utf16_conversion_tests[] = {
717*2d1272b8SAndroid Build Coastguard Worker {{0x41, 0x004D, 0x0430, 0x4E8C, 0xD800, 0xDF02, 0x61} , {0x004D, 0x0430, 0x4E8C, 0x10302}},
718*2d1272b8SAndroid Build Coastguard Worker {{0x41, 0xD800, 0xDF02, 0x61}, {0x10302}},
719*2d1272b8SAndroid Build Coastguard Worker {{0x41, 0xD800, 0xDF02}, {(hb_codepoint_t) -1}},
720*2d1272b8SAndroid Build Coastguard Worker {{0x41, 0x61, 0xD800, 0xDF02}, {0x61, (hb_codepoint_t) -1}},
721*2d1272b8SAndroid Build Coastguard Worker {{0x41, 0xD800, 0x61, 0xDF02}, {(hb_codepoint_t) -1, 0x61}},
722*2d1272b8SAndroid Build Coastguard Worker {{0x41, 0xDF00, 0x61}, {(hb_codepoint_t) -1}},
723*2d1272b8SAndroid Build Coastguard Worker {{0x41, 0x61}, {0}}
724*2d1272b8SAndroid Build Coastguard Worker };
725*2d1272b8SAndroid Build Coastguard Worker
726*2d1272b8SAndroid Build Coastguard Worker static void
test_buffer_utf16_conversion(void)727*2d1272b8SAndroid Build Coastguard Worker test_buffer_utf16_conversion (void)
728*2d1272b8SAndroid Build Coastguard Worker {
729*2d1272b8SAndroid Build Coastguard Worker hb_buffer_t *b;
730*2d1272b8SAndroid Build Coastguard Worker unsigned int i;
731*2d1272b8SAndroid Build Coastguard Worker
732*2d1272b8SAndroid Build Coastguard Worker b = hb_buffer_create ();
733*2d1272b8SAndroid Build Coastguard Worker hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -1);
734*2d1272b8SAndroid Build Coastguard Worker
735*2d1272b8SAndroid Build Coastguard Worker for (i = 0; i < G_N_ELEMENTS (utf16_conversion_tests); i++)
736*2d1272b8SAndroid Build Coastguard Worker {
737*2d1272b8SAndroid Build Coastguard Worker const utf16_conversion_test_t *test = &utf16_conversion_tests[i];
738*2d1272b8SAndroid Build Coastguard Worker unsigned int u_len, chars, j, len;
739*2d1272b8SAndroid Build Coastguard Worker hb_glyph_info_t *glyphs;
740*2d1272b8SAndroid Build Coastguard Worker
741*2d1272b8SAndroid Build Coastguard Worker g_test_message ("UTF-16 test #%d", i);
742*2d1272b8SAndroid Build Coastguard Worker
743*2d1272b8SAndroid Build Coastguard Worker for (u_len = 0; test->utf16[u_len]; u_len++)
744*2d1272b8SAndroid Build Coastguard Worker ;
745*2d1272b8SAndroid Build Coastguard Worker for (chars = 0; test->codepoints[chars]; chars++)
746*2d1272b8SAndroid Build Coastguard Worker ;
747*2d1272b8SAndroid Build Coastguard Worker
748*2d1272b8SAndroid Build Coastguard Worker hb_buffer_clear_contents (b);
749*2d1272b8SAndroid Build Coastguard Worker hb_buffer_add_utf16 (b, test->utf16, u_len, 1, u_len - 2);
750*2d1272b8SAndroid Build Coastguard Worker
751*2d1272b8SAndroid Build Coastguard Worker glyphs = hb_buffer_get_glyph_infos (b, &len);
752*2d1272b8SAndroid Build Coastguard Worker g_assert_cmpint (len, ==, chars);
753*2d1272b8SAndroid Build Coastguard Worker for (j = 0; j < chars; j++)
754*2d1272b8SAndroid Build Coastguard Worker g_assert_cmphex (glyphs[j].codepoint, ==, test->codepoints[j]);
755*2d1272b8SAndroid Build Coastguard Worker }
756*2d1272b8SAndroid Build Coastguard Worker
757*2d1272b8SAndroid Build Coastguard Worker hb_buffer_destroy (b);
758*2d1272b8SAndroid Build Coastguard Worker }
759*2d1272b8SAndroid Build Coastguard Worker
760*2d1272b8SAndroid Build Coastguard Worker
761*2d1272b8SAndroid Build Coastguard Worker typedef struct {
762*2d1272b8SAndroid Build Coastguard Worker const uint32_t utf32[8];
763*2d1272b8SAndroid Build Coastguard Worker const uint32_t codepoints[8];
764*2d1272b8SAndroid Build Coastguard Worker } utf32_conversion_test_t;
765*2d1272b8SAndroid Build Coastguard Worker
766*2d1272b8SAndroid Build Coastguard Worker /* note: we skip the first and last item from utf32 when adding to buffer */
767*2d1272b8SAndroid Build Coastguard Worker static const utf32_conversion_test_t utf32_conversion_tests[] = {
768*2d1272b8SAndroid Build Coastguard Worker {{0x41, 0x004D, 0x0430, 0x4E8C, 0xD800, 0xDF02, 0x61} , {0x004D, 0x0430, 0x4E8C, (hb_codepoint_t) -3, (hb_codepoint_t) -3}},
769*2d1272b8SAndroid Build Coastguard Worker {{0x41, 0x004D, 0x0430, 0x4E8C, 0x10302, 0x61} , {0x004D, 0x0430, 0x4E8C, 0x10302}},
770*2d1272b8SAndroid Build Coastguard Worker {{0x41, 0xD800, 0xDF02, 0x61}, {(hb_codepoint_t) -3, (hb_codepoint_t) -3}},
771*2d1272b8SAndroid Build Coastguard Worker {{0x41, 0xD800, 0xDF02}, {(hb_codepoint_t) -3}},
772*2d1272b8SAndroid Build Coastguard Worker {{0x41, 0x61, 0xD800, 0xDF02}, {0x61, (hb_codepoint_t) -3}},
773*2d1272b8SAndroid Build Coastguard Worker {{0x41, 0xD800, 0x61, 0xDF02}, {(hb_codepoint_t) -3, 0x61}},
774*2d1272b8SAndroid Build Coastguard Worker {{0x41, 0xDF00, 0x61}, {(hb_codepoint_t) -3}},
775*2d1272b8SAndroid Build Coastguard Worker {{0x41, 0x10FFFF, 0x61}, {0x10FFFF}},
776*2d1272b8SAndroid Build Coastguard Worker {{0x41, 0x110000, 0x61}, {(hb_codepoint_t) -3}},
777*2d1272b8SAndroid Build Coastguard Worker {{0x41, 0x61}, {0}}
778*2d1272b8SAndroid Build Coastguard Worker };
779*2d1272b8SAndroid Build Coastguard Worker
780*2d1272b8SAndroid Build Coastguard Worker static void
test_buffer_utf32_conversion(void)781*2d1272b8SAndroid Build Coastguard Worker test_buffer_utf32_conversion (void)
782*2d1272b8SAndroid Build Coastguard Worker {
783*2d1272b8SAndroid Build Coastguard Worker hb_buffer_t *b;
784*2d1272b8SAndroid Build Coastguard Worker unsigned int i;
785*2d1272b8SAndroid Build Coastguard Worker
786*2d1272b8SAndroid Build Coastguard Worker b = hb_buffer_create ();
787*2d1272b8SAndroid Build Coastguard Worker hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -3);
788*2d1272b8SAndroid Build Coastguard Worker
789*2d1272b8SAndroid Build Coastguard Worker for (i = 0; i < G_N_ELEMENTS (utf32_conversion_tests); i++)
790*2d1272b8SAndroid Build Coastguard Worker {
791*2d1272b8SAndroid Build Coastguard Worker const utf32_conversion_test_t *test = &utf32_conversion_tests[i];
792*2d1272b8SAndroid Build Coastguard Worker unsigned int u_len, chars, j, len;
793*2d1272b8SAndroid Build Coastguard Worker hb_glyph_info_t *glyphs;
794*2d1272b8SAndroid Build Coastguard Worker
795*2d1272b8SAndroid Build Coastguard Worker g_test_message ("UTF-32 test #%d", i);
796*2d1272b8SAndroid Build Coastguard Worker
797*2d1272b8SAndroid Build Coastguard Worker for (u_len = 0; test->utf32[u_len]; u_len++)
798*2d1272b8SAndroid Build Coastguard Worker ;
799*2d1272b8SAndroid Build Coastguard Worker for (chars = 0; test->codepoints[chars]; chars++)
800*2d1272b8SAndroid Build Coastguard Worker ;
801*2d1272b8SAndroid Build Coastguard Worker
802*2d1272b8SAndroid Build Coastguard Worker hb_buffer_clear_contents (b);
803*2d1272b8SAndroid Build Coastguard Worker hb_buffer_add_utf32 (b, test->utf32, u_len, 1, u_len - 2);
804*2d1272b8SAndroid Build Coastguard Worker
805*2d1272b8SAndroid Build Coastguard Worker glyphs = hb_buffer_get_glyph_infos (b, &len);
806*2d1272b8SAndroid Build Coastguard Worker g_assert_cmpint (len, ==, chars);
807*2d1272b8SAndroid Build Coastguard Worker for (j = 0; j < chars; j++)
808*2d1272b8SAndroid Build Coastguard Worker g_assert_cmphex (glyphs[j].codepoint, ==, test->codepoints[j]);
809*2d1272b8SAndroid Build Coastguard Worker }
810*2d1272b8SAndroid Build Coastguard Worker
811*2d1272b8SAndroid Build Coastguard Worker hb_buffer_destroy (b);
812*2d1272b8SAndroid Build Coastguard Worker }
813*2d1272b8SAndroid Build Coastguard Worker
814*2d1272b8SAndroid Build Coastguard Worker
815*2d1272b8SAndroid Build Coastguard Worker static void
test_empty(hb_buffer_t * b)816*2d1272b8SAndroid Build Coastguard Worker test_empty (hb_buffer_t *b)
817*2d1272b8SAndroid Build Coastguard Worker {
818*2d1272b8SAndroid Build Coastguard Worker g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
819*2d1272b8SAndroid Build Coastguard Worker g_assert (!hb_buffer_get_glyph_infos (b, NULL));
820*2d1272b8SAndroid Build Coastguard Worker g_assert (!hb_buffer_get_glyph_positions (b, NULL));
821*2d1272b8SAndroid Build Coastguard Worker }
822*2d1272b8SAndroid Build Coastguard Worker
823*2d1272b8SAndroid Build Coastguard Worker static void
test_buffer_empty(void)824*2d1272b8SAndroid Build Coastguard Worker test_buffer_empty (void)
825*2d1272b8SAndroid Build Coastguard Worker {
826*2d1272b8SAndroid Build Coastguard Worker hb_buffer_t *b = hb_buffer_get_empty ();
827*2d1272b8SAndroid Build Coastguard Worker
828*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_empty ());
829*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_get_empty () == b);
830*2d1272b8SAndroid Build Coastguard Worker
831*2d1272b8SAndroid Build Coastguard Worker g_assert (!hb_buffer_allocation_successful (b));
832*2d1272b8SAndroid Build Coastguard Worker
833*2d1272b8SAndroid Build Coastguard Worker test_empty (b);
834*2d1272b8SAndroid Build Coastguard Worker
835*2d1272b8SAndroid Build Coastguard Worker hb_buffer_add_utf32 (b, utf32, G_N_ELEMENTS (utf32), 1, G_N_ELEMENTS (utf32) - 2);
836*2d1272b8SAndroid Build Coastguard Worker
837*2d1272b8SAndroid Build Coastguard Worker test_empty (b);
838*2d1272b8SAndroid Build Coastguard Worker
839*2d1272b8SAndroid Build Coastguard Worker hb_buffer_reverse (b);
840*2d1272b8SAndroid Build Coastguard Worker hb_buffer_reverse_clusters (b);
841*2d1272b8SAndroid Build Coastguard Worker
842*2d1272b8SAndroid Build Coastguard Worker g_assert (!hb_buffer_set_length (b, 10));
843*2d1272b8SAndroid Build Coastguard Worker
844*2d1272b8SAndroid Build Coastguard Worker test_empty (b);
845*2d1272b8SAndroid Build Coastguard Worker
846*2d1272b8SAndroid Build Coastguard Worker g_assert (hb_buffer_set_length (b, 0));
847*2d1272b8SAndroid Build Coastguard Worker
848*2d1272b8SAndroid Build Coastguard Worker test_empty (b);
849*2d1272b8SAndroid Build Coastguard Worker
850*2d1272b8SAndroid Build Coastguard Worker g_assert (!hb_buffer_allocation_successful (b));
851*2d1272b8SAndroid Build Coastguard Worker
852*2d1272b8SAndroid Build Coastguard Worker hb_buffer_reset (b);
853*2d1272b8SAndroid Build Coastguard Worker
854*2d1272b8SAndroid Build Coastguard Worker test_empty (b);
855*2d1272b8SAndroid Build Coastguard Worker
856*2d1272b8SAndroid Build Coastguard Worker g_assert (!hb_buffer_allocation_successful (b));
857*2d1272b8SAndroid Build Coastguard Worker }
858*2d1272b8SAndroid Build Coastguard Worker
859*2d1272b8SAndroid Build Coastguard Worker typedef struct {
860*2d1272b8SAndroid Build Coastguard Worker const char *contents;
861*2d1272b8SAndroid Build Coastguard Worker hb_buffer_serialize_format_t format;
862*2d1272b8SAndroid Build Coastguard Worker unsigned int num_items;
863*2d1272b8SAndroid Build Coastguard Worker hb_bool_t success;
864*2d1272b8SAndroid Build Coastguard Worker } serialization_test_t;
865*2d1272b8SAndroid Build Coastguard Worker
866*2d1272b8SAndroid Build Coastguard Worker static const serialization_test_t serialization_tests[] = {
867*2d1272b8SAndroid Build Coastguard Worker { "<U+0640=0|U+0635=1>", HB_BUFFER_SERIALIZE_FORMAT_TEXT, 2, 1 },
868*2d1272b8SAndroid Build Coastguard Worker { "[{\"u\":1600,\"cl\":0},{\"u\":1589,\"cl\":1}]", HB_BUFFER_SERIALIZE_FORMAT_JSON, 2, 1 },
869*2d1272b8SAndroid Build Coastguard Worker
870*2d1272b8SAndroid Build Coastguard Worker /* Mixed glyphs/Unicodes -> parse fail */
871*2d1272b8SAndroid Build Coastguard Worker { "[{\"u\":1600,\"cl\":0},{\"g\":1589,\"cl\":1}]", HB_BUFFER_SERIALIZE_FORMAT_JSON, 0, 0 },
872*2d1272b8SAndroid Build Coastguard Worker { "<U+0640=0|uni0635=1>", HB_BUFFER_SERIALIZE_FORMAT_TEXT, 0, 0 },
873*2d1272b8SAndroid Build Coastguard Worker };
874*2d1272b8SAndroid Build Coastguard Worker
875*2d1272b8SAndroid Build Coastguard Worker static void
test_buffer_serialize_deserialize(void)876*2d1272b8SAndroid Build Coastguard Worker test_buffer_serialize_deserialize (void)
877*2d1272b8SAndroid Build Coastguard Worker {
878*2d1272b8SAndroid Build Coastguard Worker hb_buffer_t *b;
879*2d1272b8SAndroid Build Coastguard Worker unsigned int i;
880*2d1272b8SAndroid Build Coastguard Worker
881*2d1272b8SAndroid Build Coastguard Worker for (i = 0; i < G_N_ELEMENTS (serialization_tests); i++)
882*2d1272b8SAndroid Build Coastguard Worker {
883*2d1272b8SAndroid Build Coastguard Worker unsigned int consumed;
884*2d1272b8SAndroid Build Coastguard Worker char round_trip[1024];
885*2d1272b8SAndroid Build Coastguard Worker
886*2d1272b8SAndroid Build Coastguard Worker b = hb_buffer_create ();
887*2d1272b8SAndroid Build Coastguard Worker hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -1);
888*2d1272b8SAndroid Build Coastguard Worker
889*2d1272b8SAndroid Build Coastguard Worker const serialization_test_t *test = &serialization_tests[i];
890*2d1272b8SAndroid Build Coastguard Worker g_test_message ("serialize test #%d", i);
891*2d1272b8SAndroid Build Coastguard Worker
892*2d1272b8SAndroid Build Coastguard Worker (void) hb_buffer_deserialize_unicode (b, test->contents, -1, NULL, test->format);
893*2d1272b8SAndroid Build Coastguard Worker
894*2d1272b8SAndroid Build Coastguard Worker // Expected parse failure, got one, don't round-trip
895*2d1272b8SAndroid Build Coastguard Worker if (test->success != 0)
896*2d1272b8SAndroid Build Coastguard Worker {
897*2d1272b8SAndroid Build Coastguard Worker unsigned int num_glyphs = hb_buffer_get_length (b);
898*2d1272b8SAndroid Build Coastguard Worker g_assert_cmpint (num_glyphs, ==, test->num_items);
899*2d1272b8SAndroid Build Coastguard Worker
900*2d1272b8SAndroid Build Coastguard Worker hb_buffer_serialize_unicode (b, 0, num_glyphs, round_trip,
901*2d1272b8SAndroid Build Coastguard Worker sizeof(round_trip), &consumed, test->format,
902*2d1272b8SAndroid Build Coastguard Worker HB_BUFFER_SERIALIZE_FLAG_DEFAULT);
903*2d1272b8SAndroid Build Coastguard Worker g_assert_cmpstr (round_trip, ==, test->contents);
904*2d1272b8SAndroid Build Coastguard Worker }
905*2d1272b8SAndroid Build Coastguard Worker
906*2d1272b8SAndroid Build Coastguard Worker hb_buffer_destroy (b);
907*2d1272b8SAndroid Build Coastguard Worker
908*2d1272b8SAndroid Build Coastguard Worker }
909*2d1272b8SAndroid Build Coastguard Worker
910*2d1272b8SAndroid Build Coastguard Worker char test[1024];
911*2d1272b8SAndroid Build Coastguard Worker unsigned int consumed;
912*2d1272b8SAndroid Build Coastguard Worker hb_buffer_t *indeterminate = hb_buffer_get_empty ();
913*2d1272b8SAndroid Build Coastguard Worker hb_buffer_serialize (indeterminate, 0, (unsigned) -1,
914*2d1272b8SAndroid Build Coastguard Worker test, sizeof(test), &consumed, NULL,
915*2d1272b8SAndroid Build Coastguard Worker HB_BUFFER_SERIALIZE_FORMAT_JSON,
916*2d1272b8SAndroid Build Coastguard Worker HB_BUFFER_SERIALIZE_FLAG_DEFAULT);
917*2d1272b8SAndroid Build Coastguard Worker g_assert_cmpstr ( test, ==, "[]");
918*2d1272b8SAndroid Build Coastguard Worker
919*2d1272b8SAndroid Build Coastguard Worker hb_buffer_serialize (indeterminate, 0, (unsigned) - 1,
920*2d1272b8SAndroid Build Coastguard Worker test, sizeof(test), &consumed, NULL,
921*2d1272b8SAndroid Build Coastguard Worker HB_BUFFER_SERIALIZE_FORMAT_TEXT,
922*2d1272b8SAndroid Build Coastguard Worker HB_BUFFER_SERIALIZE_FLAG_DEFAULT);
923*2d1272b8SAndroid Build Coastguard Worker g_assert_cmpstr ( test, ==, "!!");
924*2d1272b8SAndroid Build Coastguard Worker
925*2d1272b8SAndroid Build Coastguard Worker }
926*2d1272b8SAndroid Build Coastguard Worker
927*2d1272b8SAndroid Build Coastguard Worker int
main(int argc,char ** argv)928*2d1272b8SAndroid Build Coastguard Worker main (int argc, char **argv)
929*2d1272b8SAndroid Build Coastguard Worker {
930*2d1272b8SAndroid Build Coastguard Worker unsigned int i;
931*2d1272b8SAndroid Build Coastguard Worker
932*2d1272b8SAndroid Build Coastguard Worker hb_test_init (&argc, &argv);
933*2d1272b8SAndroid Build Coastguard Worker
934*2d1272b8SAndroid Build Coastguard Worker for (i = 0; i < BUFFER_NUM_TYPES; i++)
935*2d1272b8SAndroid Build Coastguard Worker {
936*2d1272b8SAndroid Build Coastguard Worker const void *buffer_type = GINT_TO_POINTER (i);
937*2d1272b8SAndroid Build Coastguard Worker const char *buffer_name = buffer_names[i];
938*2d1272b8SAndroid Build Coastguard Worker
939*2d1272b8SAndroid Build Coastguard Worker hb_test_add_fixture_flavor (fixture, buffer_type, buffer_name, test_buffer_properties);
940*2d1272b8SAndroid Build Coastguard Worker hb_test_add_fixture_flavor (fixture, buffer_type, buffer_name, test_buffer_contents);
941*2d1272b8SAndroid Build Coastguard Worker hb_test_add_fixture_flavor (fixture, buffer_type, buffer_name, test_buffer_positions);
942*2d1272b8SAndroid Build Coastguard Worker }
943*2d1272b8SAndroid Build Coastguard Worker
944*2d1272b8SAndroid Build Coastguard Worker hb_test_add_fixture (fixture, GINT_TO_POINTER (BUFFER_EMPTY), test_buffer_allocation);
945*2d1272b8SAndroid Build Coastguard Worker
946*2d1272b8SAndroid Build Coastguard Worker hb_test_add (test_buffer_utf8_conversion);
947*2d1272b8SAndroid Build Coastguard Worker hb_test_add (test_buffer_utf8_validity);
948*2d1272b8SAndroid Build Coastguard Worker hb_test_add (test_buffer_utf16_conversion);
949*2d1272b8SAndroid Build Coastguard Worker hb_test_add (test_buffer_utf32_conversion);
950*2d1272b8SAndroid Build Coastguard Worker hb_test_add (test_buffer_empty);
951*2d1272b8SAndroid Build Coastguard Worker hb_test_add (test_buffer_serialize_deserialize);
952*2d1272b8SAndroid Build Coastguard Worker
953*2d1272b8SAndroid Build Coastguard Worker return hb_test_run();
954*2d1272b8SAndroid Build Coastguard Worker }
955