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 47static hb_bool_t 48hb_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 62static hb_position_t 63hb_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 74static hb_position_t 75hb_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 86static hb_bool_t 87hb_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 105static hb_bool_t 106hb_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 124static hb_position_t 125hb_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 137static hb_position_t 138hb_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 150static hb_bool_t 151hb_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 170static hb_bool_t 171hb_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 190static hb_bool_t 191hb_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 204static hb_bool_t 205hb_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 219static 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: 1.0 240 **/ 241hb_font_funcs_t * 242hb_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: 1.0 262 **/ 263hb_font_funcs_t * 264hb_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: 1.0 278 **/ 279hb_font_funcs_t * 280hb_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: 1.0 292 **/ 293void 294hb_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: 1.0 319 **/ 320hb_bool_t 321hb_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: 1.0 340 **/ 341void * 342hb_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: 1.0 356 **/ 357void 358hb_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: 1.0 375 **/ 376hb_bool_t 377hb_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 \ 385void \ 386hb_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 411HB_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: 1.0 429 **/ 430hb_bool_t 431hb_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: 1.0 448 **/ 449hb_position_t 450hb_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: 1.0 466 **/ 467hb_position_t 468hb_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: 1.0 486 **/ 487hb_bool_t 488hb_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: 1.0 507 **/ 508hb_bool_t 509hb_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: 1.0 527 **/ 528hb_position_t 529hb_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: 1.0 546 **/ 547hb_position_t 548hb_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: 1.0 565 **/ 566hb_bool_t 567hb_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: 1.0 587 **/ 588hb_bool_t 589hb_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: 1.0 608 **/ 609hb_bool_t 610hb_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: 1.0 629 **/ 630hb_bool_t 631hb_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: 1.0 652 **/ 653void 654hb_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: 1.0 673 **/ 674void 675hb_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: 1.0 694 **/ 695void 696hb_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: 1.0 715 **/ 716void 717hb_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: 1.0 737 **/ 738void 739hb_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: 1.0 759 **/ 760hb_bool_t 761hb_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: 1.0 783 **/ 784hb_bool_t 785hb_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: 1.0 804 **/ 805void 806hb_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): 818 * @len: 819 * @glyph: (out): 820 * 821 * 822 * 823 * Return value: 824 * 825 * Since: 1.0 826 **/ 827hb_bool_t 828hb_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: 1.0 849 **/ 850hb_font_t * 851hb_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 (unlikely (hb_object_is_inert (face))) 858 return hb_font_get_empty (); 859 if (!(font = hb_object_create<hb_font_t> ())) 860 return hb_font_get_empty (); 861 862 hb_face_make_immutable (face); 863 font->face = hb_face_reference (face); 864 font->klass = hb_font_funcs_get_empty (); 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: 1.0 878 **/ 879hb_font_t * 880hb_font_create_sub_font (hb_font_t *parent) 881{ 882 if (unlikely (!parent)) 883 return 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 hb_font_make_immutable (parent); 891 font->parent = hb_font_reference (parent); 892 893 font->x_scale = parent->x_scale; 894 font->y_scale = parent->y_scale; 895 font->x_ppem = parent->x_ppem; 896 font->y_ppem = parent->y_ppem; 897 898 return font; 899} 900 901/** 902 * hb_font_get_empty: 903 * 904 * 905 * 906 * Return value: (transfer full) 907 * 908 * Since: 1.0 909 **/ 910hb_font_t * 911hb_font_get_empty (void) 912{ 913 static const hb_font_t _hb_font_nil = { 914 HB_OBJECT_HEADER_STATIC, 915 916 true, /* immutable */ 917 918 NULL, /* parent */ 919 const_cast<hb_face_t *> (&_hb_face_nil), 920 921 0, /* x_scale */ 922 0, /* y_scale */ 923 924 0, /* x_ppem */ 925 0, /* y_ppem */ 926 927 const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil), /* klass */ 928 NULL, /* user_data */ 929 NULL, /* destroy */ 930 931 { 932#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID, 933#include "hb-shaper-list.hh" 934#undef HB_SHAPER_IMPLEMENT 935 } 936 }; 937 938 return const_cast<hb_font_t *> (&_hb_font_nil); 939} 940 941/** 942 * hb_font_reference: (skip) 943 * @font: a font. 944 * 945 * 946 * 947 * Return value: (transfer full): 948 * 949 * Since: 1.0 950 **/ 951hb_font_t * 952hb_font_reference (hb_font_t *font) 953{ 954 return hb_object_reference (font); 955} 956 957/** 958 * hb_font_destroy: (skip) 959 * @font: a font. 960 * 961 * 962 * 963 * Since: 1.0 964 **/ 965void 966hb_font_destroy (hb_font_t *font) 967{ 968 if (!hb_object_destroy (font)) return; 969 970#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, font); 971#include "hb-shaper-list.hh" 972#undef HB_SHAPER_IMPLEMENT 973 974 if (font->destroy) 975 font->destroy (font->user_data); 976 977 hb_font_destroy (font->parent); 978 hb_face_destroy (font->face); 979 hb_font_funcs_destroy (font->klass); 980 981 free (font); 982} 983 984/** 985 * hb_font_set_user_data: (skip) 986 * @font: a font. 987 * @key: 988 * @data: 989 * @destroy: 990 * @replace: 991 * 992 * 993 * 994 * Return value: 995 * 996 * Since: 1.0 997 **/ 998hb_bool_t 999hb_font_set_user_data (hb_font_t *font, 1000 hb_user_data_key_t *key, 1001 void * data, 1002 hb_destroy_func_t destroy, 1003 hb_bool_t replace) 1004{ 1005 return hb_object_set_user_data (font, key, data, destroy, replace); 1006} 1007 1008/** 1009 * hb_font_get_user_data: (skip) 1010 * @font: a font. 1011 * @key: 1012 * 1013 * 1014 * 1015 * Return value: (transfer none): 1016 * 1017 * Since: 1.0 1018 **/ 1019void * 1020hb_font_get_user_data (hb_font_t *font, 1021 hb_user_data_key_t *key) 1022{ 1023 return hb_object_get_user_data (font, key); 1024} 1025 1026/** 1027 * hb_font_make_immutable: 1028 * @font: a font. 1029 * 1030 * 1031 * 1032 * Since: 1.0 1033 **/ 1034void 1035hb_font_make_immutable (hb_font_t *font) 1036{ 1037 if (unlikely (hb_object_is_inert (font))) 1038 return; 1039 1040 font->immutable = true; 1041} 1042 1043/** 1044 * hb_font_is_immutable: 1045 * @font: a font. 1046 * 1047 * 1048 * 1049 * Return value: 1050 * 1051 * Since: 1.0 1052 **/ 1053hb_bool_t 1054hb_font_is_immutable (hb_font_t *font) 1055{ 1056 return font->immutable; 1057} 1058 1059/** 1060 * hb_font_get_parent: 1061 * @font: a font. 1062 * 1063 * 1064 * 1065 * Return value: (transfer none): 1066 * 1067 * Since: 1.0 1068 **/ 1069hb_font_t * 1070hb_font_get_parent (hb_font_t *font) 1071{ 1072 return font->parent; 1073} 1074 1075/** 1076 * hb_font_get_face: 1077 * @font: a font. 1078 * 1079 * 1080 * 1081 * Return value: (transfer none): 1082 * 1083 * Since: 1.0 1084 **/ 1085hb_face_t * 1086hb_font_get_face (hb_font_t *font) 1087{ 1088 return font->face; 1089} 1090 1091 1092/** 1093 * hb_font_set_funcs: 1094 * @font: a font. 1095 * @klass: (closure font_data) (destroy destroy) (scope notified): 1096 * @font_data: 1097 * @destroy: 1098 * 1099 * 1100 * 1101 * Since: 1.0 1102 **/ 1103void 1104hb_font_set_funcs (hb_font_t *font, 1105 hb_font_funcs_t *klass, 1106 void *font_data, 1107 hb_destroy_func_t destroy) 1108{ 1109 if (font->immutable) { 1110 if (destroy) 1111 destroy (font_data); 1112 return; 1113 } 1114 1115 if (font->destroy) 1116 font->destroy (font->user_data); 1117 1118 if (!klass) 1119 klass = hb_font_funcs_get_empty (); 1120 1121 hb_font_funcs_reference (klass); 1122 hb_font_funcs_destroy (font->klass); 1123 font->klass = klass; 1124 font->user_data = font_data; 1125 font->destroy = destroy; 1126} 1127 1128/** 1129 * hb_font_set_funcs_data: 1130 * @font: a font. 1131 * @font_data: (destroy destroy) (scope notified): 1132 * @destroy: 1133 * 1134 * 1135 * 1136 * Since: 1.0 1137 **/ 1138void 1139hb_font_set_funcs_data (hb_font_t *font, 1140 void *font_data, 1141 hb_destroy_func_t destroy) 1142{ 1143 /* Destroy user_data? */ 1144 if (font->immutable) { 1145 if (destroy) 1146 destroy (font_data); 1147 return; 1148 } 1149 1150 if (font->destroy) 1151 font->destroy (font->user_data); 1152 1153 font->user_data = font_data; 1154 font->destroy = destroy; 1155} 1156 1157 1158/** 1159 * hb_font_set_scale: 1160 * @font: a font. 1161 * @x_scale: 1162 * @y_scale: 1163 * 1164 * 1165 * 1166 * Since: 1.0 1167 **/ 1168void 1169hb_font_set_scale (hb_font_t *font, 1170 int x_scale, 1171 int y_scale) 1172{ 1173 if (font->immutable) 1174 return; 1175 1176 font->x_scale = x_scale; 1177 font->y_scale = y_scale; 1178} 1179 1180/** 1181 * hb_font_get_scale: 1182 * @font: a font. 1183 * @x_scale: (out): 1184 * @y_scale: (out): 1185 * 1186 * 1187 * 1188 * Since: 1.0 1189 **/ 1190void 1191hb_font_get_scale (hb_font_t *font, 1192 int *x_scale, 1193 int *y_scale) 1194{ 1195 if (x_scale) *x_scale = font->x_scale; 1196 if (y_scale) *y_scale = font->y_scale; 1197} 1198 1199/** 1200 * hb_font_set_ppem: 1201 * @font: a font. 1202 * @x_ppem: 1203 * @y_ppem: 1204 * 1205 * 1206 * 1207 * Since: 1.0 1208 **/ 1209void 1210hb_font_set_ppem (hb_font_t *font, 1211 unsigned int x_ppem, 1212 unsigned int y_ppem) 1213{ 1214 if (font->immutable) 1215 return; 1216 1217 font->x_ppem = x_ppem; 1218 font->y_ppem = y_ppem; 1219} 1220 1221/** 1222 * hb_font_get_ppem: 1223 * @font: a font. 1224 * @x_ppem: (out): 1225 * @y_ppem: (out): 1226 * 1227 * 1228 * 1229 * Since: 1.0 1230 **/ 1231void 1232hb_font_get_ppem (hb_font_t *font, 1233 unsigned int *x_ppem, 1234 unsigned int *y_ppem) 1235{ 1236 if (x_ppem) *x_ppem = font->x_ppem; 1237 if (y_ppem) *y_ppem = font->y_ppem; 1238} 1239