1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. Oracle designates this 7 * particular file as subject to the "Classpath" exception as provided 8 * by Oracle in the LICENSE file that accompanied this code. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 // This file is available under and governed by the GNU General Public 26 // License version 2 only, as published by the Free Software Foundation. 27 // However, the following notice accompanied the original version of this 28 // file: 29 // 30 /* 31 * Copyright © 2009 Red Hat, Inc. 32 * Copyright © 2011 Codethink Limited 33 * Copyright © 2010,2011,2012 Google, Inc. 34 * 35 * This is part of HarfBuzz, a text shaping library. 36 * 37 * Permission is hereby granted, without written agreement and without 38 * license or royalty fees, to use, copy, modify, and distribute this 39 * software and its documentation for any purpose, provided that the 40 * above copyright notice and the following two paragraphs appear in 41 * all copies of this software. 42 * 43 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 44 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 45 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 46 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 47 * DAMAGE. 48 * 49 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 50 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 51 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 52 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 53 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 54 * 55 * Red Hat Author(s): Behdad Esfahbod 56 * Codethink Author(s): Ryan Lortie 57 * Google Author(s): Behdad Esfahbod 58 */ 59 60 #include "hb-private.hh" 61 62 #include "hb-unicode-private.hh" 63 64 65 66 /* 67 * hb_unicode_funcs_t 68 */ 69 70 static hb_unicode_combining_class_t 71 hb_unicode_combining_class_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED, 72 hb_codepoint_t unicode HB_UNUSED, 73 void *user_data HB_UNUSED) 74 { 75 return HB_UNICODE_COMBINING_CLASS_NOT_REORDERED; 76 } 77 78 static unsigned int 79 hb_unicode_eastasian_width_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED, 80 hb_codepoint_t unicode HB_UNUSED, 81 void *user_data HB_UNUSED) 82 { 83 return 1; 84 } 85 86 static hb_unicode_general_category_t 87 hb_unicode_general_category_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED, 88 hb_codepoint_t unicode HB_UNUSED, 89 void *user_data HB_UNUSED) 90 { 91 return HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER; 92 } 93 94 static hb_codepoint_t 95 hb_unicode_mirroring_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED, 96 hb_codepoint_t unicode HB_UNUSED, 97 void *user_data HB_UNUSED) 98 { 99 return unicode; 100 } 101 102 static hb_script_t 103 hb_unicode_script_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED, 104 hb_codepoint_t unicode HB_UNUSED, 105 void *user_data HB_UNUSED) 106 { 107 return HB_SCRIPT_UNKNOWN; 108 } 109 110 static hb_bool_t 111 hb_unicode_compose_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED, 112 hb_codepoint_t a HB_UNUSED, 113 hb_codepoint_t b HB_UNUSED, 114 hb_codepoint_t *ab HB_UNUSED, 115 void *user_data HB_UNUSED) 116 { 117 return false; 118 } 119 120 static hb_bool_t 121 hb_unicode_decompose_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED, 122 hb_codepoint_t ab HB_UNUSED, 123 hb_codepoint_t *a HB_UNUSED, 124 hb_codepoint_t *b HB_UNUSED, 125 void *user_data HB_UNUSED) 126 { 127 return false; 128 } 129 130 131 static unsigned int 132 hb_unicode_decompose_compatibility_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED, 133 hb_codepoint_t u HB_UNUSED, 134 hb_codepoint_t *decomposed HB_UNUSED, 135 void *user_data HB_UNUSED) 136 { 137 return 0; 138 } 139 140 141 #define HB_UNICODE_FUNCS_IMPLEMENT_SET \ 142 HB_UNICODE_FUNCS_IMPLEMENT (glib) \ 143 HB_UNICODE_FUNCS_IMPLEMENT (icu) \ 144 HB_UNICODE_FUNCS_IMPLEMENT (ucdn) \ 145 HB_UNICODE_FUNCS_IMPLEMENT (nil) \ 146 /* ^--- Add new callbacks before nil */ 147 148 #define hb_nil_get_unicode_funcs hb_unicode_funcs_get_empty 149 150 /* Prototype them all */ 151 #define HB_UNICODE_FUNCS_IMPLEMENT(set) \ 152 extern "C" hb_unicode_funcs_t *hb_##set##_get_unicode_funcs (void); 153 HB_UNICODE_FUNCS_IMPLEMENT_SET 154 #undef HB_UNICODE_FUNCS_IMPLEMENT 155 156 157 hb_unicode_funcs_t * 158 hb_unicode_funcs_get_default (void) 159 { 160 #define HB_UNICODE_FUNCS_IMPLEMENT(set) \ 161 return hb_##set##_get_unicode_funcs (); 162 163 #ifdef HAVE_GLIB 164 HB_UNICODE_FUNCS_IMPLEMENT(glib) 165 #elif defined(HAVE_ICU) && defined(HAVE_ICU_BUILTIN) 166 HB_UNICODE_FUNCS_IMPLEMENT(icu) 167 #elif defined(HAVE_UCDN) 168 HB_UNICODE_FUNCS_IMPLEMENT(ucdn) 169 #else 170 #define HB_UNICODE_FUNCS_NIL 1 171 HB_UNICODE_FUNCS_IMPLEMENT(nil) 172 #endif 173 174 #undef HB_UNICODE_FUNCS_IMPLEMENT 175 } 176 177 #if !defined(HB_NO_UNICODE_FUNCS) && defined(HB_UNICODE_FUNCS_NIL) 178 #error "Could not find any Unicode functions implementation, you have to provide your own" 179 #error "Consider building hb-ucdn.c. If you absolutely want to build without any, check the code." 180 #endif 181 182 /** 183 * hb_unicode_funcs_create: (Xconstructor) 184 * @parent: (nullable): 185 * 186 * 187 * 188 * Return value: (transfer full): 189 * 190 * Since: 0.9.2 191 **/ 192 hb_unicode_funcs_t * 193 hb_unicode_funcs_create (hb_unicode_funcs_t *parent) 194 { 195 hb_unicode_funcs_t *ufuncs; 196 197 if (!(ufuncs = hb_object_create<hb_unicode_funcs_t> ())) 198 return hb_unicode_funcs_get_empty (); 199 200 if (!parent) 201 parent = hb_unicode_funcs_get_empty (); 202 203 hb_unicode_funcs_make_immutable (parent); 204 ufuncs->parent = hb_unicode_funcs_reference (parent); 205 206 ufuncs->func = parent->func; 207 208 /* We can safely copy user_data from parent since we hold a reference 209 * onto it and it's immutable. We should not copy the destroy notifiers 210 * though. */ 211 ufuncs->user_data = parent->user_data; 212 213 return ufuncs; 214 } 215 216 217 const hb_unicode_funcs_t _hb_unicode_funcs_nil = { 218 HB_OBJECT_HEADER_STATIC, 219 220 NULL, /* parent */ 221 true, /* immutable */ 222 { 223 #define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_nil, 224 HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS 225 #undef HB_UNICODE_FUNC_IMPLEMENT 226 } 227 }; 228 229 /** 230 * hb_unicode_funcs_get_empty: 231 * 232 * 233 * 234 * Return value: (transfer full): 235 * 236 * Since: 0.9.2 237 **/ 238 hb_unicode_funcs_t * 239 hb_unicode_funcs_get_empty (void) 240 { 241 return const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil); 242 } 243 244 /** 245 * hb_unicode_funcs_reference: (skip) 246 * @ufuncs: Unicode functions. 247 * 248 * 249 * 250 * Return value: (transfer full): 251 * 252 * Since: 0.9.2 253 **/ 254 hb_unicode_funcs_t * 255 hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs) 256 { 257 return hb_object_reference (ufuncs); 258 } 259 260 /** 261 * hb_unicode_funcs_destroy: (skip) 262 * @ufuncs: Unicode functions. 263 * 264 * 265 * 266 * Since: 0.9.2 267 **/ 268 void 269 hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs) 270 { 271 if (!hb_object_destroy (ufuncs)) return; 272 273 #define HB_UNICODE_FUNC_IMPLEMENT(name) \ 274 if (ufuncs->destroy.name) ufuncs->destroy.name (ufuncs->user_data.name); 275 HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS 276 #undef HB_UNICODE_FUNC_IMPLEMENT 277 278 hb_unicode_funcs_destroy (ufuncs->parent); 279 280 free (ufuncs); 281 } 282 283 /** 284 * hb_unicode_funcs_set_user_data: (skip) 285 * @ufuncs: Unicode functions. 286 * @key: 287 * @data: 288 * @destroy: 289 * @replace: 290 * 291 * 292 * 293 * Return value: 294 * 295 * Since: 0.9.2 296 **/ 297 hb_bool_t 298 hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs, 299 hb_user_data_key_t *key, 300 void * data, 301 hb_destroy_func_t destroy, 302 hb_bool_t replace) 303 { 304 return hb_object_set_user_data (ufuncs, key, data, destroy, replace); 305 } 306 307 /** 308 * hb_unicode_funcs_get_user_data: (skip) 309 * @ufuncs: Unicode functions. 310 * @key: 311 * 312 * 313 * 314 * Return value: (transfer none): 315 * 316 * Since: 0.9.2 317 **/ 318 void * 319 hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs, 320 hb_user_data_key_t *key) 321 { 322 return hb_object_get_user_data (ufuncs, key); 323 } 324 325 326 /** 327 * hb_unicode_funcs_make_immutable: 328 * @ufuncs: Unicode functions. 329 * 330 * 331 * 332 * Since: 0.9.2 333 **/ 334 void 335 hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs) 336 { 337 if (unlikely (hb_object_is_inert (ufuncs))) 338 return; 339 340 ufuncs->immutable = true; 341 } 342 343 /** 344 * hb_unicode_funcs_is_immutable: 345 * @ufuncs: Unicode functions. 346 * 347 * 348 * 349 * Return value: 350 * 351 * Since: 0.9.2 352 **/ 353 hb_bool_t 354 hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs) 355 { 356 return ufuncs->immutable; 357 } 358 359 /** 360 * hb_unicode_funcs_get_parent: 361 * @ufuncs: Unicode functions. 362 * 363 * 364 * 365 * Return value: 366 * 367 * Since: 0.9.2 368 **/ 369 hb_unicode_funcs_t * 370 hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs) 371 { 372 return ufuncs->parent ? ufuncs->parent : hb_unicode_funcs_get_empty (); 373 } 374 375 376 #define HB_UNICODE_FUNC_IMPLEMENT(name) \ 377 \ 378 void \ 379 hb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t *ufuncs, \ 380 hb_unicode_##name##_func_t func, \ 381 void *user_data, \ 382 hb_destroy_func_t destroy) \ 383 { \ 384 if (ufuncs->immutable) \ 385 return; \ 386 \ 387 if (ufuncs->destroy.name) \ 388 ufuncs->destroy.name (ufuncs->user_data.name); \ 389 \ 390 if (func) { \ 391 ufuncs->func.name = func; \ 392 ufuncs->user_data.name = user_data; \ 393 ufuncs->destroy.name = destroy; \ 394 } else { \ 395 ufuncs->func.name = ufuncs->parent->func.name; \ 396 ufuncs->user_data.name = ufuncs->parent->user_data.name; \ 397 ufuncs->destroy.name = NULL; \ 398 } \ 399 } 400 401 HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS 402 #undef HB_UNICODE_FUNC_IMPLEMENT 403 404 405 #define HB_UNICODE_FUNC_IMPLEMENT(return_type, name) \ 406 \ 407 return_type \ 408 hb_unicode_##name (hb_unicode_funcs_t *ufuncs, \ 409 hb_codepoint_t unicode) \ 410 { \ 411 return ufuncs->name (unicode); \ 412 } 413 HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE 414 #undef HB_UNICODE_FUNC_IMPLEMENT 415 416 /** 417 * hb_unicode_compose: 418 * @ufuncs: Unicode functions. 419 * @a: 420 * @b: 421 * @ab: (out): 422 * 423 * 424 * 425 * Return value: 426 * 427 * Since: 0.9.2 428 **/ 429 hb_bool_t 430 hb_unicode_compose (hb_unicode_funcs_t *ufuncs, 431 hb_codepoint_t a, 432 hb_codepoint_t b, 433 hb_codepoint_t *ab) 434 { 435 return ufuncs->compose (a, b, ab); 436 } 437 438 /** 439 * hb_unicode_decompose: 440 * @ufuncs: Unicode functions. 441 * @ab: 442 * @a: (out): 443 * @b: (out): 444 * 445 * 446 * 447 * Return value: 448 * 449 * Since: 0.9.2 450 **/ 451 hb_bool_t 452 hb_unicode_decompose (hb_unicode_funcs_t *ufuncs, 453 hb_codepoint_t ab, 454 hb_codepoint_t *a, 455 hb_codepoint_t *b) 456 { 457 return ufuncs->decompose (ab, a, b); 458 } 459 460 /** 461 * hb_unicode_decompose_compatibility: 462 * @ufuncs: Unicode functions. 463 * @u: 464 * @decomposed: (out): 465 * 466 * 467 * 468 * Return value: 469 * 470 * Since: 0.9.2 471 **/ 472 unsigned int 473 hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs, 474 hb_codepoint_t u, 475 hb_codepoint_t *decomposed) 476 { 477 return ufuncs->decompose_compatibility (u, decomposed); 478 } 479 480 481 /* See hb-unicode-private.hh for details. */ 482 const uint8_t 483 _hb_modified_combining_class[256] = 484 { 485 0, /* HB_UNICODE_COMBINING_CLASS_NOT_REORDERED */ 486 1, /* HB_UNICODE_COMBINING_CLASS_OVERLAY */ 487 2, 3, 4, 5, 6, 488 7, /* HB_UNICODE_COMBINING_CLASS_NUKTA */ 489 8, /* HB_UNICODE_COMBINING_CLASS_KANA_VOICING */ 490 9, /* HB_UNICODE_COMBINING_CLASS_VIRAMA */ 491 492 /* Hebrew */ 493 HB_MODIFIED_COMBINING_CLASS_CCC10, 494 HB_MODIFIED_COMBINING_CLASS_CCC11, 495 HB_MODIFIED_COMBINING_CLASS_CCC12, 496 HB_MODIFIED_COMBINING_CLASS_CCC13, 497 HB_MODIFIED_COMBINING_CLASS_CCC14, 498 HB_MODIFIED_COMBINING_CLASS_CCC15, 499 HB_MODIFIED_COMBINING_CLASS_CCC16, 500 HB_MODIFIED_COMBINING_CLASS_CCC17, 501 HB_MODIFIED_COMBINING_CLASS_CCC18, 502 HB_MODIFIED_COMBINING_CLASS_CCC19, 503 HB_MODIFIED_COMBINING_CLASS_CCC20, 504 HB_MODIFIED_COMBINING_CLASS_CCC21, 505 HB_MODIFIED_COMBINING_CLASS_CCC22, 506 HB_MODIFIED_COMBINING_CLASS_CCC23, 507 HB_MODIFIED_COMBINING_CLASS_CCC24, 508 HB_MODIFIED_COMBINING_CLASS_CCC25, 509 HB_MODIFIED_COMBINING_CLASS_CCC26, 510 511 /* Arabic */ 512 HB_MODIFIED_COMBINING_CLASS_CCC27, 513 HB_MODIFIED_COMBINING_CLASS_CCC28, 514 HB_MODIFIED_COMBINING_CLASS_CCC29, 515 HB_MODIFIED_COMBINING_CLASS_CCC30, 516 HB_MODIFIED_COMBINING_CLASS_CCC31, 517 HB_MODIFIED_COMBINING_CLASS_CCC32, 518 HB_MODIFIED_COMBINING_CLASS_CCC33, 519 HB_MODIFIED_COMBINING_CLASS_CCC34, 520 HB_MODIFIED_COMBINING_CLASS_CCC35, 521 522 /* Syriac */ 523 HB_MODIFIED_COMBINING_CLASS_CCC36, 524 525 37, 38, 39, 526 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 527 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 528 80, 81, 82, 83, 529 530 /* Telugu */ 531 HB_MODIFIED_COMBINING_CLASS_CCC84, 532 85, 86, 87, 88, 89, 90, 533 HB_MODIFIED_COMBINING_CLASS_CCC91, 534 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 535 536 /* Thai */ 537 HB_MODIFIED_COMBINING_CLASS_CCC103, 538 104, 105, 106, 539 HB_MODIFIED_COMBINING_CLASS_CCC107, 540 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 541 542 /* Lao */ 543 HB_MODIFIED_COMBINING_CLASS_CCC118, 544 119, 120, 121, 545 HB_MODIFIED_COMBINING_CLASS_CCC122, 546 123, 124, 125, 126, 127, 128, 547 548 /* Tibetan */ 549 HB_MODIFIED_COMBINING_CLASS_CCC129, 550 HB_MODIFIED_COMBINING_CLASS_CCC130, 551 131, 552 HB_MODIFIED_COMBINING_CLASS_CCC132, 553 133, 134, 135, 136, 137, 138, 139, 554 555 556 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 557 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 558 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 559 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 560 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 561 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 562 563 200, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT */ 564 201, 565 202, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW */ 566 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 567 214, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE */ 568 215, 569 216, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT */ 570 217, 571 218, /* HB_UNICODE_COMBINING_CLASS_BELOW_LEFT */ 572 219, 573 220, /* HB_UNICODE_COMBINING_CLASS_BELOW */ 574 221, 575 222, /* HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT */ 576 223, 577 224, /* HB_UNICODE_COMBINING_CLASS_LEFT */ 578 225, 579 226, /* HB_UNICODE_COMBINING_CLASS_RIGHT */ 580 227, 581 228, /* HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT */ 582 229, 583 230, /* HB_UNICODE_COMBINING_CLASS_ABOVE */ 584 231, 585 232, /* HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT */ 586 233, /* HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW */ 587 234, /* HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE */ 588 235, 236, 237, 238, 239, 589 240, /* HB_UNICODE_COMBINING_CLASS_IOTA_SUBSCRIPT */ 590 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 591 255, /* HB_UNICODE_COMBINING_CLASS_INVALID */ 592 };