| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright © 2009 Red Hat, Inc. | 2 * Copyright © 2009 Red Hat, Inc. |
| 3 * Copyright © 2009 Keith Stribley | 3 * Copyright © 2009 Keith Stribley |
| 4 * Copyright © 2015 Google, Inc. | 4 * Copyright © 2015 Google, Inc. |
| 5 * | 5 * |
| 6 * This is part of HarfBuzz, a text shaping library. | 6 * This is part of HarfBuzz, a text shaping library. |
| 7 * | 7 * |
| 8 * Permission is hereby granted, without written agreement and without | 8 * Permission is hereby granted, without written agreement and without |
| 9 * license or royalty fees, to use, copy, modify, and distribute this | 9 * license or royalty fees, to use, copy, modify, and distribute this |
| 10 * software and its documentation for any purpose, provided that the | 10 * software and its documentation for any purpose, provided that the |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 * - In the future, we should add constructors to create fonts in font space? | 63 * - In the future, we should add constructors to create fonts in font space? |
| 64 * | 64 * |
| 65 * - FT_Load_Glyph() is exteremely costly. Do something about it? | 65 * - FT_Load_Glyph() is exteremely costly. Do something about it? |
| 66 */ | 66 */ |
| 67 | 67 |
| 68 | 68 |
| 69 struct hb_ft_font_t | 69 struct hb_ft_font_t |
| 70 { | 70 { |
| 71 FT_Face ft_face; | 71 FT_Face ft_face; |
| 72 int load_flags; | 72 int load_flags; |
| 73 bool symbol; /* Whether selected cmap is symbol cmap. */ |
| 73 bool unref; /* Whether to destroy ft_face when done. */ | 74 bool unref; /* Whether to destroy ft_face when done. */ |
| 74 }; | 75 }; |
| 75 | 76 |
| 76 static hb_ft_font_t * | 77 static hb_ft_font_t * |
| 77 _hb_ft_font_create (FT_Face ft_face, bool unref) | 78 _hb_ft_font_create (FT_Face ft_face, bool symbol, bool unref) |
| 78 { | 79 { |
| 79 hb_ft_font_t *ft_font = (hb_ft_font_t *) calloc (1, sizeof (hb_ft_font_t)); | 80 hb_ft_font_t *ft_font = (hb_ft_font_t *) calloc (1, sizeof (hb_ft_font_t)); |
| 80 | 81 |
| 81 if (unlikely (!ft_font)) | 82 if (unlikely (!ft_font)) |
| 82 return NULL; | 83 return NULL; |
| 83 | 84 |
| 84 ft_font->ft_face = ft_face; | 85 ft_font->ft_face = ft_face; |
| 86 ft_font->symbol = symbol; |
| 85 ft_font->unref = unref; | 87 ft_font->unref = unref; |
| 86 | 88 |
| 87 ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING; | 89 ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING; |
| 88 | 90 |
| 89 return ft_font; | 91 return ft_font; |
| 90 } | 92 } |
| 91 | 93 |
| 92 static void | 94 static void |
| 95 _hb_ft_face_destroy (FT_Face ft_face) |
| 96 { |
| 97 FT_Done_Face (ft_face); |
| 98 } |
| 99 |
| 100 static void |
| 93 _hb_ft_font_destroy (hb_ft_font_t *ft_font) | 101 _hb_ft_font_destroy (hb_ft_font_t *ft_font) |
| 94 { | 102 { |
| 95 if (ft_font->unref) | 103 if (ft_font->unref) |
| 96 FT_Done_Face (ft_font->ft_face); | 104 _hb_ft_face_destroy (ft_font->ft_face); |
| 97 | 105 |
| 98 free (ft_font); | 106 free (ft_font); |
| 99 } | 107 } |
| 100 | 108 |
| 101 /** | 109 /** |
| 102 * hb_ft_font_set_load_flags: | 110 * hb_ft_font_set_load_flags: |
| 103 * @font: | 111 * @font: |
| 104 * @load_flags: | 112 * @load_flags: |
| 105 * | 113 * |
| 106 * | 114 * |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 hb_ft_get_nominal_glyph (hb_font_t *font HB_UNUSED, | 166 hb_ft_get_nominal_glyph (hb_font_t *font HB_UNUSED, |
| 159 void *font_data, | 167 void *font_data, |
| 160 hb_codepoint_t unicode, | 168 hb_codepoint_t unicode, |
| 161 hb_codepoint_t *glyph, | 169 hb_codepoint_t *glyph, |
| 162 void *user_data HB_UNUSED) | 170 void *user_data HB_UNUSED) |
| 163 { | 171 { |
| 164 const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; | 172 const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; |
| 165 unsigned int g = FT_Get_Char_Index (ft_font->ft_face, unicode); | 173 unsigned int g = FT_Get_Char_Index (ft_font->ft_face, unicode); |
| 166 | 174 |
| 167 if (unlikely (!g)) | 175 if (unlikely (!g)) |
| 168 return false; | 176 { |
| 177 if (unlikely (ft_font->symbol) && unicode <= 0x00FFu) |
| 178 { |
| 179 /* For symbol-encoded OpenType fonts, we duplicate the |
| 180 * U+F000..F0FF range at U+0000..U+00FF. That's what |
| 181 * Windows seems to do, and that's hinted about at: |
| 182 * http://www.microsoft.com/typography/otspec/recom.htm |
| 183 * under "Non-Standard (Symbol) Fonts". */ |
| 184 g = FT_Get_Char_Index (ft_font->ft_face, 0xF000u + unicode); |
| 185 if (!g) |
| 186 » return false; |
| 187 } |
| 188 else |
| 189 return false; |
| 190 } |
| 169 | 191 |
| 170 *glyph = g; | 192 *glyph = g; |
| 171 return true; | 193 return true; |
| 172 } | 194 } |
| 173 | 195 |
| 174 static hb_bool_t | 196 static hb_bool_t |
| 175 hb_ft_get_variation_glyph (hb_font_t *font HB_UNUSED, | 197 hb_ft_get_variation_glyph (hb_font_t *font HB_UNUSED, |
| 176 void *font_data, | 198 void *font_data, |
| 177 hb_codepoint_t unicode, | 199 hb_codepoint_t unicode, |
| 178 hb_codepoint_t variation_selector, | 200 hb_codepoint_t variation_selector, |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 437 if (!hb_atomic_ptr_cmpexch (&static_ft_funcs, NULL, funcs)) { | 459 if (!hb_atomic_ptr_cmpexch (&static_ft_funcs, NULL, funcs)) { |
| 438 hb_font_funcs_destroy (funcs); | 460 hb_font_funcs_destroy (funcs); |
| 439 goto retry; | 461 goto retry; |
| 440 } | 462 } |
| 441 | 463 |
| 442 #ifdef HB_USE_ATEXIT | 464 #ifdef HB_USE_ATEXIT |
| 443 atexit (free_static_ft_funcs); /* First person registers atexit() callback.
*/ | 465 atexit (free_static_ft_funcs); /* First person registers atexit() callback.
*/ |
| 444 #endif | 466 #endif |
| 445 }; | 467 }; |
| 446 | 468 |
| 469 bool symbol = ft_face->charmap && ft_face->charmap->encoding == FT_ENCODING_MS
_SYMBOL; |
| 470 |
| 447 hb_font_set_funcs (font, | 471 hb_font_set_funcs (font, |
| 448 funcs, | 472 funcs, |
| 449 » » _hb_ft_font_create (ft_face, unref), | 473 » » _hb_ft_font_create (ft_face, symbol, unref), |
| 450 (hb_destroy_func_t) _hb_ft_font_destroy); | 474 (hb_destroy_func_t) _hb_ft_font_destroy); |
| 451 } | 475 } |
| 452 | 476 |
| 453 | 477 |
| 454 static hb_blob_t * | 478 static hb_blob_t * |
| 455 reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) | 479 reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) |
| 456 { | 480 { |
| 457 FT_Face ft_face = (FT_Face) user_data; | 481 FT_Face ft_face = (FT_Face) user_data; |
| 458 FT_Byte *buffer; | 482 FT_Byte *buffer; |
| 459 FT_ULong length = 0; | 483 FT_ULong length = 0; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 519 * | 543 * |
| 520 * | 544 * |
| 521 * | 545 * |
| 522 * Return value: (transfer full): | 546 * Return value: (transfer full): |
| 523 * Since: 0.9.38 | 547 * Since: 0.9.38 |
| 524 **/ | 548 **/ |
| 525 hb_face_t * | 549 hb_face_t * |
| 526 hb_ft_face_create_referenced (FT_Face ft_face) | 550 hb_ft_face_create_referenced (FT_Face ft_face) |
| 527 { | 551 { |
| 528 FT_Reference_Face (ft_face); | 552 FT_Reference_Face (ft_face); |
| 529 return hb_ft_face_create (ft_face, (hb_destroy_func_t) FT_Done_Face); | 553 return hb_ft_face_create (ft_face, (hb_destroy_func_t) _hb_ft_face_destroy); |
| 530 } | 554 } |
| 531 | 555 |
| 532 static void | 556 static void |
| 533 hb_ft_face_finalize (FT_Face ft_face) | 557 hb_ft_face_finalize (FT_Face ft_face) |
| 534 { | 558 { |
| 535 hb_face_destroy ((hb_face_t *) ft_face->generic.data); | 559 hb_face_destroy ((hb_face_t *) ft_face->generic.data); |
| 536 } | 560 } |
| 537 | 561 |
| 538 /** | 562 /** |
| 539 * hb_ft_face_create_cached: | 563 * hb_ft_face_create_cached: |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 * | 623 * |
| 600 * | 624 * |
| 601 * | 625 * |
| 602 * Return value: (transfer full): | 626 * Return value: (transfer full): |
| 603 * Since: 0.9.38 | 627 * Since: 0.9.38 |
| 604 **/ | 628 **/ |
| 605 hb_font_t * | 629 hb_font_t * |
| 606 hb_ft_font_create_referenced (FT_Face ft_face) | 630 hb_ft_font_create_referenced (FT_Face ft_face) |
| 607 { | 631 { |
| 608 FT_Reference_Face (ft_face); | 632 FT_Reference_Face (ft_face); |
| 609 return hb_ft_font_create (ft_face, (hb_destroy_func_t) FT_Done_Face); | 633 return hb_ft_font_create (ft_face, (hb_destroy_func_t) _hb_ft_face_destroy); |
| 610 } | 634 } |
| 611 | 635 |
| 612 | 636 |
| 613 /* Thread-safe, lock-free, FT_Library */ | 637 /* Thread-safe, lock-free, FT_Library */ |
| 614 | 638 |
| 615 static FT_Library ft_library; | 639 static FT_Library ft_library; |
| 616 | 640 |
| 617 #ifdef HB_USE_ATEXIT | 641 #ifdef HB_USE_ATEXIT |
| 618 static | 642 static |
| 619 void free_ft_library (void) | 643 void free_ft_library (void) |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 668 blob_length, | 692 blob_length, |
| 669 hb_face_get_index (font->face), | 693 hb_face_get_index (font->face), |
| 670 &ft_face); | 694 &ft_face); |
| 671 | 695 |
| 672 if (unlikely (err)) { | 696 if (unlikely (err)) { |
| 673 hb_blob_destroy (blob); | 697 hb_blob_destroy (blob); |
| 674 DEBUG_MSG (FT, font, "Font face FT_New_Memory_Face() failed"); | 698 DEBUG_MSG (FT, font, "Font face FT_New_Memory_Face() failed"); |
| 675 return; | 699 return; |
| 676 } | 700 } |
| 677 | 701 |
| 678 FT_Select_Charmap (ft_face, FT_ENCODING_UNICODE); | 702 if (FT_Select_Charmap (ft_face, FT_ENCODING_UNICODE)) |
| 703 FT_Select_Charmap (ft_face, FT_ENCODING_MS_SYMBOL); |
| 679 | 704 |
| 680 FT_Set_Char_Size (ft_face, | 705 FT_Set_Char_Size (ft_face, |
| 681 abs (font->x_scale), abs (font->y_scale), | 706 abs (font->x_scale), abs (font->y_scale), |
| 682 0, 0); | 707 0, 0); |
| 683 #if 0 | 708 #if 0 |
| 684 font->x_ppem * 72 * 64 / font->x_scale, | 709 font->x_ppem * 72 * 64 / font->x_scale, |
| 685 font->y_ppem * 72 * 64 / font->y_scale); | 710 font->y_ppem * 72 * 64 / font->y_scale); |
| 686 #endif | 711 #endif |
| 687 if (font->x_scale < 0 || font->y_scale < 0) | 712 if (font->x_scale < 0 || font->y_scale < 0) |
| 688 { | 713 { |
| 689 FT_Matrix matrix = { font->x_scale < 0 ? -1 : +1, 0, | 714 FT_Matrix matrix = { font->x_scale < 0 ? -1 : +1, 0, |
| 690 0, font->y_scale < 0 ? -1 : +1}; | 715 0, font->y_scale < 0 ? -1 : +1}; |
| 691 FT_Set_Transform (ft_face, &matrix, NULL); | 716 FT_Set_Transform (ft_face, &matrix, NULL); |
| 692 } | 717 } |
| 693 | 718 |
| 694 ft_face->generic.data = blob; | 719 ft_face->generic.data = blob; |
| 695 ft_face->generic.finalizer = (FT_Generic_Finalizer) _release_blob; | 720 ft_face->generic.finalizer = (FT_Generic_Finalizer) _release_blob; |
| 696 | 721 |
| 697 _hb_ft_font_set_funcs (font, ft_face, true); | 722 _hb_ft_font_set_funcs (font, ft_face, true); |
| 698 hb_ft_font_set_load_flags (font, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING); | 723 hb_ft_font_set_load_flags (font, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING); |
| 699 } | 724 } |
| OLD | NEW |