Home | History | Annotate | Download | only in api
      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 
     36 static void
     37 test_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 
     53 static void
     54 test_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 
     72 static void
     73 test_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 
     91 static void
     92 test_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 
    123 static void
    124 test_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 
    142 static void
    143 test_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 
    154 static void
    155 test_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 
    165 static void
    166 test_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 
    176 static void
    177 test_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 
    230 int
    231 main (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