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-ot-layout-private.hh" 32 33 #include "hb-font-private.hh" 34 #include "hb-open-file-private.hh" 35 #include "hb-ot-head-table.hh" 36 #include "hb-ot-maxp-table.hh" 37 38 #include "hb-cache-private.hh" 39 40 #include <string.h> 41 42 43 /* 44 * hb_font_funcs_t 45 */ 46 47 static hb_bool_t 48 hb_font_get_glyph_nil (hb_font_t *font, 49 void *font_data HB_UNUSED, 50 hb_codepoint_t unicode, 51 hb_codepoint_t variation_selector, 52 hb_codepoint_t *glyph, 53 void *user_data HB_UNUSED) 54 { 55 if (font->parent) 56 return font->parent->get_glyph (unicode, variation_selector, glyph); 57 58 *glyph = 0; 59 return false; 60 } 61 62 static hb_position_t 63 hb_font_get_glyph_h_advance_nil (hb_font_t *font, 64 void *font_data HB_UNUSED, 65 hb_codepoint_t glyph, 66 void *user_data HB_UNUSED) 67 { 68 if (font->parent) 69 return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph)); 70 71 return font->x_scale; 72 } 73 74 static hb_position_t 75 hb_font_get_glyph_v_advance_nil (hb_font_t *font, 76 void *font_data HB_UNUSED, 77 hb_codepoint_t glyph, 78 void *user_data HB_UNUSED) 79 { 80 if (font->parent) 81 return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph)); 82 83 return font->y_scale; 84 } 85 86 static hb_bool_t 87 hb_font_get_glyph_h_origin_nil (hb_font_t *font, 88 void *font_data HB_UNUSED, 89 hb_codepoint_t glyph, 90 hb_position_t *x, 91 hb_position_t *y, 92 void *user_data HB_UNUSED) 93 { 94 if (font->parent) { 95 hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y); 96 if (ret) 97 font->parent_scale_position (x, y); 98 return ret; 99 } 100 101 *x = *y = 0; 102 return false; 103 } 104 105 static hb_bool_t 106 hb_font_get_glyph_v_origin_nil (hb_font_t *font, 107 void *font_data HB_UNUSED, 108 hb_codepoint_t glyph, 109 hb_position_t *x, 110 hb_position_t *y, 111 void *user_data HB_UNUSED) 112 { 113 if (font->parent) { 114 hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y); 115 if (ret) 116 font->parent_scale_position (x, y); 117 return ret; 118 } 119 120 *x = *y = 0; 121 return false; 122 } 123 124 static hb_position_t 125 hb_font_get_glyph_h_kerning_nil (hb_font_t *font, 126 void *font_data HB_UNUSED, 127 hb_codepoint_t left_glyph, 128 hb_codepoint_t right_glyph, 129 void *user_data HB_UNUSED) 130 { 131 if (font->parent) 132 return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph)); 133 134 return 0; 135 } 136 137 static hb_position_t 138 hb_font_get_glyph_v_kerning_nil (hb_font_t *font, 139 void *font_data HB_UNUSED, 140 hb_codepoint_t top_glyph, 141 hb_codepoint_t bottom_glyph, 142 void *user_data HB_UNUSED) 143 { 144 if (font->parent) 145 return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph)); 146 147 return 0; 148 } 149 150 static hb_bool_t 151 hb_font_get_glyph_extents_nil (hb_font_t *font, 152 void *font_data HB_UNUSED, 153 hb_codepoint_t glyph, 154 hb_glyph_extents_t *extents, 155 void *user_data HB_UNUSED) 156 { 157 if (font->parent) { 158 hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents); 159 if (ret) { 160 font->parent_scale_position (&extents->x_bearing, &extents->y_bearing); 161 font->parent_scale_distance (&extents->width, &extents->height); 162 } 163 return ret; 164 } 165 166 memset (extents, 0, sizeof (*extents)); 167 return false; 168 } 169 170 static hb_bool_t 171 hb_font_get_glyph_contour_point_nil (hb_font_t *font, 172 void *font_data HB_UNUSED, 173 hb_codepoint_t glyph, 174 unsigned int point_index, 175 hb_position_t *x, 176 hb_position_t *y, 177 void *user_data HB_UNUSED) 178 { 179 if (font->parent) { 180 hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y); 181 if (ret) 182 font->parent_scale_position (x, y); 183 return ret; 184 } 185 186 *x = *y = 0; 187 return false; 188 } 189 190 static hb_bool_t 191 hb_font_get_glyph_name_nil (hb_font_t *font, 192 void *font_data HB_UNUSED, 193 hb_codepoint_t glyph, 194 char *name, unsigned int size, 195 void *user_data HB_UNUSED) 196 { 197 if (font->parent) 198 return font->parent->get_glyph_name (glyph, name, size); 199 200 if (size) *name = '\0'; 201 return false; 202 } 203 204 static hb_bool_t 205 hb_font_get_glyph_from_name_nil (hb_font_t *font, 206 void *font_data HB_UNUSED, 207 const char *name, int len, /* -1 means nul-terminated */ 208 hb_codepoint_t *glyph, 209 void *user_data HB_UNUSED) 210 { 211 if (font->parent) 212 return font->parent->get_glyph_from_name (name, len, glyph); 213 214 *glyph = 0; 215 return false; 216 } 217 218 219 static const hb_font_funcs_t _hb_font_funcs_nil = { 220 HB_OBJECT_HEADER_STATIC, 221 222 true, /* immutable */ 223 224 { 225 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil, 226 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 227 #undef HB_FONT_FUNC_IMPLEMENT 228 } 229 }; 230 231 232 /** 233 * hb_font_funcs_create: (Xconstructor) 234 * 235 * 236 * 237 * Return value: (transfer full): 238 * 239 * Since: 0.9.2 240 **/ 241 hb_font_funcs_t * 242 hb_font_funcs_create (void) 243 { 244 hb_font_funcs_t *ffuncs; 245 246 if (!(ffuncs = hb_object_create<hb_font_funcs_t> ())) 247 return hb_font_funcs_get_empty (); 248 249 ffuncs->get = _hb_font_funcs_nil.get; 250 251 return ffuncs; 252 } 253 254 /** 255 * hb_font_funcs_get_empty: 256 * 257 * 258 * 259 * Return value: (transfer full): 260 * 261 * Since: 0.9.2 262 **/ 263 hb_font_funcs_t * 264 hb_font_funcs_get_empty (void) 265 { 266 return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil); 267 } 268 269 /** 270 * hb_font_funcs_reference: (skip) 271 * @ffuncs: font functions. 272 * 273 * 274 * 275 * Return value: 276 * 277 * Since: 0.9.2 278 **/ 279 hb_font_funcs_t * 280 hb_font_funcs_reference (hb_font_funcs_t *ffuncs) 281 { 282 return hb_object_reference (ffuncs); 283 } 284 285 /** 286 * hb_font_funcs_destroy: (skip) 287 * @ffuncs: font functions. 288 * 289 * 290 * 291 * Since: 0.9.2 292 **/ 293 void 294 hb_font_funcs_destroy (hb_font_funcs_t *ffuncs) 295 { 296 if (!hb_object_destroy (ffuncs)) return; 297 298 #define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \ 299 ffuncs->destroy.name (ffuncs->user_data.name); 300 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 301 #undef HB_FONT_FUNC_IMPLEMENT 302 303 free (ffuncs); 304 } 305 306 /** 307 * hb_font_funcs_set_user_data: (skip) 308 * @ffuncs: font functions. 309 * @key: 310 * @data: 311 * @destroy: 312 * @replace: 313 * 314 * 315 * 316 * Return value: 317 * 318 * Since: 0.9.2 319 **/ 320 hb_bool_t 321 hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs, 322 hb_user_data_key_t *key, 323 void * data, 324 hb_destroy_func_t destroy, 325 hb_bool_t replace) 326 { 327 return hb_object_set_user_data (ffuncs, key, data, destroy, replace); 328 } 329 330 /** 331 * hb_font_funcs_get_user_data: (skip) 332 * @ffuncs: font functions. 333 * @key: 334 * 335 * 336 * 337 * Return value: (transfer none): 338 * 339 * Since: 0.9.2 340 **/ 341 void * 342 hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs, 343 hb_user_data_key_t *key) 344 { 345 return hb_object_get_user_data (ffuncs, key); 346 } 347 348 349 /** 350 * hb_font_funcs_make_immutable: 351 * @ffuncs: font functions. 352 * 353 * 354 * 355 * Since: 0.9.2 356 **/ 357 void 358 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs) 359 { 360 if (unlikely (hb_object_is_inert (ffuncs))) 361 return; 362 363 ffuncs->immutable = true; 364 } 365 366 /** 367 * hb_font_funcs_is_immutable: 368 * @ffuncs: font functions. 369 * 370 * 371 * 372 * Return value: 373 * 374 * Since: 0.9.2 375 **/ 376 hb_bool_t 377 hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs) 378 { 379 return ffuncs->immutable; 380 } 381 382 383 #define HB_FONT_FUNC_IMPLEMENT(name) \ 384 \ 385 void \ 386 hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \ 387 hb_font_get_##name##_func_t func, \ 388 void *user_data, \ 389 hb_destroy_func_t destroy) \ 390 { \ 391 if (ffuncs->immutable) { \ 392 if (destroy) \ 393 destroy (user_data); \ 394 return; \ 395 } \ 396 \ 397 if (ffuncs->destroy.name) \ 398 ffuncs->destroy.name (ffuncs->user_data.name); \ 399 \ 400 if (func) { \ 401 ffuncs->get.name = func; \ 402 ffuncs->user_data.name = user_data; \ 403 ffuncs->destroy.name = destroy; \ 404 } else { \ 405 ffuncs->get.name = hb_font_get_##name##_nil; \ 406 ffuncs->user_data.name = NULL; \ 407 ffuncs->destroy.name = NULL; \ 408 } \ 409 } 410 411 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 412 #undef HB_FONT_FUNC_IMPLEMENT 413 414 415 /* Public getters */ 416 417 /** 418 * hb_font_get_glyph: 419 * @font: a font. 420 * @unicode: 421 * @variation_selector: 422 * @glyph: (out): 423 * 424 * 425 * 426 * Return value: 427 * 428 * Since: 0.9.2 429 **/ 430 hb_bool_t 431 hb_font_get_glyph (hb_font_t *font, 432 hb_codepoint_t unicode, hb_codepoint_t variation_selector, 433 hb_codepoint_t *glyph) 434 { 435 return font->get_glyph (unicode, variation_selector, glyph); 436 } 437 438 /** 439 * hb_font_get_glyph_h_advance: 440 * @font: a font. 441 * @glyph: 442 * 443 * 444 * 445 * Return value: 446 * 447 * Since: 0.9.2 448 **/ 449 hb_position_t 450 hb_font_get_glyph_h_advance (hb_font_t *font, 451 hb_codepoint_t glyph) 452 { 453 return font->get_glyph_h_advance (glyph); 454 } 455 456 /** 457 * hb_font_get_glyph_v_advance: 458 * @font: a font. 459 * @glyph: 460 * 461 * 462 * 463 * Return value: 464 * 465 * Since: 0.9.2 466 **/ 467 hb_position_t 468 hb_font_get_glyph_v_advance (hb_font_t *font, 469 hb_codepoint_t glyph) 470 { 471 return font->get_glyph_v_advance (glyph); 472 } 473 474 /** 475 * hb_font_get_glyph_h_origin: 476 * @font: a font. 477 * @glyph: 478 * @x: (out): 479 * @y: (out): 480 * 481 * 482 * 483 * Return value: 484 * 485 * Since: 0.9.2 486 **/ 487 hb_bool_t 488 hb_font_get_glyph_h_origin (hb_font_t *font, 489 hb_codepoint_t glyph, 490 hb_position_t *x, hb_position_t *y) 491 { 492 return font->get_glyph_h_origin (glyph, x, y); 493 } 494 495 /** 496 * hb_font_get_glyph_v_origin: 497 * @font: a font. 498 * @glyph: 499 * @x: (out): 500 * @y: (out): 501 * 502 * 503 * 504 * Return value: 505 * 506 * Since: 0.9.2 507 **/ 508 hb_bool_t 509 hb_font_get_glyph_v_origin (hb_font_t *font, 510 hb_codepoint_t glyph, 511 hb_position_t *x, hb_position_t *y) 512 { 513 return font->get_glyph_v_origin (glyph, x, y); 514 } 515 516 /** 517 * hb_font_get_glyph_h_kerning: 518 * @font: a font. 519 * @left_glyph: 520 * @right_glyph: 521 * 522 * 523 * 524 * Return value: 525 * 526 * Since: 0.9.2 527 **/ 528 hb_position_t 529 hb_font_get_glyph_h_kerning (hb_font_t *font, 530 hb_codepoint_t left_glyph, hb_codepoint_t right_glyph) 531 { 532 return font->get_glyph_h_kerning (left_glyph, right_glyph); 533 } 534 535 /** 536 * hb_font_get_glyph_v_kerning: 537 * @font: a font. 538 * @top_glyph: 539 * @bottom_glyph: 540 * 541 * 542 * 543 * Return value: 544 * 545 * Since: 0.9.2 546 **/ 547 hb_position_t 548 hb_font_get_glyph_v_kerning (hb_font_t *font, 549 hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph) 550 { 551 return font->get_glyph_v_kerning (top_glyph, bottom_glyph); 552 } 553 554 /** 555 * hb_font_get_glyph_extents: 556 * @font: a font. 557 * @glyph: 558 * @extents: (out): 559 * 560 * 561 * 562 * Return value: 563 * 564 * Since: 0.9.2 565 **/ 566 hb_bool_t 567 hb_font_get_glyph_extents (hb_font_t *font, 568 hb_codepoint_t glyph, 569 hb_glyph_extents_t *extents) 570 { 571 return font->get_glyph_extents (glyph, extents); 572 } 573 574 /** 575 * hb_font_get_glyph_contour_point: 576 * @font: a font. 577 * @glyph: 578 * @point_index: 579 * @x: (out): 580 * @y: (out): 581 * 582 * 583 * 584 * Return value: 585 * 586 * Since: 0.9.2 587 **/ 588 hb_bool_t 589 hb_font_get_glyph_contour_point (hb_font_t *font, 590 hb_codepoint_t glyph, unsigned int point_index, 591 hb_position_t *x, hb_position_t *y) 592 { 593 return font->get_glyph_contour_point (glyph, point_index, x, y); 594 } 595 596 /** 597 * hb_font_get_glyph_name: 598 * @font: a font. 599 * @glyph: 600 * @name: (array length=size): 601 * @size: 602 * 603 * 604 * 605 * Return value: 606 * 607 * Since: 0.9.2 608 **/ 609 hb_bool_t 610 hb_font_get_glyph_name (hb_font_t *font, 611 hb_codepoint_t glyph, 612 char *name, unsigned int size) 613 { 614 return font->get_glyph_name (glyph, name, size); 615 } 616 617 /** 618 * hb_font_get_glyph_from_name: 619 * @font: a font. 620 * @name: (array length=len): 621 * @len: 622 * @glyph: (out): 623 * 624 * 625 * 626 * Return value: 627 * 628 * Since: 0.9.2 629 **/ 630 hb_bool_t 631 hb_font_get_glyph_from_name (hb_font_t *font, 632 const char *name, int len, /* -1 means nul-terminated */ 633 hb_codepoint_t *glyph) 634 { 635 return font->get_glyph_from_name (name, len, glyph); 636 } 637 638 639 /* A bit higher-level, and with fallback */ 640 641 /** 642 * hb_font_get_glyph_advance_for_direction: 643 * @font: a font. 644 * @glyph: 645 * @direction: 646 * @x: (out): 647 * @y: (out): 648 * 649 * 650 * 651 * Since: 0.9.2 652 **/ 653 void 654 hb_font_get_glyph_advance_for_direction (hb_font_t *font, 655 hb_codepoint_t glyph, 656 hb_direction_t direction, 657 hb_position_t *x, hb_position_t *y) 658 { 659 return font->get_glyph_advance_for_direction (glyph, direction, x, y); 660 } 661 662 /** 663 * hb_font_get_glyph_origin_for_direction: 664 * @font: a font. 665 * @glyph: 666 * @direction: 667 * @x: (out): 668 * @y: (out): 669 * 670 * 671 * 672 * Since: 0.9.2 673 **/ 674 void 675 hb_font_get_glyph_origin_for_direction (hb_font_t *font, 676 hb_codepoint_t glyph, 677 hb_direction_t direction, 678 hb_position_t *x, hb_position_t *y) 679 { 680 return font->get_glyph_origin_for_direction (glyph, direction, x, y); 681 } 682 683 /** 684 * hb_font_add_glyph_origin_for_direction: 685 * @font: a font. 686 * @glyph: 687 * @direction: 688 * @x: (out): 689 * @y: (out): 690 * 691 * 692 * 693 * Since: 0.9.2 694 **/ 695 void 696 hb_font_add_glyph_origin_for_direction (hb_font_t *font, 697 hb_codepoint_t glyph, 698 hb_direction_t direction, 699 hb_position_t *x, hb_position_t *y) 700 { 701 return font->add_glyph_origin_for_direction (glyph, direction, x, y); 702 } 703 704 /** 705 * hb_font_subtract_glyph_origin_for_direction: 706 * @font: a font. 707 * @glyph: 708 * @direction: 709 * @x: (out): 710 * @y: (out): 711 * 712 * 713 * 714 * Since: 0.9.2 715 **/ 716 void 717 hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, 718 hb_codepoint_t glyph, 719 hb_direction_t direction, 720 hb_position_t *x, hb_position_t *y) 721 { 722 return font->subtract_glyph_origin_for_direction (glyph, direction, x, y); 723 } 724 725 /** 726 * hb_font_get_glyph_kerning_for_direction: 727 * @font: a font. 728 * @first_glyph: 729 * @second_glyph: 730 * @direction: 731 * @x: (out): 732 * @y: (out): 733 * 734 * 735 * 736 * Since: 0.9.2 737 **/ 738 void 739 hb_font_get_glyph_kerning_for_direction (hb_font_t *font, 740 hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, 741 hb_direction_t direction, 742 hb_position_t *x, hb_position_t *y) 743 { 744 return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y); 745 } 746 747 /** 748 * hb_font_get_glyph_extents_for_origin: 749 * @font: a font. 750 * @glyph: 751 * @direction: 752 * @extents: (out): 753 * 754 * 755 * 756 * Return value: 757 * 758 * Since: 0.9.2 759 **/ 760 hb_bool_t 761 hb_font_get_glyph_extents_for_origin (hb_font_t *font, 762 hb_codepoint_t glyph, 763 hb_direction_t direction, 764 hb_glyph_extents_t *extents) 765 { 766 return font->get_glyph_extents_for_origin (glyph, direction, extents); 767 } 768 769 /** 770 * hb_font_get_glyph_contour_point_for_origin: 771 * @font: a font. 772 * @glyph: 773 * @point_index: 774 * @direction: 775 * @x: (out): 776 * @y: (out): 777 * 778 * 779 * 780 * Return value: 781 * 782 * Since: 0.9.2 783 **/ 784 hb_bool_t 785 hb_font_get_glyph_contour_point_for_origin (hb_font_t *font, 786 hb_codepoint_t glyph, unsigned int point_index, 787 hb_direction_t direction, 788 hb_position_t *x, hb_position_t *y) 789 { 790 return font->get_glyph_contour_point_for_origin (glyph, point_index, direction, x, y); 791 } 792 793 /* Generates gidDDD if glyph has no name. */ 794 /** 795 * hb_font_glyph_to_string: 796 * @font: a font. 797 * @glyph: 798 * @s: (array length=size): 799 * @size: 800 * 801 * 802 * 803 * Since: 0.9.2 804 **/ 805 void 806 hb_font_glyph_to_string (hb_font_t *font, 807 hb_codepoint_t glyph, 808 char *s, unsigned int size) 809 { 810 font->glyph_to_string (glyph, s, size); 811 } 812 813 /* Parses gidDDD and uniUUUU strings automatically. */ 814 /** 815 * hb_font_glyph_from_string: 816 * @font: a font. 817 * @s: (array length=len) (element-type uint8_t): 818 * @len: 819 * @glyph: (out): 820 * 821 * 822 * 823 * Return value: 824 * 825 * Since: 0.9.2 826 **/ 827 hb_bool_t 828 hb_font_glyph_from_string (hb_font_t *font, 829 const char *s, int len, /* -1 means nul-terminated */ 830 hb_codepoint_t *glyph) 831 { 832 return font->glyph_from_string (s, len, glyph); 833 } 834 835 836 /* 837 * hb_font_t 838 */ 839 840 /** 841 * hb_font_create: (Xconstructor) 842 * @face: a face. 843 * 844 * 845 * 846 * Return value: (transfer full): 847 * 848 * Since: 0.9.2 849 **/ 850 hb_font_t * 851 hb_font_create (hb_face_t *face) 852 { 853 hb_font_t *font; 854 855 if (unlikely (!face)) 856 face = hb_face_get_empty (); 857 if (!(font = hb_object_create<hb_font_t> ())) 858 return hb_font_get_empty (); 859 860 hb_face_make_immutable (face); 861 font->face = hb_face_reference (face); 862 font->klass = hb_font_funcs_get_empty (); 863 864 font->x_scale = font->y_scale = hb_face_get_upem (face); 865 866 return font; 867 } 868 869 /** 870 * hb_font_create_sub_font: 871 * @parent: parent font. 872 * 873 * 874 * 875 * Return value: (transfer full): 876 * 877 * Since: 0.9.2 878 **/ 879 hb_font_t * 880 hb_font_create_sub_font (hb_font_t *parent) 881 { 882 if (unlikely (!parent)) 883 parent = hb_font_get_empty (); 884 885 hb_font_t *font = hb_font_create (parent->face); 886 887 if (unlikely (hb_object_is_inert (font))) 888 return font; 889 890 font->parent = hb_font_reference (parent); 891 892 font->x_scale = parent->x_scale; 893 font->y_scale = parent->y_scale; 894 font->x_ppem = parent->x_ppem; 895 font->y_ppem = parent->y_ppem; 896 897 return font; 898 } 899 900 /** 901 * hb_font_get_empty: 902 * 903 * 904 * 905 * Return value: (transfer full) 906 * 907 * Since: 0.9.2 908 **/ 909 hb_font_t * 910 hb_font_get_empty (void) 911 { 912 static const hb_font_t _hb_font_nil = { 913 HB_OBJECT_HEADER_STATIC, 914 915 true, /* immutable */ 916 917 NULL, /* parent */ 918 const_cast<hb_face_t *> (&_hb_face_nil), 919 920 0, /* x_scale */ 921 0, /* y_scale */ 922 923 0, /* x_ppem */ 924 0, /* y_ppem */ 925 926 const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil), /* klass */ 927 NULL, /* user_data */ 928 NULL, /* destroy */ 929 930 { 931 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID, 932 #include "hb-shaper-list.hh" 933 #undef HB_SHAPER_IMPLEMENT 934 } 935 }; 936 937 return const_cast<hb_font_t *> (&_hb_font_nil); 938 } 939 940 /** 941 * hb_font_reference: (skip) 942 * @font: a font. 943 * 944 * 945 * 946 * Return value: (transfer full): 947 * 948 * Since: 0.9.2 949 **/ 950 hb_font_t * 951 hb_font_reference (hb_font_t *font) 952 { 953 return hb_object_reference (font); 954 } 955 956 /** 957 * hb_font_destroy: (skip) 958 * @font: a font. 959 * 960 * 961 * 962 * Since: 0.9.2 963 **/ 964 void 965 hb_font_destroy (hb_font_t *font) 966 { 967 if (!hb_object_destroy (font)) return; 968 969 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, font); 970 #include "hb-shaper-list.hh" 971 #undef HB_SHAPER_IMPLEMENT 972 973 if (font->destroy) 974 font->destroy (font->user_data); 975 976 hb_font_destroy (font->parent); 977 hb_face_destroy (font->face); 978 hb_font_funcs_destroy (font->klass); 979 980 free (font); 981 } 982 983 /** 984 * hb_font_set_user_data: (skip) 985 * @font: a font. 986 * @key: 987 * @data: 988 * @destroy: 989 * @replace: 990 * 991 * 992 * 993 * Return value: 994 * 995 * Since: 0.9.2 996 **/ 997 hb_bool_t 998 hb_font_set_user_data (hb_font_t *font, 999 hb_user_data_key_t *key, 1000 void * data, 1001 hb_destroy_func_t destroy, 1002 hb_bool_t replace) 1003 { 1004 return hb_object_set_user_data (font, key, data, destroy, replace); 1005 } 1006 1007 /** 1008 * hb_font_get_user_data: (skip) 1009 * @font: a font. 1010 * @key: 1011 * 1012 * 1013 * 1014 * Return value: (transfer none): 1015 * 1016 * Since: 0.9.2 1017 **/ 1018 void * 1019 hb_font_get_user_data (hb_font_t *font, 1020 hb_user_data_key_t *key) 1021 { 1022 return hb_object_get_user_data (font, key); 1023 } 1024 1025 /** 1026 * hb_font_make_immutable: 1027 * @font: a font. 1028 * 1029 * 1030 * 1031 * Since: 0.9.2 1032 **/ 1033 void 1034 hb_font_make_immutable (hb_font_t *font) 1035 { 1036 if (unlikely (hb_object_is_inert (font))) 1037 return; 1038 1039 if (font->parent) 1040 hb_font_make_immutable (font->parent); 1041 1042 font->immutable = true; 1043 } 1044 1045 /** 1046 * hb_font_is_immutable: 1047 * @font: a font. 1048 * 1049 * 1050 * 1051 * Return value: 1052 * 1053 * Since: 0.9.2 1054 **/ 1055 hb_bool_t 1056 hb_font_is_immutable (hb_font_t *font) 1057 { 1058 return font->immutable; 1059 } 1060 1061 /** 1062 * hb_font_set_parent: 1063 * @font: a font. 1064 * @parent: new parent. 1065 * 1066 * Sets parent font of @font. 1067 * 1068 * Since: 1.0.5 1069 **/ 1070 void 1071 hb_font_set_parent (hb_font_t *font, 1072 hb_font_t *parent) 1073 { 1074 if (font->immutable) 1075 return; 1076 1077 if (!parent) 1078 parent = hb_font_get_empty (); 1079 1080 hb_font_t *old = font->parent; 1081 1082 font->parent = hb_font_reference (parent); 1083 1084 hb_font_destroy (old); 1085 } 1086 1087 /** 1088 * hb_font_get_parent: 1089 * @font: a font. 1090 * 1091 * 1092 * 1093 * Return value: (transfer none): 1094 * 1095 * Since: 0.9.2 1096 **/ 1097 hb_font_t * 1098 hb_font_get_parent (hb_font_t *font) 1099 { 1100 return font->parent; 1101 } 1102 1103 /** 1104 * hb_font_get_face: 1105 * @font: a font. 1106 * 1107 * 1108 * 1109 * Return value: (transfer none): 1110 * 1111 * Since: 0.9.2 1112 **/ 1113 hb_face_t * 1114 hb_font_get_face (hb_font_t *font) 1115 { 1116 return font->face; 1117 } 1118 1119 1120 /** 1121 * hb_font_set_funcs: 1122 * @font: a font. 1123 * @klass: (closure font_data) (destroy destroy) (scope notified): 1124 * @font_data: 1125 * @destroy: 1126 * 1127 * 1128 * 1129 * Since: 0.9.2 1130 **/ 1131 void 1132 hb_font_set_funcs (hb_font_t *font, 1133 hb_font_funcs_t *klass, 1134 void *font_data, 1135 hb_destroy_func_t destroy) 1136 { 1137 if (font->immutable) { 1138 if (destroy) 1139 destroy (font_data); 1140 return; 1141 } 1142 1143 if (font->destroy) 1144 font->destroy (font->user_data); 1145 1146 if (!klass) 1147 klass = hb_font_funcs_get_empty (); 1148 1149 hb_font_funcs_reference (klass); 1150 hb_font_funcs_destroy (font->klass); 1151 font->klass = klass; 1152 font->user_data = font_data; 1153 font->destroy = destroy; 1154 } 1155 1156 /** 1157 * hb_font_set_funcs_data: 1158 * @font: a font. 1159 * @font_data: (destroy destroy) (scope notified): 1160 * @destroy: 1161 * 1162 * 1163 * 1164 * Since: 0.9.2 1165 **/ 1166 void 1167 hb_font_set_funcs_data (hb_font_t *font, 1168 void *font_data, 1169 hb_destroy_func_t destroy) 1170 { 1171 /* Destroy user_data? */ 1172 if (font->immutable) { 1173 if (destroy) 1174 destroy (font_data); 1175 return; 1176 } 1177 1178 if (font->destroy) 1179 font->destroy (font->user_data); 1180 1181 font->user_data = font_data; 1182 font->destroy = destroy; 1183 } 1184 1185 1186 /** 1187 * hb_font_set_scale: 1188 * @font: a font. 1189 * @x_scale: 1190 * @y_scale: 1191 * 1192 * 1193 * 1194 * Since: 0.9.2 1195 **/ 1196 void 1197 hb_font_set_scale (hb_font_t *font, 1198 int x_scale, 1199 int y_scale) 1200 { 1201 if (font->immutable) 1202 return; 1203 1204 font->x_scale = x_scale; 1205 font->y_scale = y_scale; 1206 } 1207 1208 /** 1209 * hb_font_get_scale: 1210 * @font: a font. 1211 * @x_scale: (out): 1212 * @y_scale: (out): 1213 * 1214 * 1215 * 1216 * Since: 0.9.2 1217 **/ 1218 void 1219 hb_font_get_scale (hb_font_t *font, 1220 int *x_scale, 1221 int *y_scale) 1222 { 1223 if (x_scale) *x_scale = font->x_scale; 1224 if (y_scale) *y_scale = font->y_scale; 1225 } 1226 1227 /** 1228 * hb_font_set_ppem: 1229 * @font: a font. 1230 * @x_ppem: 1231 * @y_ppem: 1232 * 1233 * 1234 * 1235 * Since: 0.9.2 1236 **/ 1237 void 1238 hb_font_set_ppem (hb_font_t *font, 1239 unsigned int x_ppem, 1240 unsigned int y_ppem) 1241 { 1242 if (font->immutable) 1243 return; 1244 1245 font->x_ppem = x_ppem; 1246 font->y_ppem = y_ppem; 1247 } 1248 1249 /** 1250 * hb_font_get_ppem: 1251 * @font: a font. 1252 * @x_ppem: (out): 1253 * @y_ppem: (out): 1254 * 1255 * 1256 * 1257 * Since: 0.9.2 1258 **/ 1259 void 1260 hb_font_get_ppem (hb_font_t *font, 1261 unsigned int *x_ppem, 1262 unsigned int *y_ppem) 1263 { 1264 if (x_ppem) *x_ppem = font->x_ppem; 1265 if (y_ppem) *y_ppem = font->y_ppem; 1266 }