1/*
2 * Copyright © 2011  Google, Inc.
3 *
4 *  This is part of HarfBuzz, a text shaping library.
5 *
6 * Permission is hereby granted, without written agreement and without
7 * license or royalty fees, to use, copy, modify, and distribute this
8 * software and its documentation for any purpose, provided that the
9 * above copyright notice and the following two paragraphs appear in
10 * all copies of this software.
11 *
12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16 * DAMAGE.
17 *
18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23 *
24 * Google Author(s): Behdad Esfahbod
25 */
26
27#include "hb-test.h"
28
29#include <hb-ot.h>
30
31/* Unit tests for hb-ot-tag.h */
32
33
34/* https://www.microsoft.com/typography/otspec/scripttags.htm */
35
36static void
37test_simple_tags (const char *s, hb_script_t script)
38{
39  hb_script_t tag;
40  hb_script_t t1, t2;
41
42  g_test_message ("Testing script %c%c%c%c: tag %s", HB_UNTAG (hb_script_to_iso15924_tag (script)), s);
43  tag = hb_tag_from_string (s, -1);
44
45  hb_ot_tags_from_script (script, &t1, &t2);
46
47  g_assert_cmphex (t1, ==, tag);
48  g_assert_cmphex (t2, ==, HB_OT_TAG_DEFAULT_SCRIPT);
49
50  g_assert_cmphex (hb_ot_tag_to_script (tag), ==, script);
51}
52
53static void
54test_indic_tags (const char *s1, const char *s2, hb_script_t script)
55{
56  hb_script_t tag1, tag2;
57  hb_script_t t1, t2;
58
59  g_test_message ("Testing script %c%c%c%c: new tag %s, old tag %s", HB_UNTAG (hb_script_to_iso15924_tag (script)), s1, s2);
60  tag1 = hb_tag_from_string (s1, -1);
61  tag2 = hb_tag_from_string (s2, -1);
62
63  hb_ot_tags_from_script (script, &t1, &t2);
64
65  g_assert_cmphex (t1, ==, tag1);
66  g_assert_cmphex (t2, ==, tag2);
67
68  g_assert_cmphex (hb_ot_tag_to_script (tag1), ==, script);
69  g_assert_cmphex (hb_ot_tag_to_script (tag2), ==, script);
70}
71
72static void
73test_ot_tag_script_degenerate (void)
74{
75  hb_script_t t1, t2;
76
77  g_assert_cmphex (HB_TAG_CHAR4 ("DFLT"), ==, HB_OT_TAG_DEFAULT_SCRIPT);
78
79  /* HIRAGANA and KATAKANA both map to 'kana' */
80  test_simple_tags ("kana", HB_SCRIPT_KATAKANA);
81  hb_ot_tags_from_script (HB_SCRIPT_HIRAGANA, &t1, &t2);
82  g_assert_cmphex (t1, ==, HB_TAG_CHAR4 ("kana"));
83  g_assert_cmphex (t2, ==, HB_OT_TAG_DEFAULT_SCRIPT);
84
85  test_simple_tags ("DFLT", HB_SCRIPT_INVALID);
86
87  /* Spaces are replaced */
88  g_assert_cmphex (hb_ot_tag_to_script (HB_TAG_CHAR4 ("be  ")), ==, hb_script_from_string ("Beee", -1));
89}
90
91static void
92test_ot_tag_script_simple (void)
93{
94  /* Arbitrary non-existent script */
95  test_simple_tags ("wwyz", hb_script_from_string ("wWyZ", -1));
96
97  /* These we don't really care about */
98  test_simple_tags ("zyyy", HB_SCRIPT_COMMON);
99  test_simple_tags ("zinh", HB_SCRIPT_INHERITED);
100  test_simple_tags ("zzzz", HB_SCRIPT_UNKNOWN);
101
102  test_simple_tags ("arab", HB_SCRIPT_ARABIC);
103  test_simple_tags ("copt", HB_SCRIPT_COPTIC);
104  test_simple_tags ("kana", HB_SCRIPT_KATAKANA);
105  test_simple_tags ("latn", HB_SCRIPT_LATIN);
106
107  /* These are trickier since their OT script tags have space. */
108  test_simple_tags ("lao ", HB_SCRIPT_LAO);
109  test_simple_tags ("yi  ", HB_SCRIPT_YI);
110  /* Unicode-5.0 additions */
111  test_simple_tags ("nko ", HB_SCRIPT_NKO);
112  /* Unicode-5.1 additions */
113  test_simple_tags ("vai ", HB_SCRIPT_VAI);
114
115  /* https://www.microsoft.com/typography/otspec160/scripttagsProposed.htm */
116
117  /* Unicode-5.2 additions */
118  test_simple_tags ("mtei", HB_SCRIPT_MEETEI_MAYEK);
119  /* Unicode-6.0 additions */
120  test_simple_tags ("mand", HB_SCRIPT_MANDAIC);
121}
122
123static void
124test_ot_tag_script_indic (void)
125{
126  test_indic_tags ("bng2", "beng", HB_SCRIPT_BENGALI);
127  test_indic_tags ("dev2", "deva", HB_SCRIPT_DEVANAGARI);
128  test_indic_tags ("gjr2", "gujr", HB_SCRIPT_GUJARATI);
129  test_indic_tags ("gur2", "guru", HB_SCRIPT_GURMUKHI);
130  test_indic_tags ("knd2", "knda", HB_SCRIPT_KANNADA);
131  test_indic_tags ("mlm2", "mlym", HB_SCRIPT_MALAYALAM);
132  test_indic_tags ("ory2", "orya", HB_SCRIPT_ORIYA);
133  test_indic_tags ("tml2", "taml", HB_SCRIPT_TAMIL);
134  test_indic_tags ("tel2", "telu", HB_SCRIPT_TELUGU);
135  test_indic_tags ("mym2", "mymr", HB_SCRIPT_MYANMAR);
136}
137
138
139
140/* https://www.microsoft.com/typography/otspec/languagetags.htm */
141
142static void
143test_language_two_way (const char *tag_s, const char *lang_s)
144{
145  hb_language_t lang = hb_language_from_string (lang_s, -1);
146  hb_tag_t tag = hb_tag_from_string (tag_s, -1);
147
148  g_test_message ("Testing language %s <-> tag %s", lang_s, tag_s);
149
150  g_assert_cmphex (tag, ==, hb_ot_tag_from_language (lang));
151  g_assert (lang == hb_ot_tag_to_language (tag));
152}
153
154static void
155test_tag_from_language (const char *tag_s, const char *lang_s)
156{
157  hb_language_t lang = hb_language_from_string (lang_s, -1);
158  hb_tag_t tag = hb_tag_from_string (tag_s, -1);
159
160  g_test_message ("Testing language %s -> tag %s", lang_s, tag_s);
161
162  g_assert_cmphex (tag, ==, hb_ot_tag_from_language (lang));
163}
164
165static void
166test_tag_to_language (const char *tag_s, const char *lang_s)
167{
168  hb_language_t lang = hb_language_from_string (lang_s, -1);
169  hb_tag_t tag = hb_tag_from_string (tag_s, -1);
170
171  g_test_message ("Testing tag %s -> language %s", tag_s, lang_s);
172
173  g_assert (lang == hb_ot_tag_to_language (tag));
174}
175
176static void
177test_ot_tag_language (void)
178{
179  g_assert_cmphex (HB_TAG_CHAR4 ("dflt"), ==, HB_OT_TAG_DEFAULT_LANGUAGE);
180  test_language_two_way ("dflt", NULL);
181
182  test_language_two_way ("ARA", "ar");
183
184  test_language_two_way ("AZE", "az");
185  test_tag_from_language ("AZE", "az-ir");
186  test_tag_from_language ("AZE", "az-az");
187
188  test_language_two_way ("ENG", "en");
189  test_tag_from_language ("ENG", "en_US");
190
191  test_language_two_way ("EVN", "eve");
192
193  test_language_two_way ("FAR", "fa");
194  test_tag_from_language ("FAR", "fa_IR");
195
196  test_language_two_way ("ZHH", "zh-hk"); /* Chinese (Hong Kong) */
197
198  test_tag_from_language ("ZHS", "zh-cn"); /* Chinese (China) */
199  test_tag_from_language ("ZHS", "zh-sg"); /* Chinese (Singapore) */
200  test_tag_from_language ("ZHT", "zh-mo"); /* Chinese (Macao) */
201  test_tag_from_language ("ZHT", "zh-tw"); /* Chinese (Taiwan) */
202
203  test_tag_from_language ("ZHS", "zh"); /* Chinese */
204  test_tag_from_language ("ZHS", "zh-xx");
205
206  test_tag_to_language ("ZHS", "zh-x-hbotzhs");
207  test_tag_to_language ("ZHT", "zh-x-hbotzht");
208  test_tag_to_language ("ZHP", "zh-x-hbotzhp");
209
210  test_language_two_way ("ABC", "x-hbotabc");
211  test_tag_from_language ("ABC", "asdf-asdf-wer-x-hbotabc-zxc");
212  test_tag_from_language ("ABC", "asdf-asdf-wer-x-hbotabc");
213  test_tag_from_language ("ABCD", "asdf-asdf-wer-x-hbotabcd");
214
215  test_tag_from_language ("dflt", "asdf-asdf-wer-x-hbot-zxc");
216
217  test_tag_from_language ("dflt", "xy");
218  test_tag_from_language ("XYZ", "xyz"); /* Unknown ISO 639-3 */
219  test_tag_from_language ("XYZ", "xyz-qw"); /* Unknown ISO 639-3 */
220
221  /* Test that x-hbot overrides the base language */
222  test_tag_from_language ("ABC", "fa-x-hbotabc-zxc");
223  test_tag_from_language ("ABC", "fa-ir-x-hbotabc-zxc");
224  test_tag_from_language ("ABC", "zh-x-hbotabc-zxc");
225  test_tag_from_language ("ABC", "zh-cn-x-hbotabc-zxc");
226  test_tag_from_language ("ABC", "zh-xy-x-hbotabc-zxc");
227  test_tag_from_language ("ABC", "xyz-xy-x-hbotabc-zxc");
228}
229
230int
231main (int argc, char **argv)
232{
233  hb_test_init (&argc, &argv);
234
235  hb_test_add (test_ot_tag_script_degenerate);
236  hb_test_add (test_ot_tag_script_simple);
237  hb_test_add (test_ot_tag_script_indic);
238
239  hb_test_add (test_ot_tag_language);
240
241  return hb_test_run();
242}
243