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