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.hh" 30 31 #include "hb-font.hh" 32 #include "hb-machinery.hh" 33 34 #include "hb-ot.h" 35 36 37 /** 38 * SECTION:hb-font 39 * @title: hb-font 40 * @short_description: Font objects 41 * @include: hb.h 42 * 43 * Font objects represent a font face at a certain size and other 44 * parameters (pixels per EM, points per EM, variation settings.) 45 * Fonts are created from font faces, and are used as input to 46 * hb_shape() among other things. 47 **/ 48 49 50 /* 51 * hb_font_funcs_t 52 */ 53 54 static hb_bool_t 55 hb_font_get_font_h_extents_nil (hb_font_t *font HB_UNUSED, 56 void *font_data HB_UNUSED, 57 hb_font_extents_t *extents, 58 void *user_data HB_UNUSED) 59 { 60 memset (extents, 0, sizeof (*extents)); 61 return false; 62 } 63 static hb_bool_t 64 hb_font_get_font_h_extents_default (hb_font_t *font, 65 void *font_data HB_UNUSED, 66 hb_font_extents_t *extents, 67 void *user_data HB_UNUSED) 68 { 69 hb_bool_t ret = font->parent->get_font_h_extents (extents); 70 if (ret) { 71 extents->ascender = font->parent_scale_y_distance (extents->ascender); 72 extents->descender = font->parent_scale_y_distance (extents->descender); 73 extents->line_gap = font->parent_scale_y_distance (extents->line_gap); 74 } 75 return ret; 76 } 77 78 static hb_bool_t 79 hb_font_get_font_v_extents_nil (hb_font_t *font HB_UNUSED, 80 void *font_data HB_UNUSED, 81 hb_font_extents_t *extents, 82 void *user_data HB_UNUSED) 83 { 84 memset (extents, 0, sizeof (*extents)); 85 return false; 86 } 87 static hb_bool_t 88 hb_font_get_font_v_extents_default (hb_font_t *font, 89 void *font_data HB_UNUSED, 90 hb_font_extents_t *extents, 91 void *user_data HB_UNUSED) 92 { 93 hb_bool_t ret = font->parent->get_font_v_extents (extents); 94 if (ret) { 95 extents->ascender = font->parent_scale_x_distance (extents->ascender); 96 extents->descender = font->parent_scale_x_distance (extents->descender); 97 extents->line_gap = font->parent_scale_x_distance (extents->line_gap); 98 } 99 return ret; 100 } 101 102 static hb_bool_t 103 hb_font_get_nominal_glyph_nil (hb_font_t *font HB_UNUSED, 104 void *font_data HB_UNUSED, 105 hb_codepoint_t unicode HB_UNUSED, 106 hb_codepoint_t *glyph, 107 void *user_data HB_UNUSED) 108 { 109 *glyph = 0; 110 return false; 111 } 112 static hb_bool_t 113 hb_font_get_nominal_glyph_default (hb_font_t *font, 114 void *font_data HB_UNUSED, 115 hb_codepoint_t unicode, 116 hb_codepoint_t *glyph, 117 void *user_data HB_UNUSED) 118 { 119 if (font->has_nominal_glyphs_func_set ()) 120 { 121 return font->get_nominal_glyphs (1, &unicode, 0, glyph, 0); 122 } 123 return font->parent->get_nominal_glyph (unicode, glyph); 124 } 125 126 #define hb_font_get_nominal_glyphs_nil hb_font_get_nominal_glyphs_default 127 static unsigned int 128 hb_font_get_nominal_glyphs_default (hb_font_t *font, 129 void *font_data HB_UNUSED, 130 unsigned int count, 131 const hb_codepoint_t *first_unicode, 132 unsigned int unicode_stride, 133 hb_codepoint_t *first_glyph, 134 unsigned int glyph_stride, 135 void *user_data HB_UNUSED) 136 { 137 if (font->has_nominal_glyph_func_set ()) 138 { 139 for (unsigned int i = 0; i < count; i++) 140 { 141 if (!font->get_nominal_glyph (*first_unicode, first_glyph)) 142 return i; 143 144 first_unicode = &StructAtOffset<hb_codepoint_t> (first_unicode, unicode_stride); 145 first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride); 146 } 147 return count; 148 } 149 150 return font->parent->get_nominal_glyphs (count, 151 first_unicode, unicode_stride, 152 first_glyph, glyph_stride); 153 } 154 155 static hb_bool_t 156 hb_font_get_variation_glyph_nil (hb_font_t *font HB_UNUSED, 157 void *font_data HB_UNUSED, 158 hb_codepoint_t unicode HB_UNUSED, 159 hb_codepoint_t variation_selector HB_UNUSED, 160 hb_codepoint_t *glyph, 161 void *user_data HB_UNUSED) 162 { 163 *glyph = 0; 164 return false; 165 } 166 static hb_bool_t 167 hb_font_get_variation_glyph_default (hb_font_t *font, 168 void *font_data HB_UNUSED, 169 hb_codepoint_t unicode, 170 hb_codepoint_t variation_selector, 171 hb_codepoint_t *glyph, 172 void *user_data HB_UNUSED) 173 { 174 return font->parent->get_variation_glyph (unicode, variation_selector, glyph); 175 } 176 177 178 static hb_position_t 179 hb_font_get_glyph_h_advance_nil (hb_font_t *font, 180 void *font_data HB_UNUSED, 181 hb_codepoint_t glyph HB_UNUSED, 182 void *user_data HB_UNUSED) 183 { 184 return font->x_scale; 185 } 186 static hb_position_t 187 hb_font_get_glyph_h_advance_default (hb_font_t *font, 188 void *font_data HB_UNUSED, 189 hb_codepoint_t glyph, 190 void *user_data HB_UNUSED) 191 { 192 if (font->has_glyph_h_advances_func_set ()) 193 { 194 hb_position_t ret; 195 font->get_glyph_h_advances (1, &glyph, 0, &ret, 0); 196 return ret; 197 } 198 return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph)); 199 } 200 201 static hb_position_t 202 hb_font_get_glyph_v_advance_nil (hb_font_t *font, 203 void *font_data HB_UNUSED, 204 hb_codepoint_t glyph HB_UNUSED, 205 void *user_data HB_UNUSED) 206 { 207 /* TODO use font_extents.ascender+descender */ 208 return font->y_scale; 209 } 210 static hb_position_t 211 hb_font_get_glyph_v_advance_default (hb_font_t *font, 212 void *font_data HB_UNUSED, 213 hb_codepoint_t glyph, 214 void *user_data HB_UNUSED) 215 { 216 if (font->has_glyph_v_advances_func_set ()) 217 { 218 hb_position_t ret; 219 font->get_glyph_v_advances (1, &glyph, 0, &ret, 0); 220 return ret; 221 } 222 return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph)); 223 } 224 225 #define hb_font_get_glyph_h_advances_nil hb_font_get_glyph_h_advances_default 226 static void 227 hb_font_get_glyph_h_advances_default (hb_font_t* font, 228 void* font_data HB_UNUSED, 229 unsigned int count, 230 const hb_codepoint_t *first_glyph, 231 unsigned int glyph_stride, 232 hb_position_t *first_advance, 233 unsigned int advance_stride, 234 void *user_data HB_UNUSED) 235 { 236 if (font->has_glyph_h_advance_func_set ()) 237 { 238 for (unsigned int i = 0; i < count; i++) 239 { 240 *first_advance = font->get_glyph_h_advance (*first_glyph); 241 first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride); 242 first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride); 243 } 244 return; 245 } 246 247 font->parent->get_glyph_h_advances (count, 248 first_glyph, glyph_stride, 249 first_advance, advance_stride); 250 for (unsigned int i = 0; i < count; i++) 251 { 252 *first_advance = font->parent_scale_x_distance (*first_advance); 253 first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride); 254 } 255 } 256 257 #define hb_font_get_glyph_v_advances_nil hb_font_get_glyph_v_advances_default 258 static void 259 hb_font_get_glyph_v_advances_default (hb_font_t* font, 260 void* font_data HB_UNUSED, 261 unsigned int count, 262 const hb_codepoint_t *first_glyph, 263 unsigned int glyph_stride, 264 hb_position_t *first_advance, 265 unsigned int advance_stride, 266 void *user_data HB_UNUSED) 267 { 268 if (font->has_glyph_v_advance_func_set ()) 269 { 270 for (unsigned int i = 0; i < count; i++) 271 { 272 *first_advance = font->get_glyph_v_advance (*first_glyph); 273 first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride); 274 first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride); 275 } 276 return; 277 } 278 279 font->parent->get_glyph_v_advances (count, 280 first_glyph, glyph_stride, 281 first_advance, advance_stride); 282 for (unsigned int i = 0; i < count; i++) 283 { 284 *first_advance = font->parent_scale_y_distance (*first_advance); 285 first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride); 286 } 287 } 288 289 static hb_bool_t 290 hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED, 291 void *font_data HB_UNUSED, 292 hb_codepoint_t glyph HB_UNUSED, 293 hb_position_t *x, 294 hb_position_t *y, 295 void *user_data HB_UNUSED) 296 { 297 *x = *y = 0; 298 return true; 299 } 300 static hb_bool_t 301 hb_font_get_glyph_h_origin_default (hb_font_t *font, 302 void *font_data HB_UNUSED, 303 hb_codepoint_t glyph, 304 hb_position_t *x, 305 hb_position_t *y, 306 void *user_data HB_UNUSED) 307 { 308 hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y); 309 if (ret) 310 font->parent_scale_position (x, y); 311 return ret; 312 } 313 314 static hb_bool_t 315 hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED, 316 void *font_data HB_UNUSED, 317 hb_codepoint_t glyph HB_UNUSED, 318 hb_position_t *x, 319 hb_position_t *y, 320 void *user_data HB_UNUSED) 321 { 322 *x = *y = 0; 323 return false; 324 } 325 static hb_bool_t 326 hb_font_get_glyph_v_origin_default (hb_font_t *font, 327 void *font_data HB_UNUSED, 328 hb_codepoint_t glyph, 329 hb_position_t *x, 330 hb_position_t *y, 331 void *user_data HB_UNUSED) 332 { 333 hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y); 334 if (ret) 335 font->parent_scale_position (x, y); 336 return ret; 337 } 338 339 static hb_position_t 340 hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED, 341 void *font_data HB_UNUSED, 342 hb_codepoint_t left_glyph HB_UNUSED, 343 hb_codepoint_t right_glyph HB_UNUSED, 344 void *user_data HB_UNUSED) 345 { 346 return 0; 347 } 348 static hb_position_t 349 hb_font_get_glyph_h_kerning_default (hb_font_t *font, 350 void *font_data HB_UNUSED, 351 hb_codepoint_t left_glyph, 352 hb_codepoint_t right_glyph, 353 void *user_data HB_UNUSED) 354 { 355 return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph)); 356 } 357 358 static hb_position_t 359 hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED, 360 void *font_data HB_UNUSED, 361 hb_codepoint_t top_glyph HB_UNUSED, 362 hb_codepoint_t bottom_glyph HB_UNUSED, 363 void *user_data HB_UNUSED) 364 { 365 return 0; 366 } 367 static hb_position_t 368 hb_font_get_glyph_v_kerning_default (hb_font_t *font, 369 void *font_data HB_UNUSED, 370 hb_codepoint_t top_glyph, 371 hb_codepoint_t bottom_glyph, 372 void *user_data HB_UNUSED) 373 { 374 return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph)); 375 } 376 377 static hb_bool_t 378 hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED, 379 void *font_data HB_UNUSED, 380 hb_codepoint_t glyph HB_UNUSED, 381 hb_glyph_extents_t *extents, 382 void *user_data HB_UNUSED) 383 { 384 memset (extents, 0, sizeof (*extents)); 385 return false; 386 } 387 static hb_bool_t 388 hb_font_get_glyph_extents_default (hb_font_t *font, 389 void *font_data HB_UNUSED, 390 hb_codepoint_t glyph, 391 hb_glyph_extents_t *extents, 392 void *user_data HB_UNUSED) 393 { 394 hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents); 395 if (ret) { 396 font->parent_scale_position (&extents->x_bearing, &extents->y_bearing); 397 font->parent_scale_distance (&extents->width, &extents->height); 398 } 399 return ret; 400 } 401 402 static hb_bool_t 403 hb_font_get_glyph_contour_point_nil (hb_font_t *font HB_UNUSED, 404 void *font_data HB_UNUSED, 405 hb_codepoint_t glyph HB_UNUSED, 406 unsigned int point_index HB_UNUSED, 407 hb_position_t *x, 408 hb_position_t *y, 409 void *user_data HB_UNUSED) 410 { 411 *x = *y = 0; 412 return false; 413 } 414 static hb_bool_t 415 hb_font_get_glyph_contour_point_default (hb_font_t *font, 416 void *font_data HB_UNUSED, 417 hb_codepoint_t glyph, 418 unsigned int point_index, 419 hb_position_t *x, 420 hb_position_t *y, 421 void *user_data HB_UNUSED) 422 { 423 hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y); 424 if (ret) 425 font->parent_scale_position (x, y); 426 return ret; 427 } 428 429 static hb_bool_t 430 hb_font_get_glyph_name_nil (hb_font_t *font HB_UNUSED, 431 void *font_data HB_UNUSED, 432 hb_codepoint_t glyph HB_UNUSED, 433 char *name, unsigned int size, 434 void *user_data HB_UNUSED) 435 { 436 if (size) *name = '\0'; 437 return false; 438 } 439 static hb_bool_t 440 hb_font_get_glyph_name_default (hb_font_t *font, 441 void *font_data HB_UNUSED, 442 hb_codepoint_t glyph, 443 char *name, unsigned int size, 444 void *user_data HB_UNUSED) 445 { 446 return font->parent->get_glyph_name (glyph, name, size); 447 } 448 449 static hb_bool_t 450 hb_font_get_glyph_from_name_nil (hb_font_t *font HB_UNUSED, 451 void *font_data HB_UNUSED, 452 const char *name HB_UNUSED, 453 int len HB_UNUSED, /* -1 means nul-terminated */ 454 hb_codepoint_t *glyph, 455 void *user_data HB_UNUSED) 456 { 457 *glyph = 0; 458 return false; 459 } 460 static hb_bool_t 461 hb_font_get_glyph_from_name_default (hb_font_t *font, 462 void *font_data HB_UNUSED, 463 const char *name, int len, /* -1 means nul-terminated */ 464 hb_codepoint_t *glyph, 465 void *user_data HB_UNUSED) 466 { 467 return font->parent->get_glyph_from_name (name, len, glyph); 468 } 469 470 DEFINE_NULL_INSTANCE (hb_font_funcs_t) = 471 { 472 HB_OBJECT_HEADER_STATIC, 473 474 { 475 #define HB_FONT_FUNC_IMPLEMENT(name) nullptr, 476 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 477 #undef HB_FONT_FUNC_IMPLEMENT 478 }, 479 { 480 #define HB_FONT_FUNC_IMPLEMENT(name) nullptr, 481 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 482 #undef HB_FONT_FUNC_IMPLEMENT 483 }, 484 { 485 { 486 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil, 487 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 488 #undef HB_FONT_FUNC_IMPLEMENT 489 } 490 } 491 }; 492 493 static const hb_font_funcs_t _hb_font_funcs_default = { 494 HB_OBJECT_HEADER_STATIC, 495 496 { 497 #define HB_FONT_FUNC_IMPLEMENT(name) nullptr, 498 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 499 #undef HB_FONT_FUNC_IMPLEMENT 500 }, 501 { 502 #define HB_FONT_FUNC_IMPLEMENT(name) nullptr, 503 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 504 #undef HB_FONT_FUNC_IMPLEMENT 505 }, 506 { 507 { 508 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_default, 509 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 510 #undef HB_FONT_FUNC_IMPLEMENT 511 } 512 } 513 }; 514 515 516 /** 517 * hb_font_funcs_create: (Xconstructor) 518 * 519 * 520 * 521 * Return value: (transfer full): 522 * 523 * Since: 0.9.2 524 **/ 525 hb_font_funcs_t * 526 hb_font_funcs_create () 527 { 528 hb_font_funcs_t *ffuncs; 529 530 if (!(ffuncs = hb_object_create<hb_font_funcs_t> ())) 531 return hb_font_funcs_get_empty (); 532 533 ffuncs->get = _hb_font_funcs_default.get; 534 535 return ffuncs; 536 } 537 538 /** 539 * hb_font_funcs_get_empty: 540 * 541 * 542 * 543 * Return value: (transfer full): 544 * 545 * Since: 0.9.2 546 **/ 547 hb_font_funcs_t * 548 hb_font_funcs_get_empty () 549 { 550 return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_default); 551 } 552 553 /** 554 * hb_font_funcs_reference: (skip) 555 * @ffuncs: font functions. 556 * 557 * 558 * 559 * Return value: 560 * 561 * Since: 0.9.2 562 **/ 563 hb_font_funcs_t * 564 hb_font_funcs_reference (hb_font_funcs_t *ffuncs) 565 { 566 return hb_object_reference (ffuncs); 567 } 568 569 /** 570 * hb_font_funcs_destroy: (skip) 571 * @ffuncs: font functions. 572 * 573 * 574 * 575 * Since: 0.9.2 576 **/ 577 void 578 hb_font_funcs_destroy (hb_font_funcs_t *ffuncs) 579 { 580 if (!hb_object_destroy (ffuncs)) return; 581 582 #define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \ 583 ffuncs->destroy.name (ffuncs->user_data.name); 584 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 585 #undef HB_FONT_FUNC_IMPLEMENT 586 587 free (ffuncs); 588 } 589 590 /** 591 * hb_font_funcs_set_user_data: (skip) 592 * @ffuncs: font functions. 593 * @key: 594 * @data: 595 * @destroy: 596 * @replace: 597 * 598 * 599 * 600 * Return value: 601 * 602 * Since: 0.9.2 603 **/ 604 hb_bool_t 605 hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs, 606 hb_user_data_key_t *key, 607 void * data, 608 hb_destroy_func_t destroy, 609 hb_bool_t replace) 610 { 611 return hb_object_set_user_data (ffuncs, key, data, destroy, replace); 612 } 613 614 /** 615 * hb_font_funcs_get_user_data: (skip) 616 * @ffuncs: font functions. 617 * @key: 618 * 619 * 620 * 621 * Return value: (transfer none): 622 * 623 * Since: 0.9.2 624 **/ 625 void * 626 hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs, 627 hb_user_data_key_t *key) 628 { 629 return hb_object_get_user_data (ffuncs, key); 630 } 631 632 633 /** 634 * hb_font_funcs_make_immutable: 635 * @ffuncs: font functions. 636 * 637 * 638 * 639 * Since: 0.9.2 640 **/ 641 void 642 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs) 643 { 644 if (hb_object_is_immutable (ffuncs)) 645 return; 646 647 hb_object_make_immutable (ffuncs); 648 } 649 650 /** 651 * hb_font_funcs_is_immutable: 652 * @ffuncs: font functions. 653 * 654 * 655 * 656 * Return value: 657 * 658 * Since: 0.9.2 659 **/ 660 hb_bool_t 661 hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs) 662 { 663 return hb_object_is_immutable (ffuncs); 664 } 665 666 667 #define HB_FONT_FUNC_IMPLEMENT(name) \ 668 \ 669 void \ 670 hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \ 671 hb_font_get_##name##_func_t func, \ 672 void *user_data, \ 673 hb_destroy_func_t destroy) \ 674 { \ 675 if (hb_object_is_immutable (ffuncs)) { \ 676 if (destroy) \ 677 destroy (user_data); \ 678 return; \ 679 } \ 680 \ 681 if (ffuncs->destroy.name) \ 682 ffuncs->destroy.name (ffuncs->user_data.name); \ 683 \ 684 if (func) { \ 685 ffuncs->get.f.name = func; \ 686 ffuncs->user_data.name = user_data; \ 687 ffuncs->destroy.name = destroy; \ 688 } else { \ 689 ffuncs->get.f.name = hb_font_get_##name##_default; \ 690 ffuncs->user_data.name = nullptr; \ 691 ffuncs->destroy.name = nullptr; \ 692 } \ 693 } 694 695 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 696 #undef HB_FONT_FUNC_IMPLEMENT 697 698 bool 699 hb_font_t::has_func_set (unsigned int i) 700 { 701 return this->klass->get.array[i] != _hb_font_funcs_default.get.array[i]; 702 } 703 704 bool 705 hb_font_t::has_func (unsigned int i) 706 { 707 return has_func_set (i) || 708 (parent && parent != &_hb_Null_hb_font_t && parent->has_func (i)); 709 } 710 711 /* Public getters */ 712 713 /** 714 * hb_font_get_h_extents: 715 * @font: a font. 716 * @extents: (out): 717 * 718 * 719 * 720 * Return value: 721 * 722 * Since: 1.1.3 723 **/ 724 hb_bool_t 725 hb_font_get_h_extents (hb_font_t *font, 726 hb_font_extents_t *extents) 727 { 728 return font->get_font_h_extents (extents); 729 } 730 731 /** 732 * hb_font_get_v_extents: 733 * @font: a font. 734 * @extents: (out): 735 * 736 * 737 * 738 * Return value: 739 * 740 * Since: 1.1.3 741 **/ 742 hb_bool_t 743 hb_font_get_v_extents (hb_font_t *font, 744 hb_font_extents_t *extents) 745 { 746 return font->get_font_v_extents (extents); 747 } 748 749 /** 750 * hb_font_get_glyph: 751 * @font: a font. 752 * @unicode: 753 * @variation_selector: 754 * @glyph: (out): 755 * 756 * 757 * 758 * Return value: 759 * 760 * Since: 0.9.2 761 **/ 762 hb_bool_t 763 hb_font_get_glyph (hb_font_t *font, 764 hb_codepoint_t unicode, hb_codepoint_t variation_selector, 765 hb_codepoint_t *glyph) 766 { 767 if (unlikely (variation_selector)) 768 return font->get_variation_glyph (unicode, variation_selector, glyph); 769 return font->get_nominal_glyph (unicode, glyph); 770 } 771 772 /** 773 * hb_font_get_nominal_glyph: 774 * @font: a font. 775 * @unicode: 776 * @glyph: (out): 777 * 778 * 779 * 780 * Return value: 781 * 782 * Since: 1.2.3 783 **/ 784 hb_bool_t 785 hb_font_get_nominal_glyph (hb_font_t *font, 786 hb_codepoint_t unicode, 787 hb_codepoint_t *glyph) 788 { 789 return font->get_nominal_glyph (unicode, glyph); 790 } 791 792 /** 793 * hb_font_get_variation_glyph: 794 * @font: a font. 795 * @unicode: 796 * @variation_selector: 797 * @glyph: (out): 798 * 799 * 800 * 801 * Return value: 802 * 803 * Since: 1.2.3 804 **/ 805 hb_bool_t 806 hb_font_get_variation_glyph (hb_font_t *font, 807 hb_codepoint_t unicode, hb_codepoint_t variation_selector, 808 hb_codepoint_t *glyph) 809 { 810 return font->get_variation_glyph (unicode, variation_selector, glyph); 811 } 812 813 /** 814 * hb_font_get_glyph_h_advance: 815 * @font: a font. 816 * @glyph: 817 * 818 * 819 * 820 * Return value: 821 * 822 * Since: 0.9.2 823 **/ 824 hb_position_t 825 hb_font_get_glyph_h_advance (hb_font_t *font, 826 hb_codepoint_t glyph) 827 { 828 return font->get_glyph_h_advance (glyph); 829 } 830 831 /** 832 * hb_font_get_glyph_v_advance: 833 * @font: a font. 834 * @glyph: 835 * 836 * 837 * 838 * Return value: 839 * 840 * Since: 0.9.2 841 **/ 842 hb_position_t 843 hb_font_get_glyph_v_advance (hb_font_t *font, 844 hb_codepoint_t glyph) 845 { 846 return font->get_glyph_v_advance (glyph); 847 } 848 849 /** 850 * hb_font_get_glyph_h_advances: 851 * @font: a font. 852 * 853 * 854 * 855 * Since: 1.8.6 856 **/ 857 void 858 hb_font_get_glyph_h_advances (hb_font_t* font, 859 unsigned int count, 860 const hb_codepoint_t *first_glyph, 861 unsigned glyph_stride, 862 hb_position_t *first_advance, 863 unsigned advance_stride) 864 { 865 font->get_glyph_h_advances (count, first_glyph, glyph_stride, first_advance, advance_stride); 866 } 867 /** 868 * hb_font_get_glyph_v_advances: 869 * @font: a font. 870 * 871 * 872 * 873 * Since: 1.8.6 874 **/ 875 void 876 hb_font_get_glyph_v_advances (hb_font_t* font, 877 unsigned int count, 878 const hb_codepoint_t *first_glyph, 879 unsigned glyph_stride, 880 hb_position_t *first_advance, 881 unsigned advance_stride) 882 { 883 font->get_glyph_v_advances (count, first_glyph, glyph_stride, first_advance, advance_stride); 884 } 885 886 /** 887 * hb_font_get_glyph_h_origin: 888 * @font: a font. 889 * @glyph: 890 * @x: (out): 891 * @y: (out): 892 * 893 * 894 * 895 * Return value: 896 * 897 * Since: 0.9.2 898 **/ 899 hb_bool_t 900 hb_font_get_glyph_h_origin (hb_font_t *font, 901 hb_codepoint_t glyph, 902 hb_position_t *x, hb_position_t *y) 903 { 904 return font->get_glyph_h_origin (glyph, x, y); 905 } 906 907 /** 908 * hb_font_get_glyph_v_origin: 909 * @font: a font. 910 * @glyph: 911 * @x: (out): 912 * @y: (out): 913 * 914 * 915 * 916 * Return value: 917 * 918 * Since: 0.9.2 919 **/ 920 hb_bool_t 921 hb_font_get_glyph_v_origin (hb_font_t *font, 922 hb_codepoint_t glyph, 923 hb_position_t *x, hb_position_t *y) 924 { 925 return font->get_glyph_v_origin (glyph, x, y); 926 } 927 928 /** 929 * hb_font_get_glyph_h_kerning: 930 * @font: a font. 931 * @left_glyph: 932 * @right_glyph: 933 * 934 * 935 * 936 * Return value: 937 * 938 * Since: 0.9.2 939 * Deprecated: 2.0.0 940 **/ 941 hb_position_t 942 hb_font_get_glyph_h_kerning (hb_font_t *font, 943 hb_codepoint_t left_glyph, hb_codepoint_t right_glyph) 944 { 945 return font->get_glyph_h_kerning (left_glyph, right_glyph); 946 } 947 948 /** 949 * hb_font_get_glyph_v_kerning: 950 * @font: a font. 951 * @top_glyph: 952 * @bottom_glyph: 953 * 954 * 955 * 956 * Return value: 957 * 958 * Since: 0.9.2 959 * Deprecated: 2.0.0 960 **/ 961 hb_position_t 962 hb_font_get_glyph_v_kerning (hb_font_t *font, 963 hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph) 964 { 965 return font->get_glyph_v_kerning (top_glyph, bottom_glyph); 966 } 967 968 /** 969 * hb_font_get_glyph_extents: 970 * @font: a font. 971 * @glyph: 972 * @extents: (out): 973 * 974 * 975 * 976 * Return value: 977 * 978 * Since: 0.9.2 979 **/ 980 hb_bool_t 981 hb_font_get_glyph_extents (hb_font_t *font, 982 hb_codepoint_t glyph, 983 hb_glyph_extents_t *extents) 984 { 985 return font->get_glyph_extents (glyph, extents); 986 } 987 988 /** 989 * hb_font_get_glyph_contour_point: 990 * @font: a font. 991 * @glyph: 992 * @point_index: 993 * @x: (out): 994 * @y: (out): 995 * 996 * 997 * 998 * Return value: 999 * 1000 * Since: 0.9.2 1001 **/ 1002 hb_bool_t 1003 hb_font_get_glyph_contour_point (hb_font_t *font, 1004 hb_codepoint_t glyph, unsigned int point_index, 1005 hb_position_t *x, hb_position_t *y) 1006 { 1007 return font->get_glyph_contour_point (glyph, point_index, x, y); 1008 } 1009 1010 /** 1011 * hb_font_get_glyph_name: 1012 * @font: a font. 1013 * @glyph: 1014 * @name: (array length=size): 1015 * @size: 1016 * 1017 * 1018 * 1019 * Return value: 1020 * 1021 * Since: 0.9.2 1022 **/ 1023 hb_bool_t 1024 hb_font_get_glyph_name (hb_font_t *font, 1025 hb_codepoint_t glyph, 1026 char *name, unsigned int size) 1027 { 1028 return font->get_glyph_name (glyph, name, size); 1029 } 1030 1031 /** 1032 * hb_font_get_glyph_from_name: 1033 * @font: a font. 1034 * @name: (array length=len): 1035 * @len: 1036 * @glyph: (out): 1037 * 1038 * 1039 * 1040 * Return value: 1041 * 1042 * Since: 0.9.2 1043 **/ 1044 hb_bool_t 1045 hb_font_get_glyph_from_name (hb_font_t *font, 1046 const char *name, int len, /* -1 means nul-terminated */ 1047 hb_codepoint_t *glyph) 1048 { 1049 return font->get_glyph_from_name (name, len, glyph); 1050 } 1051 1052 1053 /* A bit higher-level, and with fallback */ 1054 1055 /** 1056 * hb_font_get_extents_for_direction: 1057 * @font: a font. 1058 * @direction: 1059 * @extents: (out): 1060 * 1061 * 1062 * 1063 * Since: 1.1.3 1064 **/ 1065 void 1066 hb_font_get_extents_for_direction (hb_font_t *font, 1067 hb_direction_t direction, 1068 hb_font_extents_t *extents) 1069 { 1070 return font->get_extents_for_direction (direction, extents); 1071 } 1072 /** 1073 * hb_font_get_glyph_advance_for_direction: 1074 * @font: a font. 1075 * @glyph: 1076 * @direction: 1077 * @x: (out): 1078 * @y: (out): 1079 * 1080 * 1081 * 1082 * Since: 0.9.2 1083 **/ 1084 void 1085 hb_font_get_glyph_advance_for_direction (hb_font_t *font, 1086 hb_codepoint_t glyph, 1087 hb_direction_t direction, 1088 hb_position_t *x, hb_position_t *y) 1089 { 1090 return font->get_glyph_advance_for_direction (glyph, direction, x, y); 1091 } 1092 /** 1093 * hb_font_get_glyph_advances_for_direction: 1094 * @font: a font. 1095 * @direction: 1096 * 1097 * 1098 * 1099 * Since: 1.8.6 1100 **/ 1101 HB_EXTERN void 1102 hb_font_get_glyph_advances_for_direction (hb_font_t* font, 1103 hb_direction_t direction, 1104 unsigned int count, 1105 const hb_codepoint_t *first_glyph, 1106 unsigned glyph_stride, 1107 hb_position_t *first_advance, 1108 unsigned advance_stride) 1109 { 1110 font->get_glyph_advances_for_direction (direction, count, first_glyph, glyph_stride, first_advance, advance_stride); 1111 } 1112 1113 /** 1114 * hb_font_get_glyph_origin_for_direction: 1115 * @font: a font. 1116 * @glyph: 1117 * @direction: 1118 * @x: (out): 1119 * @y: (out): 1120 * 1121 * 1122 * 1123 * Since: 0.9.2 1124 **/ 1125 void 1126 hb_font_get_glyph_origin_for_direction (hb_font_t *font, 1127 hb_codepoint_t glyph, 1128 hb_direction_t direction, 1129 hb_position_t *x, hb_position_t *y) 1130 { 1131 return font->get_glyph_origin_for_direction (glyph, direction, x, y); 1132 } 1133 1134 /** 1135 * hb_font_add_glyph_origin_for_direction: 1136 * @font: a font. 1137 * @glyph: 1138 * @direction: 1139 * @x: (out): 1140 * @y: (out): 1141 * 1142 * 1143 * 1144 * Since: 0.9.2 1145 **/ 1146 void 1147 hb_font_add_glyph_origin_for_direction (hb_font_t *font, 1148 hb_codepoint_t glyph, 1149 hb_direction_t direction, 1150 hb_position_t *x, hb_position_t *y) 1151 { 1152 return font->add_glyph_origin_for_direction (glyph, direction, x, y); 1153 } 1154 1155 /** 1156 * hb_font_subtract_glyph_origin_for_direction: 1157 * @font: a font. 1158 * @glyph: 1159 * @direction: 1160 * @x: (out): 1161 * @y: (out): 1162 * 1163 * 1164 * 1165 * Since: 0.9.2 1166 **/ 1167 void 1168 hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, 1169 hb_codepoint_t glyph, 1170 hb_direction_t direction, 1171 hb_position_t *x, hb_position_t *y) 1172 { 1173 return font->subtract_glyph_origin_for_direction (glyph, direction, x, y); 1174 } 1175 1176 /** 1177 * hb_font_get_glyph_kerning_for_direction: 1178 * @font: a font. 1179 * @first_glyph: 1180 * @second_glyph: 1181 * @direction: 1182 * @x: (out): 1183 * @y: (out): 1184 * 1185 * 1186 * 1187 * Since: 0.9.2 1188 * Deprecated: 2.0.0 1189 **/ 1190 void 1191 hb_font_get_glyph_kerning_for_direction (hb_font_t *font, 1192 hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, 1193 hb_direction_t direction, 1194 hb_position_t *x, hb_position_t *y) 1195 { 1196 return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y); 1197 } 1198 1199 /** 1200 * hb_font_get_glyph_extents_for_origin: 1201 * @font: a font. 1202 * @glyph: 1203 * @direction: 1204 * @extents: (out): 1205 * 1206 * 1207 * 1208 * Return value: 1209 * 1210 * Since: 0.9.2 1211 **/ 1212 hb_bool_t 1213 hb_font_get_glyph_extents_for_origin (hb_font_t *font, 1214 hb_codepoint_t glyph, 1215 hb_direction_t direction, 1216 hb_glyph_extents_t *extents) 1217 { 1218 return font->get_glyph_extents_for_origin (glyph, direction, extents); 1219 } 1220 1221 /** 1222 * hb_font_get_glyph_contour_point_for_origin: 1223 * @font: a font. 1224 * @glyph: 1225 * @point_index: 1226 * @direction: 1227 * @x: (out): 1228 * @y: (out): 1229 * 1230 * 1231 * 1232 * Return value: 1233 * 1234 * Since: 0.9.2 1235 **/ 1236 hb_bool_t 1237 hb_font_get_glyph_contour_point_for_origin (hb_font_t *font, 1238 hb_codepoint_t glyph, unsigned int point_index, 1239 hb_direction_t direction, 1240 hb_position_t *x, hb_position_t *y) 1241 { 1242 return font->get_glyph_contour_point_for_origin (glyph, point_index, direction, x, y); 1243 } 1244 1245 /* Generates gidDDD if glyph has no name. */ 1246 /** 1247 * hb_font_glyph_to_string: 1248 * @font: a font. 1249 * @glyph: 1250 * @s: (array length=size): 1251 * @size: 1252 * 1253 * 1254 * 1255 * Since: 0.9.2 1256 **/ 1257 void 1258 hb_font_glyph_to_string (hb_font_t *font, 1259 hb_codepoint_t glyph, 1260 char *s, unsigned int size) 1261 { 1262 font->glyph_to_string (glyph, s, size); 1263 } 1264 1265 /* Parses gidDDD and uniUUUU strings automatically. */ 1266 /** 1267 * hb_font_glyph_from_string: 1268 * @font: a font. 1269 * @s: (array length=len) (element-type uint8_t): 1270 * @len: 1271 * @glyph: (out): 1272 * 1273 * 1274 * 1275 * Return value: 1276 * 1277 * Since: 0.9.2 1278 **/ 1279 hb_bool_t 1280 hb_font_glyph_from_string (hb_font_t *font, 1281 const char *s, int len, /* -1 means nul-terminated */ 1282 hb_codepoint_t *glyph) 1283 { 1284 return font->glyph_from_string (s, len, glyph); 1285 } 1286 1287 1288 /* 1289 * hb_font_t 1290 */ 1291 1292 DEFINE_NULL_INSTANCE (hb_font_t) = 1293 { 1294 HB_OBJECT_HEADER_STATIC, 1295 1296 nullptr, /* parent */ 1297 const_cast<hb_face_t *> (&_hb_Null_hb_face_t), 1298 1299 1000, /* x_scale */ 1300 1000, /* y_scale */ 1301 1302 0, /* x_ppem */ 1303 0, /* y_ppem */ 1304 0, /* ptem */ 1305 1306 0, /* num_coords */ 1307 nullptr, /* coords */ 1308 1309 const_cast<hb_font_funcs_t *> (&_hb_Null_hb_font_funcs_t), 1310 1311 /* Zero for the rest is fine. */ 1312 }; 1313 1314 1315 static hb_font_t * 1316 _hb_font_create (hb_face_t *face) 1317 { 1318 hb_font_t *font; 1319 1320 if (unlikely (!face)) 1321 face = hb_face_get_empty (); 1322 if (!(font = hb_object_create<hb_font_t> ())) 1323 return hb_font_get_empty (); 1324 1325 hb_face_make_immutable (face); 1326 font->parent = hb_font_get_empty (); 1327 font->face = hb_face_reference (face); 1328 font->klass = hb_font_funcs_get_empty (); 1329 font->data.init0 (font); 1330 font->x_scale = font->y_scale = hb_face_get_upem (face); 1331 1332 return font; 1333 } 1334 1335 /** 1336 * hb_font_create: (Xconstructor) 1337 * @face: a face. 1338 * 1339 * 1340 * 1341 * Return value: (transfer full): 1342 * 1343 * Since: 0.9.2 1344 **/ 1345 hb_font_t * 1346 hb_font_create (hb_face_t *face) 1347 { 1348 hb_font_t *font = _hb_font_create (face); 1349 1350 /* Install our in-house, very lightweight, funcs. */ 1351 hb_ot_font_set_funcs (font); 1352 1353 return font; 1354 } 1355 1356 /** 1357 * hb_font_create_sub_font: 1358 * @parent: parent font. 1359 * 1360 * 1361 * 1362 * Return value: (transfer full): 1363 * 1364 * Since: 0.9.2 1365 **/ 1366 hb_font_t * 1367 hb_font_create_sub_font (hb_font_t *parent) 1368 { 1369 if (unlikely (!parent)) 1370 parent = hb_font_get_empty (); 1371 1372 hb_font_t *font = _hb_font_create (parent->face); 1373 1374 if (unlikely (hb_object_is_immutable (font))) 1375 return font; 1376 1377 font->parent = hb_font_reference (parent); 1378 1379 font->x_scale = parent->x_scale; 1380 font->y_scale = parent->y_scale; 1381 font->x_ppem = parent->x_ppem; 1382 font->y_ppem = parent->y_ppem; 1383 font->ptem = parent->ptem; 1384 1385 font->num_coords = parent->num_coords; 1386 if (!font->num_coords) 1387 font->coords = nullptr; 1388 else 1389 { 1390 unsigned int size = parent->num_coords * sizeof (parent->coords[0]); 1391 font->coords = (int *) malloc (size); 1392 if (unlikely (!font->coords)) 1393 font->num_coords = 0; 1394 else 1395 memcpy (font->coords, parent->coords, size); 1396 } 1397 1398 return font; 1399 } 1400 1401 /** 1402 * hb_font_get_empty: 1403 * 1404 * 1405 * 1406 * Return value: (transfer full) 1407 * 1408 * Since: 0.9.2 1409 **/ 1410 hb_font_t * 1411 hb_font_get_empty () 1412 { 1413 return const_cast<hb_font_t *> (&Null(hb_font_t)); 1414 } 1415 1416 /** 1417 * hb_font_reference: (skip) 1418 * @font: a font. 1419 * 1420 * 1421 * 1422 * Return value: (transfer full): 1423 * 1424 * Since: 0.9.2 1425 **/ 1426 hb_font_t * 1427 hb_font_reference (hb_font_t *font) 1428 { 1429 return hb_object_reference (font); 1430 } 1431 1432 /** 1433 * hb_font_destroy: (skip) 1434 * @font: a font. 1435 * 1436 * 1437 * 1438 * Since: 0.9.2 1439 **/ 1440 void 1441 hb_font_destroy (hb_font_t *font) 1442 { 1443 if (!hb_object_destroy (font)) return; 1444 1445 font->data.fini (); 1446 1447 if (font->destroy) 1448 font->destroy (font->user_data); 1449 1450 hb_font_destroy (font->parent); 1451 hb_face_destroy (font->face); 1452 hb_font_funcs_destroy (font->klass); 1453 1454 free (font->coords); 1455 1456 free (font); 1457 } 1458 1459 /** 1460 * hb_font_set_user_data: (skip) 1461 * @font: a font. 1462 * @key: 1463 * @data: 1464 * @destroy: 1465 * @replace: 1466 * 1467 * 1468 * 1469 * Return value: 1470 * 1471 * Since: 0.9.2 1472 **/ 1473 hb_bool_t 1474 hb_font_set_user_data (hb_font_t *font, 1475 hb_user_data_key_t *key, 1476 void * data, 1477 hb_destroy_func_t destroy, 1478 hb_bool_t replace) 1479 { 1480 return hb_object_set_user_data (font, key, data, destroy, replace); 1481 } 1482 1483 /** 1484 * hb_font_get_user_data: (skip) 1485 * @font: a font. 1486 * @key: 1487 * 1488 * 1489 * 1490 * Return value: (transfer none): 1491 * 1492 * Since: 0.9.2 1493 **/ 1494 void * 1495 hb_font_get_user_data (hb_font_t *font, 1496 hb_user_data_key_t *key) 1497 { 1498 return hb_object_get_user_data (font, key); 1499 } 1500 1501 /** 1502 * hb_font_make_immutable: 1503 * @font: a font. 1504 * 1505 * 1506 * 1507 * Since: 0.9.2 1508 **/ 1509 void 1510 hb_font_make_immutable (hb_font_t *font) 1511 { 1512 if (hb_object_is_immutable (font)) 1513 return; 1514 1515 if (font->parent) 1516 hb_font_make_immutable (font->parent); 1517 1518 hb_object_make_immutable (font); 1519 } 1520 1521 /** 1522 * hb_font_is_immutable: 1523 * @font: a font. 1524 * 1525 * 1526 * 1527 * Return value: 1528 * 1529 * Since: 0.9.2 1530 **/ 1531 hb_bool_t 1532 hb_font_is_immutable (hb_font_t *font) 1533 { 1534 return hb_object_is_immutable (font); 1535 } 1536 1537 /** 1538 * hb_font_set_parent: 1539 * @font: a font. 1540 * @parent: new parent. 1541 * 1542 * Sets parent font of @font. 1543 * 1544 * Since: 1.0.5 1545 **/ 1546 void 1547 hb_font_set_parent (hb_font_t *font, 1548 hb_font_t *parent) 1549 { 1550 if (hb_object_is_immutable (font)) 1551 return; 1552 1553 if (!parent) 1554 parent = hb_font_get_empty (); 1555 1556 hb_font_t *old = font->parent; 1557 1558 font->parent = hb_font_reference (parent); 1559 1560 hb_font_destroy (old); 1561 } 1562 1563 /** 1564 * hb_font_get_parent: 1565 * @font: a font. 1566 * 1567 * 1568 * 1569 * Return value: (transfer none): 1570 * 1571 * Since: 0.9.2 1572 **/ 1573 hb_font_t * 1574 hb_font_get_parent (hb_font_t *font) 1575 { 1576 return font->parent; 1577 } 1578 1579 /** 1580 * hb_font_set_face: 1581 * @font: a font. 1582 * @face: new face. 1583 * 1584 * Sets font-face of @font. 1585 * 1586 * Since: 1.4.3 1587 **/ 1588 void 1589 hb_font_set_face (hb_font_t *font, 1590 hb_face_t *face) 1591 { 1592 if (hb_object_is_immutable (font)) 1593 return; 1594 1595 if (unlikely (!face)) 1596 face = hb_face_get_empty (); 1597 1598 hb_face_t *old = font->face; 1599 1600 font->face = hb_face_reference (face); 1601 1602 hb_face_destroy (old); 1603 } 1604 1605 /** 1606 * hb_font_get_face: 1607 * @font: a font. 1608 * 1609 * 1610 * 1611 * Return value: (transfer none): 1612 * 1613 * Since: 0.9.2 1614 **/ 1615 hb_face_t * 1616 hb_font_get_face (hb_font_t *font) 1617 { 1618 return font->face; 1619 } 1620 1621 1622 /** 1623 * hb_font_set_funcs: 1624 * @font: a font. 1625 * @klass: (closure font_data) (destroy destroy) (scope notified): 1626 * @font_data: 1627 * @destroy: 1628 * 1629 * 1630 * 1631 * Since: 0.9.2 1632 **/ 1633 void 1634 hb_font_set_funcs (hb_font_t *font, 1635 hb_font_funcs_t *klass, 1636 void *font_data, 1637 hb_destroy_func_t destroy) 1638 { 1639 if (hb_object_is_immutable (font)) 1640 { 1641 if (destroy) 1642 destroy (font_data); 1643 return; 1644 } 1645 1646 if (font->destroy) 1647 font->destroy (font->user_data); 1648 1649 if (!klass) 1650 klass = hb_font_funcs_get_empty (); 1651 1652 hb_font_funcs_reference (klass); 1653 hb_font_funcs_destroy (font->klass); 1654 font->klass = klass; 1655 font->user_data = font_data; 1656 font->destroy = destroy; 1657 } 1658 1659 /** 1660 * hb_font_set_funcs_data: 1661 * @font: a font. 1662 * @font_data: (destroy destroy) (scope notified): 1663 * @destroy: 1664 * 1665 * 1666 * 1667 * Since: 0.9.2 1668 **/ 1669 void 1670 hb_font_set_funcs_data (hb_font_t *font, 1671 void *font_data, 1672 hb_destroy_func_t destroy) 1673 { 1674 /* Destroy user_data? */ 1675 if (hb_object_is_immutable (font)) 1676 { 1677 if (destroy) 1678 destroy (font_data); 1679 return; 1680 } 1681 1682 if (font->destroy) 1683 font->destroy (font->user_data); 1684 1685 font->user_data = font_data; 1686 font->destroy = destroy; 1687 } 1688 1689 1690 /** 1691 * hb_font_set_scale: 1692 * @font: a font. 1693 * @x_scale: 1694 * @y_scale: 1695 * 1696 * 1697 * 1698 * Since: 0.9.2 1699 **/ 1700 void 1701 hb_font_set_scale (hb_font_t *font, 1702 int x_scale, 1703 int y_scale) 1704 { 1705 if (hb_object_is_immutable (font)) 1706 return; 1707 1708 font->x_scale = x_scale; 1709 font->y_scale = y_scale; 1710 } 1711 1712 /** 1713 * hb_font_get_scale: 1714 * @font: a font. 1715 * @x_scale: (out): 1716 * @y_scale: (out): 1717 * 1718 * 1719 * 1720 * Since: 0.9.2 1721 **/ 1722 void 1723 hb_font_get_scale (hb_font_t *font, 1724 int *x_scale, 1725 int *y_scale) 1726 { 1727 if (x_scale) *x_scale = font->x_scale; 1728 if (y_scale) *y_scale = font->y_scale; 1729 } 1730 1731 /** 1732 * hb_font_set_ppem: 1733 * @font: a font. 1734 * @x_ppem: 1735 * @y_ppem: 1736 * 1737 * 1738 * 1739 * Since: 0.9.2 1740 **/ 1741 void 1742 hb_font_set_ppem (hb_font_t *font, 1743 unsigned int x_ppem, 1744 unsigned int y_ppem) 1745 { 1746 if (hb_object_is_immutable (font)) 1747 return; 1748 1749 font->x_ppem = x_ppem; 1750 font->y_ppem = y_ppem; 1751 } 1752 1753 /** 1754 * hb_font_get_ppem: 1755 * @font: a font. 1756 * @x_ppem: (out): 1757 * @y_ppem: (out): 1758 * 1759 * 1760 * 1761 * Since: 0.9.2 1762 **/ 1763 void 1764 hb_font_get_ppem (hb_font_t *font, 1765 unsigned int *x_ppem, 1766 unsigned int *y_ppem) 1767 { 1768 if (x_ppem) *x_ppem = font->x_ppem; 1769 if (y_ppem) *y_ppem = font->y_ppem; 1770 } 1771 1772 /** 1773 * hb_font_set_ptem: 1774 * @font: a font. 1775 * @ptem: font size in points. 1776 * 1777 * Sets "point size" of the font. Set to 0 to unset. 1778 * 1779 * There are 72 points in an inch. 1780 * 1781 * Since: 1.6.0 1782 **/ 1783 void 1784 hb_font_set_ptem (hb_font_t *font, float ptem) 1785 { 1786 if (hb_object_is_immutable (font)) 1787 return; 1788 1789 font->ptem = ptem; 1790 } 1791 1792 /** 1793 * hb_font_get_ptem: 1794 * @font: a font. 1795 * 1796 * Gets the "point size" of the font. A value of 0 means unset. 1797 * 1798 * Return value: Point size. 1799 * 1800 * Since: 0.9.2 1801 **/ 1802 float 1803 hb_font_get_ptem (hb_font_t *font) 1804 { 1805 return font->ptem; 1806 } 1807 1808 /* 1809 * Variations 1810 */ 1811 1812 static void 1813 _hb_font_adopt_var_coords_normalized (hb_font_t *font, 1814 int *coords, /* 2.14 normalized */ 1815 unsigned int coords_length) 1816 { 1817 free (font->coords); 1818 1819 font->coords = coords; 1820 font->num_coords = coords_length; 1821 } 1822 1823 /** 1824 * hb_font_set_variations: 1825 * 1826 * Since: 1.4.2 1827 */ 1828 void 1829 hb_font_set_variations (hb_font_t *font, 1830 const hb_variation_t *variations, 1831 unsigned int variations_length) 1832 { 1833 if (hb_object_is_immutable (font)) 1834 return; 1835 1836 if (!variations_length) 1837 { 1838 hb_font_set_var_coords_normalized (font, nullptr, 0); 1839 return; 1840 } 1841 1842 unsigned int coords_length = hb_ot_var_get_axis_count (font->face); 1843 1844 int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : nullptr; 1845 if (unlikely (coords_length && !normalized)) 1846 return; 1847 1848 hb_ot_var_normalize_variations (font->face, 1849 variations, variations_length, 1850 normalized, coords_length); 1851 _hb_font_adopt_var_coords_normalized (font, normalized, coords_length); 1852 } 1853 1854 /** 1855 * hb_font_set_var_coords_design: 1856 * 1857 * Since: 1.4.2 1858 */ 1859 void 1860 hb_font_set_var_coords_design (hb_font_t *font, 1861 const float *coords, 1862 unsigned int coords_length) 1863 { 1864 if (hb_object_is_immutable (font)) 1865 return; 1866 1867 int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : nullptr; 1868 if (unlikely (coords_length && !normalized)) 1869 return; 1870 1871 hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized); 1872 _hb_font_adopt_var_coords_normalized (font, normalized, coords_length); 1873 } 1874 1875 /** 1876 * hb_font_set_var_coords_normalized: 1877 * 1878 * Since: 1.4.2 1879 */ 1880 void 1881 hb_font_set_var_coords_normalized (hb_font_t *font, 1882 const int *coords, /* 2.14 normalized */ 1883 unsigned int coords_length) 1884 { 1885 if (hb_object_is_immutable (font)) 1886 return; 1887 1888 int *copy = coords_length ? (int *) calloc (coords_length, sizeof (coords[0])) : nullptr; 1889 if (unlikely (coords_length && !copy)) 1890 return; 1891 1892 if (coords_length) 1893 memcpy (copy, coords, coords_length * sizeof (coords[0])); 1894 1895 _hb_font_adopt_var_coords_normalized (font, copy, coords_length); 1896 } 1897 1898 /** 1899 * hb_font_get_var_coords_normalized: 1900 * 1901 * Return value is valid as long as variation coordinates of the font 1902 * are not modified. 1903 * 1904 * Since: 1.4.2 1905 */ 1906 const int * 1907 hb_font_get_var_coords_normalized (hb_font_t *font, 1908 unsigned int *length) 1909 { 1910 if (length) 1911 *length = font->num_coords; 1912 1913 return font->coords; 1914 } 1915 1916 1917 /* 1918 * Deprecated get_glyph_func(): 1919 */ 1920 1921 struct hb_trampoline_closure_t 1922 { 1923 void *user_data; 1924 hb_destroy_func_t destroy; 1925 unsigned int ref_count; 1926 }; 1927 1928 template <typename FuncType> 1929 struct hb_trampoline_t 1930 { 1931 hb_trampoline_closure_t closure; /* Must be first. */ 1932 FuncType func; 1933 }; 1934 1935 template <typename FuncType> 1936 static hb_trampoline_t<FuncType> * 1937 trampoline_create (FuncType func, 1938 void *user_data, 1939 hb_destroy_func_t destroy) 1940 { 1941 typedef hb_trampoline_t<FuncType> trampoline_t; 1942 1943 trampoline_t *trampoline = (trampoline_t *) calloc (1, sizeof (trampoline_t)); 1944 1945 if (unlikely (!trampoline)) 1946 return nullptr; 1947 1948 trampoline->closure.user_data = user_data; 1949 trampoline->closure.destroy = destroy; 1950 trampoline->closure.ref_count = 1; 1951 trampoline->func = func; 1952 1953 return trampoline; 1954 } 1955 1956 static void 1957 trampoline_reference (hb_trampoline_closure_t *closure) 1958 { 1959 closure->ref_count++; 1960 } 1961 1962 static void 1963 trampoline_destroy (void *user_data) 1964 { 1965 hb_trampoline_closure_t *closure = (hb_trampoline_closure_t *) user_data; 1966 1967 if (--closure->ref_count) 1968 return; 1969 1970 if (closure->destroy) 1971 closure->destroy (closure->user_data); 1972 free (closure); 1973 } 1974 1975 typedef hb_trampoline_t<hb_font_get_glyph_func_t> hb_font_get_glyph_trampoline_t; 1976 1977 static hb_bool_t 1978 hb_font_get_nominal_glyph_trampoline (hb_font_t *font, 1979 void *font_data, 1980 hb_codepoint_t unicode, 1981 hb_codepoint_t *glyph, 1982 void *user_data) 1983 { 1984 hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data; 1985 return trampoline->func (font, font_data, unicode, 0, glyph, trampoline->closure.user_data); 1986 } 1987 1988 static hb_bool_t 1989 hb_font_get_variation_glyph_trampoline (hb_font_t *font, 1990 void *font_data, 1991 hb_codepoint_t unicode, 1992 hb_codepoint_t variation_selector, 1993 hb_codepoint_t *glyph, 1994 void *user_data) 1995 { 1996 hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data; 1997 return trampoline->func (font, font_data, unicode, variation_selector, glyph, trampoline->closure.user_data); 1998 } 1999 2000 /** 2001 * hb_font_funcs_set_glyph_func: 2002 * @ffuncs: font functions. 2003 * @func: (closure user_data) (destroy destroy) (scope notified): callback function. 2004 * @user_data: data to pass to @func. 2005 * @destroy: function to call when @user_data is not needed anymore. 2006 * 2007 * Deprecated. Use hb_font_funcs_set_nominal_glyph_func() and 2008 * hb_font_funcs_set_variation_glyph_func() instead. 2009 * 2010 * Since: 0.9.2 2011 * Deprecated: 1.2.3 2012 **/ 2013 void 2014 hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, 2015 hb_font_get_glyph_func_t func, 2016 void *user_data, hb_destroy_func_t destroy) 2017 { 2018 hb_font_get_glyph_trampoline_t *trampoline; 2019 2020 trampoline = trampoline_create (func, user_data, destroy); 2021 if (unlikely (!trampoline)) 2022 { 2023 if (destroy) 2024 destroy (user_data); 2025 return; 2026 } 2027 2028 hb_font_funcs_set_nominal_glyph_func (ffuncs, 2029 hb_font_get_nominal_glyph_trampoline, 2030 trampoline, 2031 trampoline_destroy); 2032 2033 trampoline_reference (&trampoline->closure); 2034 hb_font_funcs_set_variation_glyph_func (ffuncs, 2035 hb_font_get_variation_glyph_trampoline, 2036 trampoline, 2037 trampoline_destroy); 2038 } 2039