Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright  2009  Red Hat, Inc.
      3  * Copyright  2011  Codethink Limited
      4  * Copyright  2010,2011,2012  Google, Inc.
      5  *
      6  *  This is part of HarfBuzz, a text shaping library.
      7  *
      8  * Permission is hereby granted, without written agreement and without
      9  * license or royalty fees, to use, copy, modify, and distribute this
     10  * software and its documentation for any purpose, provided that the
     11  * above copyright notice and the following two paragraphs appear in
     12  * all copies of this software.
     13  *
     14  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
     15  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
     16  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
     17  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
     18  * DAMAGE.
     19  *
     20  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
     21  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
     22  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
     23  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
     24  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
     25  *
     26  * Red Hat Author(s): Behdad Esfahbod
     27  * Codethink Author(s): Ryan Lortie
     28  * Google Author(s): Behdad Esfahbod
     29  */
     30 
     31 #include "hb-private.hh"
     32 
     33 #include "hb-unicode-private.hh"
     34 
     35 
     36 
     37 /*
     38  * hb_unicode_funcs_t
     39  */
     40 
     41 static hb_unicode_combining_class_t
     42 hb_unicode_combining_class_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
     43 				hb_codepoint_t      unicode   HB_UNUSED,
     44 				void               *user_data HB_UNUSED)
     45 {
     46   return HB_UNICODE_COMBINING_CLASS_NOT_REORDERED;
     47 }
     48 
     49 static unsigned int
     50 hb_unicode_eastasian_width_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
     51 				hb_codepoint_t      unicode   HB_UNUSED,
     52 				void               *user_data HB_UNUSED)
     53 {
     54   return 1;
     55 }
     56 
     57 static hb_unicode_general_category_t
     58 hb_unicode_general_category_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
     59 				 hb_codepoint_t      unicode   HB_UNUSED,
     60 				 void               *user_data HB_UNUSED)
     61 {
     62   return HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER;
     63 }
     64 
     65 static hb_codepoint_t
     66 hb_unicode_mirroring_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
     67 			  hb_codepoint_t      unicode   HB_UNUSED,
     68 			  void               *user_data HB_UNUSED)
     69 {
     70   return unicode;
     71 }
     72 
     73 static hb_script_t
     74 hb_unicode_script_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
     75 		       hb_codepoint_t      unicode   HB_UNUSED,
     76 		       void               *user_data HB_UNUSED)
     77 {
     78   return HB_SCRIPT_UNKNOWN;
     79 }
     80 
     81 static hb_bool_t
     82 hb_unicode_compose_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
     83 			hb_codepoint_t      a         HB_UNUSED,
     84 			hb_codepoint_t      b         HB_UNUSED,
     85 			hb_codepoint_t     *ab        HB_UNUSED,
     86 			void               *user_data HB_UNUSED)
     87 {
     88   return false;
     89 }
     90 
     91 static hb_bool_t
     92 hb_unicode_decompose_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
     93 			  hb_codepoint_t      ab        HB_UNUSED,
     94 			  hb_codepoint_t     *a         HB_UNUSED,
     95 			  hb_codepoint_t     *b         HB_UNUSED,
     96 			  void               *user_data HB_UNUSED)
     97 {
     98   return false;
     99 }
    100 
    101 
    102 static unsigned int
    103 hb_unicode_decompose_compatibility_nil (hb_unicode_funcs_t *ufuncs     HB_UNUSED,
    104 					hb_codepoint_t      u          HB_UNUSED,
    105 					hb_codepoint_t     *decomposed HB_UNUSED,
    106 					void               *user_data  HB_UNUSED)
    107 {
    108   return 0;
    109 }
    110 
    111 
    112 #define HB_UNICODE_FUNCS_IMPLEMENT_SET \
    113   HB_UNICODE_FUNCS_IMPLEMENT (glib) \
    114   HB_UNICODE_FUNCS_IMPLEMENT (icu) \
    115   HB_UNICODE_FUNCS_IMPLEMENT (ucdn) \
    116   HB_UNICODE_FUNCS_IMPLEMENT (nil) \
    117   /* ^--- Add new callbacks before nil */
    118 
    119 #define hb_nil_get_unicode_funcs hb_unicode_funcs_get_empty
    120 
    121 /* Prototype them all */
    122 #define HB_UNICODE_FUNCS_IMPLEMENT(set) \
    123 extern "C" hb_unicode_funcs_t *hb_##set##_get_unicode_funcs (void);
    124 HB_UNICODE_FUNCS_IMPLEMENT_SET
    125 #undef HB_UNICODE_FUNCS_IMPLEMENT
    126 
    127 
    128 hb_unicode_funcs_t *
    129 hb_unicode_funcs_get_default (void)
    130 {
    131 #define HB_UNICODE_FUNCS_IMPLEMENT(set) \
    132   return hb_##set##_get_unicode_funcs ();
    133 
    134 #ifdef HAVE_GLIB
    135   HB_UNICODE_FUNCS_IMPLEMENT(glib)
    136 #elif defined(HAVE_ICU)
    137   HB_UNICODE_FUNCS_IMPLEMENT(icu)
    138 #elif defined(HAVE_UCDN)
    139   HB_UNICODE_FUNCS_IMPLEMENT(ucdn)
    140 #else
    141 #define HB_UNICODE_FUNCS_NIL 1
    142   HB_UNICODE_FUNCS_IMPLEMENT(nil)
    143 #endif
    144 
    145 #undef HB_UNICODE_FUNCS_IMPLEMENT
    146 }
    147 
    148 #if !defined(HB_NO_UNICODE_FUNCS) && defined(HB_UNICODE_FUNCS_NIL)
    149 #pragma message("Could not find any Unicode functions implementation, you have to provide your own.")
    150 #pragma message("To suppress this warnings, define HB_NO_UNICODE_FUNCS.")
    151 #endif
    152 
    153 hb_unicode_funcs_t *
    154 hb_unicode_funcs_create (hb_unicode_funcs_t *parent)
    155 {
    156   hb_unicode_funcs_t *ufuncs;
    157 
    158   if (!(ufuncs = hb_object_create<hb_unicode_funcs_t> ()))
    159     return hb_unicode_funcs_get_empty ();
    160 
    161   if (!parent)
    162     parent = hb_unicode_funcs_get_empty ();
    163 
    164   hb_unicode_funcs_make_immutable (parent);
    165   ufuncs->parent = hb_unicode_funcs_reference (parent);
    166 
    167   ufuncs->func = parent->func;
    168 
    169   /* We can safely copy user_data from parent since we hold a reference
    170    * onto it and it's immutable.  We should not copy the destroy notifiers
    171    * though. */
    172   ufuncs->user_data = parent->user_data;
    173 
    174   return ufuncs;
    175 }
    176 
    177 
    178 const hb_unicode_funcs_t _hb_unicode_funcs_nil = {
    179   HB_OBJECT_HEADER_STATIC,
    180 
    181   NULL, /* parent */
    182   true, /* immutable */
    183   {
    184 #define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_nil,
    185     HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
    186 #undef HB_UNICODE_FUNC_IMPLEMENT
    187   }
    188 };
    189 
    190 hb_unicode_funcs_t *
    191 hb_unicode_funcs_get_empty (void)
    192 {
    193   return const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil);
    194 }
    195 
    196 hb_unicode_funcs_t *
    197 hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs)
    198 {
    199   return hb_object_reference (ufuncs);
    200 }
    201 
    202 void
    203 hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
    204 {
    205   if (!hb_object_destroy (ufuncs)) return;
    206 
    207 #define HB_UNICODE_FUNC_IMPLEMENT(name) \
    208   if (ufuncs->destroy.name) ufuncs->destroy.name (ufuncs->user_data.name);
    209     HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
    210 #undef HB_UNICODE_FUNC_IMPLEMENT
    211 
    212   hb_unicode_funcs_destroy (ufuncs->parent);
    213 
    214   free (ufuncs);
    215 }
    216 
    217 hb_bool_t
    218 hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
    219 			        hb_user_data_key_t *key,
    220 			        void *              data,
    221 			        hb_destroy_func_t   destroy,
    222 				hb_bool_t           replace)
    223 {
    224   return hb_object_set_user_data (ufuncs, key, data, destroy, replace);
    225 }
    226 
    227 void *
    228 hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
    229 			        hb_user_data_key_t *key)
    230 {
    231   return hb_object_get_user_data (ufuncs, key);
    232 }
    233 
    234 
    235 void
    236 hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs)
    237 {
    238   if (hb_object_is_inert (ufuncs))
    239     return;
    240 
    241   ufuncs->immutable = true;
    242 }
    243 
    244 hb_bool_t
    245 hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs)
    246 {
    247   return ufuncs->immutable;
    248 }
    249 
    250 hb_unicode_funcs_t *
    251 hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs)
    252 {
    253   return ufuncs->parent ? ufuncs->parent : hb_unicode_funcs_get_empty ();
    254 }
    255 
    256 
    257 #define HB_UNICODE_FUNC_IMPLEMENT(name)						\
    258 										\
    259 void										\
    260 hb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t		   *ufuncs,	\
    261 				    hb_unicode_##name##_func_t	    func,	\
    262 				    void			   *user_data,	\
    263 				    hb_destroy_func_t		    destroy)	\
    264 {										\
    265   if (ufuncs->immutable)							\
    266     return;									\
    267 										\
    268   if (ufuncs->destroy.name)							\
    269     ufuncs->destroy.name (ufuncs->user_data.name);				\
    270 										\
    271   if (func) {									\
    272     ufuncs->func.name = func;							\
    273     ufuncs->user_data.name = user_data;						\
    274     ufuncs->destroy.name = destroy;						\
    275   } else {									\
    276     ufuncs->func.name = ufuncs->parent->func.name;				\
    277     ufuncs->user_data.name = ufuncs->parent->user_data.name;			\
    278     ufuncs->destroy.name = NULL;						\
    279   }										\
    280 }
    281 
    282 HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
    283 #undef HB_UNICODE_FUNC_IMPLEMENT
    284 
    285 
    286 #define HB_UNICODE_FUNC_IMPLEMENT(return_type, name)				\
    287 										\
    288 return_type									\
    289 hb_unicode_##name (hb_unicode_funcs_t *ufuncs,					\
    290 		   hb_codepoint_t      unicode)					\
    291 {										\
    292   return ufuncs->name (unicode);						\
    293 }
    294 HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
    295 #undef HB_UNICODE_FUNC_IMPLEMENT
    296 
    297 hb_bool_t
    298 hb_unicode_compose (hb_unicode_funcs_t *ufuncs,
    299 		    hb_codepoint_t      a,
    300 		    hb_codepoint_t      b,
    301 		    hb_codepoint_t     *ab)
    302 {
    303   return ufuncs->compose (a, b, ab);
    304 }
    305 
    306 hb_bool_t
    307 hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
    308 		      hb_codepoint_t      ab,
    309 		      hb_codepoint_t     *a,
    310 		      hb_codepoint_t     *b)
    311 {
    312   return ufuncs->decompose (ab, a, b);
    313 }
    314 
    315 unsigned int
    316 hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
    317 				    hb_codepoint_t      u,
    318 				    hb_codepoint_t     *decomposed)
    319 {
    320   return ufuncs->decompose_compatibility (u, decomposed);
    321 }
    322 
    323 
    324 /* See hb-unicode-private.hh for details. */
    325 const uint8_t
    326 _hb_modified_combining_class[256] =
    327 {
    328   0, /* HB_UNICODE_COMBINING_CLASS_NOT_REORDERED */
    329   1, /* HB_UNICODE_COMBINING_CLASS_OVERLAY */
    330   2, 3, 4, 5, 6,
    331   7, /* HB_UNICODE_COMBINING_CLASS_NUKTA */
    332   8, /* HB_UNICODE_COMBINING_CLASS_KANA_VOICING */
    333   9, /* HB_UNICODE_COMBINING_CLASS_VIRAMA */
    334 
    335   /* Hebrew */
    336   HB_MODIFIED_COMBINING_CLASS_CCC10,
    337   HB_MODIFIED_COMBINING_CLASS_CCC11,
    338   HB_MODIFIED_COMBINING_CLASS_CCC12,
    339   HB_MODIFIED_COMBINING_CLASS_CCC13,
    340   HB_MODIFIED_COMBINING_CLASS_CCC14,
    341   HB_MODIFIED_COMBINING_CLASS_CCC15,
    342   HB_MODIFIED_COMBINING_CLASS_CCC16,
    343   HB_MODIFIED_COMBINING_CLASS_CCC17,
    344   HB_MODIFIED_COMBINING_CLASS_CCC18,
    345   HB_MODIFIED_COMBINING_CLASS_CCC19,
    346   HB_MODIFIED_COMBINING_CLASS_CCC20,
    347   HB_MODIFIED_COMBINING_CLASS_CCC21,
    348   HB_MODIFIED_COMBINING_CLASS_CCC22,
    349   HB_MODIFIED_COMBINING_CLASS_CCC23,
    350   HB_MODIFIED_COMBINING_CLASS_CCC24,
    351   HB_MODIFIED_COMBINING_CLASS_CCC25,
    352   HB_MODIFIED_COMBINING_CLASS_CCC26,
    353 
    354   /* Arabic */
    355   HB_MODIFIED_COMBINING_CLASS_CCC27,
    356   HB_MODIFIED_COMBINING_CLASS_CCC28,
    357   HB_MODIFIED_COMBINING_CLASS_CCC29,
    358   HB_MODIFIED_COMBINING_CLASS_CCC30,
    359   HB_MODIFIED_COMBINING_CLASS_CCC31,
    360   HB_MODIFIED_COMBINING_CLASS_CCC32,
    361   HB_MODIFIED_COMBINING_CLASS_CCC33,
    362   HB_MODIFIED_COMBINING_CLASS_CCC34,
    363   HB_MODIFIED_COMBINING_CLASS_CCC35,
    364 
    365   /* Syriac */
    366   HB_MODIFIED_COMBINING_CLASS_CCC36,
    367 
    368   37, 38, 39,
    369   40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
    370   60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
    371   80, 81, 82, 83,
    372 
    373   /* Telugu */
    374   HB_MODIFIED_COMBINING_CLASS_CCC84,
    375   85, 86, 87, 88, 89, 90,
    376   HB_MODIFIED_COMBINING_CLASS_CCC91,
    377   92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
    378 
    379   /* Thai */
    380   HB_MODIFIED_COMBINING_CLASS_CCC103,
    381   104, 105, 106,
    382   HB_MODIFIED_COMBINING_CLASS_CCC107,
    383   108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
    384 
    385   /* Lao */
    386   HB_MODIFIED_COMBINING_CLASS_CCC118,
    387   119, 120, 121,
    388   HB_MODIFIED_COMBINING_CLASS_CCC122,
    389   123, 124, 125, 126, 127, 128,
    390 
    391   /* Tibetan */
    392   HB_MODIFIED_COMBINING_CLASS_CCC129,
    393   HB_MODIFIED_COMBINING_CLASS_CCC130,
    394   131,
    395   HB_MODIFIED_COMBINING_CLASS_CCC132,
    396   133, 134, 135, 136, 137, 138, 139,
    397 
    398 
    399   140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
    400   150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
    401   160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
    402   170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
    403   180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
    404   190, 191, 192, 193, 194, 195, 196, 197, 198, 199,
    405 
    406   200, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT */
    407   201,
    408   202, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW */
    409   203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213,
    410   214, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE */
    411   215,
    412   216, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT */
    413   217,
    414   218, /* HB_UNICODE_COMBINING_CLASS_BELOW_LEFT */
    415   219,
    416   220, /* HB_UNICODE_COMBINING_CLASS_BELOW */
    417   221,
    418   222, /* HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT */
    419   223,
    420   224, /* HB_UNICODE_COMBINING_CLASS_LEFT */
    421   225,
    422   226, /* HB_UNICODE_COMBINING_CLASS_RIGHT */
    423   227,
    424   228, /* HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT */
    425   229,
    426   230, /* HB_UNICODE_COMBINING_CLASS_ABOVE */
    427   231,
    428   232, /* HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT */
    429   233, /* HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW */
    430   234, /* HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE */
    431   235, 236, 237, 238, 239,
    432   240, /* HB_UNICODE_COMBINING_CLASS_IOTA_SUBSCRIPT */
    433   241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
    434   255, /* HB_UNICODE_COMBINING_CLASS_INVALID */
    435 };
    436