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 HB_UNUSED, 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 HB_UNUSED, 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) nullptr, 351 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 352 #undef HB_FONT_FUNC_IMPLEMENT 353 }, 354 { 355 #define HB_FONT_FUNC_IMPLEMENT(name) nullptr, 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) nullptr, 374 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 375 #undef HB_FONT_FUNC_IMPLEMENT 376 }, 377 { 378 #define HB_FONT_FUNC_IMPLEMENT(name) nullptr, 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 = nullptr; \ 567 ffuncs->destroy.name = nullptr; \ 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 font->ptem = parent->ptem; 1161 1162 font->num_coords = parent->num_coords; 1163 if (!font->num_coords) 1164 font->coords = nullptr; 1165 else 1166 { 1167 unsigned int size = parent->num_coords * sizeof (parent->coords[0]); 1168 font->coords = (int *) malloc (size); 1169 if (unlikely (!font->coords)) 1170 font->num_coords = 0; 1171 else 1172 memcpy (font->coords, parent->coords, size); 1173 } 1174 1175 return font; 1176 } 1177 1178 /** 1179 * hb_font_get_empty: 1180 * 1181 * 1182 * 1183 * Return value: (transfer full) 1184 * 1185 * Since: 0.9.2 1186 **/ 1187 hb_font_t * 1188 hb_font_get_empty (void) 1189 { 1190 static const hb_font_t _hb_font_nil = { 1191 HB_OBJECT_HEADER_STATIC, 1192 1193 true, /* immutable */ 1194 1195 nullptr, /* parent */ 1196 const_cast<hb_face_t *> (&_hb_face_nil), 1197 1198 1000, /* x_scale */ 1199 1000, /* y_scale */ 1200 1201 0, /* x_ppem */ 1202 0, /* y_ppem */ 1203 0, /* ptem */ 1204 1205 0, /* num_coords */ 1206 nullptr, /* coords */ 1207 1208 const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil), /* klass */ 1209 nullptr, /* user_data */ 1210 nullptr, /* destroy */ 1211 1212 { 1213 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID, 1214 #include "hb-shaper-list.hh" 1215 #undef HB_SHAPER_IMPLEMENT 1216 } 1217 }; 1218 1219 return const_cast<hb_font_t *> (&_hb_font_nil); 1220 } 1221 1222 /** 1223 * hb_font_reference: (skip) 1224 * @font: a font. 1225 * 1226 * 1227 * 1228 * Return value: (transfer full): 1229 * 1230 * Since: 0.9.2 1231 **/ 1232 hb_font_t * 1233 hb_font_reference (hb_font_t *font) 1234 { 1235 return hb_object_reference (font); 1236 } 1237 1238 /** 1239 * hb_font_destroy: (skip) 1240 * @font: a font. 1241 * 1242 * 1243 * 1244 * Since: 0.9.2 1245 **/ 1246 void 1247 hb_font_destroy (hb_font_t *font) 1248 { 1249 if (!hb_object_destroy (font)) return; 1250 1251 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, font); 1252 #include "hb-shaper-list.hh" 1253 #undef HB_SHAPER_IMPLEMENT 1254 1255 if (font->destroy) 1256 font->destroy (font->user_data); 1257 1258 hb_font_destroy (font->parent); 1259 hb_face_destroy (font->face); 1260 hb_font_funcs_destroy (font->klass); 1261 1262 free (font->coords); 1263 1264 free (font); 1265 } 1266 1267 /** 1268 * hb_font_set_user_data: (skip) 1269 * @font: a font. 1270 * @key: 1271 * @data: 1272 * @destroy: 1273 * @replace: 1274 * 1275 * 1276 * 1277 * Return value: 1278 * 1279 * Since: 0.9.2 1280 **/ 1281 hb_bool_t 1282 hb_font_set_user_data (hb_font_t *font, 1283 hb_user_data_key_t *key, 1284 void * data, 1285 hb_destroy_func_t destroy, 1286 hb_bool_t replace) 1287 { 1288 return hb_object_set_user_data (font, key, data, destroy, replace); 1289 } 1290 1291 /** 1292 * hb_font_get_user_data: (skip) 1293 * @font: a font. 1294 * @key: 1295 * 1296 * 1297 * 1298 * Return value: (transfer none): 1299 * 1300 * Since: 0.9.2 1301 **/ 1302 void * 1303 hb_font_get_user_data (hb_font_t *font, 1304 hb_user_data_key_t *key) 1305 { 1306 return hb_object_get_user_data (font, key); 1307 } 1308 1309 /** 1310 * hb_font_make_immutable: 1311 * @font: a font. 1312 * 1313 * 1314 * 1315 * Since: 0.9.2 1316 **/ 1317 void 1318 hb_font_make_immutable (hb_font_t *font) 1319 { 1320 if (unlikely (hb_object_is_inert (font))) 1321 return; 1322 1323 if (font->parent) 1324 hb_font_make_immutable (font->parent); 1325 1326 font->immutable = true; 1327 } 1328 1329 /** 1330 * hb_font_is_immutable: 1331 * @font: a font. 1332 * 1333 * 1334 * 1335 * Return value: 1336 * 1337 * Since: 0.9.2 1338 **/ 1339 hb_bool_t 1340 hb_font_is_immutable (hb_font_t *font) 1341 { 1342 return font->immutable; 1343 } 1344 1345 /** 1346 * hb_font_set_parent: 1347 * @font: a font. 1348 * @parent: new parent. 1349 * 1350 * Sets parent font of @font. 1351 * 1352 * Since: 1.0.5 1353 **/ 1354 void 1355 hb_font_set_parent (hb_font_t *font, 1356 hb_font_t *parent) 1357 { 1358 if (font->immutable) 1359 return; 1360 1361 if (!parent) 1362 parent = hb_font_get_empty (); 1363 1364 hb_font_t *old = font->parent; 1365 1366 font->parent = hb_font_reference (parent); 1367 1368 hb_font_destroy (old); 1369 } 1370 1371 /** 1372 * hb_font_get_parent: 1373 * @font: a font. 1374 * 1375 * 1376 * 1377 * Return value: (transfer none): 1378 * 1379 * Since: 0.9.2 1380 **/ 1381 hb_font_t * 1382 hb_font_get_parent (hb_font_t *font) 1383 { 1384 return font->parent; 1385 } 1386 1387 /** 1388 * hb_font_set_face: 1389 * @font: a font. 1390 * @face: new face. 1391 * 1392 * Sets font-face of @font. 1393 * 1394 * Since: 1.4.3 1395 **/ 1396 void 1397 hb_font_set_face (hb_font_t *font, 1398 hb_face_t *face) 1399 { 1400 if (font->immutable) 1401 return; 1402 1403 if (unlikely (!face)) 1404 face = hb_face_get_empty (); 1405 1406 hb_face_t *old = font->face; 1407 1408 font->face = hb_face_reference (face); 1409 1410 hb_face_destroy (old); 1411 } 1412 1413 /** 1414 * hb_font_get_face: 1415 * @font: a font. 1416 * 1417 * 1418 * 1419 * Return value: (transfer none): 1420 * 1421 * Since: 0.9.2 1422 **/ 1423 hb_face_t * 1424 hb_font_get_face (hb_font_t *font) 1425 { 1426 return font->face; 1427 } 1428 1429 1430 /** 1431 * hb_font_set_funcs: 1432 * @font: a font. 1433 * @klass: (closure font_data) (destroy destroy) (scope notified): 1434 * @font_data: 1435 * @destroy: 1436 * 1437 * 1438 * 1439 * Since: 0.9.2 1440 **/ 1441 void 1442 hb_font_set_funcs (hb_font_t *font, 1443 hb_font_funcs_t *klass, 1444 void *font_data, 1445 hb_destroy_func_t destroy) 1446 { 1447 if (font->immutable) { 1448 if (destroy) 1449 destroy (font_data); 1450 return; 1451 } 1452 1453 if (font->destroy) 1454 font->destroy (font->user_data); 1455 1456 if (!klass) 1457 klass = hb_font_funcs_get_empty (); 1458 1459 hb_font_funcs_reference (klass); 1460 hb_font_funcs_destroy (font->klass); 1461 font->klass = klass; 1462 font->user_data = font_data; 1463 font->destroy = destroy; 1464 } 1465 1466 /** 1467 * hb_font_set_funcs_data: 1468 * @font: a font. 1469 * @font_data: (destroy destroy) (scope notified): 1470 * @destroy: 1471 * 1472 * 1473 * 1474 * Since: 0.9.2 1475 **/ 1476 void 1477 hb_font_set_funcs_data (hb_font_t *font, 1478 void *font_data, 1479 hb_destroy_func_t destroy) 1480 { 1481 /* Destroy user_data? */ 1482 if (font->immutable) { 1483 if (destroy) 1484 destroy (font_data); 1485 return; 1486 } 1487 1488 if (font->destroy) 1489 font->destroy (font->user_data); 1490 1491 font->user_data = font_data; 1492 font->destroy = destroy; 1493 } 1494 1495 1496 /** 1497 * hb_font_set_scale: 1498 * @font: a font. 1499 * @x_scale: 1500 * @y_scale: 1501 * 1502 * 1503 * 1504 * Since: 0.9.2 1505 **/ 1506 void 1507 hb_font_set_scale (hb_font_t *font, 1508 int x_scale, 1509 int y_scale) 1510 { 1511 if (font->immutable) 1512 return; 1513 1514 font->x_scale = x_scale; 1515 font->y_scale = y_scale; 1516 } 1517 1518 /** 1519 * hb_font_get_scale: 1520 * @font: a font. 1521 * @x_scale: (out): 1522 * @y_scale: (out): 1523 * 1524 * 1525 * 1526 * Since: 0.9.2 1527 **/ 1528 void 1529 hb_font_get_scale (hb_font_t *font, 1530 int *x_scale, 1531 int *y_scale) 1532 { 1533 if (x_scale) *x_scale = font->x_scale; 1534 if (y_scale) *y_scale = font->y_scale; 1535 } 1536 1537 /** 1538 * hb_font_set_ppem: 1539 * @font: a font. 1540 * @x_ppem: 1541 * @y_ppem: 1542 * 1543 * 1544 * 1545 * Since: 0.9.2 1546 **/ 1547 void 1548 hb_font_set_ppem (hb_font_t *font, 1549 unsigned int x_ppem, 1550 unsigned int y_ppem) 1551 { 1552 if (font->immutable) 1553 return; 1554 1555 font->x_ppem = x_ppem; 1556 font->y_ppem = y_ppem; 1557 } 1558 1559 /** 1560 * hb_font_get_ppem: 1561 * @font: a font. 1562 * @x_ppem: (out): 1563 * @y_ppem: (out): 1564 * 1565 * 1566 * 1567 * Since: 0.9.2 1568 **/ 1569 void 1570 hb_font_get_ppem (hb_font_t *font, 1571 unsigned int *x_ppem, 1572 unsigned int *y_ppem) 1573 { 1574 if (x_ppem) *x_ppem = font->x_ppem; 1575 if (y_ppem) *y_ppem = font->y_ppem; 1576 } 1577 1578 /** 1579 * hb_font_set_ptem: 1580 * @font: a font. 1581 * @ptem: 1582 * 1583 * Sets "point size" of the font. 1584 * 1585 * Since: 1.6.0 1586 **/ 1587 void 1588 hb_font_set_ptem (hb_font_t *font, float ptem) 1589 { 1590 if (font->immutable) 1591 return; 1592 1593 font->ptem = ptem; 1594 } 1595 1596 /** 1597 * hb_font_get_ptem: 1598 * @font: a font. 1599 * 1600 * Gets the "point size" of the font. A value of 0 means unset. 1601 * 1602 * Return value: Point size. 1603 * 1604 * Since: 0.9.2 1605 **/ 1606 float 1607 hb_font_get_ptem (hb_font_t *font) 1608 { 1609 return font->ptem; 1610 } 1611 1612 /* 1613 * Variations 1614 */ 1615 1616 static void 1617 _hb_font_adopt_var_coords_normalized (hb_font_t *font, 1618 int *coords, /* 2.14 normalized */ 1619 unsigned int coords_length) 1620 { 1621 free (font->coords); 1622 1623 font->coords = coords; 1624 font->num_coords = coords_length; 1625 } 1626 1627 /** 1628 * hb_font_set_variations: 1629 * 1630 * Since: 1.4.2 1631 */ 1632 void 1633 hb_font_set_variations (hb_font_t *font, 1634 const hb_variation_t *variations, 1635 unsigned int variations_length) 1636 { 1637 if (font->immutable) 1638 return; 1639 1640 if (!variations_length) 1641 { 1642 hb_font_set_var_coords_normalized (font, nullptr, 0); 1643 return; 1644 } 1645 1646 unsigned int coords_length = hb_ot_var_get_axis_count (font->face); 1647 1648 int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : nullptr; 1649 if (unlikely (coords_length && !normalized)) 1650 return; 1651 1652 hb_ot_var_normalize_variations (font->face, 1653 variations, variations_length, 1654 normalized, coords_length); 1655 _hb_font_adopt_var_coords_normalized (font, normalized, coords_length); 1656 } 1657 1658 /** 1659 * hb_font_set_var_coords_design: 1660 * 1661 * Since: 1.4.2 1662 */ 1663 void 1664 hb_font_set_var_coords_design (hb_font_t *font, 1665 const float *coords, 1666 unsigned int coords_length) 1667 { 1668 if (font->immutable) 1669 return; 1670 1671 int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : nullptr; 1672 if (unlikely (coords_length && !normalized)) 1673 return; 1674 1675 hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized); 1676 _hb_font_adopt_var_coords_normalized (font, normalized, coords_length); 1677 } 1678 1679 /** 1680 * hb_font_set_var_coords_normalized: 1681 * 1682 * Since: 1.4.2 1683 */ 1684 void 1685 hb_font_set_var_coords_normalized (hb_font_t *font, 1686 const int *coords, /* 2.14 normalized */ 1687 unsigned int coords_length) 1688 { 1689 if (font->immutable) 1690 return; 1691 1692 int *copy = coords_length ? (int *) calloc (coords_length, sizeof (coords[0])) : nullptr; 1693 if (unlikely (coords_length && !copy)) 1694 return; 1695 1696 if (coords_length) 1697 memcpy (copy, coords, coords_length * sizeof (coords[0])); 1698 1699 _hb_font_adopt_var_coords_normalized (font, copy, coords_length); 1700 } 1701 1702 /** 1703 * hb_font_get_var_coords_normalized: 1704 * 1705 * Return value is valid as long as variation coordinates of the font 1706 * are not modified. 1707 * 1708 * Since: 1.4.2 1709 */ 1710 const int * 1711 hb_font_get_var_coords_normalized (hb_font_t *font, 1712 unsigned int *length) 1713 { 1714 if (length) 1715 *length = font->num_coords; 1716 1717 return font->coords; 1718 } 1719 1720 1721 #ifndef HB_DISABLE_DEPRECATED 1722 1723 /* 1724 * Deprecated get_glyph_func(): 1725 */ 1726 1727 struct hb_trampoline_closure_t 1728 { 1729 void *user_data; 1730 hb_destroy_func_t destroy; 1731 unsigned int ref_count; 1732 }; 1733 1734 template <typename FuncType> 1735 struct hb_trampoline_t 1736 { 1737 hb_trampoline_closure_t closure; /* Must be first. */ 1738 FuncType func; 1739 }; 1740 1741 template <typename FuncType> 1742 static hb_trampoline_t<FuncType> * 1743 trampoline_create (FuncType func, 1744 void *user_data, 1745 hb_destroy_func_t destroy) 1746 { 1747 typedef hb_trampoline_t<FuncType> trampoline_t; 1748 1749 trampoline_t *trampoline = (trampoline_t *) calloc (1, sizeof (trampoline_t)); 1750 1751 if (unlikely (!trampoline)) 1752 return nullptr; 1753 1754 trampoline->closure.user_data = user_data; 1755 trampoline->closure.destroy = destroy; 1756 trampoline->closure.ref_count = 1; 1757 trampoline->func = func; 1758 1759 return trampoline; 1760 } 1761 1762 static void 1763 trampoline_reference (hb_trampoline_closure_t *closure) 1764 { 1765 closure->ref_count++; 1766 } 1767 1768 static void 1769 trampoline_destroy (void *user_data) 1770 { 1771 hb_trampoline_closure_t *closure = (hb_trampoline_closure_t *) user_data; 1772 1773 if (--closure->ref_count) 1774 return; 1775 1776 if (closure->destroy) 1777 closure->destroy (closure->user_data); 1778 free (closure); 1779 } 1780 1781 typedef hb_trampoline_t<hb_font_get_glyph_func_t> hb_font_get_glyph_trampoline_t; 1782 1783 static hb_bool_t 1784 hb_font_get_nominal_glyph_trampoline (hb_font_t *font, 1785 void *font_data, 1786 hb_codepoint_t unicode, 1787 hb_codepoint_t *glyph, 1788 void *user_data) 1789 { 1790 hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data; 1791 return trampoline->func (font, font_data, unicode, 0, glyph, trampoline->closure.user_data); 1792 } 1793 1794 static hb_bool_t 1795 hb_font_get_variation_glyph_trampoline (hb_font_t *font, 1796 void *font_data, 1797 hb_codepoint_t unicode, 1798 hb_codepoint_t variation_selector, 1799 hb_codepoint_t *glyph, 1800 void *user_data) 1801 { 1802 hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data; 1803 return trampoline->func (font, font_data, unicode, variation_selector, glyph, trampoline->closure.user_data); 1804 } 1805 1806 /** 1807 * hb_font_funcs_set_glyph_func: 1808 * @ffuncs: font functions. 1809 * @func: (closure user_data) (destroy destroy) (scope notified): 1810 * @user_data: 1811 * @destroy: 1812 * 1813 * Deprecated. Use hb_font_funcs_set_nominal_glyph_func() and 1814 * hb_font_funcs_set_variation_glyph_func() instead. 1815 * 1816 * Since: 0.9.2 1817 * Deprecated: 1.2.3 1818 **/ 1819 void 1820 hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, 1821 hb_font_get_glyph_func_t func, 1822 void *user_data, hb_destroy_func_t destroy) 1823 { 1824 hb_font_get_glyph_trampoline_t *trampoline; 1825 1826 trampoline = trampoline_create (func, user_data, destroy); 1827 if (unlikely (!trampoline)) 1828 { 1829 if (destroy) 1830 destroy (user_data); 1831 return; 1832 } 1833 1834 hb_font_funcs_set_nominal_glyph_func (ffuncs, 1835 hb_font_get_nominal_glyph_trampoline, 1836 trampoline, 1837 trampoline_destroy); 1838 1839 trampoline_reference (&trampoline->closure); 1840 hb_font_funcs_set_variation_glyph_func (ffuncs, 1841 hb_font_get_variation_glyph_trampoline, 1842 trampoline, 1843 trampoline_destroy); 1844 } 1845 1846 #endif /* HB_DISABLE_DEPRECATED */ 1847