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);
1134dc798de19c767b91fd3025c85593fa6809d1340Behdad Esfahbod  g_assert (hb_buffer_get_flags (b) == HB_BUFFER_FLAG_DEFAULT);
114d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
1151e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
1161e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  /* test property changes are retained */
1171e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  ufuncs = hb_unicode_funcs_create (NULL);
1180617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_set_unicode_funcs (b, ufuncs);
1191e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  hb_unicode_funcs_destroy (ufuncs);
1200617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_get_unicode_funcs (b) == ufuncs);
1211e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
1220617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_set_direction (b, HB_DIRECTION_RTL);
1230617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_RTL);
124d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
1250617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_set_script (b, HB_SCRIPT_ARABIC);
1260617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_get_script (b) == HB_SCRIPT_ARABIC);
127d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
1284c9fe88d30036340fe592bcbc375049b84602b8bBehdad Esfahbod  hb_buffer_set_language (b, hb_language_from_string ("fa", -1));
1294c9fe88d30036340fe592bcbc375049b84602b8bBehdad Esfahbod  g_assert (hb_buffer_get_language (b) == hb_language_from_string ("Fa", -1));
1301e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
1310c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod  hb_buffer_set_flags (b, HB_BUFFER_FLAG_BOT);
1320c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod  g_assert (hb_buffer_get_flags (b) == HB_BUFFER_FLAG_BOT);
1330c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod
1341e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
13582ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod
13682ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod  /* test clear clears all properties but unicode_funcs */
13782ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod
1381172dc736280566426eb6dade1a886b2a0ca9aa4Behdad Esfahbod  hb_buffer_clear_contents (b);
13982ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod
14082ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod  g_assert (hb_buffer_get_unicode_funcs (b) == ufuncs);
14182ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod  g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_INVALID);
14282ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod  g_assert (hb_buffer_get_script (b) == HB_SCRIPT_INVALID);
14382ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod  g_assert (hb_buffer_get_language (b) == NULL);
1440c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod  g_assert (hb_buffer_get_flags (b) == HB_BUFFER_FLAGS_DEFAULT);
14582ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod
14682ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod
14782ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod  /* test reset clears all properties */
14882ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod
14982ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod  hb_buffer_set_direction (b, HB_DIRECTION_RTL);
15082ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod  g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_RTL);
15182ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod
15282ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod  hb_buffer_set_script (b, HB_SCRIPT_ARABIC);
15382ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod  g_assert (hb_buffer_get_script (b) == HB_SCRIPT_ARABIC);
15482ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod
15582ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod  hb_buffer_set_language (b, hb_language_from_string ("fa", -1));
15682ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod  g_assert (hb_buffer_get_language (b) == hb_language_from_string ("Fa", -1));
1571e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
1580c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod  hb_buffer_set_flags (b, HB_BUFFER_FLAG_BOT);
1590c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod  g_assert (hb_buffer_get_flags (b) == HB_BUFFER_FLAG_BOT);
1600c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod
1610617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reset (b);
1621e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
1630617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_get_unicode_funcs (b) == hb_unicode_funcs_get_default ());
1640617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_INVALID);
1650617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_get_script (b) == HB_SCRIPT_INVALID);
1660617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_get_language (b) == NULL);
1670c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod  g_assert (hb_buffer_get_flags (b) == HB_BUFFER_FLAGS_DEFAULT);
168d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod}
169d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
170d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbodstatic void
17115c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbodtest_buffer_contents (fixture_t *fixture, gconstpointer user_data)
172d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod{
1730617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_t *b = fixture->buffer;
1741e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  unsigned int i, len, len2;
175d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  buffer_type_t buffer_type = GPOINTER_TO_INT (user_data);
176d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  hb_glyph_info_t *glyphs;
177d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
178d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  if (buffer_type == BUFFER_EMPTY) {
1790617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod    g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
180d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    return;
181d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  }
182d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
1830617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  len = hb_buffer_get_length (b);
184a18280a8ce9128fc9d75f8a367ae8ce0886a9599Behdad Esfahbod  hb_buffer_get_glyph_infos (b, NULL); /* test NULL */
1850617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  glyphs = hb_buffer_get_glyph_infos (b, &len2);
1861e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  g_assert_cmpint (len, ==, len2);
187d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  g_assert_cmpint (len, ==, 5);
188d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
189d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  for (i = 0; i < len; i++) {
190db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    g_assert_cmphex (glyphs[i].mask,      ==, 1);
191db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    g_assert_cmphex (glyphs[i].var1.u32,  ==, 0);
192db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    g_assert_cmphex (glyphs[i].var2.u32,  ==, 0);
193db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  }
194db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
195db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  for (i = 0; i < len; i++) {
196d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    unsigned int cluster;
197d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    cluster = 1+i;
198d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    if (i >= 2) {
199d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod      if (buffer_type == BUFFER_UTF16)
200d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod	cluster++;
201d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod      else if (buffer_type == BUFFER_UTF8)
202d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod        cluster += 3;
203d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    }
204d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
205d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    g_assert_cmphex (glyphs[i].cluster,   ==, cluster);
206d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  }
207db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
208db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  /* reverse, test, and reverse back */
209db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
2100617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reverse (b);
211db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  for (i = 0; i < len; i++)
212db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[len-i]);
213db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
2140617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reverse (b);
215db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  for (i = 0; i < len; i++)
216db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
217db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
218db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  /* reverse_clusters works same as reverse for now since each codepoint is
219db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod   * in its own cluster */
220db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
2210617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reverse_clusters (b);
222db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  for (i = 0; i < len; i++)
223db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[len-i]);
224db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
2250617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reverse_clusters (b);
226db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  for (i = 0; i < len; i++)
227db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
228db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
229db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  /* now form a cluster and test again */
230db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  glyphs[2].cluster = glyphs[1].cluster;
231db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
232db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  /* reverse, test, and reverse back */
233db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
2340617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reverse (b);
235db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  for (i = 0; i < len; i++)
236db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[len-i]);
237db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
2380617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reverse (b);
239db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  for (i = 0; i < len; i++)
240db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
241db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
242db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  /* reverse_clusters twice still should return the original string,
243db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod   * but when applied once, the 1-2 cluster should be retained. */
244db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
2450617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reverse_clusters (b);
246db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  for (i = 0; i < len; i++) {
247db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    unsigned int j = len-1-i;
248db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    if (j == 1)
249db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod      j = 2;
250db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    else if (j == 2)
251db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod      j = 1;
252db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+j]);
253db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  }
254db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod
2550617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reverse_clusters (b);
256db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod  for (i = 0; i < len; i++)
257db126b5448ec802285cf2b6f0e7da412d02dfb28Behdad Esfahbod    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
2581e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
2591e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
2601e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  /* test setting length */
2611e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
2621e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  /* enlarge */
2630617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_set_length (b, 10));
2640617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  glyphs = hb_buffer_get_glyph_infos (b, NULL);
2650617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert_cmpint (hb_buffer_get_length (b), ==, 10);
2661e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  for (i = 0; i < 5; i++)
2671e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
2681e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  for (i = 5; i < 10; i++)
2691e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod    g_assert_cmphex (glyphs[i].codepoint, ==, 0);
2701e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  /* shrink */
2710617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_set_length (b, 3));
2720617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  glyphs = hb_buffer_get_glyph_infos (b, NULL);
2730617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert_cmpint (hb_buffer_get_length (b), ==, 3);
2741e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  for (i = 0; i < 3; i++)
2751e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
2761e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
2771e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
2780617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_allocation_successful (b));
27915c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbod
28015c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbod
2811e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  /* test reset clears content */
2821e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
2830617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reset (b);
2840617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
285d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod}
286d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
287d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbodstatic void
28815c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbodtest_buffer_positions (fixture_t *fixture, gconstpointer user_data)
289d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod{
2900617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_t *b = fixture->buffer;
2911e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  unsigned int i, len, len2;
292d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  hb_glyph_position_t *positions;
293d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
294d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  /* Without shaping, positions should all be zero */
2950617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  len = hb_buffer_get_length (b);
296a18280a8ce9128fc9d75f8a367ae8ce0886a9599Behdad Esfahbod  hb_buffer_get_glyph_positions (b, NULL); /* test NULL */
2970617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  positions = hb_buffer_get_glyph_positions (b, &len2);
2981e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  g_assert_cmpint (len, ==, len2);
299d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  for (i = 0; i < len; i++) {
300d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    g_assert_cmpint (0, ==, positions[i].x_advance);
301d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    g_assert_cmpint (0, ==, positions[i].y_advance);
302d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    g_assert_cmpint (0, ==, positions[i].x_offset);
303d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    g_assert_cmpint (0, ==, positions[i].y_offset);
304d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod    g_assert_cmpint (0, ==, positions[i].var.i32);
305d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  }
3061e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod
3071e5527e2d60ed3b4a5adf62b258415ec3aef41fbBehdad Esfahbod  /* test reset clears content */
3080617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reset (b);
3090617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
310d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod}
311d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
31215c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbodstatic void
31315c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbodtest_buffer_allocation (fixture_t *fixture, gconstpointer user_data)
31415c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbod{
3150617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_t *b = fixture->buffer;
3160617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod
3170617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
31815c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbod
3190617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_pre_allocate (b, 100));
3200617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
3210617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_allocation_successful (b));
32215c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbod
32315c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbod  /* lets try a huge allocation, make sure it fails */
3240617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (!hb_buffer_pre_allocate (b, (unsigned int) -1));
3250617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
3260617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (!hb_buffer_allocation_successful (b));
3273264042873fd639f3ef8ff0acfad777a0a9f3355Behdad Esfahbod
3283264042873fd639f3ef8ff0acfad777a0a9f3355Behdad Esfahbod  /* small one again */
3290617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_pre_allocate (b, 50));
3300617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
3310617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (!hb_buffer_allocation_successful (b));
3323264042873fd639f3ef8ff0acfad777a0a9f3355Behdad Esfahbod
3330617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reset (b);
3340617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_allocation_successful (b));
3353264042873fd639f3ef8ff0acfad777a0a9f3355Behdad Esfahbod
3363264042873fd639f3ef8ff0acfad777a0a9f3355Behdad Esfahbod  /* all allocation and size  */
3370617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (!hb_buffer_pre_allocate (b, ((unsigned int) -1) / 20 + 1));
3380617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (!hb_buffer_allocation_successful (b));
3393264042873fd639f3ef8ff0acfad777a0a9f3355Behdad Esfahbod
3400617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reset (b);
3410617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_allocation_successful (b));
3423264042873fd639f3ef8ff0acfad777a0a9f3355Behdad Esfahbod
3433264042873fd639f3ef8ff0acfad777a0a9f3355Behdad Esfahbod  /* technically, this one can actually pass on 64bit machines, but
3441d39d6e42b3d7628512d675a84a831a0f58624ebBehdad Esfahbod   * I'm doubtful that any malloc allows 4GB allocations at a time.
3451d39d6e42b3d7628512d675a84a831a0f58624ebBehdad Esfahbod   * But let's only enable it on a 32-bit machine. */
3461d39d6e42b3d7628512d675a84a831a0f58624ebBehdad Esfahbod  if (sizeof (long) == 4) {
3470617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod    g_assert (!hb_buffer_pre_allocate (b, ((unsigned int) -1) / 20 - 1));
3480617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod    g_assert (!hb_buffer_allocation_successful (b));
3491d39d6e42b3d7628512d675a84a831a0f58624ebBehdad Esfahbod  }
3503264042873fd639f3ef8ff0acfad777a0a9f3355Behdad Esfahbod
3510617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  hb_buffer_reset (b);
3520617b1558234673d3924f37541be01b04d36f05aBehdad Esfahbod  g_assert (hb_buffer_allocation_successful (b));
35315c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbod}
35415c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbod
355243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
356243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbodtypedef struct {
357243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  const char utf8[8];
358243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  const uint32_t codepoints[8];
359c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod} utf8_conversion_test_t;
360243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
361243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod/* note: we skip the first and last byte when adding to buffer */
362c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbodstatic const utf8_conversion_test_t utf8_conversion_tests[] = {
363243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  {"a\303\207", {-1}},
364243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  {"a\303\207b", {0xC7}},
365243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  {"ab\303cd", {'b', -1, 'c'}},
366243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  {"ab\303\302\301cd", {'b', -1, -1, -1, 'c'}}
367243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod};
368243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
369dfec67f958482e5c3bb01e06b08694cd4ded6f66Behdad Esfahbodstatic void
370c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbodtest_buffer_utf8_conversion (void)
371dfec67f958482e5c3bb01e06b08694cd4ded6f66Behdad Esfahbod{
372dfec67f958482e5c3bb01e06b08694cd4ded6f66Behdad Esfahbod  hb_buffer_t *b;
373dfec67f958482e5c3bb01e06b08694cd4ded6f66Behdad Esfahbod  hb_glyph_info_t *glyphs;
374c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  unsigned int bytes, chars, i, j, len;
375dfec67f958482e5c3bb01e06b08694cd4ded6f66Behdad Esfahbod
376e6c09cdf43201ff1b7f38e411ae1f9977e4f9271Behdad Esfahbod  b = hb_buffer_create ();
377976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod  hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -1);
378dfec67f958482e5c3bb01e06b08694cd4ded6f66Behdad Esfahbod
379c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  for (i = 0; i < G_N_ELEMENTS (utf8_conversion_tests); i++)
380c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  {
381c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    const utf8_conversion_test_t *test = &utf8_conversion_tests[i];
382c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    char *escaped;
383c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod
384c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    escaped = g_strescape (test->utf8, NULL);
385c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    g_test_message ("UTF-8 test #%d: %s", i, escaped);
386c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    g_free (escaped);
387c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod
388c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    bytes = strlen (test->utf8);
389c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    for (chars = 0; test->codepoints[chars]; chars++)
390c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod      ;
391c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod
392976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod    hb_buffer_clear_contents (b);
393c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    hb_buffer_add_utf8 (b, test->utf8, bytes,  1, bytes - 2);
394c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod
395c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    glyphs = hb_buffer_get_glyph_infos (b, &len);
396c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    g_assert_cmpint (len, ==, chars);
397c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    for (j = 0; j < chars; j++)
398c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod      g_assert_cmphex (glyphs[j].codepoint, ==, test->codepoints[j]);
399c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  }
400dfec67f958482e5c3bb01e06b08694cd4ded6f66Behdad Esfahbod
401dfec67f958482e5c3bb01e06b08694cd4ded6f66Behdad Esfahbod  hb_buffer_destroy (b);
402dfec67f958482e5c3bb01e06b08694cd4ded6f66Behdad Esfahbod}
403dfec67f958482e5c3bb01e06b08694cd4ded6f66Behdad Esfahbod
40415c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbod
405243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
406243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod/* Following test table is adapted from glib/glib/tests/utf8-validate.c
407243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod * with relicensing permission from Matthias Clasen. */
408243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
409243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbodtypedef struct {
410c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  const char *utf8;
411243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  int max_len;
412243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  unsigned int offset;
413243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  gboolean valid;
414243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod} utf8_validity_test_t;
415243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
416243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbodstatic const utf8_validity_test_t utf8_validity_tests[] = {
417243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* some tests to check max_len handling */
418243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* length 1 */
419243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "abcde", -1, 5, TRUE },
420243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "abcde", 3, 3, TRUE },
421243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "abcde", 5, 5, TRUE },
422243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* length 2 */
423243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc2\xa9\xc2\xa9\xc2\xa9", -1, 6, TRUE },
424243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc2\xa9\xc2\xa9\xc2\xa9",  1, 0, FALSE },
425243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc2\xa9\xc2\xa9\xc2\xa9",  2, 2, TRUE },
426243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc2\xa9\xc2\xa9\xc2\xa9",  3, 2, FALSE },
427243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc2\xa9\xc2\xa9\xc2\xa9",  4, 4, TRUE },
428243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc2\xa9\xc2\xa9\xc2\xa9",  5, 4, FALSE },
429243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc2\xa9\xc2\xa9\xc2\xa9",  6, 6, TRUE },
430243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* length 3 */
431243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe2\x89\xa0\xe2\x89\xa0", -1, 6, TRUE },
432243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe2\x89\xa0\xe2\x89\xa0",  1, 0, FALSE },
433243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe2\x89\xa0\xe2\x89\xa0",  2, 0, FALSE },
434243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe2\x89\xa0\xe2\x89\xa0",  3, 3, TRUE },
435243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe2\x89\xa0\xe2\x89\xa0",  4, 3, FALSE },
436243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe2\x89\xa0\xe2\x89\xa0",  5, 3, FALSE },
437243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe2\x89\xa0\xe2\x89\xa0",  6, 6, TRUE },
438243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
439243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* examples from http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt */
440243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* greek 'kosme' */
441243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce\xb5", -1, 11, TRUE },
442243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* first sequence of each length */
443243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x00", -1, 0, TRUE },
444243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc2\x80", -1, 2, TRUE },
445243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe0\xa0\x80", -1, 3, TRUE },
446243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xf0\x90\x80\x80", -1, 4, TRUE },
447243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xf8\x88\x80\x80\x80", -1, 0, FALSE },
448243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xfc\x84\x80\x80\x80\x80", -1, 0, FALSE },
449243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* last sequence of each length */
450243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x7f", -1, 1, TRUE },
451243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xdf\xbf", -1, 2, TRUE },
452243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xef\xbf\xbf", -1, 0, TRUE },
453af2490c0959daa0fe7f32a8b3b3a3699c7fc5f48Behdad Esfahbod  { "\xf4\x8f\xbf\xbf", -1, 0, TRUE },
454af2490c0959daa0fe7f32a8b3b3a3699c7fc5f48Behdad Esfahbod  { "\xf4\x90\xbf\xbf", -1, 0, FALSE },
455af2490c0959daa0fe7f32a8b3b3a3699c7fc5f48Behdad Esfahbod  { "\xf7\xbf\xbf\xbf", -1, 0, FALSE },
456243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xfb\xbf\xbf\xbf\xbf", -1, 0, FALSE },
457243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xfd\xbf\xbf\xbf\xbf\xbf", -1, 0, FALSE },
458243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* other boundary conditions */
459243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xed\x9f\xbf", -1, 3, TRUE },
460af2490c0959daa0fe7f32a8b3b3a3699c7fc5f48Behdad Esfahbod  { "\xed\xa0\x80", -1, 0, FALSE },
461af2490c0959daa0fe7f32a8b3b3a3699c7fc5f48Behdad Esfahbod  { "\xed\xbf\xbf", -1, 0, FALSE },
462243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xee\x80\x80", -1, 3, TRUE },
463243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xef\xbf\xbd", -1, 3, TRUE },
464243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xf4\x8f\xbf\xbf", -1, 0, TRUE },
465243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* malformed sequences */
466243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* continuation bytes */
467243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x80", -1, 0, FALSE },
468243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xbf", -1, 0, FALSE },
469243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x80\xbf", -1, 0, FALSE },
470243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x80\xbf\x80", -1, 0, FALSE },
471243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x80\xbf\x80\xbf", -1, 0, FALSE },
472243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x80\xbf\x80\xbf\x80", -1, 0, FALSE },
473243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x80\xbf\x80\xbf\x80\xbf", -1, 0, FALSE },
474243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x80\xbf\x80\xbf\x80\xbf\x80", -1, 0, FALSE },
475243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
476243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* all possible continuation byte */
477243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x80", -1, 0, FALSE },
478243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x81", -1, 0, FALSE },
479243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x82", -1, 0, FALSE },
480243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x83", -1, 0, FALSE },
481243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x84", -1, 0, FALSE },
482243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x85", -1, 0, FALSE },
483243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x86", -1, 0, FALSE },
484243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x87", -1, 0, FALSE },
485243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x88", -1, 0, FALSE },
486243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x89", -1, 0, FALSE },
487243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x8a", -1, 0, FALSE },
488243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x8b", -1, 0, FALSE },
489243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x8c", -1, 0, FALSE },
490243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x8d", -1, 0, FALSE },
491243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x8e", -1, 0, FALSE },
492243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x8f", -1, 0, FALSE },
493243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x90", -1, 0, FALSE },
494243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x91", -1, 0, FALSE },
495243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x92", -1, 0, FALSE },
496243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x93", -1, 0, FALSE },
497243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x94", -1, 0, FALSE },
498243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x95", -1, 0, FALSE },
499243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x96", -1, 0, FALSE },
500243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x97", -1, 0, FALSE },
501243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x98", -1, 0, FALSE },
502243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x99", -1, 0, FALSE },
503243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x9a", -1, 0, FALSE },
504243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x9b", -1, 0, FALSE },
505243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x9c", -1, 0, FALSE },
506243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x9d", -1, 0, FALSE },
507243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x9e", -1, 0, FALSE },
508243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x9f", -1, 0, FALSE },
509243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xa0", -1, 0, FALSE },
510243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xa1", -1, 0, FALSE },
511243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xa2", -1, 0, FALSE },
512243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xa3", -1, 0, FALSE },
513243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xa4", -1, 0, FALSE },
514243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xa5", -1, 0, FALSE },
515243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xa6", -1, 0, FALSE },
516243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xa7", -1, 0, FALSE },
517243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xa8", -1, 0, FALSE },
518243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xa9", -1, 0, FALSE },
519243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xaa", -1, 0, FALSE },
520243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xab", -1, 0, FALSE },
521243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xac", -1, 0, FALSE },
522243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xad", -1, 0, FALSE },
523243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xae", -1, 0, FALSE },
524243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xaf", -1, 0, FALSE },
525243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xb0", -1, 0, FALSE },
526243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xb1", -1, 0, FALSE },
527243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xb2", -1, 0, FALSE },
528243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xb3", -1, 0, FALSE },
529243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xb4", -1, 0, FALSE },
530243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xb5", -1, 0, FALSE },
531243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xb6", -1, 0, FALSE },
532243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xb7", -1, 0, FALSE },
533243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xb8", -1, 0, FALSE },
534243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xb9", -1, 0, FALSE },
535243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xba", -1, 0, FALSE },
536243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xbb", -1, 0, FALSE },
537243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xbc", -1, 0, FALSE },
538243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xbd", -1, 0, FALSE },
539243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xbe", -1, 0, FALSE },
540243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xbf", -1, 0, FALSE },
541243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* lone start characters */
542243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc0\x20", -1, 0, FALSE },
543243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc1\x20", -1, 0, FALSE },
544243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc2\x20", -1, 0, FALSE },
545243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc3\x20", -1, 0, FALSE },
546243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc4\x20", -1, 0, FALSE },
547243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc5\x20", -1, 0, FALSE },
548243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc6\x20", -1, 0, FALSE },
549243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc7\x20", -1, 0, FALSE },
550243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc8\x20", -1, 0, FALSE },
551243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xc9\x20", -1, 0, FALSE },
552243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xca\x20", -1, 0, FALSE },
553243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xcb\x20", -1, 0, FALSE },
554243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xcc\x20", -1, 0, FALSE },
555243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xcd\x20", -1, 0, FALSE },
556243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xce\x20", -1, 0, FALSE },
557243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xcf\x20", -1, 0, FALSE },
558243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xd0\x20", -1, 0, FALSE },
559243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xd1\x20", -1, 0, FALSE },
560243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xd2\x20", -1, 0, FALSE },
561243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xd3\x20", -1, 0, FALSE },
562243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xd4\x20", -1, 0, FALSE },
563243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xd5\x20", -1, 0, FALSE },
564243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xd6\x20", -1, 0, FALSE },
565243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xd7\x20", -1, 0, FALSE },
566243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xd8\x20", -1, 0, FALSE },
567243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xd9\x20", -1, 0, FALSE },
568243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xda\x20", -1, 0, FALSE },
569243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xdb\x20", -1, 0, FALSE },
570243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xdc\x20", -1, 0, FALSE },
571243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xdd\x20", -1, 0, FALSE },
572243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xde\x20", -1, 0, FALSE },
573243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xdf\x20", -1, 0, FALSE },
574243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe0\x20", -1, 0, FALSE },
575243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe1\x20", -1, 0, FALSE },
576243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe2\x20", -1, 0, FALSE },
577243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe3\x20", -1, 0, FALSE },
578243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe4\x20", -1, 0, FALSE },
579243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe5\x20", -1, 0, FALSE },
580243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe6\x20", -1, 0, FALSE },
581243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe7\x20", -1, 0, FALSE },
582243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe8\x20", -1, 0, FALSE },
583243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xe9\x20", -1, 0, FALSE },
584243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xea\x20", -1, 0, FALSE },
585243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xeb\x20", -1, 0, FALSE },
586243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xec\x20", -1, 0, FALSE },
587243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xed\x20", -1, 0, FALSE },
588243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xee\x20", -1, 0, FALSE },
589243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xef\x20", -1, 0, FALSE },
590243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xf0\x20", -1, 0, FALSE },
591243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xf1\x20", -1, 0, FALSE },
592243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xf2\x20", -1, 0, FALSE },
593243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xf3\x20", -1, 0, FALSE },
594243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xf4\x20", -1, 0, FALSE },
595243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xf5\x20", -1, 0, FALSE },
596243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xf6\x20", -1, 0, FALSE },
597243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xf7\x20", -1, 0, FALSE },
598243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xf8\x20", -1, 0, FALSE },
599243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xf9\x20", -1, 0, FALSE },
600243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xfa\x20", -1, 0, FALSE },
601243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xfb\x20", -1, 0, FALSE },
602243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xfc\x20", -1, 0, FALSE },
603243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\xfd\x20", -1, 0, FALSE },
604243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* missing continuation bytes */
605243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xc0", -1, 1, FALSE },
606243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xe0\x80", -1, 1, FALSE },
607243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xf0\x80\x80", -1, 1, FALSE },
608243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xf8\x80\x80\x80", -1, 1, FALSE },
609243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xfc\x80\x80\x80\x80", -1, 1, FALSE },
610243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xdf", -1, 1, FALSE },
611243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xef\xbf", -1, 1, FALSE },
612243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xf7\xbf\xbf", -1, 1, FALSE },
613243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xfb\xbf\xbf\xbf", -1, 1, FALSE },
614243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xfd\xbf\xbf\xbf\xbf", -1, 1, FALSE },
615243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* impossible bytes */
616243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xfe\x20", -1, 1, FALSE },
617243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xff\x20", -1, 1, FALSE },
618243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* overlong sequences */
619243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xc0\xaf\x20", -1, 1, FALSE },
620243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xe0\x80\xaf\x20", -1, 1, FALSE },
621243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xf0\x80\x80\xaf\x20", -1, 1, FALSE },
622243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xf8\x80\x80\x80\xaf\x20", -1, 1, FALSE },
623243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xfc\x80\x80\x80\x80\xaf\x20", -1, 1, FALSE },
624243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xc1\xbf\x20", -1, 1, FALSE },
625243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xe0\x9f\xbf\x20", -1, 1, FALSE },
626243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xf0\x8f\xbf\xbf\x20", -1, 1, FALSE },
627243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xf8\x87\xbf\xbf\xbf\x20", -1, 1, FALSE },
628243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xfc\x83\xbf\xbf\xbf\xbf\x20", -1, 1, FALSE },
629243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xc0\x80\x20", -1, 1, FALSE },
630243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xe0\x80\x80\x20", -1, 1, FALSE },
631243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xf0\x80\x80\x80\x20", -1, 1, FALSE },
632243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xf8\x80\x80\x80\x80\x20", -1, 1, FALSE },
633243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xfc\x80\x80\x80\x80\x80\x20", -1, 1, FALSE },
634243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  /* illegal code positions */
635243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xa0\x80\x20", -1, 1, FALSE },
636243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xad\xbf\x20", -1, 1, FALSE },
637243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xae\x80\x20", -1, 1, FALSE },
638243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xaf\xbf\x20", -1, 1, FALSE },
639243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xb0\x80\x20", -1, 1, FALSE },
640243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xbe\x80\x20", -1, 1, FALSE },
641243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xbf\xbf\x20", -1, 1, FALSE },
642243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xa0\x80\xed\xb0\x80\x20", -1, 1, FALSE },
643243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xa0\x80\xed\xbf\xbf\x20", -1, 1, FALSE },
644243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xad\xbf\xed\xb0\x80\x20", -1, 1, FALSE },
645243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xad\xbf\xed\xbf\xbf\x20", -1, 1, FALSE },
646243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xae\x80\xed\xb0\x80\x20", -1, 1, FALSE },
647243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xae\x80\xed\xbf\xbf\x20", -1, 1, FALSE },
648243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xaf\xbf\xed\xb0\x80\x20", -1, 1, FALSE },
649243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xed\xaf\xbf\xed\xbf\xbf\x20", -1, 1, FALSE },
650af2490c0959daa0fe7f32a8b3b3a3699c7fc5f48Behdad Esfahbod#if 0 /* We don't consider U+FFFE / U+FFFF and similar invalid. */
651243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xef\xbf\xbe\x20", -1, 1, FALSE },
652243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "\x20\xef\xbf\xbf\x20", -1, 1, FALSE },
653243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod#endif
654243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  { "", -1, 0, TRUE }
655243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod};
656243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
657243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbodstatic void
658c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbodtest_buffer_utf8_validity (void)
659243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod{
660243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  hb_buffer_t *b;
661c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  unsigned int i;
662243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
663e6c09cdf43201ff1b7f38e411ae1f9977e4f9271Behdad Esfahbod  b = hb_buffer_create ();
664976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod  hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -1);
665243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
666c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  for (i = 0; i < G_N_ELEMENTS (utf8_validity_tests); i++)
667c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  {
668c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    const utf8_validity_test_t *test = &utf8_validity_tests[i];
669c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    unsigned int text_bytes, segment_bytes, j, len;
670c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    hb_glyph_info_t *glyphs;
671c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    char *escaped;
672c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod
673c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    escaped = g_strescape (test->utf8, NULL);
674c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    g_test_message ("UTF-8 test #%d: %s", i, escaped);
675c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    g_free (escaped);
676c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod
677c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    text_bytes = strlen (test->utf8);
678c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    if (test->max_len == -1)
679c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod      segment_bytes = text_bytes;
680c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    else
681c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod      segment_bytes = test->max_len;
682c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod
683976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod    hb_buffer_clear_contents (b);
684c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    hb_buffer_add_utf8 (b, test->utf8, text_bytes,  0, segment_bytes);
685c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod
686c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    glyphs = hb_buffer_get_glyph_infos (b, &len);
687c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    for (j = 0; j < len; j++)
688c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod      if (glyphs[j].codepoint == (hb_codepoint_t) -1)
689c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod	break;
690c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod
691c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    g_assert (test->valid ? j == len : j < len);
692c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    if (!test->valid)
693c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod      g_assert (glyphs[j].cluster == test->offset);
694c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  }
695243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
696243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod  hb_buffer_destroy (b);
697243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod}
698243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
699243673d601588a6f704ceafbff5dd5cdf66c47b7Behdad Esfahbod
70013db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbodtypedef struct {
70113db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod  const uint16_t utf16[8];
70213db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod  const uint32_t codepoints[8];
703c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod} utf16_conversion_test_t;
70413db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod
70513db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod/* note: we skip the first and last item from utf16 when adding to buffer */
706c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbodstatic const utf16_conversion_test_t utf16_conversion_tests[] = {
70713db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod  {{0x41, 0x004D, 0x0430, 0x4E8C, 0xD800, 0xDF02, 0x61} , {0x004D, 0x0430, 0x4E8C, 0x10302}},
70813db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod  {{0x41, 0xD800, 0xDF02, 0x61}, {0x10302}},
70913db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod  {{0x41, 0xD800, 0xDF02}, {-1}},
71013db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod  {{0x41, 0x61, 0xD800, 0xDF02}, {0x61, -1}},
71113db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod  {{0x41, 0xD800, 0x61, 0xDF02}, {-1, 0x61}},
71224b2ba9dfa7c35769cd843a07079ef88fa594bf8Behdad Esfahbod  {{0x41, 0xDF00, 0x61}, {-1}},
713a4446b10bfe0a9e7236bf941fa69a96697939e11Behdad Esfahbod  {{0x41, 0x61}, {0}}
71413db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod};
71513db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod
71613db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbodstatic void
717c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbodtest_buffer_utf16_conversion (void)
71813db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod{
71913db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod  hb_buffer_t *b;
720c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  unsigned int i;
72113db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod
722e6c09cdf43201ff1b7f38e411ae1f9977e4f9271Behdad Esfahbod  b = hb_buffer_create ();
723976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod  hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -1);
72413db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod
725c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  for (i = 0; i < G_N_ELEMENTS (utf16_conversion_tests); i++)
726c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  {
727c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    const utf16_conversion_test_t *test = &utf16_conversion_tests[i];
728c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    unsigned int u_len, chars, j, len;
729c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    hb_glyph_info_t *glyphs;
730c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod
731c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    g_test_message ("UTF-16 test #%d", i);
732c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod
733c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    for (u_len = 0; test->utf16[u_len]; u_len++)
734c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod      ;
735c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    for (chars = 0; test->codepoints[chars]; chars++)
736c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod      ;
737c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod
738976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod    hb_buffer_clear_contents (b);
739c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    hb_buffer_add_utf16 (b, test->utf16, u_len,  1, u_len - 2);
740c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod
741c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    glyphs = hb_buffer_get_glyph_infos (b, &len);
742c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    g_assert_cmpint (len, ==, chars);
743c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod    for (j = 0; j < chars; j++)
744c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod      g_assert_cmphex (glyphs[j].codepoint, ==, test->codepoints[j]);
745c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  }
74613db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod
74713db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod  hb_buffer_destroy (b);
74813db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod}
74913db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod
750e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod
751e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbodtypedef struct {
752e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod  const uint32_t utf32[8];
753e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod  const uint32_t codepoints[8];
754e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod} utf32_conversion_test_t;
755e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod
756e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod/* note: we skip the first and last item from utf32 when adding to buffer */
757e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbodstatic const utf32_conversion_test_t utf32_conversion_tests[] = {
758976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod  {{0x41, 0x004D, 0x0430, 0x4E8C, 0xD800, 0xDF02, 0x61} , {0x004D, 0x0430, 0x4E8C, -3, -3}},
759e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod  {{0x41, 0x004D, 0x0430, 0x4E8C, 0x10302, 0x61} , {0x004D, 0x0430, 0x4E8C, 0x10302}},
760976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod  {{0x41, 0xD800, 0xDF02, 0x61}, {-3, -3}},
761976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod  {{0x41, 0xD800, 0xDF02}, {-3}},
762976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod  {{0x41, 0x61, 0xD800, 0xDF02}, {0x61, -3}},
763976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod  {{0x41, 0xD800, 0x61, 0xDF02}, {-3, 0x61}},
764976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod  {{0x41, 0xDF00, 0x61}, {-3}},
765e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod  {{0x41, 0x10FFFF, 0x61}, {0x10FFFF}},
766976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod  {{0x41, 0x110000, 0x61}, {-3}},
767e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod  {{0x41, 0x61}, {0}}
768e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod};
769e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod
770e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbodstatic void
771e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbodtest_buffer_utf32_conversion (void)
772e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod{
773e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod  hb_buffer_t *b;
774e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod  unsigned int i;
775e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod
776e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod  b = hb_buffer_create ();
777976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod  hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -3);
778e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod
779e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod  for (i = 0; i < G_N_ELEMENTS (utf32_conversion_tests); i++)
780e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod  {
781e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod    const utf32_conversion_test_t *test = &utf32_conversion_tests[i];
782e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod    unsigned int u_len, chars, j, len;
783e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod    hb_glyph_info_t *glyphs;
784e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod
785e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod    g_test_message ("UTF-32 test #%d", i);
786e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod
787e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod    for (u_len = 0; test->utf32[u_len]; u_len++)
788e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod      ;
789e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod    for (chars = 0; test->codepoints[chars]; chars++)
790e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod      ;
791e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod
792976c8f455221eb599d1c446eafd88d51d7d2aa65Behdad Esfahbod    hb_buffer_clear_contents (b);
793e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod    hb_buffer_add_utf32 (b, test->utf32, u_len,  1, u_len - 2);
794e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod
795e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod    glyphs = hb_buffer_get_glyph_infos (b, &len);
796e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod    g_assert_cmpint (len, ==, chars);
797e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod    for (j = 0; j < chars; j++)
798e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod      g_assert_cmphex (glyphs[j].codepoint, ==, test->codepoints[j]);
799e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod  }
800e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod
801e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod  hb_buffer_destroy (b);
802e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod}
803e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod
804e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod
805b8477e1da2785708f3232f8f2577f602a5d320d1Behdad Esfahbodstatic void
80692de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbodtest_empty (hb_buffer_t *b)
80792de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod{
80892de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
80992de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  g_assert (!hb_buffer_get_glyph_infos (b, NULL));
81092de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  g_assert (!hb_buffer_get_glyph_positions (b, NULL));
81192de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod}
81292de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
81392de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbodstatic void
814b8477e1da2785708f3232f8f2577f602a5d320d1Behdad Esfahbodtest_buffer_empty (void)
815b8477e1da2785708f3232f8f2577f602a5d320d1Behdad Esfahbod{
81692de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  hb_buffer_t *b = hb_buffer_get_empty ();
81792de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
818b8477e1da2785708f3232f8f2577f602a5d320d1Behdad Esfahbod  g_assert (hb_buffer_get_empty ());
81992de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  g_assert (hb_buffer_get_empty () == b);
82092de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
82192de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  g_assert (!hb_buffer_allocation_successful (b));
82292de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
82392de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  test_empty (b);
82492de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
82592de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  hb_buffer_add_utf32 (b, utf32, G_N_ELEMENTS (utf32), 1, G_N_ELEMENTS (utf32) - 2);
82692de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
82792de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  test_empty (b);
82892de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
82992de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  hb_buffer_reverse (b);
83092de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  hb_buffer_reverse_clusters (b);
83192de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
83292de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  g_assert (!hb_buffer_set_length (b, 10));
83392de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
83492de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  test_empty (b);
83592de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
83692de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  g_assert (hb_buffer_set_length (b, 0));
83792de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
83892de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  test_empty (b);
83992de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
84092de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  g_assert (!hb_buffer_allocation_successful (b));
84192de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
84292de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  hb_buffer_reset (b);
84392de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
84492de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  test_empty (b);
84592de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod
84692de53ea450eaee077eb1730e6d7a487b20ac721Behdad Esfahbod  g_assert (!hb_buffer_allocation_successful (b));
847b8477e1da2785708f3232f8f2577f602a5d320d1Behdad Esfahbod}
84813db3d40bfc09c68f9761a71435b1840b9d34099Behdad Esfahbod
849d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbodint
850d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbodmain (int argc, char **argv)
851d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod{
852dfec67f958482e5c3bb01e06b08694cd4ded6f66Behdad Esfahbod  unsigned int i;
853d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
854aafe395ab550d3ba2fabc69155662e87d45e74a8Behdad Esfahbod  hb_test_init (&argc, &argv);
855aafe395ab550d3ba2fabc69155662e87d45e74a8Behdad Esfahbod
856aafe395ab550d3ba2fabc69155662e87d45e74a8Behdad Esfahbod  for (i = 0; i < BUFFER_NUM_TYPES; i++)
857aafe395ab550d3ba2fabc69155662e87d45e74a8Behdad Esfahbod  {
858aafe395ab550d3ba2fabc69155662e87d45e74a8Behdad Esfahbod    const void *buffer_type = GINT_TO_POINTER (i);
859aafe395ab550d3ba2fabc69155662e87d45e74a8Behdad Esfahbod    const char *buffer_name = buffer_names[i];
860aafe395ab550d3ba2fabc69155662e87d45e74a8Behdad Esfahbod
861aafe395ab550d3ba2fabc69155662e87d45e74a8Behdad Esfahbod    hb_test_add_fixture_flavor (fixture, buffer_type, buffer_name, test_buffer_properties);
862aafe395ab550d3ba2fabc69155662e87d45e74a8Behdad Esfahbod    hb_test_add_fixture_flavor (fixture, buffer_type, buffer_name, test_buffer_contents);
863aafe395ab550d3ba2fabc69155662e87d45e74a8Behdad Esfahbod    hb_test_add_fixture_flavor (fixture, buffer_type, buffer_name, test_buffer_positions);
864d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod  }
865d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
866aafe395ab550d3ba2fabc69155662e87d45e74a8Behdad Esfahbod  hb_test_add_fixture (fixture, GINT_TO_POINTER (BUFFER_EMPTY), test_buffer_allocation);
86715c57e04bf05026ef424f8ae912d2f379301bf93Behdad Esfahbod
868c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  hb_test_add (test_buffer_utf8_conversion);
869c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  hb_test_add (test_buffer_utf8_validity);
870c763aa42b46eaee95359806cab56fa632ff3ad58Behdad Esfahbod  hb_test_add (test_buffer_utf16_conversion);
871e634fed4285ce440d277345727ed01757df6d779Behdad Esfahbod  hb_test_add (test_buffer_utf32_conversion);
872b8477e1da2785708f3232f8f2577f602a5d320d1Behdad Esfahbod  hb_test_add (test_buffer_empty);
873d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod
874aafe395ab550d3ba2fabc69155662e87d45e74a8Behdad Esfahbod  return hb_test_run();
875d0f53fdbead15d9003b521b8ed47d02fd29a4c64Behdad Esfahbod}
876