1 /* 2 * Copyright 2009 Red Hat, Inc. 3 * Copyright 2012 Google, Inc. 4 * 5 * This is part of HarfBuzz, a text shaping library. 6 * 7 * Permission is hereby granted, without written agreement and without 8 * license or royalty fees, to use, copy, modify, and distribute this 9 * software and its documentation for any purpose, provided that the 10 * above copyright notice and the following two paragraphs appear in 11 * all copies of this software. 12 * 13 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 14 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 15 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 16 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 17 * DAMAGE. 18 * 19 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 20 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 21 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 22 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 23 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 24 * 25 * Red Hat Author(s): Behdad Esfahbod 26 * Google Author(s): Behdad Esfahbod 27 */ 28 29 #include "hb-private.hh" 30 31 #include "hb-font-private.hh" 32 33 34 /* 35 * hb_font_funcs_t 36 */ 37 38 static hb_bool_t 39 hb_font_get_font_h_extents_nil (hb_font_t *font, 40 void *font_data HB_UNUSED, 41 hb_font_extents_t *metrics, 42 void *user_data HB_UNUSED) 43 { 44 memset (metrics, 0, sizeof (*metrics)); 45 return false; 46 } 47 static hb_bool_t 48 hb_font_get_font_h_extents_parent (hb_font_t *font, 49 void *font_data HB_UNUSED, 50 hb_font_extents_t *metrics, 51 void *user_data HB_UNUSED) 52 { 53 hb_bool_t ret = font->parent->get_font_h_extents (metrics); 54 if (ret) { 55 metrics->ascender = font->parent_scale_y_distance (metrics->ascender); 56 metrics->descender = font->parent_scale_y_distance (metrics->descender); 57 metrics->line_gap = font->parent_scale_y_distance (metrics->line_gap); 58 } 59 return ret; 60 } 61 62 static hb_bool_t 63 hb_font_get_font_v_extents_nil (hb_font_t *font, 64 void *font_data HB_UNUSED, 65 hb_font_extents_t *metrics, 66 void *user_data HB_UNUSED) 67 { 68 memset (metrics, 0, sizeof (*metrics)); 69 return false; 70 } 71 static hb_bool_t 72 hb_font_get_font_v_extents_parent (hb_font_t *font, 73 void *font_data HB_UNUSED, 74 hb_font_extents_t *metrics, 75 void *user_data HB_UNUSED) 76 { 77 hb_bool_t ret = font->parent->get_font_v_extents (metrics); 78 if (ret) { 79 metrics->ascender = font->parent_scale_x_distance (metrics->ascender); 80 metrics->descender = font->parent_scale_x_distance (metrics->descender); 81 metrics->line_gap = font->parent_scale_x_distance (metrics->line_gap); 82 } 83 return ret; 84 } 85 86 static hb_bool_t 87 hb_font_get_nominal_glyph_nil (hb_font_t *font HB_UNUSED, 88 void *font_data HB_UNUSED, 89 hb_codepoint_t unicode, 90 hb_codepoint_t *glyph, 91 void *user_data HB_UNUSED) 92 { 93 *glyph = 0; 94 return false; 95 } 96 static hb_bool_t 97 hb_font_get_nominal_glyph_parent (hb_font_t *font, 98 void *font_data HB_UNUSED, 99 hb_codepoint_t unicode, 100 hb_codepoint_t *glyph, 101 void *user_data HB_UNUSED) 102 { 103 return font->parent->get_nominal_glyph (unicode, glyph); 104 } 105 106 static hb_bool_t 107 hb_font_get_variation_glyph_nil (hb_font_t *font HB_UNUSED, 108 void *font_data HB_UNUSED, 109 hb_codepoint_t unicode, 110 hb_codepoint_t variation_selector, 111 hb_codepoint_t *glyph, 112 void *user_data HB_UNUSED) 113 { 114 *glyph = 0; 115 return false; 116 } 117 static hb_bool_t 118 hb_font_get_variation_glyph_parent (hb_font_t *font, 119 void *font_data HB_UNUSED, 120 hb_codepoint_t unicode, 121 hb_codepoint_t variation_selector, 122 hb_codepoint_t *glyph, 123 void *user_data HB_UNUSED) 124 { 125 return font->parent->get_variation_glyph (unicode, variation_selector, glyph); 126 } 127 128 129 static hb_position_t 130 hb_font_get_glyph_h_advance_nil (hb_font_t *font HB_UNUSED, 131 void *font_data HB_UNUSED, 132 hb_codepoint_t glyph, 133 void *user_data HB_UNUSED) 134 { 135 return font->x_scale; 136 } 137 static hb_position_t 138 hb_font_get_glyph_h_advance_parent (hb_font_t *font, 139 void *font_data HB_UNUSED, 140 hb_codepoint_t glyph, 141 void *user_data HB_UNUSED) 142 { 143 return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph)); 144 } 145 146 static hb_position_t 147 hb_font_get_glyph_v_advance_nil (hb_font_t *font HB_UNUSED, 148 void *font_data HB_UNUSED, 149 hb_codepoint_t glyph, 150 void *user_data HB_UNUSED) 151 { 152 /* TODO use font_extents.ascender+descender */ 153 return font->y_scale; 154 } 155 static hb_position_t 156 hb_font_get_glyph_v_advance_parent (hb_font_t *font, 157 void *font_data HB_UNUSED, 158 hb_codepoint_t glyph, 159 void *user_data HB_UNUSED) 160 { 161 return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph)); 162 } 163 164 static hb_bool_t 165 hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED, 166 void *font_data HB_UNUSED, 167 hb_codepoint_t glyph, 168 hb_position_t *x, 169 hb_position_t *y, 170 void *user_data HB_UNUSED) 171 { 172 *x = *y = 0; 173 return true; 174 } 175 static hb_bool_t 176 hb_font_get_glyph_h_origin_parent (hb_font_t *font, 177 void *font_data HB_UNUSED, 178 hb_codepoint_t glyph, 179 hb_position_t *x, 180 hb_position_t *y, 181 void *user_data HB_UNUSED) 182 { 183 hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y); 184 if (ret) 185 font->parent_scale_position (x, y); 186 return ret; 187 } 188 189 static hb_bool_t 190 hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED, 191 void *font_data HB_UNUSED, 192 hb_codepoint_t glyph, 193 hb_position_t *x, 194 hb_position_t *y, 195 void *user_data HB_UNUSED) 196 { 197 *x = *y = 0; 198 return false; 199 } 200 static hb_bool_t 201 hb_font_get_glyph_v_origin_parent (hb_font_t *font, 202 void *font_data HB_UNUSED, 203 hb_codepoint_t glyph, 204 hb_position_t *x, 205 hb_position_t *y, 206 void *user_data HB_UNUSED) 207 { 208 hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y); 209 if (ret) 210 font->parent_scale_position (x, y); 211 return ret; 212 } 213 214 static hb_position_t 215 hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED, 216 void *font_data HB_UNUSED, 217 hb_codepoint_t left_glyph, 218 hb_codepoint_t right_glyph, 219 void *user_data HB_UNUSED) 220 { 221 return 0; 222 } 223 static hb_position_t 224 hb_font_get_glyph_h_kerning_parent (hb_font_t *font, 225 void *font_data HB_UNUSED, 226 hb_codepoint_t left_glyph, 227 hb_codepoint_t right_glyph, 228 void *user_data HB_UNUSED) 229 { 230 return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph)); 231 } 232 233 static hb_position_t 234 hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED, 235 void *font_data HB_UNUSED, 236 hb_codepoint_t top_glyph, 237 hb_codepoint_t bottom_glyph, 238 void *user_data HB_UNUSED) 239 { 240 return 0; 241 } 242 static hb_position_t 243 hb_font_get_glyph_v_kerning_parent (hb_font_t *font, 244 void *font_data HB_UNUSED, 245 hb_codepoint_t top_glyph, 246 hb_codepoint_t bottom_glyph, 247 void *user_data HB_UNUSED) 248 { 249 return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph)); 250 } 251 252 static hb_bool_t 253 hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED, 254 void *font_data HB_UNUSED, 255 hb_codepoint_t glyph, 256 hb_glyph_extents_t *extents, 257 void *user_data HB_UNUSED) 258 { 259 memset (extents, 0, sizeof (*extents)); 260 return false; 261 } 262 static hb_bool_t 263 hb_font_get_glyph_extents_parent (hb_font_t *font, 264 void *font_data HB_UNUSED, 265 hb_codepoint_t glyph, 266 hb_glyph_extents_t *extents, 267 void *user_data HB_UNUSED) 268 { 269 hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents); 270 if (ret) { 271 font->parent_scale_position (&extents->x_bearing, &extents->y_bearing); 272 font->parent_scale_distance (&extents->width, &extents->height); 273 } 274 return ret; 275 } 276 277 static hb_bool_t 278 hb_font_get_glyph_contour_point_nil (hb_font_t *font HB_UNUSED, 279 void *font_data HB_UNUSED, 280 hb_codepoint_t glyph, 281 unsigned int point_index, 282 hb_position_t *x, 283 hb_position_t *y, 284 void *user_data HB_UNUSED) 285 { 286 *x = *y = 0; 287 return false; 288 } 289 static hb_bool_t 290 hb_font_get_glyph_contour_point_parent (hb_font_t *font, 291 void *font_data HB_UNUSED, 292 hb_codepoint_t glyph, 293 unsigned int point_index, 294 hb_position_t *x, 295 hb_position_t *y, 296 void *user_data HB_UNUSED) 297 { 298 hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y); 299 if (ret) 300 font->parent_scale_position (x, y); 301 return ret; 302 } 303 304 static hb_bool_t 305 hb_font_get_glyph_name_nil (hb_font_t *font HB_UNUSED, 306 void *font_data HB_UNUSED, 307 hb_codepoint_t glyph, 308 char *name, unsigned int size, 309 void *user_data HB_UNUSED) 310 { 311 if (size) *name = '\0'; 312 return false; 313 } 314 static hb_bool_t 315 hb_font_get_glyph_name_parent (hb_font_t *font, 316 void *font_data HB_UNUSED, 317 hb_codepoint_t glyph, 318 char *name, unsigned int size, 319 void *user_data HB_UNUSED) 320 { 321 return font->parent->get_glyph_name (glyph, name, size); 322 } 323 324 static hb_bool_t 325 hb_font_get_glyph_from_name_nil (hb_font_t *font HB_UNUSED, 326 void *font_data HB_UNUSED, 327 const char *name, int len, /* -1 means nul-terminated */ 328 hb_codepoint_t *glyph, 329 void *user_data HB_UNUSED) 330 { 331 *glyph = 0; 332 return false; 333 } 334 static hb_bool_t 335 hb_font_get_glyph_from_name_parent (hb_font_t *font, 336 void *font_data HB_UNUSED, 337 const char *name, int len, /* -1 means nul-terminated */ 338 hb_codepoint_t *glyph, 339 void *user_data HB_UNUSED) 340 { 341 return font->parent->get_glyph_from_name (name, len, glyph); 342 } 343 344 static const hb_font_funcs_t _hb_font_funcs_nil = { 345 HB_OBJECT_HEADER_STATIC, 346 347 true, /* immutable */ 348 349 { 350 #define HB_FONT_FUNC_IMPLEMENT(name) NULL, 351 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 352 #undef HB_FONT_FUNC_IMPLEMENT 353 }, 354 { 355 #define HB_FONT_FUNC_IMPLEMENT(name) NULL, 356 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 357 #undef HB_FONT_FUNC_IMPLEMENT 358 }, 359 { 360 { 361 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil, 362 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 363 #undef HB_FONT_FUNC_IMPLEMENT 364 } 365 } 366 }; 367 static const hb_font_funcs_t _hb_font_funcs_parent = { 368 HB_OBJECT_HEADER_STATIC, 369 370 true, /* immutable */ 371 372 { 373 #define HB_FONT_FUNC_IMPLEMENT(name) NULL, 374 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 375 #undef HB_FONT_FUNC_IMPLEMENT 376 }, 377 { 378 #define HB_FONT_FUNC_IMPLEMENT(name) NULL, 379 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 380 #undef HB_FONT_FUNC_IMPLEMENT 381 }, 382 { 383 { 384 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_parent, 385 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 386 #undef HB_FONT_FUNC_IMPLEMENT 387 } 388 } 389 }; 390 391 392 /** 393 * hb_font_funcs_create: (Xconstructor) 394 * 395 * 396 * 397 * Return value: (transfer full): 398 * 399 * Since: 0.9.2 400 **/ 401 hb_font_funcs_t * 402 hb_font_funcs_create (void) 403 { 404 hb_font_funcs_t *ffuncs; 405 406 if (!(ffuncs = hb_object_create<hb_font_funcs_t> ())) 407 return hb_font_funcs_get_empty (); 408 409 ffuncs->get = _hb_font_funcs_parent.get; 410 411 return ffuncs; 412 } 413 414 /** 415 * hb_font_funcs_get_empty: 416 * 417 * 418 * 419 * Return value: (transfer full): 420 * 421 * Since: 0.9.2 422 **/ 423 hb_font_funcs_t * 424 hb_font_funcs_get_empty (void) 425 { 426 return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_parent); 427 } 428 429 /** 430 * hb_font_funcs_reference: (skip) 431 * @ffuncs: font functions. 432 * 433 * 434 * 435 * Return value: 436 * 437 * Since: 0.9.2 438 **/ 439 hb_font_funcs_t * 440 hb_font_funcs_reference (hb_font_funcs_t *ffuncs) 441 { 442 return hb_object_reference (ffuncs); 443 } 444 445 /** 446 * hb_font_funcs_destroy: (skip) 447 * @ffuncs: font functions. 448 * 449 * 450 * 451 * Since: 0.9.2 452 **/ 453 void 454 hb_font_funcs_destroy (hb_font_funcs_t *ffuncs) 455 { 456 if (!hb_object_destroy (ffuncs)) return; 457 458 #define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \ 459 ffuncs->destroy.name (ffuncs->user_data.name); 460 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 461 #undef HB_FONT_FUNC_IMPLEMENT 462 463 free (ffuncs); 464 } 465 466 /** 467 * hb_font_funcs_set_user_data: (skip) 468 * @ffuncs: font functions. 469 * @key: 470 * @data: 471 * @destroy: 472 * @replace: 473 * 474 * 475 * 476 * Return value: 477 * 478 * Since: 0.9.2 479 **/ 480 hb_bool_t 481 hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs, 482 hb_user_data_key_t *key, 483 void * data, 484 hb_destroy_func_t destroy, 485 hb_bool_t replace) 486 { 487 return hb_object_set_user_data (ffuncs, key, data, destroy, replace); 488 } 489 490 /** 491 * hb_font_funcs_get_user_data: (skip) 492 * @ffuncs: font functions. 493 * @key: 494 * 495 * 496 * 497 * Return value: (transfer none): 498 * 499 * Since: 0.9.2 500 **/ 501 void * 502 hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs, 503 hb_user_data_key_t *key) 504 { 505 return hb_object_get_user_data (ffuncs, key); 506 } 507 508 509 /** 510 * hb_font_funcs_make_immutable: 511 * @ffuncs: font functions. 512 * 513 * 514 * 515 * Since: 0.9.2 516 **/ 517 void 518 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs) 519 { 520 if (unlikely (hb_object_is_inert (ffuncs))) 521 return; 522 523 ffuncs->immutable = true; 524 } 525 526 /** 527 * hb_font_funcs_is_immutable: 528 * @ffuncs: font functions. 529 * 530 * 531 * 532 * Return value: 533 * 534 * Since: 0.9.2 535 **/ 536 hb_bool_t 537 hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs) 538 { 539 return ffuncs->immutable; 540 } 541 542 543 #define HB_FONT_FUNC_IMPLEMENT(name) \ 544 \ 545 void \ 546 hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \ 547 hb_font_get_##name##_func_t func, \ 548 void *user_data, \ 549 hb_destroy_func_t destroy) \ 550 { \ 551 if (ffuncs->immutable) { \ 552 if (destroy) \ 553 destroy (user_data); \ 554 return; \ 555 } \ 556 \ 557 if (ffuncs->destroy.name) \ 558 ffuncs->destroy.name (ffuncs->user_data.name); \ 559 \ 560 if (func) { \ 561 ffuncs->get.f.name = func; \ 562 ffuncs->user_data.name = user_data; \ 563 ffuncs->destroy.name = destroy; \ 564 } else { \ 565 ffuncs->get.f.name = hb_font_get_##name##_parent; \ 566 ffuncs->user_data.name = NULL; \ 567 ffuncs->destroy.name = NULL; \ 568 } \ 569 } 570 571 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 572 #undef HB_FONT_FUNC_IMPLEMENT 573 574 bool 575 hb_font_t::has_func (unsigned int i) 576 { 577 if (parent && parent != hb_font_get_empty () && parent->has_func (i)) 578 return true; 579 return this->klass->get.array[i] != _hb_font_funcs_parent.get.array[i]; 580 } 581 582 /* Public getters */ 583 584 /** 585 * hb_font_get_h_extents: 586 * @font: a font. 587 * @extents: (out): 588 * 589 * 590 * 591 * Return value: 592 * 593 * Since: 1.1.3 594 **/ 595 hb_bool_t 596 hb_font_get_h_extents (hb_font_t *font, 597 hb_font_extents_t *extents) 598 { 599 return font->get_font_h_extents (extents); 600 } 601 602 /** 603 * hb_font_get_v_extents: 604 * @font: a font. 605 * @extents: (out): 606 * 607 * 608 * 609 * Return value: 610 * 611 * Since: 1.1.3 612 **/ 613 hb_bool_t 614 hb_font_get_v_extents (hb_font_t *font, 615 hb_font_extents_t *extents) 616 { 617 return font->get_font_v_extents (extents); 618 } 619 620 /** 621 * hb_font_get_glyph: 622 * @font: a font. 623 * @unicode: 624 * @variation_selector: 625 * @glyph: (out): 626 * 627 * 628 * 629 * Return value: 630 * 631 * Since: 0.9.2 632 **/ 633 hb_bool_t 634 hb_font_get_glyph (hb_font_t *font, 635 hb_codepoint_t unicode, hb_codepoint_t variation_selector, 636 hb_codepoint_t *glyph) 637 { 638 if (unlikely (variation_selector)) 639 return font->get_variation_glyph (unicode, variation_selector, glyph); 640 return font->get_nominal_glyph (unicode, glyph); 641 } 642 643 /** 644 * hb_font_get_nominal_glyph: 645 * @font: a font. 646 * @unicode: 647 * @glyph: (out): 648 * 649 * 650 * 651 * Return value: 652 * 653 * Since: 1.2.3 654 **/ 655 hb_bool_t 656 hb_font_get_nominal_glyph (hb_font_t *font, 657 hb_codepoint_t unicode, 658 hb_codepoint_t *glyph) 659 { 660 return font->get_nominal_glyph (unicode, glyph); 661 } 662 663 /** 664 * hb_font_get_variation_glyph: 665 * @font: a font. 666 * @unicode: 667 * @variation_selector: 668 * @glyph: (out): 669 * 670 * 671 * 672 * Return value: 673 * 674 * Since: 1.2.3 675 **/ 676 hb_bool_t 677 hb_font_get_variation_glyph (hb_font_t *font, 678 hb_codepoint_t unicode, hb_codepoint_t variation_selector, 679 hb_codepoint_t *glyph) 680 { 681 return font->get_variation_glyph (unicode, variation_selector, glyph); 682 } 683 684 /** 685 * hb_font_get_glyph_h_advance: 686 * @font: a font. 687 * @glyph: 688 * 689 * 690 * 691 * Return value: 692 * 693 * Since: 0.9.2 694 **/ 695 hb_position_t 696 hb_font_get_glyph_h_advance (hb_font_t *font, 697 hb_codepoint_t glyph) 698 { 699 return font->get_glyph_h_advance (glyph); 700 } 701 702 /** 703 * hb_font_get_glyph_v_advance: 704 * @font: a font. 705 * @glyph: 706 * 707 * 708 * 709 * Return value: 710 * 711 * Since: 0.9.2 712 **/ 713 hb_position_t 714 hb_font_get_glyph_v_advance (hb_font_t *font, 715 hb_codepoint_t glyph) 716 { 717 return font->get_glyph_v_advance (glyph); 718 } 719 720 /** 721 * hb_font_get_glyph_h_origin: 722 * @font: a font. 723 * @glyph: 724 * @x: (out): 725 * @y: (out): 726 * 727 * 728 * 729 * Return value: 730 * 731 * Since: 0.9.2 732 **/ 733 hb_bool_t 734 hb_font_get_glyph_h_origin (hb_font_t *font, 735 hb_codepoint_t glyph, 736 hb_position_t *x, hb_position_t *y) 737 { 738 return font->get_glyph_h_origin (glyph, x, y); 739 } 740 741 /** 742 * hb_font_get_glyph_v_origin: 743 * @font: a font. 744 * @glyph: 745 * @x: (out): 746 * @y: (out): 747 * 748 * 749 * 750 * Return value: 751 * 752 * Since: 0.9.2 753 **/ 754 hb_bool_t 755 hb_font_get_glyph_v_origin (hb_font_t *font, 756 hb_codepoint_t glyph, 757 hb_position_t *x, hb_position_t *y) 758 { 759 return font->get_glyph_v_origin (glyph, x, y); 760 } 761 762 /** 763 * hb_font_get_glyph_h_kerning: 764 * @font: a font. 765 * @left_glyph: 766 * @right_glyph: 767 * 768 * 769 * 770 * Return value: 771 * 772 * Since: 0.9.2 773 **/ 774 hb_position_t 775 hb_font_get_glyph_h_kerning (hb_font_t *font, 776 hb_codepoint_t left_glyph, hb_codepoint_t right_glyph) 777 { 778 return font->get_glyph_h_kerning (left_glyph, right_glyph); 779 } 780 781 /** 782 * hb_font_get_glyph_v_kerning: 783 * @font: a font. 784 * @top_glyph: 785 * @bottom_glyph: 786 * 787 * 788 * 789 * Return value: 790 * 791 * Since: 0.9.2 792 **/ 793 hb_position_t 794 hb_font_get_glyph_v_kerning (hb_font_t *font, 795 hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph) 796 { 797 return font->get_glyph_v_kerning (top_glyph, bottom_glyph); 798 } 799 800 /** 801 * hb_font_get_glyph_extents: 802 * @font: a font. 803 * @glyph: 804 * @extents: (out): 805 * 806 * 807 * 808 * Return value: 809 * 810 * Since: 0.9.2 811 **/ 812 hb_bool_t 813 hb_font_get_glyph_extents (hb_font_t *font, 814 hb_codepoint_t glyph, 815 hb_glyph_extents_t *extents) 816 { 817 return font->get_glyph_extents (glyph, extents); 818 } 819 820 /** 821 * hb_font_get_glyph_contour_point: 822 * @font: a font. 823 * @glyph: 824 * @point_index: 825 * @x: (out): 826 * @y: (out): 827 * 828 * 829 * 830 * Return value: 831 * 832 * Since: 0.9.2 833 **/ 834 hb_bool_t 835 hb_font_get_glyph_contour_point (hb_font_t *font, 836 hb_codepoint_t glyph, unsigned int point_index, 837 hb_position_t *x, hb_position_t *y) 838 { 839 return font->get_glyph_contour_point (glyph, point_index, x, y); 840 } 841 842 /** 843 * hb_font_get_glyph_name: 844 * @font: a font. 845 * @glyph: 846 * @name: (array length=size): 847 * @size: 848 * 849 * 850 * 851 * Return value: 852 * 853 * Since: 0.9.2 854 **/ 855 hb_bool_t 856 hb_font_get_glyph_name (hb_font_t *font, 857 hb_codepoint_t glyph, 858 char *name, unsigned int size) 859 { 860 return font->get_glyph_name (glyph, name, size); 861 } 862 863 /** 864 * hb_font_get_glyph_from_name: 865 * @font: a font. 866 * @name: (array length=len): 867 * @len: 868 * @glyph: (out): 869 * 870 * 871 * 872 * Return value: 873 * 874 * Since: 0.9.2 875 **/ 876 hb_bool_t 877 hb_font_get_glyph_from_name (hb_font_t *font, 878 const char *name, int len, /* -1 means nul-terminated */ 879 hb_codepoint_t *glyph) 880 { 881 return font->get_glyph_from_name (name, len, glyph); 882 } 883 884 885 /* A bit higher-level, and with fallback */ 886 887 /** 888 * hb_font_get_extents_for_direction: 889 * @font: a font. 890 * @direction: 891 * @extents: 892 * 893 * 894 * 895 * Since: 1.1.3 896 **/ 897 void 898 hb_font_get_extents_for_direction (hb_font_t *font, 899 hb_direction_t direction, 900 hb_font_extents_t *extents) 901 { 902 return font->get_extents_for_direction (direction, extents); 903 } 904 /** 905 * hb_font_get_glyph_advance_for_direction: 906 * @font: a font. 907 * @glyph: 908 * @direction: 909 * @x: (out): 910 * @y: (out): 911 * 912 * 913 * 914 * Since: 0.9.2 915 **/ 916 void 917 hb_font_get_glyph_advance_for_direction (hb_font_t *font, 918 hb_codepoint_t glyph, 919 hb_direction_t direction, 920 hb_position_t *x, hb_position_t *y) 921 { 922 return font->get_glyph_advance_for_direction (glyph, direction, x, y); 923 } 924 925 /** 926 * hb_font_get_glyph_origin_for_direction: 927 * @font: a font. 928 * @glyph: 929 * @direction: 930 * @x: (out): 931 * @y: (out): 932 * 933 * 934 * 935 * Since: 0.9.2 936 **/ 937 void 938 hb_font_get_glyph_origin_for_direction (hb_font_t *font, 939 hb_codepoint_t glyph, 940 hb_direction_t direction, 941 hb_position_t *x, hb_position_t *y) 942 { 943 return font->get_glyph_origin_for_direction (glyph, direction, x, y); 944 } 945 946 /** 947 * hb_font_add_glyph_origin_for_direction: 948 * @font: a font. 949 * @glyph: 950 * @direction: 951 * @x: (out): 952 * @y: (out): 953 * 954 * 955 * 956 * Since: 0.9.2 957 **/ 958 void 959 hb_font_add_glyph_origin_for_direction (hb_font_t *font, 960 hb_codepoint_t glyph, 961 hb_direction_t direction, 962 hb_position_t *x, hb_position_t *y) 963 { 964 return font->add_glyph_origin_for_direction (glyph, direction, x, y); 965 } 966 967 /** 968 * hb_font_subtract_glyph_origin_for_direction: 969 * @font: a font. 970 * @glyph: 971 * @direction: 972 * @x: (out): 973 * @y: (out): 974 * 975 * 976 * 977 * Since: 0.9.2 978 **/ 979 void 980 hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, 981 hb_codepoint_t glyph, 982 hb_direction_t direction, 983 hb_position_t *x, hb_position_t *y) 984 { 985 return font->subtract_glyph_origin_for_direction (glyph, direction, x, y); 986 } 987 988 /** 989 * hb_font_get_glyph_kerning_for_direction: 990 * @font: a font. 991 * @first_glyph: 992 * @second_glyph: 993 * @direction: 994 * @x: (out): 995 * @y: (out): 996 * 997 * 998 * 999 * Since: 0.9.2 1000 **/ 1001 void 1002 hb_font_get_glyph_kerning_for_direction (hb_font_t *font, 1003 hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, 1004 hb_direction_t direction, 1005 hb_position_t *x, hb_position_t *y) 1006 { 1007 return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y); 1008 } 1009 1010 /** 1011 * hb_font_get_glyph_extents_for_origin: 1012 * @font: a font. 1013 * @glyph: 1014 * @direction: 1015 * @extents: (out): 1016 * 1017 * 1018 * 1019 * Return value: 1020 * 1021 * Since: 0.9.2 1022 **/ 1023 hb_bool_t 1024 hb_font_get_glyph_extents_for_origin (hb_font_t *font, 1025 hb_codepoint_t glyph, 1026 hb_direction_t direction, 1027 hb_glyph_extents_t *extents) 1028 { 1029 return font->get_glyph_extents_for_origin (glyph, direction, extents); 1030 } 1031 1032 /** 1033 * hb_font_get_glyph_contour_point_for_origin: 1034 * @font: a font. 1035 * @glyph: 1036 * @point_index: 1037 * @direction: 1038 * @x: (out): 1039 * @y: (out): 1040 * 1041 * 1042 * 1043 * Return value: 1044 * 1045 * Since: 0.9.2 1046 **/ 1047 hb_bool_t 1048 hb_font_get_glyph_contour_point_for_origin (hb_font_t *font, 1049 hb_codepoint_t glyph, unsigned int point_index, 1050 hb_direction_t direction, 1051 hb_position_t *x, hb_position_t *y) 1052 { 1053 return font->get_glyph_contour_point_for_origin (glyph, point_index, direction, x, y); 1054 } 1055 1056 /* Generates gidDDD if glyph has no name. */ 1057 /** 1058 * hb_font_glyph_to_string: 1059 * @font: a font. 1060 * @glyph: 1061 * @s: (array length=size): 1062 * @size: 1063 * 1064 * 1065 * 1066 * Since: 0.9.2 1067 **/ 1068 void 1069 hb_font_glyph_to_string (hb_font_t *font, 1070 hb_codepoint_t glyph, 1071 char *s, unsigned int size) 1072 { 1073 font->glyph_to_string (glyph, s, size); 1074 } 1075 1076 /* Parses gidDDD and uniUUUU strings automatically. */ 1077 /** 1078 * hb_font_glyph_from_string: 1079 * @font: a font. 1080 * @s: (array length=len) (element-type uint8_t): 1081 * @len: 1082 * @glyph: (out): 1083 * 1084 * 1085 * 1086 * Return value: 1087 * 1088 * Since: 0.9.2 1089 **/ 1090 hb_bool_t 1091 hb_font_glyph_from_string (hb_font_t *font, 1092 const char *s, int len, /* -1 means nul-terminated */ 1093 hb_codepoint_t *glyph) 1094 { 1095 return font->glyph_from_string (s, len, glyph); 1096 } 1097 1098 1099 /* 1100 * hb_font_t 1101 */ 1102 1103 /** 1104 * hb_font_create: (Xconstructor) 1105 * @face: a face. 1106 * 1107 * 1108 * 1109 * Return value: (transfer full): 1110 * 1111 * Since: 0.9.2 1112 **/ 1113 hb_font_t * 1114 hb_font_create (hb_face_t *face) 1115 { 1116 hb_font_t *font; 1117 1118 if (unlikely (!face)) 1119 face = hb_face_get_empty (); 1120 if (!(font = hb_object_create<hb_font_t> ())) 1121 return hb_font_get_empty (); 1122 1123 hb_face_make_immutable (face); 1124 font->parent = hb_font_get_empty (); 1125 font->face = hb_face_reference (face); 1126 font->klass = hb_font_funcs_get_empty (); 1127 1128 font->x_scale = font->y_scale = hb_face_get_upem (face); 1129 1130 return font; 1131 } 1132 1133 /** 1134 * hb_font_create_sub_font: 1135 * @parent: parent font. 1136 * 1137 * 1138 * 1139 * Return value: (transfer full): 1140 * 1141 * Since: 0.9.2 1142 **/ 1143 hb_font_t * 1144 hb_font_create_sub_font (hb_font_t *parent) 1145 { 1146 if (unlikely (!parent)) 1147 parent = hb_font_get_empty (); 1148 1149 hb_font_t *font = hb_font_create (parent->face); 1150 1151 if (unlikely (hb_object_is_inert (font))) 1152 return font; 1153 1154 font->parent = hb_font_reference (parent); 1155 1156 font->x_scale = parent->x_scale; 1157 font->y_scale = parent->y_scale; 1158 font->x_ppem = parent->x_ppem; 1159 font->y_ppem = parent->y_ppem; 1160 1161 /* TODO: copy variation coordinates. */ 1162 1163 return font; 1164 } 1165 1166 /** 1167 * hb_font_get_empty: 1168 * 1169 * 1170 * 1171 * Return value: (transfer full) 1172 * 1173 * Since: 0.9.2 1174 **/ 1175 hb_font_t * 1176 hb_font_get_empty (void) 1177 { 1178 static const hb_font_t _hb_font_nil = { 1179 HB_OBJECT_HEADER_STATIC, 1180 1181 true, /* immutable */ 1182 1183 NULL, /* parent */ 1184 const_cast<hb_face_t *> (&_hb_face_nil), 1185 1186 1000, /* x_scale */ 1187 1000, /* y_scale */ 1188 1189 0, /* x_ppem */ 1190 0, /* y_ppem */ 1191 1192 0, /* num_coords */ 1193 NULL, /* coords */ 1194 1195 const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil), /* klass */ 1196 NULL, /* user_data */ 1197 NULL, /* destroy */ 1198 1199 { 1200 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID, 1201 #include "hb-shaper-list.hh" 1202 #undef HB_SHAPER_IMPLEMENT 1203 } 1204 }; 1205 1206 return const_cast<hb_font_t *> (&_hb_font_nil); 1207 } 1208 1209 /** 1210 * hb_font_reference: (skip) 1211 * @font: a font. 1212 * 1213 * 1214 * 1215 * Return value: (transfer full): 1216 * 1217 * Since: 0.9.2 1218 **/ 1219 hb_font_t * 1220 hb_font_reference (hb_font_t *font) 1221 { 1222 return hb_object_reference (font); 1223 } 1224 1225 /** 1226 * hb_font_destroy: (skip) 1227 * @font: a font. 1228 * 1229 * 1230 * 1231 * Since: 0.9.2 1232 **/ 1233 void 1234 hb_font_destroy (hb_font_t *font) 1235 { 1236 if (!hb_object_destroy (font)) return; 1237 1238 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, font); 1239 #include "hb-shaper-list.hh" 1240 #undef HB_SHAPER_IMPLEMENT 1241 1242 if (font->destroy) 1243 font->destroy (font->user_data); 1244 1245 hb_font_destroy (font->parent); 1246 hb_face_destroy (font->face); 1247 hb_font_funcs_destroy (font->klass); 1248 1249 free (font->coords); 1250 1251 free (font); 1252 } 1253 1254 /** 1255 * hb_font_set_user_data: (skip) 1256 * @font: a font. 1257 * @key: 1258 * @data: 1259 * @destroy: 1260 * @replace: 1261 * 1262 * 1263 * 1264 * Return value: 1265 * 1266 * Since: 0.9.2 1267 **/ 1268 hb_bool_t 1269 hb_font_set_user_data (hb_font_t *font, 1270 hb_user_data_key_t *key, 1271 void * data, 1272 hb_destroy_func_t destroy, 1273 hb_bool_t replace) 1274 { 1275 return hb_object_set_user_data (font, key, data, destroy, replace); 1276 } 1277 1278 /** 1279 * hb_font_get_user_data: (skip) 1280 * @font: a font. 1281 * @key: 1282 * 1283 * 1284 * 1285 * Return value: (transfer none): 1286 * 1287 * Since: 0.9.2 1288 **/ 1289 void * 1290 hb_font_get_user_data (hb_font_t *font, 1291 hb_user_data_key_t *key) 1292 { 1293 return hb_object_get_user_data (font, key); 1294 } 1295 1296 /** 1297 * hb_font_make_immutable: 1298 * @font: a font. 1299 * 1300 * 1301 * 1302 * Since: 0.9.2 1303 **/ 1304 void 1305 hb_font_make_immutable (hb_font_t *font) 1306 { 1307 if (unlikely (hb_object_is_inert (font))) 1308 return; 1309 1310 if (font->parent) 1311 hb_font_make_immutable (font->parent); 1312 1313 font->immutable = true; 1314 } 1315 1316 /** 1317 * hb_font_is_immutable: 1318 * @font: a font. 1319 * 1320 * 1321 * 1322 * Return value: 1323 * 1324 * Since: 0.9.2 1325 **/ 1326 hb_bool_t 1327 hb_font_is_immutable (hb_font_t *font) 1328 { 1329 return font->immutable; 1330 } 1331 1332 /** 1333 * hb_font_set_parent: 1334 * @font: a font. 1335 * @parent: new parent. 1336 * 1337 * Sets parent font of @font. 1338 * 1339 * Since: 1.0.5 1340 **/ 1341 void 1342 hb_font_set_parent (hb_font_t *font, 1343 hb_font_t *parent) 1344 { 1345 if (font->immutable) 1346 return; 1347 1348 if (!parent) 1349 parent = hb_font_get_empty (); 1350 1351 hb_font_t *old = font->parent; 1352 1353 font->parent = hb_font_reference (parent); 1354 1355 hb_font_destroy (old); 1356 } 1357 1358 /** 1359 * hb_font_get_parent: 1360 * @font: a font. 1361 * 1362 * 1363 * 1364 * Return value: (transfer none): 1365 * 1366 * Since: 0.9.2 1367 **/ 1368 hb_font_t * 1369 hb_font_get_parent (hb_font_t *font) 1370 { 1371 return font->parent; 1372 } 1373 1374 /** 1375 * hb_font_get_face: 1376 * @font: a font. 1377 * 1378 * 1379 * 1380 * Return value: (transfer none): 1381 * 1382 * Since: 0.9.2 1383 **/ 1384 hb_face_t * 1385 hb_font_get_face (hb_font_t *font) 1386 { 1387 return font->face; 1388 } 1389 1390 1391 /** 1392 * hb_font_set_funcs: 1393 * @font: a font. 1394 * @klass: (closure font_data) (destroy destroy) (scope notified): 1395 * @font_data: 1396 * @destroy: 1397 * 1398 * 1399 * 1400 * Since: 0.9.2 1401 **/ 1402 void 1403 hb_font_set_funcs (hb_font_t *font, 1404 hb_font_funcs_t *klass, 1405 void *font_data, 1406 hb_destroy_func_t destroy) 1407 { 1408 if (font->immutable) { 1409 if (destroy) 1410 destroy (font_data); 1411 return; 1412 } 1413 1414 if (font->destroy) 1415 font->destroy (font->user_data); 1416 1417 if (!klass) 1418 klass = hb_font_funcs_get_empty (); 1419 1420 hb_font_funcs_reference (klass); 1421 hb_font_funcs_destroy (font->klass); 1422 font->klass = klass; 1423 font->user_data = font_data; 1424 font->destroy = destroy; 1425 } 1426 1427 /** 1428 * hb_font_set_funcs_data: 1429 * @font: a font. 1430 * @font_data: (destroy destroy) (scope notified): 1431 * @destroy: 1432 * 1433 * 1434 * 1435 * Since: 0.9.2 1436 **/ 1437 void 1438 hb_font_set_funcs_data (hb_font_t *font, 1439 void *font_data, 1440 hb_destroy_func_t destroy) 1441 { 1442 /* Destroy user_data? */ 1443 if (font->immutable) { 1444 if (destroy) 1445 destroy (font_data); 1446 return; 1447 } 1448 1449 if (font->destroy) 1450 font->destroy (font->user_data); 1451 1452 font->user_data = font_data; 1453 font->destroy = destroy; 1454 } 1455 1456 1457 /** 1458 * hb_font_set_scale: 1459 * @font: a font. 1460 * @x_scale: 1461 * @y_scale: 1462 * 1463 * 1464 * 1465 * Since: 0.9.2 1466 **/ 1467 void 1468 hb_font_set_scale (hb_font_t *font, 1469 int x_scale, 1470 int y_scale) 1471 { 1472 if (font->immutable) 1473 return; 1474 1475 font->x_scale = x_scale; 1476 font->y_scale = y_scale; 1477 } 1478 1479 /** 1480 * hb_font_get_scale: 1481 * @font: a font. 1482 * @x_scale: (out): 1483 * @y_scale: (out): 1484 * 1485 * 1486 * 1487 * Since: 0.9.2 1488 **/ 1489 void 1490 hb_font_get_scale (hb_font_t *font, 1491 int *x_scale, 1492 int *y_scale) 1493 { 1494 if (x_scale) *x_scale = font->x_scale; 1495 if (y_scale) *y_scale = font->y_scale; 1496 } 1497 1498 /** 1499 * hb_font_set_ppem: 1500 * @font: a font. 1501 * @x_ppem: 1502 * @y_ppem: 1503 * 1504 * 1505 * 1506 * Since: 0.9.2 1507 **/ 1508 void 1509 hb_font_set_ppem (hb_font_t *font, 1510 unsigned int x_ppem, 1511 unsigned int y_ppem) 1512 { 1513 if (font->immutable) 1514 return; 1515 1516 font->x_ppem = x_ppem; 1517 font->y_ppem = y_ppem; 1518 } 1519 1520 /** 1521 * hb_font_get_ppem: 1522 * @font: a font. 1523 * @x_ppem: (out): 1524 * @y_ppem: (out): 1525 * 1526 * 1527 * 1528 * Since: 0.9.2 1529 **/ 1530 void 1531 hb_font_get_ppem (hb_font_t *font, 1532 unsigned int *x_ppem, 1533 unsigned int *y_ppem) 1534 { 1535 if (x_ppem) *x_ppem = font->x_ppem; 1536 if (y_ppem) *y_ppem = font->y_ppem; 1537 } 1538 1539 /* 1540 * Variations 1541 */ 1542 1543 static void 1544 _hb_font_adopt_var_coords_normalized (hb_font_t *font, 1545 int *coords, /* 2.14 normalized */ 1546 unsigned int coords_length) 1547 { 1548 free (font->coords); 1549 1550 font->coords = coords; 1551 font->num_coords = coords_length; 1552 } 1553 1554 /** 1555 * hb_font_set_variations: 1556 * 1557 * Since: 1.4.2 1558 */ 1559 void 1560 hb_font_set_variations (hb_font_t *font, 1561 const hb_variation_t *variations, 1562 unsigned int variations_length) 1563 { 1564 if (font->immutable) 1565 return; 1566 1567 if (!variations_length) 1568 { 1569 hb_font_set_var_coords_normalized (font, NULL, 0); 1570 return; 1571 } 1572 1573 unsigned int coords_length = hb_ot_var_get_axis_count (font->face); 1574 1575 int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : NULL; 1576 if (unlikely (coords_length && !normalized)) 1577 return; 1578 1579 hb_ot_var_normalize_variations (font->face, 1580 variations, variations_length, 1581 normalized, coords_length); 1582 _hb_font_adopt_var_coords_normalized (font, normalized, coords_length); 1583 } 1584 1585 /** 1586 * hb_font_set_var_coords_design: 1587 * 1588 * Since: 1.4.2 1589 */ 1590 void 1591 hb_font_set_var_coords_design (hb_font_t *font, 1592 const float *coords, 1593 unsigned int coords_length) 1594 { 1595 if (font->immutable) 1596 return; 1597 1598 int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : NULL; 1599 if (unlikely (coords_length && !normalized)) 1600 return; 1601 1602 hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized); 1603 _hb_font_adopt_var_coords_normalized (font, normalized, coords_length); 1604 } 1605 1606 /** 1607 * hb_font_set_var_coords_normalized: 1608 * 1609 * Since: 1.4.2 1610 */ 1611 void 1612 hb_font_set_var_coords_normalized (hb_font_t *font, 1613 const int *coords, /* 2.14 normalized */ 1614 unsigned int coords_length) 1615 { 1616 if (font->immutable) 1617 return; 1618 1619 int *copy = coords_length ? (int *) calloc (coords_length, sizeof (coords[0])) : NULL; 1620 if (unlikely (coords_length && !copy)) 1621 return; 1622 1623 if (coords_length) 1624 memcpy (copy, coords, coords_length * sizeof (coords[0])); 1625 1626 _hb_font_adopt_var_coords_normalized (font, copy, coords_length); 1627 } 1628 1629 /** 1630 * hb_font_set_var_coords_normalized: 1631 * 1632 * Return value is valid as long as variation coordinates of the font 1633 * are not modified. 1634 * 1635 * Since: 1.4.2 1636 */ 1637 const int * 1638 hb_font_get_var_coords_normalized (hb_font_t *font, 1639 unsigned int *length) 1640 { 1641 if (length) 1642 *length = font->num_coords; 1643 1644 return font->coords; 1645 } 1646 1647 1648 #ifndef HB_DISABLE_DEPRECATED 1649 1650 /* 1651 * Deprecated get_glyph_func(): 1652 */ 1653 1654 struct hb_trampoline_closure_t 1655 { 1656 void *user_data; 1657 hb_destroy_func_t destroy; 1658 unsigned int ref_count; 1659 }; 1660 1661 template <typename FuncType> 1662 struct hb_trampoline_t 1663 { 1664 hb_trampoline_closure_t closure; /* Must be first. */ 1665 FuncType func; 1666 }; 1667 1668 template <typename FuncType> 1669 static hb_trampoline_t<FuncType> * 1670 trampoline_create (FuncType func, 1671 void *user_data, 1672 hb_destroy_func_t destroy) 1673 { 1674 typedef hb_trampoline_t<FuncType> trampoline_t; 1675 1676 trampoline_t *trampoline = (trampoline_t *) calloc (1, sizeof (trampoline_t)); 1677 1678 if (unlikely (!trampoline)) 1679 return NULL; 1680 1681 trampoline->closure.user_data = user_data; 1682 trampoline->closure.destroy = destroy; 1683 trampoline->closure.ref_count = 1; 1684 trampoline->func = func; 1685 1686 return trampoline; 1687 } 1688 1689 static void 1690 trampoline_reference (hb_trampoline_closure_t *closure) 1691 { 1692 closure->ref_count++; 1693 } 1694 1695 static void 1696 trampoline_destroy (void *user_data) 1697 { 1698 hb_trampoline_closure_t *closure = (hb_trampoline_closure_t *) user_data; 1699 1700 if (--closure->ref_count) 1701 return; 1702 1703 if (closure->destroy) 1704 closure->destroy (closure->user_data); 1705 free (closure); 1706 } 1707 1708 typedef hb_trampoline_t<hb_font_get_glyph_func_t> hb_font_get_glyph_trampoline_t; 1709 1710 static hb_bool_t 1711 hb_font_get_nominal_glyph_trampoline (hb_font_t *font, 1712 void *font_data, 1713 hb_codepoint_t unicode, 1714 hb_codepoint_t *glyph, 1715 void *user_data) 1716 { 1717 hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data; 1718 return trampoline->func (font, font_data, unicode, 0, glyph, trampoline->closure.user_data); 1719 } 1720 1721 static hb_bool_t 1722 hb_font_get_variation_glyph_trampoline (hb_font_t *font, 1723 void *font_data, 1724 hb_codepoint_t unicode, 1725 hb_codepoint_t variation_selector, 1726 hb_codepoint_t *glyph, 1727 void *user_data) 1728 { 1729 hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data; 1730 return trampoline->func (font, font_data, unicode, variation_selector, glyph, trampoline->closure.user_data); 1731 } 1732 1733 /** 1734 * hb_font_funcs_set_glyph_func: 1735 * @ffuncs: font functions. 1736 * @func: (closure user_data) (destroy destroy) (scope notified): 1737 * @user_data: 1738 * @destroy: 1739 * 1740 * Deprecated. Use hb_font_funcs_set_nominal_glyph_func() and 1741 * hb_font_funcs_set_variation_glyph_func() instead. 1742 * 1743 * Since: 0.9.2 1744 * Deprecated: 1.2.3 1745 **/ 1746 void 1747 hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, 1748 hb_font_get_glyph_func_t func, 1749 void *user_data, hb_destroy_func_t destroy) 1750 { 1751 hb_font_get_glyph_trampoline_t *trampoline; 1752 1753 trampoline = trampoline_create (func, user_data, destroy); 1754 if (unlikely (!trampoline)) 1755 { 1756 if (destroy) 1757 destroy (user_data); 1758 return; 1759 } 1760 1761 hb_font_funcs_set_nominal_glyph_func (ffuncs, 1762 hb_font_get_nominal_glyph_trampoline, 1763 trampoline, 1764 trampoline_destroy); 1765 1766 trampoline_reference (&trampoline->closure); 1767 hb_font_funcs_set_variation_glyph_func (ffuncs, 1768 hb_font_get_variation_glyph_trampoline, 1769 trampoline, 1770 trampoline_destroy); 1771 } 1772 1773 #endif /* HB_DISABLE_DEPRECATED */ 1774