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