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-blob.h" 35 #include "hb-open-file-private.hh" 36 #include "hb-ot-head-table.hh" 37 #include "hb-ot-maxp-table.hh" 38 39 #include "hb-cache-private.hh" 40 41 #include <string.h> 42 43 44 45 /* 46 * hb_font_funcs_t 47 */ 48 49 static hb_bool_t 50 hb_font_get_glyph_nil (hb_font_t *font, 51 void *font_data HB_UNUSED, 52 hb_codepoint_t unicode, 53 hb_codepoint_t variation_selector, 54 hb_codepoint_t *glyph, 55 void *user_data HB_UNUSED) 56 { 57 if (font->parent) 58 return font->parent->get_glyph (unicode, variation_selector, glyph); 59 60 *glyph = 0; 61 return false; 62 } 63 64 static hb_position_t 65 hb_font_get_glyph_h_advance_nil (hb_font_t *font, 66 void *font_data HB_UNUSED, 67 hb_codepoint_t glyph, 68 void *user_data HB_UNUSED) 69 { 70 if (font->parent) 71 return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph)); 72 73 return font->x_scale; 74 } 75 76 static hb_position_t 77 hb_font_get_glyph_v_advance_nil (hb_font_t *font, 78 void *font_data HB_UNUSED, 79 hb_codepoint_t glyph, 80 void *user_data HB_UNUSED) 81 { 82 if (font->parent) 83 return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph)); 84 85 return font->y_scale; 86 } 87 88 static hb_bool_t 89 hb_font_get_glyph_h_origin_nil (hb_font_t *font, 90 void *font_data HB_UNUSED, 91 hb_codepoint_t glyph, 92 hb_position_t *x, 93 hb_position_t *y, 94 void *user_data HB_UNUSED) 95 { 96 if (font->parent) { 97 hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y); 98 if (ret) 99 font->parent_scale_position (x, y); 100 return ret; 101 } 102 103 *x = *y = 0; 104 return false; 105 } 106 107 static hb_bool_t 108 hb_font_get_glyph_v_origin_nil (hb_font_t *font, 109 void *font_data HB_UNUSED, 110 hb_codepoint_t glyph, 111 hb_position_t *x, 112 hb_position_t *y, 113 void *user_data HB_UNUSED) 114 { 115 if (font->parent) { 116 hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y); 117 if (ret) 118 font->parent_scale_position (x, y); 119 return ret; 120 } 121 122 *x = *y = 0; 123 return false; 124 } 125 126 static hb_position_t 127 hb_font_get_glyph_h_kerning_nil (hb_font_t *font, 128 void *font_data HB_UNUSED, 129 hb_codepoint_t left_glyph, 130 hb_codepoint_t right_glyph, 131 void *user_data HB_UNUSED) 132 { 133 if (font->parent) 134 return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph)); 135 136 return 0; 137 } 138 139 static hb_position_t 140 hb_font_get_glyph_v_kerning_nil (hb_font_t *font, 141 void *font_data HB_UNUSED, 142 hb_codepoint_t top_glyph, 143 hb_codepoint_t bottom_glyph, 144 void *user_data HB_UNUSED) 145 { 146 if (font->parent) 147 return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph)); 148 149 return 0; 150 } 151 152 static hb_bool_t 153 hb_font_get_glyph_extents_nil (hb_font_t *font, 154 void *font_data HB_UNUSED, 155 hb_codepoint_t glyph, 156 hb_glyph_extents_t *extents, 157 void *user_data HB_UNUSED) 158 { 159 if (font->parent) { 160 hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents); 161 if (ret) { 162 font->parent_scale_position (&extents->x_bearing, &extents->y_bearing); 163 font->parent_scale_distance (&extents->width, &extents->height); 164 } 165 return ret; 166 } 167 168 memset (extents, 0, sizeof (*extents)); 169 return false; 170 } 171 172 static hb_bool_t 173 hb_font_get_glyph_contour_point_nil (hb_font_t *font, 174 void *font_data HB_UNUSED, 175 hb_codepoint_t glyph, 176 unsigned int point_index, 177 hb_position_t *x, 178 hb_position_t *y, 179 void *user_data HB_UNUSED) 180 { 181 if (font->parent) { 182 hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y); 183 if (ret) 184 font->parent_scale_position (x, y); 185 return ret; 186 } 187 188 *x = *y = 0; 189 return false; 190 } 191 192 static hb_bool_t 193 hb_font_get_glyph_name_nil (hb_font_t *font, 194 void *font_data HB_UNUSED, 195 hb_codepoint_t glyph, 196 char *name, unsigned int size, 197 void *user_data HB_UNUSED) 198 { 199 if (font->parent) 200 return font->parent->get_glyph_name (glyph, name, size); 201 202 if (size) *name = '\0'; 203 return false; 204 } 205 206 static hb_bool_t 207 hb_font_get_glyph_from_name_nil (hb_font_t *font, 208 void *font_data HB_UNUSED, 209 const char *name, int len, /* -1 means nul-terminated */ 210 hb_codepoint_t *glyph, 211 void *user_data HB_UNUSED) 212 { 213 if (font->parent) 214 return font->parent->get_glyph_from_name (name, len, glyph); 215 216 *glyph = 0; 217 return false; 218 } 219 220 221 static const hb_font_funcs_t _hb_font_funcs_nil = { 222 HB_OBJECT_HEADER_STATIC, 223 224 true, /* immutable */ 225 226 { 227 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil, 228 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 229 #undef HB_FONT_FUNC_IMPLEMENT 230 } 231 }; 232 233 234 hb_font_funcs_t * 235 hb_font_funcs_create (void) 236 { 237 hb_font_funcs_t *ffuncs; 238 239 if (!(ffuncs = hb_object_create<hb_font_funcs_t> ())) 240 return hb_font_funcs_get_empty (); 241 242 ffuncs->get = _hb_font_funcs_nil.get; 243 244 return ffuncs; 245 } 246 247 hb_font_funcs_t * 248 hb_font_funcs_get_empty (void) 249 { 250 return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil); 251 } 252 253 hb_font_funcs_t * 254 hb_font_funcs_reference (hb_font_funcs_t *ffuncs) 255 { 256 return hb_object_reference (ffuncs); 257 } 258 259 void 260 hb_font_funcs_destroy (hb_font_funcs_t *ffuncs) 261 { 262 if (!hb_object_destroy (ffuncs)) return; 263 264 #define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \ 265 ffuncs->destroy.name (ffuncs->user_data.name); 266 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 267 #undef HB_FONT_FUNC_IMPLEMENT 268 269 free (ffuncs); 270 } 271 272 hb_bool_t 273 hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs, 274 hb_user_data_key_t *key, 275 void * data, 276 hb_destroy_func_t destroy, 277 hb_bool_t replace) 278 { 279 return hb_object_set_user_data (ffuncs, key, data, destroy, replace); 280 } 281 282 void * 283 hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs, 284 hb_user_data_key_t *key) 285 { 286 return hb_object_get_user_data (ffuncs, key); 287 } 288 289 290 void 291 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs) 292 { 293 if (hb_object_is_inert (ffuncs)) 294 return; 295 296 ffuncs->immutable = true; 297 } 298 299 hb_bool_t 300 hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs) 301 { 302 return ffuncs->immutable; 303 } 304 305 306 #define HB_FONT_FUNC_IMPLEMENT(name) \ 307 \ 308 void \ 309 hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \ 310 hb_font_get_##name##_func_t func, \ 311 void *user_data, \ 312 hb_destroy_func_t destroy) \ 313 { \ 314 if (ffuncs->immutable) { \ 315 if (destroy) \ 316 destroy (user_data); \ 317 return; \ 318 } \ 319 \ 320 if (ffuncs->destroy.name) \ 321 ffuncs->destroy.name (ffuncs->user_data.name); \ 322 \ 323 if (func) { \ 324 ffuncs->get.name = func; \ 325 ffuncs->user_data.name = user_data; \ 326 ffuncs->destroy.name = destroy; \ 327 } else { \ 328 ffuncs->get.name = hb_font_get_##name##_nil; \ 329 ffuncs->user_data.name = NULL; \ 330 ffuncs->destroy.name = NULL; \ 331 } \ 332 } 333 334 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS 335 #undef HB_FONT_FUNC_IMPLEMENT 336 337 338 /* Public getters */ 339 340 hb_bool_t 341 hb_font_get_glyph (hb_font_t *font, 342 hb_codepoint_t unicode, hb_codepoint_t variation_selector, 343 hb_codepoint_t *glyph) 344 { 345 return font->get_glyph (unicode, variation_selector, glyph); 346 } 347 348 hb_position_t 349 hb_font_get_glyph_h_advance (hb_font_t *font, 350 hb_codepoint_t glyph) 351 { 352 return font->get_glyph_h_advance (glyph); 353 } 354 355 hb_position_t 356 hb_font_get_glyph_v_advance (hb_font_t *font, 357 hb_codepoint_t glyph) 358 { 359 return font->get_glyph_v_advance (glyph); 360 } 361 362 hb_bool_t 363 hb_font_get_glyph_h_origin (hb_font_t *font, 364 hb_codepoint_t glyph, 365 hb_position_t *x, hb_position_t *y) 366 { 367 return font->get_glyph_h_origin (glyph, x, y); 368 } 369 370 hb_bool_t 371 hb_font_get_glyph_v_origin (hb_font_t *font, 372 hb_codepoint_t glyph, 373 hb_position_t *x, hb_position_t *y) 374 { 375 return font->get_glyph_v_origin (glyph, x, y); 376 } 377 378 hb_position_t 379 hb_font_get_glyph_h_kerning (hb_font_t *font, 380 hb_codepoint_t left_glyph, hb_codepoint_t right_glyph) 381 { 382 return font->get_glyph_h_kerning (left_glyph, right_glyph); 383 } 384 385 hb_position_t 386 hb_font_get_glyph_v_kerning (hb_font_t *font, 387 hb_codepoint_t left_glyph, hb_codepoint_t right_glyph) 388 { 389 return font->get_glyph_v_kerning (left_glyph, right_glyph); 390 } 391 392 hb_bool_t 393 hb_font_get_glyph_extents (hb_font_t *font, 394 hb_codepoint_t glyph, 395 hb_glyph_extents_t *extents) 396 { 397 return font->get_glyph_extents (glyph, extents); 398 } 399 400 hb_bool_t 401 hb_font_get_glyph_contour_point (hb_font_t *font, 402 hb_codepoint_t glyph, unsigned int point_index, 403 hb_position_t *x, hb_position_t *y) 404 { 405 return font->get_glyph_contour_point (glyph, point_index, x, y); 406 } 407 408 hb_bool_t 409 hb_font_get_glyph_name (hb_font_t *font, 410 hb_codepoint_t glyph, 411 char *name, unsigned int size) 412 { 413 return font->get_glyph_name (glyph, name, size); 414 } 415 416 hb_bool_t 417 hb_font_get_glyph_from_name (hb_font_t *font, 418 const char *name, int len, /* -1 means nul-terminated */ 419 hb_codepoint_t *glyph) 420 { 421 return font->get_glyph_from_name (name, len, glyph); 422 } 423 424 425 /* A bit higher-level, and with fallback */ 426 427 void 428 hb_font_get_glyph_advance_for_direction (hb_font_t *font, 429 hb_codepoint_t glyph, 430 hb_direction_t direction, 431 hb_position_t *x, hb_position_t *y) 432 { 433 return font->get_glyph_advance_for_direction (glyph, direction, x, y); 434 } 435 436 void 437 hb_font_get_glyph_origin_for_direction (hb_font_t *font, 438 hb_codepoint_t glyph, 439 hb_direction_t direction, 440 hb_position_t *x, hb_position_t *y) 441 { 442 return font->get_glyph_origin_for_direction (glyph, direction, x, y); 443 } 444 445 void 446 hb_font_add_glyph_origin_for_direction (hb_font_t *font, 447 hb_codepoint_t glyph, 448 hb_direction_t direction, 449 hb_position_t *x, hb_position_t *y) 450 { 451 return font->add_glyph_origin_for_direction (glyph, direction, x, y); 452 } 453 454 void 455 hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, 456 hb_codepoint_t glyph, 457 hb_direction_t direction, 458 hb_position_t *x, hb_position_t *y) 459 { 460 return font->subtract_glyph_origin_for_direction (glyph, direction, x, y); 461 } 462 463 void 464 hb_font_get_glyph_kerning_for_direction (hb_font_t *font, 465 hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, 466 hb_direction_t direction, 467 hb_position_t *x, hb_position_t *y) 468 { 469 return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y); 470 } 471 472 hb_bool_t 473 hb_font_get_glyph_extents_for_origin (hb_font_t *font, 474 hb_codepoint_t glyph, 475 hb_direction_t direction, 476 hb_glyph_extents_t *extents) 477 { 478 return font->get_glyph_extents_for_origin (glyph, direction, extents); 479 } 480 481 hb_bool_t 482 hb_font_get_glyph_contour_point_for_origin (hb_font_t *font, 483 hb_codepoint_t glyph, unsigned int point_index, 484 hb_direction_t direction, 485 hb_position_t *x, hb_position_t *y) 486 { 487 return font->get_glyph_contour_point_for_origin (glyph, point_index, direction, x, y); 488 } 489 490 /* Generates gidDDD if glyph has no name. */ 491 void 492 hb_font_glyph_to_string (hb_font_t *font, 493 hb_codepoint_t glyph, 494 char *s, unsigned int size) 495 { 496 font->glyph_to_string (glyph, s, size); 497 } 498 499 /* Parses gidDDD and uniUUUU strings automatically. */ 500 hb_bool_t 501 hb_font_glyph_from_string (hb_font_t *font, 502 const char *s, int len, /* -1 means nul-terminated */ 503 hb_codepoint_t *glyph) 504 { 505 return font->glyph_from_string (s, len, glyph); 506 } 507 508 509 /* 510 * hb_face_t 511 */ 512 513 static const hb_face_t _hb_face_nil = { 514 HB_OBJECT_HEADER_STATIC, 515 516 true, /* immutable */ 517 518 NULL, /* reference_table_func */ 519 NULL, /* user_data */ 520 NULL, /* destroy */ 521 522 0, /* index */ 523 1000, /* upem */ 524 0, /* num_glyphs */ 525 526 { 527 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID, 528 #include "hb-shaper-list.hh" 529 #undef HB_SHAPER_IMPLEMENT 530 }, 531 532 NULL, /* shape_plans */ 533 }; 534 535 536 hb_face_t * 537 hb_face_create_for_tables (hb_reference_table_func_t reference_table_func, 538 void *user_data, 539 hb_destroy_func_t destroy) 540 { 541 hb_face_t *face; 542 543 if (!reference_table_func || !(face = hb_object_create<hb_face_t> ())) { 544 if (destroy) 545 destroy (user_data); 546 return hb_face_get_empty (); 547 } 548 549 face->reference_table_func = reference_table_func; 550 face->user_data = user_data; 551 face->destroy = destroy; 552 553 face->upem = 0; 554 face->num_glyphs = (unsigned int) -1; 555 556 return face; 557 } 558 559 560 typedef struct hb_face_for_data_closure_t { 561 hb_blob_t *blob; 562 unsigned int index; 563 } hb_face_for_data_closure_t; 564 565 static hb_face_for_data_closure_t * 566 _hb_face_for_data_closure_create (hb_blob_t *blob, unsigned int index) 567 { 568 hb_face_for_data_closure_t *closure; 569 570 closure = (hb_face_for_data_closure_t *) malloc (sizeof (hb_face_for_data_closure_t)); 571 if (unlikely (!closure)) 572 return NULL; 573 574 closure->blob = blob; 575 closure->index = index; 576 577 return closure; 578 } 579 580 static void 581 _hb_face_for_data_closure_destroy (hb_face_for_data_closure_t *closure) 582 { 583 hb_blob_destroy (closure->blob); 584 free (closure); 585 } 586 587 static hb_blob_t * 588 _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) 589 { 590 hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data; 591 592 if (tag == HB_TAG_NONE) 593 return hb_blob_reference (data->blob); 594 595 const OT::OpenTypeFontFile &ot_file = *OT::Sanitizer<OT::OpenTypeFontFile>::lock_instance (data->blob); 596 const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index); 597 598 const OT::OpenTypeTable &table = ot_face.get_table_by_tag (tag); 599 600 hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, table.offset, table.length); 601 602 return blob; 603 } 604 605 hb_face_t * 606 hb_face_create (hb_blob_t *blob, 607 unsigned int index) 608 { 609 hb_face_t *face; 610 611 if (unlikely (!blob || !hb_blob_get_length (blob))) 612 return hb_face_get_empty (); 613 614 hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::Sanitizer<OT::OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index); 615 616 if (unlikely (!closure)) 617 return hb_face_get_empty (); 618 619 face = hb_face_create_for_tables (_hb_face_for_data_reference_table, 620 closure, 621 (hb_destroy_func_t) _hb_face_for_data_closure_destroy); 622 623 hb_face_set_index (face, index); 624 625 return face; 626 } 627 628 hb_face_t * 629 hb_face_get_empty (void) 630 { 631 return const_cast<hb_face_t *> (&_hb_face_nil); 632 } 633 634 635 hb_face_t * 636 hb_face_reference (hb_face_t *face) 637 { 638 return hb_object_reference (face); 639 } 640 641 void 642 hb_face_destroy (hb_face_t *face) 643 { 644 if (!hb_object_destroy (face)) return; 645 646 for (hb_face_t::plan_node_t *node = face->shape_plans; node; ) 647 { 648 hb_face_t::plan_node_t *next = node->next; 649 hb_shape_plan_destroy (node->shape_plan); 650 free (node); 651 node = next; 652 } 653 654 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, face); 655 #include "hb-shaper-list.hh" 656 #undef HB_SHAPER_IMPLEMENT 657 658 if (face->destroy) 659 face->destroy (face->user_data); 660 661 free (face); 662 } 663 664 hb_bool_t 665 hb_face_set_user_data (hb_face_t *face, 666 hb_user_data_key_t *key, 667 void * data, 668 hb_destroy_func_t destroy, 669 hb_bool_t replace) 670 { 671 return hb_object_set_user_data (face, key, data, destroy, replace); 672 } 673 674 void * 675 hb_face_get_user_data (hb_face_t *face, 676 hb_user_data_key_t *key) 677 { 678 return hb_object_get_user_data (face, key); 679 } 680 681 void 682 hb_face_make_immutable (hb_face_t *face) 683 { 684 if (hb_object_is_inert (face)) 685 return; 686 687 face->immutable = true; 688 } 689 690 hb_bool_t 691 hb_face_is_immutable (hb_face_t *face) 692 { 693 return face->immutable; 694 } 695 696 697 hb_blob_t * 698 hb_face_reference_table (hb_face_t *face, 699 hb_tag_t tag) 700 { 701 return face->reference_table (tag); 702 } 703 704 hb_blob_t * 705 hb_face_reference_blob (hb_face_t *face) 706 { 707 return face->reference_table (HB_TAG_NONE); 708 } 709 710 void 711 hb_face_set_index (hb_face_t *face, 712 unsigned int index) 713 { 714 if (hb_object_is_inert (face)) 715 return; 716 717 face->index = index; 718 } 719 720 unsigned int 721 hb_face_get_index (hb_face_t *face) 722 { 723 return face->index; 724 } 725 726 void 727 hb_face_set_upem (hb_face_t *face, 728 unsigned int upem) 729 { 730 if (hb_object_is_inert (face)) 731 return; 732 733 face->upem = upem; 734 } 735 736 unsigned int 737 hb_face_get_upem (hb_face_t *face) 738 { 739 return face->get_upem (); 740 } 741 742 void 743 hb_face_t::load_upem (void) const 744 { 745 hb_blob_t *head_blob = OT::Sanitizer<OT::head>::sanitize (reference_table (HB_OT_TAG_head)); 746 const OT::head *head_table = OT::Sanitizer<OT::head>::lock_instance (head_blob); 747 upem = head_table->get_upem (); 748 hb_blob_destroy (head_blob); 749 } 750 751 void 752 hb_face_set_glyph_count (hb_face_t *face, 753 unsigned int glyph_count) 754 { 755 if (hb_object_is_inert (face)) 756 return; 757 758 face->num_glyphs = glyph_count; 759 } 760 761 unsigned int 762 hb_face_get_glyph_count (hb_face_t *face) 763 { 764 return face->get_num_glyphs (); 765 } 766 767 void 768 hb_face_t::load_num_glyphs (void) const 769 { 770 hb_blob_t *maxp_blob = OT::Sanitizer<OT::maxp>::sanitize (reference_table (HB_OT_TAG_maxp)); 771 const OT::maxp *maxp_table = OT::Sanitizer<OT::maxp>::lock_instance (maxp_blob); 772 num_glyphs = maxp_table->get_num_glyphs (); 773 hb_blob_destroy (maxp_blob); 774 } 775 776 777 /* 778 * hb_font_t 779 */ 780 781 hb_font_t * 782 hb_font_create (hb_face_t *face) 783 { 784 hb_font_t *font; 785 786 if (unlikely (!face)) 787 face = hb_face_get_empty (); 788 if (unlikely (hb_object_is_inert (face))) 789 return hb_font_get_empty (); 790 if (!(font = hb_object_create<hb_font_t> ())) 791 return hb_font_get_empty (); 792 793 hb_face_make_immutable (face); 794 font->face = hb_face_reference (face); 795 font->klass = hb_font_funcs_get_empty (); 796 797 return font; 798 } 799 800 hb_font_t * 801 hb_font_create_sub_font (hb_font_t *parent) 802 { 803 if (unlikely (!parent)) 804 return hb_font_get_empty (); 805 806 hb_font_t *font = hb_font_create (parent->face); 807 808 if (unlikely (hb_object_is_inert (font))) 809 return font; 810 811 hb_font_make_immutable (parent); 812 font->parent = hb_font_reference (parent); 813 814 font->x_scale = parent->x_scale; 815 font->y_scale = parent->y_scale; 816 font->x_ppem = parent->x_ppem; 817 font->y_ppem = parent->y_ppem; 818 819 return font; 820 } 821 822 hb_font_t * 823 hb_font_get_empty (void) 824 { 825 static const hb_font_t _hb_font_nil = { 826 HB_OBJECT_HEADER_STATIC, 827 828 true, /* immutable */ 829 830 NULL, /* parent */ 831 const_cast<hb_face_t *> (&_hb_face_nil), 832 833 0, /* x_scale */ 834 0, /* y_scale */ 835 836 0, /* x_ppem */ 837 0, /* y_ppem */ 838 839 const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil), /* klass */ 840 NULL, /* user_data */ 841 NULL, /* destroy */ 842 843 { 844 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID, 845 #include "hb-shaper-list.hh" 846 #undef HB_SHAPER_IMPLEMENT 847 } 848 }; 849 850 return const_cast<hb_font_t *> (&_hb_font_nil); 851 } 852 853 hb_font_t * 854 hb_font_reference (hb_font_t *font) 855 { 856 return hb_object_reference (font); 857 } 858 859 void 860 hb_font_destroy (hb_font_t *font) 861 { 862 if (!hb_object_destroy (font)) return; 863 864 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, font); 865 #include "hb-shaper-list.hh" 866 #undef HB_SHAPER_IMPLEMENT 867 868 if (font->destroy) 869 font->destroy (font->user_data); 870 871 hb_font_destroy (font->parent); 872 hb_face_destroy (font->face); 873 hb_font_funcs_destroy (font->klass); 874 875 free (font); 876 } 877 878 hb_bool_t 879 hb_font_set_user_data (hb_font_t *font, 880 hb_user_data_key_t *key, 881 void * data, 882 hb_destroy_func_t destroy, 883 hb_bool_t replace) 884 { 885 return hb_object_set_user_data (font, key, data, destroy, replace); 886 } 887 888 void * 889 hb_font_get_user_data (hb_font_t *font, 890 hb_user_data_key_t *key) 891 { 892 return hb_object_get_user_data (font, key); 893 } 894 895 void 896 hb_font_make_immutable (hb_font_t *font) 897 { 898 if (hb_object_is_inert (font)) 899 return; 900 901 font->immutable = true; 902 } 903 904 hb_bool_t 905 hb_font_is_immutable (hb_font_t *font) 906 { 907 return font->immutable; 908 } 909 910 hb_font_t * 911 hb_font_get_parent (hb_font_t *font) 912 { 913 return font->parent; 914 } 915 916 hb_face_t * 917 hb_font_get_face (hb_font_t *font) 918 { 919 return font->face; 920 } 921 922 923 void 924 hb_font_set_funcs (hb_font_t *font, 925 hb_font_funcs_t *klass, 926 void *user_data, 927 hb_destroy_func_t destroy) 928 { 929 if (font->immutable) { 930 if (destroy) 931 destroy (user_data); 932 return; 933 } 934 935 if (font->destroy) 936 font->destroy (font->user_data); 937 938 if (!klass) 939 klass = hb_font_funcs_get_empty (); 940 941 hb_font_funcs_reference (klass); 942 hb_font_funcs_destroy (font->klass); 943 font->klass = klass; 944 font->user_data = user_data; 945 font->destroy = destroy; 946 } 947 948 void 949 hb_font_set_funcs_data (hb_font_t *font, 950 void *user_data, 951 hb_destroy_func_t destroy) 952 { 953 /* Destroy user_data? */ 954 if (font->immutable) { 955 if (destroy) 956 destroy (user_data); 957 return; 958 } 959 960 if (font->destroy) 961 font->destroy (font->user_data); 962 963 font->user_data = user_data; 964 font->destroy = destroy; 965 } 966 967 968 void 969 hb_font_set_scale (hb_font_t *font, 970 int x_scale, 971 int y_scale) 972 { 973 if (font->immutable) 974 return; 975 976 font->x_scale = x_scale; 977 font->y_scale = y_scale; 978 } 979 980 void 981 hb_font_get_scale (hb_font_t *font, 982 int *x_scale, 983 int *y_scale) 984 { 985 if (x_scale) *x_scale = font->x_scale; 986 if (y_scale) *y_scale = font->y_scale; 987 } 988 989 void 990 hb_font_set_ppem (hb_font_t *font, 991 unsigned int x_ppem, 992 unsigned int y_ppem) 993 { 994 if (font->immutable) 995 return; 996 997 font->x_ppem = x_ppem; 998 font->y_ppem = y_ppem; 999 } 1000 1001 void 1002 hb_font_get_ppem (hb_font_t *font, 1003 unsigned int *x_ppem, 1004 unsigned int *y_ppem) 1005 { 1006 if (x_ppem) *x_ppem = font->x_ppem; 1007 if (y_ppem) *y_ppem = font->y_ppem; 1008 } 1009