1d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod/*
22409d5f8d7dd8b535ce5ea29e933f7db27d33793Behdad Esfahbod * Copyright © 2011  Google, Inc.
3d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod *
4d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod *  This is part of HarfBuzz, a text shaping library.
5d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod *
6d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod * Permission is hereby granted, without written agreement and without
7d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this
8d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod * software and its documentation for any purpose, provided that the
9d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod * above copyright notice and the following two paragraphs appear in
10d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod * all copies of this software.
11d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod *
12d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod * DAMAGE.
17d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod *
18d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod *
24d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod * Google Author(s): Behdad Esfahbod
25d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod */
26d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
27d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod#include "hb-test.h"
28d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
296af9cff5e17e82100b435c8d21aed0765296d58dBehdad Esfahbod/* Unit tests for hb-buffer.h */
30d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
31d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
32d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbodstatic const char utf8[10] = "ab\360\240\200\200defg";
33d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbodstatic const uint16_t utf16[8] = {'a', 'b', 0xD840, 0xDC00, 'd', 'e', 'f', 'g'};
34d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbodstatic const uint32_t utf32[7] = {'a', 'b', 0x20000, 'd', 'e', 'f', 'g'};
35d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
36dfec67f958482e5c3bb01e06b08694cd4ded6f66Behdad Esfahbod
37d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbodtypedef enum {
38d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  BUFFER_EMPTY,
39d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  BUFFER_ONE_BY_ONE,
40d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  BUFFER_UTF32,
41d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  BUFFER_UTF16,
42d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  BUFFER_UTF8,
43d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  BUFFER_NUM_TYPES,
44d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod} buffer_type_t;
45d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
46d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbodstatic const char *buffer_names[] = {
47d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  "empty",
48d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  "one-by-one",
49d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  "utf32",
50d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  "utf16",
51d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  "utf8"
52d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod};
53d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
54d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbodtypedef struct
55d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod{
560617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_t *buffer;
5715c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbod} fixture_t;
58d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
59d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbodstatic void
6015c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbodfixture_init (fixture_t *fixture, gconstpointer user_data)
61d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod{
620617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_t *b;
63d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  unsigned int i;
64d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
65e6c09cdf43201ff1b7f38e411ae1f9977e4f9271Behdad Esfahbod  b = fixture->buffer = hb_buffer_create ();
66d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
670617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  switch (GPOINTER_TO_INT (user_data))
680617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  {
69d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    case BUFFER_EMPTY:
70d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod      break;
71d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
72d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    case BUFFER_ONE_BY_ONE:
73d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod      for (i = 1; i < G_N_ELEMENTS (utf32) - 1; i++)
74d04b12853167d756a8cccaf4154f0fd894bce6deBehdad Esfahbod	hb_buffer_add (b, utf32[i], i);
75d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod      break;
76d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
77d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    case BUFFER_UTF32:
780617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod      hb_buffer_add_utf32 (b, utf32, G_N_ELEMENTS (utf32), 1, G_N_ELEMENTS (utf32) - 2);
79d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod      break;
80d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
81d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    case BUFFER_UTF16:
820617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod      hb_buffer_add_utf16 (b, utf16, G_N_ELEMENTS (utf16), 1, G_N_ELEMENTS (utf16) - 2);
83d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod      break;
84d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
85d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    case BUFFER_UTF8:
860617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod      hb_buffer_add_utf8  (b, utf8,  G_N_ELEMENTS (utf8),  1, G_N_ELEMENTS (utf8)  - 2);
87d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod      break;
88d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
89d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    default:
90d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod      g_assert_not_reached ();
91d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  }
92d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod}
93d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
94d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbodstatic void
95aafe395ab550d3ba2fabc69155662e87d45e74a8Behdad Esfahbodfixture_finish (fixture_t *fixture, gconstpointer user_data)
96d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod{
970617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_destroy (fixture->buffer);
98d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod}
99d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
100d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
101d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbodstatic void
10215c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbodtest_buffer_properties (fixture_t *fixture, gconstpointer user_data)
103d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod{
1040617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_t *b = fixture->buffer;
1051e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  hb_unicode_funcs_t *ufuncs;
106d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
1071e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  /* test default properties */
1081e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
1090617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_get_unicode_funcs (b) == hb_unicode_funcs_get_default ());
1100617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_INVALID);
1110617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_get_script (b) == HB_SCRIPT_INVALID);
1120617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_get_language (b) == NULL);
113d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
1141e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
1151e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  /* test property changes are retained */
1161e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  ufuncs = hb_unicode_funcs_create (NULL);
1170617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_set_unicode_funcs (b, ufuncs);
1181e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  hb_unicode_funcs_destroy (ufuncs);
1190617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_get_unicode_funcs (b) == ufuncs);
1201e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
1210617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_set_direction (b, HB_DIRECTION_RTL);
1220617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_RTL);
123d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
1240617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_set_script (b, HB_SCRIPT_ARABIC);
1250617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_get_script (b) == HB_SCRIPT_ARABIC);
126d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
1274c9fe88d30036340fe592bcbc375049b84602b8bBehdad Esfahbod  hb_buffer_set_language (b, hb_language_from_string ("fa", -1));
1284c9fe88d30036340fe592bcbc375049b84602b8bBehdad Esfahbod  g_assert (hb_buffer_get_language (b) == hb_language_from_string ("Fa", -1));
1291e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
1300c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod  hb_buffer_set_flags (b, HB_BUFFER_FLAG_BOT);
1310c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod  g_assert (hb_buffer_get_flags (b) == HB_BUFFER_FLAG_BOT);
1320c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod
133b5fbc3b8f560235d014c62e49220574ffcf89349Behdad Esfahbod  hb_buffer_set_replacement_codepoint (b, (unsigned int) -1);
134b5fbc3b8f560235d014c62e49220574ffcf89349Behdad Esfahbod  g_assert (hb_buffer_get_replacement_codepoint (b) == (unsigned int) -1);
1351e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
13682ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod
137b5fbc3b8f560235d014c62e49220574ffcf89349Behdad Esfahbod  /* test clear_contents clears all these properties: */
13882ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod
1391172dc736280566426eb6dade1a886b2a0ca9aa4Behdad Esfahbod  hb_buffer_clear_contents (b);
14082ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod
14182ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod  g_assert (hb_buffer_get_unicode_funcs (b) == ufuncs);
14282ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod  g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_INVALID);
14382ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod  g_assert (hb_buffer_get_script (b) == HB_SCRIPT_INVALID);
14482ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod  g_assert (hb_buffer_get_language (b) == NULL);
145b5fbc3b8f560235d014c62e49220574ffcf89349Behdad Esfahbod
146b5fbc3b8f560235d014c62e49220574ffcf89349Behdad Esfahbod  /* but not these: */
147b5fbc3b8f560235d014c62e49220574ffcf89349Behdad Esfahbod
148b5fbc3b8f560235d014c62e49220574ffcf89349Behdad Esfahbod  g_assert (hb_buffer_get_flags (b) != HB_BUFFER_FLAGS_DEFAULT);
149b5fbc3b8f560235d014c62e49220574ffcf89349Behdad Esfahbod  g_assert (hb_buffer_get_replacement_codepoint (b) != HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT);
15082ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod
15182ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod
15282ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod  /* test reset clears all properties */
15382ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod
15482ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod  hb_buffer_set_direction (b, HB_DIRECTION_RTL);
15582ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod  g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_RTL);
15682ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod
15782ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod  hb_buffer_set_script (b, HB_SCRIPT_ARABIC);
15882ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod  g_assert (hb_buffer_get_script (b) == HB_SCRIPT_ARABIC);
15982ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod
16082ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod  hb_buffer_set_language (b, hb_language_from_string ("fa", -1));
16182ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod  g_assert (hb_buffer_get_language (b) == hb_language_from_string ("Fa", -1));
1621e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
1630c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod  hb_buffer_set_flags (b, HB_BUFFER_FLAG_BOT);
1640c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod  g_assert (hb_buffer_get_flags (b) == HB_BUFFER_FLAG_BOT);
1650c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod
166b5fbc3b8f560235d014c62e49220574ffcf89349Behdad Esfahbod  hb_buffer_set_replacement_codepoint (b, (unsigned int) -1);
167b5fbc3b8f560235d014c62e49220574ffcf89349Behdad Esfahbod  g_assert (hb_buffer_get_replacement_codepoint (b) == (unsigned int) -1);
168b5fbc3b8f560235d014c62e49220574ffcf89349Behdad Esfahbod
1690617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reset (b);
1701e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
1710617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_get_unicode_funcs (b) == hb_unicode_funcs_get_default ());
1720617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_INVALID);
1730617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_get_script (b) == HB_SCRIPT_INVALID);
1740617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_get_language (b) == NULL);
1750c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod  g_assert (hb_buffer_get_flags (b) == HB_BUFFER_FLAGS_DEFAULT);
176b5fbc3b8f560235d014c62e49220574ffcf89349Behdad Esfahbod  g_assert (hb_buffer_get_replacement_codepoint (b) == HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT);
177d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod}
178d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
179d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbodstatic void
18015c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbodtest_buffer_contents (fixture_t *fixture, gconstpointer user_data)
181d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod{
1820617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_t *b = fixture->buffer;
1831e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  unsigned int i, len, len2;
184d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  buffer_type_t buffer_type = GPOINTER_TO_INT (user_data);
185d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  hb_glyph_info_t *glyphs;
186d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
187d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  if (buffer_type == BUFFER_EMPTY) {
1880617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod    g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
189d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    return;
190d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  }
191d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
1920617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  len = hb_buffer_get_length (b);
193a18280a8ce9128fc9d75f8a367ae8ce0886a9599Behdad Esfahbod  hb_buffer_get_glyph_infos (b, NULL); /* test NULL */
1940617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  glyphs = hb_buffer_get_glyph_infos (b, &len2);
1951e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  g_assert_cmpint (len, ==, len2);
196d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  g_assert_cmpint (len, ==, 5);
197d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
198d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  for (i = 0; i < len; i++) {
199db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    g_assert_cmphex (glyphs[i].mask,      ==, 1);
200db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    g_assert_cmphex (glyphs[i].var1.u32,  ==, 0);
201db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    g_assert_cmphex (glyphs[i].var2.u32,  ==, 0);
202db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  }
203db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
204db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  for (i = 0; i < len; i++) {
205d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    unsigned int cluster;
206d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    cluster = 1+i;
207d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    if (i >= 2) {
208d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod      if (buffer_type == BUFFER_UTF16)
209d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod	cluster++;
210d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod      else if (buffer_type == BUFFER_UTF8)
211d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod        cluster += 3;
212d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    }
213d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
214d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    g_assert_cmphex (glyphs[i].cluster,   ==, cluster);
215d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  }
216db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
217db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  /* reverse, test, and reverse back */
218db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
2190617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reverse (b);
220db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  for (i = 0; i < len; i++)
221db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[len-i]);
222db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
2230617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reverse (b);
224db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  for (i = 0; i < len; i++)
225db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
226db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
227db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  /* reverse_clusters works same as reverse for now since each codepoint is
228db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod   * in its own cluster */
229db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
2300617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reverse_clusters (b);
231db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  for (i = 0; i < len; i++)
232db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[len-i]);
233db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
2340617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reverse_clusters (b);
235db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  for (i = 0; i < len; i++)
236db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
237db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
238db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  /* now form a cluster and test again */
239db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  glyphs[2].cluster = glyphs[1].cluster;
240db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
241db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  /* reverse, test, and reverse back */
242db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
2430617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reverse (b);
244db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  for (i = 0; i < len; i++)
245db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[len-i]);
246db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
2470617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reverse (b);
248db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  for (i = 0; i < len; i++)
249db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
250db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
251db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  /* reverse_clusters twice still should return the original string,
252db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod   * but when applied once, the 1-2 cluster should be retained. */
253db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
2540617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reverse_clusters (b);
255db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  for (i = 0; i < len; i++) {
256db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    unsigned int j = len-1-i;
257db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    if (j == 1)
258db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod      j = 2;
259db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    else if (j == 2)
260db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod      j = 1;
261db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+j]);
262db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  }
263db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
2640617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reverse_clusters (b);
265db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  for (i = 0; i < len; i++)
266db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
2671e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
2681e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
2691e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  /* test setting length */
2701e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
2711e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  /* enlarge */
2720617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_set_length (b, 10));
2730617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  glyphs = hb_buffer_get_glyph_infos (b, NULL);
2740617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert_cmpint (hb_buffer_get_length (b), ==, 10);
2751e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  for (i = 0; i < 5; i++)
2761e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
2771e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  for (i = 5; i < 10; i++)
2781e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod    g_assert_cmphex (glyphs[i].codepoint, ==, 0);
2791e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  /* shrink */
2800617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_set_length (b, 3));
2810617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  glyphs = hb_buffer_get_glyph_infos (b, NULL);
2820617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert_cmpint (hb_buffer_get_length (b), ==, 3);
2831e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  for (i = 0; i < 3; i++)
2841e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
2851e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
2861e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
2870617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_allocation_successful (b));
28815c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbod
28915c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbod
2901e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  /* test reset clears content */
2911e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
2920617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reset (b);
2930617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
294d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod}
295d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
296d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbodstatic void
29715c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbodtest_buffer_positions (fixture_t *fixture, gconstpointer user_data)
298d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod{
2990617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_t *b = fixture->buffer;
3001e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  unsigned int i, len, len2;
301d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  hb_glyph_position_t *positions;
302d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
303d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  /* Without shaping, positions should all be zero */
3040617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  len = hb_buffer_get_length (b);
305a18280a8ce9128fc9d75f8a367ae8ce0886a9599Behdad Esfahbod  hb_buffer_get_glyph_positions (b, NULL); /* test NULL */
3060617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  positions = hb_buffer_get_glyph_positions (b, &len2);
3071e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  g_assert_cmpint (len, ==, len2);
308d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  for (i = 0; i < len; i++) {
309d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    g_assert_cmpint (0, ==, positions[i].x_advance);
310d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    g_assert_cmpint (0, ==, positions[i].y_advance);
311d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    g_assert_cmpint (0, ==, positions[i].x_offset);
312d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    g_assert_cmpint (0, ==, positions[i].y_offset);
313d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    g_assert_cmpint (0, ==, positions[i].var.i32);
314d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  }
3151e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
3161e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  /* test reset clears content */
3170617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reset (b);
3180617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
319d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod}
320d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
32115c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbodstatic void
32215c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbodtest_buffer_allocation (fixture_t *fixture, gconstpointer user_data)
32315c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbod{
3240617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_t *b = fixture->buffer;
3250617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod
3260617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
32715c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbod
3280617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_pre_allocate (b, 100));
3290617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
3300617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_allocation_successful (b));
33115c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbod
33215c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbod  /* lets try a huge allocation, make sure it fails */
3330617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (!hb_buffer_pre_allocate (b, (unsigned int) -1));
3340617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
3350617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (!hb_buffer_allocation_successful (b));
3363264042873fd639f3ef8ff0acfad777a0a9f3355Behdad Esfahbod
3373264042873fd639f3ef8ff0acfad777a0a9f3355Behdad Esfahbod  /* small one again */
3380617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_pre_allocate (b, 50));
3390617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
3400617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (!hb_buffer_allocation_successful (b));
3413264042873fd639f3ef8ff0acfad777a0a9f3355Behdad Esfahbod
3420617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reset (b);
3430617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_allocation_successful (b));
3443264042873fd639f3ef8ff0acfad777a0a9f3355Behdad Esfahbod
3453264042873fd639f3ef8ff0acfad777a0a9f3355Behdad Esfahbod  /* all allocation and size  */
3460617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (!hb_buffer_pre_allocate (b, ((unsigned int) -1) / 20 + 1));
3470617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (!hb_buffer_allocation_successful (b));
3483264042873fd639f3ef8ff0acfad777a0a9f3355Behdad Esfahbod
3490617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reset (b);
3500617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_allocation_successful (b));
3513264042873fd639f3ef8ff0acfad777a0a9f3355Behdad Esfahbod
3523264042873fd639f3ef8ff0acfad777a0a9f3355Behdad Esfahbod  /* technically, this one can actually pass on 64bit machines, but
3531d39d6e42b3d7628512d675a84a831a0f58624ebBehdad Esfahbod   * I'm doubtful that any malloc allows 4GB allocations at a time.
3541d39d6e42b3d7628512d675a84a831a0f58624ebBehdad Esfahbod   * But let's only enable it on a 32-bit machine. */
3551d39d6e42b3d7628512d675a84a831a0f58624ebBehdad Esfahbod  if (sizeof (long) == 4) {
3560617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod    g_assert (!hb_buffer_pre_allocate (b, ((unsigned int) -1) / 20 - 1));
3570617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod    g_assert (!hb_buffer_allocation_successful (b));
3581d39d6e42b3d7628512d675a84a831a0f58624ebBehdad Esfahbod  }
3593264042873fd639f3ef8ff0acfad777a0a9f3355Behdad Esfahbod
3600617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reset (b);
3610617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_allocation_successful (b));
36215c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbod}
36315c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbod
364243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
365243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbodtypedef struct {
366243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  const char utf8[8];
367243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  const uint32_t codepoints[8];
368c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod} utf8_conversion_test_t;
369243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
370243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod/* note: we skip the first and last byte when adding to buffer */
371c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbodstatic const utf8_conversion_test_t utf8_conversion_tests[] = {
372243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  {"a\303\207", {-1}},
373243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  {"a\303\207b", {0xC7}},
374243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  {"ab\303cd", {'b', -1, 'c'}},
375243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  {"ab\303\302\301cd", {'b', -1, -1, -1, 'c'}}
376243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod};
377243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
378dfec67f958482e5c3bb01e06b08694cd4ded6f66Behdad Esfahbodstatic void
379c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbodtest_buffer_utf8_conversion (void)
380dfec67f958482e5c3bb01e06b08694cd4ded6f66Behdad Esfahbod{
381dfec67f958482e5c3bb01e06b08694cd4ded6f66Behdad Esfahbod  hb_buffer_t *b;
382dfec67f958482e5c3bb01e06b08694cd4ded6f66Behdad Esfahbod  hb_glyph_info_t *glyphs;
383c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  unsigned int bytes, chars, i, j, len;
384dfec67f958482e5c3bb01e06b08694cd4ded6f66Behdad Esfahbod
385e6c09cdf43201ff1b7f38e411ae1f9977e4f9271Behdad Esfahbod  b = hb_buffer_create ();
386976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod  hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -1);
387dfec67f958482e5c3bb01e06b08694cd4ded6f66Behdad Esfahbod
388c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  for (i = 0; i < G_N_ELEMENTS (utf8_conversion_tests); i++)
389c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  {
390c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    const utf8_conversion_test_t *test = &utf8_conversion_tests[i];
391c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    char *escaped;
392c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod
393c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    escaped = g_strescape (test->utf8, NULL);
394c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    g_test_message ("UTF-8 test #%d: %s", i, escaped);
395c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    g_free (escaped);
396c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod
397c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    bytes = strlen (test->utf8);
398c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    for (chars = 0; test->codepoints[chars]; chars++)
399c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod      ;
400c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod
401976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod    hb_buffer_clear_contents (b);
402c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    hb_buffer_add_utf8 (b, test->utf8, bytes,  1, bytes - 2);
403c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod
404c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    glyphs = hb_buffer_get_glyph_infos (b, &len);
405c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    g_assert_cmpint (len, ==, chars);
406c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    for (j = 0; j < chars; j++)
407c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod      g_assert_cmphex (glyphs[j].codepoint, ==, test->codepoints[j]);
408c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  }
409dfec67f958482e5c3bb01e06b08694cd4ded6f66Behdad Esfahbod
410dfec67f958482e5c3bb01e06b08694cd4ded6f66Behdad Esfahbod  hb_buffer_destroy (b);
411dfec67f958482e5c3bb01e06b08694cd4ded6f66Behdad Esfahbod}
412dfec67f958482e5c3bb01e06b08694cd4ded6f66Behdad Esfahbod
41315c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbod
414243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
415243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod/* Following test table is adapted from glib/glib/tests/utf8-validate.c
416243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod * with relicensing permission from Matthias Clasen. */
417243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
418243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbodtypedef struct {
419c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  const char *utf8;
420243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  int max_len;
421243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  unsigned int offset;
422243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  gboolean valid;
423243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod} utf8_validity_test_t;
424243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
425243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbodstatic const utf8_validity_test_t utf8_validity_tests[] = {
426243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* some tests to check max_len handling */
427243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* length 1 */
428243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "abcde", -1, 5, TRUE },
429243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "abcde", 3, 3, TRUE },
430243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "abcde", 5, 5, TRUE },
431243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* length 2 */
432243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc2\xa9\xc2\xa9\xc2\xa9", -1, 6, TRUE },
433243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc2\xa9\xc2\xa9\xc2\xa9",  1, 0, FALSE },
434243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc2\xa9\xc2\xa9\xc2\xa9",  2, 2, TRUE },
435243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc2\xa9\xc2\xa9\xc2\xa9",  3, 2, FALSE },
436243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc2\xa9\xc2\xa9\xc2\xa9",  4, 4, TRUE },
437243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc2\xa9\xc2\xa9\xc2\xa9",  5, 4, FALSE },
438243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc2\xa9\xc2\xa9\xc2\xa9",  6, 6, TRUE },
439243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* length 3 */
440243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe2\x89\xa0\xe2\x89\xa0", -1, 6, TRUE },
441243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe2\x89\xa0\xe2\x89\xa0",  1, 0, FALSE },
442243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe2\x89\xa0\xe2\x89\xa0",  2, 0, FALSE },
443243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe2\x89\xa0\xe2\x89\xa0",  3, 3, TRUE },
444243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe2\x89\xa0\xe2\x89\xa0",  4, 3, FALSE },
445243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe2\x89\xa0\xe2\x89\xa0",  5, 3, FALSE },
446243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe2\x89\xa0\xe2\x89\xa0",  6, 6, TRUE },
447243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
448243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* examples from http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt */
449243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* greek 'kosme' */
450243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce\xb5", -1, 11, TRUE },
451243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* first sequence of each length */
452243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x00", -1, 0, TRUE },
453243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc2\x80", -1, 2, TRUE },
454243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe0\xa0\x80", -1, 3, TRUE },
455243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xf0\x90\x80\x80", -1, 4, TRUE },
456243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xf8\x88\x80\x80\x80", -1, 0, FALSE },
457243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xfc\x84\x80\x80\x80\x80", -1, 0, FALSE },
458243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* last sequence of each length */
459243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x7f", -1, 1, TRUE },
460243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xdf\xbf", -1, 2, TRUE },
461243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xef\xbf\xbf", -1, 0, TRUE },
462af2490c0959daa0fe7f32a8b3b3a3699c7fc5f48Behdad Esfahbod  { "\xf4\x8f\xbf\xbf", -1, 0, TRUE },
463af2490c0959daa0fe7f32a8b3b3a3699c7fc5f48Behdad Esfahbod  { "\xf4\x90\xbf\xbf", -1, 0, FALSE },
464af2490c0959daa0fe7f32a8b3b3a3699c7fc5f48Behdad Esfahbod  { "\xf7\xbf\xbf\xbf", -1, 0, FALSE },
465243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xfb\xbf\xbf\xbf\xbf", -1, 0, FALSE },
466243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xfd\xbf\xbf\xbf\xbf\xbf", -1, 0, FALSE },
467243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* other boundary conditions */
468243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xed\x9f\xbf", -1, 3, TRUE },
469af2490c0959daa0fe7f32a8b3b3a3699c7fc5f48Behdad Esfahbod  { "\xed\xa0\x80", -1, 0, FALSE },
470af2490c0959daa0fe7f32a8b3b3a3699c7fc5f48Behdad Esfahbod  { "\xed\xbf\xbf", -1, 0, FALSE },
471243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xee\x80\x80", -1, 3, TRUE },
472243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xef\xbf\xbd", -1, 3, TRUE },
473243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xf4\x8f\xbf\xbf", -1, 0, TRUE },
474243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* malformed sequences */
475243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* continuation bytes */
476243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x80", -1, 0, FALSE },
477243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xbf", -1, 0, FALSE },
478243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x80\xbf", -1, 0, FALSE },
479243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x80\xbf\x80", -1, 0, FALSE },
480243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x80\xbf\x80\xbf", -1, 0, FALSE },
481243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x80\xbf\x80\xbf\x80", -1, 0, FALSE },
482243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x80\xbf\x80\xbf\x80\xbf", -1, 0, FALSE },
483243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x80\xbf\x80\xbf\x80\xbf\x80", -1, 0, FALSE },
484243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
485243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* all possible continuation byte */
486243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x80", -1, 0, FALSE },
487243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x81", -1, 0, FALSE },
488243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x82", -1, 0, FALSE },
489243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x83", -1, 0, FALSE },
490243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x84", -1, 0, FALSE },
491243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x85", -1, 0, FALSE },
492243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x86", -1, 0, FALSE },
493243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x87", -1, 0, FALSE },
494243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x88", -1, 0, FALSE },
495243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x89", -1, 0, FALSE },
496243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x8a", -1, 0, FALSE },
497243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x8b", -1, 0, FALSE },
498243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x8c", -1, 0, FALSE },
499243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x8d", -1, 0, FALSE },
500243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x8e", -1, 0, FALSE },
501243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x8f", -1, 0, FALSE },
502243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x90", -1, 0, FALSE },
503243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x91", -1, 0, FALSE },
504243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x92", -1, 0, FALSE },
505243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x93", -1, 0, FALSE },
506243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x94", -1, 0, FALSE },
507243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x95", -1, 0, FALSE },
508243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x96", -1, 0, FALSE },
509243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x97", -1, 0, FALSE },
510243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x98", -1, 0, FALSE },
511243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x99", -1, 0, FALSE },
512243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x9a", -1, 0, FALSE },
513243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x9b", -1, 0, FALSE },
514243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x9c", -1, 0, FALSE },
515243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x9d", -1, 0, FALSE },
516243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x9e", -1, 0, FALSE },
517243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x9f", -1, 0, FALSE },
518243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xa0", -1, 0, FALSE },
519243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xa1", -1, 0, FALSE },
520243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xa2", -1, 0, FALSE },
521243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xa3", -1, 0, FALSE },
522243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xa4", -1, 0, FALSE },
523243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xa5", -1, 0, FALSE },
524243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xa6", -1, 0, FALSE },
525243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xa7", -1, 0, FALSE },
526243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xa8", -1, 0, FALSE },
527243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xa9", -1, 0, FALSE },
528243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xaa", -1, 0, FALSE },
529243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xab", -1, 0, FALSE },
530243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xac", -1, 0, FALSE },
531243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xad", -1, 0, FALSE },
532243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xae", -1, 0, FALSE },
533243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xaf", -1, 0, FALSE },
534243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xb0", -1, 0, FALSE },
535243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xb1", -1, 0, FALSE },
536243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xb2", -1, 0, FALSE },
537243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xb3", -1, 0, FALSE },
538243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xb4", -1, 0, FALSE },
539243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xb5", -1, 0, FALSE },
540243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xb6", -1, 0, FALSE },
541243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xb7", -1, 0, FALSE },
542243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xb8", -1, 0, FALSE },
543243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xb9", -1, 0, FALSE },
544243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xba", -1, 0, FALSE },
545243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xbb", -1, 0, FALSE },
546243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xbc", -1, 0, FALSE },
547243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xbd", -1, 0, FALSE },
548243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xbe", -1, 0, FALSE },
549243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xbf", -1, 0, FALSE },
550243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* lone start characters */
551243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc0\x20", -1, 0, FALSE },
552243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc1\x20", -1, 0, FALSE },
553243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc2\x20", -1, 0, FALSE },
554243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc3\x20", -1, 0, FALSE },
555243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc4\x20", -1, 0, FALSE },
556243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc5\x20", -1, 0, FALSE },
557243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc6\x20", -1, 0, FALSE },
558243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc7\x20", -1, 0, FALSE },
559243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc8\x20", -1, 0, FALSE },
560243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc9\x20", -1, 0, FALSE },
561243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xca\x20", -1, 0, FALSE },
562243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xcb\x20", -1, 0, FALSE },
563243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xcc\x20", -1, 0, FALSE },
564243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xcd\x20", -1, 0, FALSE },
565243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xce\x20", -1, 0, FALSE },
566243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xcf\x20", -1, 0, FALSE },
567243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xd0\x20", -1, 0, FALSE },
568243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xd1\x20", -1, 0, FALSE },
569243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xd2\x20", -1, 0, FALSE },
570243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xd3\x20", -1, 0, FALSE },
571243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xd4\x20", -1, 0, FALSE },
572243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xd5\x20", -1, 0, FALSE },
573243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xd6\x20", -1, 0, FALSE },
574243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xd7\x20", -1, 0, FALSE },
575243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xd8\x20", -1, 0, FALSE },
576243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xd9\x20", -1, 0, FALSE },
577243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xda\x20", -1, 0, FALSE },
578243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xdb\x20", -1, 0, FALSE },
579243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xdc\x20", -1, 0, FALSE },
580243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xdd\x20", -1, 0, FALSE },
581243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xde\x20", -1, 0, FALSE },
582243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xdf\x20", -1, 0, FALSE },
583243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe0\x20", -1, 0, FALSE },
584243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe1\x20", -1, 0, FALSE },
585243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe2\x20", -1, 0, FALSE },
586243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe3\x20", -1, 0, FALSE },
587243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe4\x20", -1, 0, FALSE },
588243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe5\x20", -1, 0, FALSE },
589243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe6\x20", -1, 0, FALSE },
590243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe7\x20", -1, 0, FALSE },
591243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe8\x20", -1, 0, FALSE },
592243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe9\x20", -1, 0, FALSE },
593243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xea\x20", -1, 0, FALSE },
594243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xeb\x20", -1, 0, FALSE },
595243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xec\x20", -1, 0, FALSE },
596243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xed\x20", -1, 0, FALSE },
597243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xee\x20", -1, 0, FALSE },
598243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xef\x20", -1, 0, FALSE },
599243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xf0\x20", -1, 0, FALSE },
600243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xf1\x20", -1, 0, FALSE },
601243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xf2\x20", -1, 0, FALSE },
602243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xf3\x20", -1, 0, FALSE },
603243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xf4\x20", -1, 0, FALSE },
604243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xf5\x20", -1, 0, FALSE },
605243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xf6\x20", -1, 0, FALSE },
606243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xf7\x20", -1, 0, FALSE },
607243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xf8\x20", -1, 0, FALSE },
608243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xf9\x20", -1, 0, FALSE },
609243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xfa\x20", -1, 0, FALSE },
610243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xfb\x20", -1, 0, FALSE },
611243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xfc\x20", -1, 0, FALSE },
612243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xfd\x20", -1, 0, FALSE },
613243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* missing continuation bytes */
614243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xc0", -1, 1, FALSE },
615243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xe0\x80", -1, 1, FALSE },
616243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xf0\x80\x80", -1, 1, FALSE },
617243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xf8\x80\x80\x80", -1, 1, FALSE },
618243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xfc\x80\x80\x80\x80", -1, 1, FALSE },
619243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xdf", -1, 1, FALSE },
620243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xef\xbf", -1, 1, FALSE },
621243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xf7\xbf\xbf", -1, 1, FALSE },
622243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xfb\xbf\xbf\xbf", -1, 1, FALSE },
623243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xfd\xbf\xbf\xbf\xbf", -1, 1, FALSE },
624243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* impossible bytes */
625243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xfe\x20", -1, 1, FALSE },
626243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xff\x20", -1, 1, FALSE },
627243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* overlong sequences */
628243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xc0\xaf\x20", -1, 1, FALSE },
629243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xe0\x80\xaf\x20", -1, 1, FALSE },
630243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xf0\x80\x80\xaf\x20", -1, 1, FALSE },
631243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xf8\x80\x80\x80\xaf\x20", -1, 1, FALSE },
632243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xfc\x80\x80\x80\x80\xaf\x20", -1, 1, FALSE },
633243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xc1\xbf\x20", -1, 1, FALSE },
634243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xe0\x9f\xbf\x20", -1, 1, FALSE },
635243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xf0\x8f\xbf\xbf\x20", -1, 1, FALSE },
636243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xf8\x87\xbf\xbf\xbf\x20", -1, 1, FALSE },
637243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xfc\x83\xbf\xbf\xbf\xbf\x20", -1, 1, FALSE },
638243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xc0\x80\x20", -1, 1, FALSE },
639243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xe0\x80\x80\x20", -1, 1, FALSE },
640243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xf0\x80\x80\x80\x20", -1, 1, FALSE },
641243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xf8\x80\x80\x80\x80\x20", -1, 1, FALSE },
642243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xfc\x80\x80\x80\x80\x80\x20", -1, 1, FALSE },
643243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* illegal code positions */
644243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xa0\x80\x20", -1, 1, FALSE },
645243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xad\xbf\x20", -1, 1, FALSE },
646243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xae\x80\x20", -1, 1, FALSE },
647243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xaf\xbf\x20", -1, 1, FALSE },
648243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xb0\x80\x20", -1, 1, FALSE },
649243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xbe\x80\x20", -1, 1, FALSE },
650243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xbf\xbf\x20", -1, 1, FALSE },
651243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xa0\x80\xed\xb0\x80\x20", -1, 1, FALSE },
652243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xa0\x80\xed\xbf\xbf\x20", -1, 1, FALSE },
653243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xad\xbf\xed\xb0\x80\x20", -1, 1, FALSE },
654243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xad\xbf\xed\xbf\xbf\x20", -1, 1, FALSE },
655243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xae\x80\xed\xb0\x80\x20", -1, 1, FALSE },
656243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xae\x80\xed\xbf\xbf\x20", -1, 1, FALSE },
657243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xaf\xbf\xed\xb0\x80\x20", -1, 1, FALSE },
658243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xaf\xbf\xed\xbf\xbf\x20", -1, 1, FALSE },
659af2490c0959daa0fe7f32a8b3b3a3699c7fc5f48Behdad Esfahbod#if 0 /* We don't consider U+FFFE / U+FFFF and similar invalid. */
660243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xef\xbf\xbe\x20", -1, 1, FALSE },
661243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xef\xbf\xbf\x20", -1, 1, FALSE },
662243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod#endif
663243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "", -1, 0, TRUE }
664243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod};
665243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
666243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbodstatic void
667c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbodtest_buffer_utf8_validity (void)
668243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod{
669243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  hb_buffer_t *b;
670c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  unsigned int i;
671243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
672e6c09cdf43201ff1b7f38e411ae1f9977e4f9271Behdad Esfahbod  b = hb_buffer_create ();
673976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod  hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -1);
674243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
675c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  for (i = 0; i < G_N_ELEMENTS (utf8_validity_tests); i++)
676c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  {
677c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    const utf8_validity_test_t *test = &utf8_validity_tests[i];
678c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    unsigned int text_bytes, segment_bytes, j, len;
679c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    hb_glyph_info_t *glyphs;
680c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    char *escaped;
681c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod
682c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    escaped = g_strescape (test->utf8, NULL);
683c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    g_test_message ("UTF-8 test #%d: %s", i, escaped);
684c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    g_free (escaped);
685c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod
686c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    text_bytes = strlen (test->utf8);
687c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    if (test->max_len == -1)
688c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod      segment_bytes = text_bytes;
689c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    else
690c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod      segment_bytes = test->max_len;
691c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod
692976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod    hb_buffer_clear_contents (b);
693c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    hb_buffer_add_utf8 (b, test->utf8, text_bytes,  0, segment_bytes);
694c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod
695c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    glyphs = hb_buffer_get_glyph_infos (b, &len);
696c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    for (j = 0; j < len; j++)
697c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod      if (glyphs[j].codepoint == (hb_codepoint_t) -1)
698c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod	break;
699c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod
700c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    g_assert (test->valid ? j == len : j < len);
701c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    if (!test->valid)
702c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod      g_assert (glyphs[j].cluster == test->offset);
703c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  }
704243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
705243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  hb_buffer_destroy (b);
706243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod}
707243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
708243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
70913db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbodtypedef struct {
71013db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod  const uint16_t utf16[8];
71113db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod  const uint32_t codepoints[8];
712c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod} utf16_conversion_test_t;
71313db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod
71413db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod/* note: we skip the first and last item from utf16 when adding to buffer */
715c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbodstatic const utf16_conversion_test_t utf16_conversion_tests[] = {
71613db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod  {{0x41, 0x004D, 0x0430, 0x4E8C, 0xD800, 0xDF02, 0x61} , {0x004D, 0x0430, 0x4E8C, 0x10302}},
71713db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod  {{0x41, 0xD800, 0xDF02, 0x61}, {0x10302}},
71813db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod  {{0x41, 0xD800, 0xDF02}, {-1}},
71913db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod  {{0x41, 0x61, 0xD800, 0xDF02}, {0x61, -1}},
72013db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod  {{0x41, 0xD800, 0x61, 0xDF02}, {-1, 0x61}},
72124b2ba9dfa7c35769cd843a07079ef88fa594bf8Behdad Esfahbod  {{0x41, 0xDF00, 0x61}, {-1}},
722a4446b10bfe0a9e7236bf941fa69a96697939e11Behdad Esfahbod  {{0x41, 0x61}, {0}}
72313db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod};
72413db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod
72513db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbodstatic void
726c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbodtest_buffer_utf16_conversion (void)
72713db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod{
72813db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod  hb_buffer_t *b;
729c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  unsigned int i;
73013db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod
731e6c09cdf43201ff1b7f38e411ae1f9977e4f9271Behdad Esfahbod  b = hb_buffer_create ();
732976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod  hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -1);
73313db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod
734c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  for (i = 0; i < G_N_ELEMENTS (utf16_conversion_tests); i++)
735c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  {
736c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    const utf16_conversion_test_t *test = &utf16_conversion_tests[i];
737c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    unsigned int u_len, chars, j, len;
738c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    hb_glyph_info_t *glyphs;
739c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod
740c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    g_test_message ("UTF-16 test #%d", i);
741c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod
742c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    for (u_len = 0; test->utf16[u_len]; u_len++)
743c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod      ;
744c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    for (chars = 0; test->codepoints[chars]; chars++)
745c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod      ;
746c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod
747976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod    hb_buffer_clear_contents (b);
748c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    hb_buffer_add_utf16 (b, test->utf16, u_len,  1, u_len - 2);
749c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod
750c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    glyphs = hb_buffer_get_glyph_infos (b, &len);
751c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    g_assert_cmpint (len, ==, chars);
752c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    for (j = 0; j < chars; j++)
753c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod      g_assert_cmphex (glyphs[j].codepoint, ==, test->codepoints[j]);
754c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  }
75513db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod
75613db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod  hb_buffer_destroy (b);
75713db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod}
75813db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod
759e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod
760e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbodtypedef struct {
761e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod  const uint32_t utf32[8];
762e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod  const uint32_t codepoints[8];
763e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod} utf32_conversion_test_t;
764e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod
765e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod/* note: we skip the first and last item from utf32 when adding to buffer */
766e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbodstatic const utf32_conversion_test_t utf32_conversion_tests[] = {
767976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod  {{0x41, 0x004D, 0x0430, 0x4E8C, 0xD800, 0xDF02, 0x61} , {0x004D, 0x0430, 0x4E8C, -3, -3}},
768e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod  {{0x41, 0x004D, 0x0430, 0x4E8C, 0x10302, 0x61} , {0x004D, 0x0430, 0x4E8C, 0x10302}},
769976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod  {{0x41, 0xD800, 0xDF02, 0x61}, {-3, -3}},
770976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod  {{0x41, 0xD800, 0xDF02}, {-3}},
771976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod  {{0x41, 0x61, 0xD800, 0xDF02}, {0x61, -3}},
772976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod  {{0x41, 0xD800, 0x61, 0xDF02}, {-3, 0x61}},
773976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod  {{0x41, 0xDF00, 0x61}, {-3}},
774e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod  {{0x41, 0x10FFFF, 0x61}, {0x10FFFF}},
775976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod  {{0x41, 0x110000, 0x61}, {-3}},
776e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod  {{0x41, 0x61}, {0}}
777e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod};
778e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod
779e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbodstatic void
780e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbodtest_buffer_utf32_conversion (void)
781e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod{
782e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod  hb_buffer_t *b;
783e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod  unsigned int i;
784e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod
785e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod  b = hb_buffer_create ();
786976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod  hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -3);
787e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod
788e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod  for (i = 0; i < G_N_ELEMENTS (utf32_conversion_tests); i++)
789e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod  {
790e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod    const utf32_conversion_test_t *test = &utf32_conversion_tests[i];
791e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod    unsigned int u_len, chars, j, len;
792e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod    hb_glyph_info_t *glyphs;
793e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod
794e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod    g_test_message ("UTF-32 test #%d", i);
795e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod
796e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod    for (u_len = 0; test->utf32[u_len]; u_len++)
797e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod      ;
798e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod    for (chars = 0; test->codepoints[chars]; chars++)
799e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod      ;
800e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod
801976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod    hb_buffer_clear_contents (b);
802e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod    hb_buffer_add_utf32 (b, test->utf32, u_len,  1, u_len - 2);
803e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod
804e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod    glyphs = hb_buffer_get_glyph_infos (b, &len);
805e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod    g_assert_cmpint (len, ==, chars);
806e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod    for (j = 0; j < chars; j++)
807e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod      g_assert_cmphex (glyphs[j].codepoint, ==, test->codepoints[j]);
808e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod  }
809e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod
810e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod  hb_buffer_destroy (b);
811e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod}
812e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod
813e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod
814b8477e1da2785708f3232f8f2577f602a5d320d1Behdad Esfahbodstatic void
81592de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbodtest_empty (hb_buffer_t *b)
81692de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod{
81792de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
81892de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  g_assert (!hb_buffer_get_glyph_infos (b, NULL));
81992de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  g_assert (!hb_buffer_get_glyph_positions (b, NULL));
82092de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod}
82192de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
82292de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbodstatic void
823b8477e1da2785708f3232f8f2577f602a5d320d1Behdad Esfahbodtest_buffer_empty (void)
824b8477e1da2785708f3232f8f2577f602a5d320d1Behdad Esfahbod{
82592de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  hb_buffer_t *b = hb_buffer_get_empty ();
82692de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
827b8477e1da2785708f3232f8f2577f602a5d320d1Behdad Esfahbod  g_assert (hb_buffer_get_empty ());
82892de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  g_assert (hb_buffer_get_empty () == b);
82992de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
83092de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  g_assert (!hb_buffer_allocation_successful (b));
83192de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
83292de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  test_empty (b);
83392de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
83492de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  hb_buffer_add_utf32 (b, utf32, G_N_ELEMENTS (utf32), 1, G_N_ELEMENTS (utf32) - 2);
83592de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
83692de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  test_empty (b);
83792de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
83892de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  hb_buffer_reverse (b);
83992de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  hb_buffer_reverse_clusters (b);
84092de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
84192de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  g_assert (!hb_buffer_set_length (b, 10));
84292de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
84392de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  test_empty (b);
84492de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
84592de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  g_assert (hb_buffer_set_length (b, 0));
84692de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
84792de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  test_empty (b);
84892de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
84992de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  g_assert (!hb_buffer_allocation_successful (b));
85092de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
85192de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  hb_buffer_reset (b);
85292de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
85392de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  test_empty (b);
85492de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
85592de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  g_assert (!hb_buffer_allocation_successful (b));
856b8477e1da2785708f3232f8f2577f602a5d320d1Behdad Esfahbod}
85713db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod
858d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbodint
859d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbodmain (int argc, char **argv)
860d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod{
861dfec67f958482e5c3bb01e06b08694cd4ded6f66Behdad Esfahbod  unsigned int i;
862d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
863aafe395ab550d3ba2fabc69155662e87d45e74a8Behdad Esfahbod  hb_test_init (&argc, &argv);
864aafe395ab550d3ba2fabc69155662e87d45e74a8Behdad Esfahbod
865aafe395ab550d3ba2fabc69155662e87d45e74a8Behdad Esfahbod  for (i = 0; i < BUFFER_NUM_TYPES; i++)
866aafe395ab550d3ba2fabc69155662e87d45e74a8Behdad Esfahbod  {
867aafe395ab550d3ba2fabc69155662e87d45e74a8Behdad Esfahbod    const void *buffer_type = GINT_TO_POINTER (i);
868aafe395ab550d3ba2fabc69155662e87d45e74a8Behdad Esfahbod    const char *buffer_name = buffer_names[i];
869aafe395ab550d3ba2fabc69155662e87d45e74a8Behdad Esfahbod
870aafe395ab550d3ba2fabc69155662e87d45e74a8Behdad Esfahbod    hb_test_add_fixture_flavor (fixture, buffer_type, buffer_name, test_buffer_properties);
871aafe395ab550d3ba2fabc69155662e87d45e74a8Behdad Esfahbod    hb_test_add_fixture_flavor (fixture, buffer_type, buffer_name, test_buffer_contents);
872aafe395ab550d3ba2fabc69155662e87d45e74a8Behdad Esfahbod    hb_test_add_fixture_flavor (fixture, buffer_type, buffer_name, test_buffer_positions);
873d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  }
874d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
875aafe395ab550d3ba2fabc69155662e87d45e74a8Behdad Esfahbod  hb_test_add_fixture (fixture, GINT_TO_POINTER (BUFFER_EMPTY), test_buffer_allocation);
87615c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbod
877c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  hb_test_add (test_buffer_utf8_conversion);
878c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  hb_test_add (test_buffer_utf8_validity);
879c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  hb_test_add (test_buffer_utf16_conversion);
880e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod  hb_test_add (test_buffer_utf32_conversion);
881b8477e1da2785708f3232f8f2577f602a5d320d1Behdad Esfahbod  hb_test_add (test_buffer_empty);
882d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
883aafe395ab550d3ba2fabc69155662e87d45e74a8Behdad Esfahbod  return hb_test_run();
884d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod}
885