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