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