1 /*
   2  * Copyright (C) 2012 Grigori Goronzy <greg@kinoho.net>
   3  *
   4  * Permission to use, copy, modify, and/or distribute this software for any
   5  * purpose with or without fee is hereby granted, provided that the above
   6  * copyright notice and this permission notice appear in all copies.
   7  *
   8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15  */
  16 
  17 #include "hb.hh"
  18 
  19 #include "hb-machinery.hh"
  20 
  21 #include "ucdn.h"
  22 
  23 static const hb_script_t ucdn_script_translate[] =
  24 {
  25     HB_SCRIPT_COMMON,
  26     HB_SCRIPT_LATIN,
  27     HB_SCRIPT_GREEK,
  28     HB_SCRIPT_CYRILLIC,
  29     HB_SCRIPT_ARMENIAN,
  30     HB_SCRIPT_HEBREW,
  31     HB_SCRIPT_ARABIC,
  32     HB_SCRIPT_SYRIAC,
  33     HB_SCRIPT_THAANA,
  34     HB_SCRIPT_DEVANAGARI,
  35     HB_SCRIPT_BENGALI,
  36     HB_SCRIPT_GURMUKHI,
  37     HB_SCRIPT_GUJARATI,
  38     HB_SCRIPT_ORIYA,
  39     HB_SCRIPT_TAMIL,
  40     HB_SCRIPT_TELUGU,
  41     HB_SCRIPT_KANNADA,
  42     HB_SCRIPT_MALAYALAM,
  43     HB_SCRIPT_SINHALA,
  44     HB_SCRIPT_THAI,
  45     HB_SCRIPT_LAO,
  46     HB_SCRIPT_TIBETAN,
  47     HB_SCRIPT_MYANMAR,
  48     HB_SCRIPT_GEORGIAN,
  49     HB_SCRIPT_HANGUL,
  50     HB_SCRIPT_ETHIOPIC,
  51     HB_SCRIPT_CHEROKEE,
  52     HB_SCRIPT_CANADIAN_SYLLABICS,
  53     HB_SCRIPT_OGHAM,
  54     HB_SCRIPT_RUNIC,
  55     HB_SCRIPT_KHMER,
  56     HB_SCRIPT_MONGOLIAN,
  57     HB_SCRIPT_HIRAGANA,
  58     HB_SCRIPT_KATAKANA,
  59     HB_SCRIPT_BOPOMOFO,
  60     HB_SCRIPT_HAN,
  61     HB_SCRIPT_YI,
  62     HB_SCRIPT_OLD_ITALIC,
  63     HB_SCRIPT_GOTHIC,
  64     HB_SCRIPT_DESERET,
  65     HB_SCRIPT_INHERITED,
  66     HB_SCRIPT_TAGALOG,
  67     HB_SCRIPT_HANUNOO,
  68     HB_SCRIPT_BUHID,
  69     HB_SCRIPT_TAGBANWA,
  70     HB_SCRIPT_LIMBU,
  71     HB_SCRIPT_TAI_LE,
  72     HB_SCRIPT_LINEAR_B,
  73     HB_SCRIPT_UGARITIC,
  74     HB_SCRIPT_SHAVIAN,
  75     HB_SCRIPT_OSMANYA,
  76     HB_SCRIPT_CYPRIOT,
  77     HB_SCRIPT_BRAILLE,
  78     HB_SCRIPT_BUGINESE,
  79     HB_SCRIPT_COPTIC,
  80     HB_SCRIPT_NEW_TAI_LUE,
  81     HB_SCRIPT_GLAGOLITIC,
  82     HB_SCRIPT_TIFINAGH,
  83     HB_SCRIPT_SYLOTI_NAGRI,
  84     HB_SCRIPT_OLD_PERSIAN,
  85     HB_SCRIPT_KHAROSHTHI,
  86     HB_SCRIPT_BALINESE,
  87     HB_SCRIPT_CUNEIFORM,
  88     HB_SCRIPT_PHOENICIAN,
  89     HB_SCRIPT_PHAGS_PA,
  90     HB_SCRIPT_NKO,
  91     HB_SCRIPT_SUNDANESE,
  92     HB_SCRIPT_LEPCHA,
  93     HB_SCRIPT_OL_CHIKI,
  94     HB_SCRIPT_VAI,
  95     HB_SCRIPT_SAURASHTRA,
  96     HB_SCRIPT_KAYAH_LI,
  97     HB_SCRIPT_REJANG,
  98     HB_SCRIPT_LYCIAN,
  99     HB_SCRIPT_CARIAN,
 100     HB_SCRIPT_LYDIAN,
 101     HB_SCRIPT_CHAM,
 102     HB_SCRIPT_TAI_THAM,
 103     HB_SCRIPT_TAI_VIET,
 104     HB_SCRIPT_AVESTAN,
 105     HB_SCRIPT_EGYPTIAN_HIEROGLYPHS,
 106     HB_SCRIPT_SAMARITAN,
 107     HB_SCRIPT_LISU,
 108     HB_SCRIPT_BAMUM,
 109     HB_SCRIPT_JAVANESE,
 110     HB_SCRIPT_MEETEI_MAYEK,
 111     HB_SCRIPT_IMPERIAL_ARAMAIC,
 112     HB_SCRIPT_OLD_SOUTH_ARABIAN,
 113     HB_SCRIPT_INSCRIPTIONAL_PARTHIAN,
 114     HB_SCRIPT_INSCRIPTIONAL_PAHLAVI,
 115     HB_SCRIPT_OLD_TURKIC,
 116     HB_SCRIPT_KAITHI,
 117     HB_SCRIPT_BATAK,
 118     HB_SCRIPT_BRAHMI,
 119     HB_SCRIPT_MANDAIC,
 120     HB_SCRIPT_CHAKMA,
 121     HB_SCRIPT_MEROITIC_CURSIVE,
 122     HB_SCRIPT_MEROITIC_HIEROGLYPHS,
 123     HB_SCRIPT_MIAO,
 124     HB_SCRIPT_SHARADA,
 125     HB_SCRIPT_SORA_SOMPENG,
 126     HB_SCRIPT_TAKRI,
 127     HB_SCRIPT_UNKNOWN,
 128     HB_SCRIPT_BASSA_VAH,
 129     HB_SCRIPT_CAUCASIAN_ALBANIAN,
 130     HB_SCRIPT_DUPLOYAN,
 131     HB_SCRIPT_ELBASAN,
 132     HB_SCRIPT_GRANTHA,
 133     HB_SCRIPT_KHOJKI,
 134     HB_SCRIPT_KHUDAWADI,
 135     HB_SCRIPT_LINEAR_A,
 136     HB_SCRIPT_MAHAJANI,
 137     HB_SCRIPT_MANICHAEAN,
 138     HB_SCRIPT_MENDE_KIKAKUI,
 139     HB_SCRIPT_MODI,
 140     HB_SCRIPT_MRO,
 141     HB_SCRIPT_NABATAEAN,
 142     HB_SCRIPT_OLD_NORTH_ARABIAN,
 143     HB_SCRIPT_OLD_PERMIC,
 144     HB_SCRIPT_PAHAWH_HMONG,
 145     HB_SCRIPT_PALMYRENE,
 146     HB_SCRIPT_PAU_CIN_HAU,
 147     HB_SCRIPT_PSALTER_PAHLAVI,
 148     HB_SCRIPT_SIDDHAM,
 149     HB_SCRIPT_TIRHUTA,
 150     HB_SCRIPT_WARANG_CITI,
 151     HB_SCRIPT_AHOM,
 152     HB_SCRIPT_ANATOLIAN_HIEROGLYPHS,
 153     HB_SCRIPT_HATRAN,
 154     HB_SCRIPT_MULTANI,
 155     HB_SCRIPT_OLD_HUNGARIAN,
 156     HB_SCRIPT_SIGNWRITING,
 157     HB_SCRIPT_ADLAM,
 158     HB_SCRIPT_BHAIKSUKI,
 159     HB_SCRIPT_MARCHEN,
 160     HB_SCRIPT_NEWA,
 161     HB_SCRIPT_OSAGE,
 162     HB_SCRIPT_TANGUT,
 163     HB_SCRIPT_MASARAM_GONDI,
 164     HB_SCRIPT_NUSHU,
 165     HB_SCRIPT_SOYOMBO,
 166     HB_SCRIPT_ZANABAZAR_SQUARE,
 167     HB_SCRIPT_DOGRA,
 168     HB_SCRIPT_GUNJALA_GONDI,
 169     HB_SCRIPT_HANIFI_ROHINGYA,
 170     HB_SCRIPT_MAKASAR,
 171     HB_SCRIPT_MEDEFAIDRIN,
 172     HB_SCRIPT_OLD_SOGDIAN,
 173     HB_SCRIPT_SOGDIAN,
 174 };
 175 
 176 static hb_unicode_combining_class_t
 177 hb_ucdn_combining_class(hb_unicode_funcs_t *ufuncs HB_UNUSED,
 178                         hb_codepoint_t unicode,
 179                         void *user_data HB_UNUSED)
 180 {
 181     return (hb_unicode_combining_class_t) ucdn_get_combining_class(unicode);
 182 }
 183 
 184 static hb_unicode_general_category_t
 185 hb_ucdn_general_category(hb_unicode_funcs_t *ufuncs HB_UNUSED,
 186                          hb_codepoint_t unicode,
 187                          void *user_data HB_UNUSED)
 188 {
 189     return (hb_unicode_general_category_t)ucdn_get_general_category(unicode);
 190 }
 191 
 192 static hb_codepoint_t
 193 hb_ucdn_mirroring(hb_unicode_funcs_t *ufuncs HB_UNUSED,
 194                   hb_codepoint_t unicode,
 195                   void *user_data HB_UNUSED)
 196 {
 197     return ucdn_mirror(unicode);
 198 }
 199 
 200 static hb_script_t
 201 hb_ucdn_script(hb_unicode_funcs_t *ufuncs HB_UNUSED,
 202                hb_codepoint_t unicode,
 203                void *user_data HB_UNUSED)
 204 {
 205     return ucdn_script_translate[ucdn_get_script(unicode)];
 206 }
 207 
 208 static hb_bool_t
 209 hb_ucdn_compose(hb_unicode_funcs_t *ufuncs HB_UNUSED,
 210                 hb_codepoint_t a, hb_codepoint_t b, hb_codepoint_t *ab,
 211                 void *user_data HB_UNUSED)
 212 {
 213     return ucdn_compose(ab, a, b);
 214 }
 215 
 216 static hb_bool_t
 217 hb_ucdn_decompose(hb_unicode_funcs_t *ufuncs HB_UNUSED,
 218                   hb_codepoint_t ab, hb_codepoint_t *a, hb_codepoint_t *b,
 219                   void *user_data HB_UNUSED)
 220 {
 221     return ucdn_decompose(ab, a, b);
 222 }
 223 
 224 
 225 #if HB_USE_ATEXIT
 226 static void free_static_ucdn_funcs ();
 227 #endif
 228 
 229 static struct hb_ucdn_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader_t<hb_ucdn_unicode_funcs_lazy_loader_t>
 230 {
 231   static hb_unicode_funcs_t *create ()
 232   {
 233     hb_unicode_funcs_t *funcs = hb_unicode_funcs_create (nullptr);
 234 
 235     hb_unicode_funcs_set_combining_class_func (funcs, hb_ucdn_combining_class, nullptr, nullptr);
 236     hb_unicode_funcs_set_general_category_func (funcs, hb_ucdn_general_category, nullptr, nullptr);
 237     hb_unicode_funcs_set_mirroring_func (funcs, hb_ucdn_mirroring, nullptr, nullptr);
 238     hb_unicode_funcs_set_script_func (funcs, hb_ucdn_script, nullptr, nullptr);
 239     hb_unicode_funcs_set_compose_func (funcs, hb_ucdn_compose, nullptr, nullptr);
 240     hb_unicode_funcs_set_decompose_func (funcs, hb_ucdn_decompose, nullptr, nullptr);
 241 
 242     hb_unicode_funcs_make_immutable (funcs);
 243 
 244 #if HB_USE_ATEXIT
 245     atexit (free_static_ucdn_funcs);
 246 #endif
 247 
 248     return funcs;
 249   }
 250 } static_ucdn_funcs;
 251 
 252 #if HB_USE_ATEXIT
 253 static
 254 void free_static_ucdn_funcs ()
 255 {
 256   static_ucdn_funcs.free_instance ();
 257 }
 258 #endif
 259 
 260 extern "C" HB_INTERNAL
 261 hb_unicode_funcs_t *
 262 hb_ucdn_get_unicode_funcs ();
 263 
 264 hb_unicode_funcs_t *
 265 hb_ucdn_get_unicode_funcs ()
 266 {
 267   return static_ucdn_funcs.get_unconst ();
 268 }