1 /**************************************************************************** 2 * 3 * sfdriver.c 4 * 5 * High-level SFNT driver interface (body). 6 * 7 * Copyright (C) 1996-2019 by 8 * David Turner, Robert Wilhelm, and Werner Lemberg. 9 * 10 * This file is part of the FreeType project, and may only be used, 11 * modified, and distributed under the terms of the FreeType project 12 * license, LICENSE.TXT. By continuing to use, modify, or distribute 13 * this file you indicate that you have read the license and 14 * understand and accept it fully. 15 * 16 */ 17 18 19 #include <ft2build.h> 20 #include FT_INTERNAL_DEBUG_H 21 #include FT_INTERNAL_SFNT_H 22 #include FT_INTERNAL_OBJECTS_H 23 #include FT_TRUETYPE_IDS_H 24 25 #include "sfdriver.h" 26 #include "ttload.h" 27 #include "sfobjs.h" 28 29 #include "sferrors.h" 30 31 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 32 #include "ttsbit.h" 33 #endif 34 35 #ifdef TT_CONFIG_OPTION_COLOR_LAYERS 36 #include "ttcolr.h" 37 #include "ttcpal.h" 38 #endif 39 40 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES 41 #include "ttpost.h" 42 #endif 43 44 #ifdef TT_CONFIG_OPTION_BDF 45 #include "ttbdf.h" 46 #include FT_SERVICE_BDF_H 47 #endif 48 49 #include "ttcmap.h" 50 #include "ttkern.h" 51 #include "ttmtx.h" 52 53 #include FT_SERVICE_GLYPH_DICT_H 54 #include FT_SERVICE_POSTSCRIPT_NAME_H 55 #include FT_SERVICE_SFNT_H 56 #include FT_SERVICE_TT_CMAP_H 57 58 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 59 #include FT_MULTIPLE_MASTERS_H 60 #include FT_SERVICE_MULTIPLE_MASTERS_H 61 #endif 62 63 64 /************************************************************************** 65 * 66 * The macro FT_COMPONENT is used in trace mode. It is an implicit 67 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log 68 * messages during execution. 69 */ 70 #undef FT_COMPONENT 71 #define FT_COMPONENT sfdriver 72 73 74 /* 75 * SFNT TABLE SERVICE 76 * 77 */ 78 79 static void* 80 get_sfnt_table( TT_Face face, 81 FT_Sfnt_Tag tag ) 82 { 83 void* table; 84 85 86 switch ( tag ) 87 { 88 case FT_SFNT_HEAD: 89 table = &face->header; 90 break; 91 92 case FT_SFNT_HHEA: 93 table = &face->horizontal; 94 break; 95 96 case FT_SFNT_VHEA: 97 table = face->vertical_info ? &face->vertical : NULL; 98 break; 99 100 case FT_SFNT_OS2: 101 table = ( face->os2.version == 0xFFFFU ) ? NULL : &face->os2; 102 break; 103 104 case FT_SFNT_POST: 105 table = &face->postscript; 106 break; 107 108 case FT_SFNT_MAXP: 109 table = &face->max_profile; 110 break; 111 112 case FT_SFNT_PCLT: 113 table = face->pclt.Version ? &face->pclt : NULL; 114 break; 115 116 default: 117 table = NULL; 118 } 119 120 return table; 121 } 122 123 124 static FT_Error 125 sfnt_table_info( TT_Face face, 126 FT_UInt idx, 127 FT_ULong *tag, 128 FT_ULong *offset, 129 FT_ULong *length ) 130 { 131 if ( !offset || !length ) 132 return FT_THROW( Invalid_Argument ); 133 134 if ( !tag ) 135 *length = face->num_tables; 136 else 137 { 138 if ( idx >= face->num_tables ) 139 return FT_THROW( Table_Missing ); 140 141 *tag = face->dir_tables[idx].Tag; 142 *offset = face->dir_tables[idx].Offset; 143 *length = face->dir_tables[idx].Length; 144 } 145 146 return FT_Err_Ok; 147 } 148 149 150 FT_DEFINE_SERVICE_SFNT_TABLEREC( 151 sfnt_service_sfnt_table, 152 153 (FT_SFNT_TableLoadFunc)tt_face_load_any, /* load_table */ 154 (FT_SFNT_TableGetFunc) get_sfnt_table, /* get_table */ 155 (FT_SFNT_TableInfoFunc)sfnt_table_info /* table_info */ 156 ) 157 158 159 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES 160 161 /* 162 * GLYPH DICT SERVICE 163 * 164 */ 165 166 static FT_Error 167 sfnt_get_glyph_name( FT_Face face, 168 FT_UInt glyph_index, 169 FT_Pointer buffer, 170 FT_UInt buffer_max ) 171 { 172 FT_String* gname; 173 FT_Error error; 174 175 176 error = tt_face_get_ps_name( (TT_Face)face, glyph_index, &gname ); 177 if ( !error ) 178 FT_STRCPYN( buffer, gname, buffer_max ); 179 180 return error; 181 } 182 183 184 static FT_UInt 185 sfnt_get_name_index( FT_Face face, 186 FT_String* glyph_name ) 187 { 188 TT_Face ttface = (TT_Face)face; 189 190 FT_UInt i, max_gid = FT_UINT_MAX; 191 192 193 if ( face->num_glyphs < 0 ) 194 return 0; 195 else if ( (FT_ULong)face->num_glyphs < FT_UINT_MAX ) 196 max_gid = (FT_UInt)face->num_glyphs; 197 else 198 FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08x\n", 199 FT_UINT_MAX, face->num_glyphs )); 200 201 for ( i = 0; i < max_gid; i++ ) 202 { 203 FT_String* gname; 204 FT_Error error = tt_face_get_ps_name( ttface, i, &gname ); 205 206 207 if ( error ) 208 continue; 209 210 if ( !ft_strcmp( glyph_name, gname ) ) 211 return i; 212 } 213 214 return 0; 215 } 216 217 218 FT_DEFINE_SERVICE_GLYPHDICTREC( 219 sfnt_service_glyph_dict, 220 221 (FT_GlyphDict_GetNameFunc) sfnt_get_glyph_name, /* get_name */ 222 (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index /* name_index */ 223 ) 224 225 #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ 226 227 228 /* 229 * POSTSCRIPT NAME SERVICE 230 * 231 */ 232 233 /* an array representing allowed ASCII characters in a PS string */ 234 static const unsigned char sfnt_ps_map[16] = 235 { 236 /* 4 0 C 8 */ 237 0x00, 0x00, /* 0x00: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 */ 238 0x00, 0x00, /* 0x10: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 */ 239 0xDE, 0x7C, /* 0x20: 1 1 0 1 1 1 1 0 0 1 1 1 1 1 0 0 */ 240 0xFF, 0xAF, /* 0x30: 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 1 */ 241 0xFF, 0xFF, /* 0x40: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 */ 242 0xFF, 0xD7, /* 0x50: 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 */ 243 0xFF, 0xFF, /* 0x60: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 */ 244 0xFF, 0x57 /* 0x70: 1 1 1 1 1 1 1 1 0 1 0 1 0 1 1 1 */ 245 }; 246 247 248 static int 249 sfnt_is_postscript( int c ) 250 { 251 unsigned int cc; 252 253 254 if ( c < 0 || c >= 0x80 ) 255 return 0; 256 257 cc = (unsigned int)c; 258 259 return sfnt_ps_map[cc >> 3] & ( 1 << ( cc & 0x07 ) ); 260 } 261 262 263 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 264 265 /* Only ASCII letters and digits are taken for a variation font */ 266 /* instance's PostScript name. */ 267 /* */ 268 /* `ft_isalnum' is a macro, but we need a function here, thus */ 269 /* this definition. */ 270 static int 271 sfnt_is_alphanumeric( int c ) 272 { 273 return ft_isalnum( c ); 274 } 275 276 277 /* the implementation of MurmurHash3 is taken and adapted from */ 278 /* https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp */ 279 280 #define ROTL32( x, r ) ( x << r ) | ( x >> ( 32 - r ) ) 281 282 283 static FT_UInt32 284 fmix32( FT_UInt32 h ) 285 { 286 h ^= h >> 16; 287 h *= 0x85ebca6b; 288 h ^= h >> 13; 289 h *= 0xc2b2ae35; 290 h ^= h >> 16; 291 292 return h; 293 } 294 295 296 static void 297 murmur_hash_3_128( const void* key, 298 const unsigned int len, 299 FT_UInt32 seed, 300 void* out ) 301 { 302 const FT_Byte* data = (const FT_Byte*)key; 303 const int nblocks = (int)len / 16; 304 305 FT_UInt32 h1 = seed; 306 FT_UInt32 h2 = seed; 307 FT_UInt32 h3 = seed; 308 FT_UInt32 h4 = seed; 309 310 const FT_UInt32 c1 = 0x239b961b; 311 const FT_UInt32 c2 = 0xab0e9789; 312 const FT_UInt32 c3 = 0x38b34ae5; 313 const FT_UInt32 c4 = 0xa1e38b93; 314 315 const FT_UInt32* blocks = (const FT_UInt32*)( data + nblocks * 16 ); 316 317 int i; 318 319 320 for( i = -nblocks; i; i++ ) 321 { 322 FT_UInt32 k1 = blocks[i * 4 + 0]; 323 FT_UInt32 k2 = blocks[i * 4 + 1]; 324 FT_UInt32 k3 = blocks[i * 4 + 2]; 325 FT_UInt32 k4 = blocks[i * 4 + 3]; 326 327 328 k1 *= c1; 329 k1 = ROTL32( k1, 15 ); 330 k1 *= c2; 331 h1 ^= k1; 332 333 h1 = ROTL32( h1, 19 ); 334 h1 += h2; 335 h1 = h1 * 5 + 0x561ccd1b; 336 337 k2 *= c2; 338 k2 = ROTL32( k2, 16 ); 339 k2 *= c3; 340 h2 ^= k2; 341 342 h2 = ROTL32( h2, 17 ); 343 h2 += h3; 344 h2 = h2 * 5 + 0x0bcaa747; 345 346 k3 *= c3; 347 k3 = ROTL32( k3, 17 ); 348 k3 *= c4; 349 h3 ^= k3; 350 351 h3 = ROTL32( h3, 15 ); 352 h3 += h4; 353 h3 = h3 * 5 + 0x96cd1c35; 354 355 k4 *= c4; 356 k4 = ROTL32( k4, 18 ); 357 k4 *= c1; 358 h4 ^= k4; 359 360 h4 = ROTL32( h4, 13 ); 361 h4 += h1; 362 h4 = h4 * 5 + 0x32ac3b17; 363 } 364 365 { 366 const FT_Byte* tail = (const FT_Byte*)( data + nblocks * 16 ); 367 368 FT_UInt32 k1 = 0; 369 FT_UInt32 k2 = 0; 370 FT_UInt32 k3 = 0; 371 FT_UInt32 k4 = 0; 372 373 374 switch ( len & 15 ) 375 { 376 case 15: 377 k4 ^= (FT_UInt32)tail[14] << 16; 378 case 14: 379 k4 ^= (FT_UInt32)tail[13] << 8; 380 case 13: 381 k4 ^= (FT_UInt32)tail[12]; 382 k4 *= c4; 383 k4 = ROTL32( k4, 18 ); 384 k4 *= c1; 385 h4 ^= k4; 386 387 case 12: 388 k3 ^= (FT_UInt32)tail[11] << 24; 389 case 11: 390 k3 ^= (FT_UInt32)tail[10] << 16; 391 case 10: 392 k3 ^= (FT_UInt32)tail[9] << 8; 393 case 9: 394 k3 ^= (FT_UInt32)tail[8]; 395 k3 *= c3; 396 k3 = ROTL32( k3, 17 ); 397 k3 *= c4; 398 h3 ^= k3; 399 400 case 8: 401 k2 ^= (FT_UInt32)tail[7] << 24; 402 case 7: 403 k2 ^= (FT_UInt32)tail[6] << 16; 404 case 6: 405 k2 ^= (FT_UInt32)tail[5] << 8; 406 case 5: 407 k2 ^= (FT_UInt32)tail[4]; 408 k2 *= c2; 409 k2 = ROTL32( k2, 16 ); 410 k2 *= c3; 411 h2 ^= k2; 412 413 case 4: 414 k1 ^= (FT_UInt32)tail[3] << 24; 415 case 3: 416 k1 ^= (FT_UInt32)tail[2] << 16; 417 case 2: 418 k1 ^= (FT_UInt32)tail[1] << 8; 419 case 1: 420 k1 ^= (FT_UInt32)tail[0]; 421 k1 *= c1; 422 k1 = ROTL32( k1, 15 ); 423 k1 *= c2; 424 h1 ^= k1; 425 } 426 } 427 428 h1 ^= len; 429 h2 ^= len; 430 h3 ^= len; 431 h4 ^= len; 432 433 h1 += h2; 434 h1 += h3; 435 h1 += h4; 436 437 h2 += h1; 438 h3 += h1; 439 h4 += h1; 440 441 h1 = fmix32( h1 ); 442 h2 = fmix32( h2 ); 443 h3 = fmix32( h3 ); 444 h4 = fmix32( h4 ); 445 446 h1 += h2; 447 h1 += h3; 448 h1 += h4; 449 450 h2 += h1; 451 h3 += h1; 452 h4 += h1; 453 454 ((FT_UInt32*)out)[0] = h1; 455 ((FT_UInt32*)out)[1] = h2; 456 ((FT_UInt32*)out)[2] = h3; 457 ((FT_UInt32*)out)[3] = h4; 458 } 459 460 461 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ 462 463 464 typedef int (*char_type_func)( int c ); 465 466 467 /* Handling of PID/EID 3/0 and 3/1 is the same. */ 468 #define IS_WIN( n ) ( (n)->platformID == 3 && \ 469 ( (n)->encodingID == 1 || (n)->encodingID == 0 ) ) 470 471 #define IS_APPLE( n ) ( (n)->platformID == 1 && \ 472 (n)->encodingID == 0 ) 473 474 static char* 475 get_win_string( FT_Memory memory, 476 FT_Stream stream, 477 TT_Name entry, 478 char_type_func char_type, 479 FT_Bool report_invalid_characters ) 480 { 481 FT_Error error = FT_Err_Ok; 482 483 char* result = NULL; 484 FT_String* r; 485 FT_Char* p; 486 FT_UInt len; 487 488 FT_UNUSED( error ); 489 490 491 if ( FT_ALLOC( result, entry->stringLength / 2 + 1 ) ) 492 return NULL; 493 494 if ( FT_STREAM_SEEK( entry->stringOffset ) || 495 FT_FRAME_ENTER( entry->stringLength ) ) 496 goto get_win_string_error; 497 498 r = (FT_String*)result; 499 p = (FT_Char*)stream->cursor; 500 501 for ( len = entry->stringLength / 2; len > 0; len--, p += 2 ) 502 { 503 if ( p[0] == 0 && char_type( p[1] ) ) 504 *r++ = p[1]; 505 else 506 { 507 if ( report_invalid_characters ) 508 FT_TRACE0(( "get_win_string:" 509 " Character 0x%X invalid in PS name string\n", 510 ((unsigned)p[0])*256 + (unsigned)p[1] )); 511 break; 512 } 513 } 514 if ( !len ) 515 *r = '\0'; 516 517 FT_FRAME_EXIT(); 518 519 if ( !len ) 520 return result; 521 522 get_win_string_error: 523 FT_FREE( result ); 524 525 entry->stringLength = 0; 526 entry->stringOffset = 0; 527 FT_FREE( entry->string ); 528 529 return NULL; 530 } 531 532 533 static char* 534 get_apple_string( FT_Memory memory, 535 FT_Stream stream, 536 TT_Name entry, 537 char_type_func char_type, 538 FT_Bool report_invalid_characters ) 539 { 540 FT_Error error = FT_Err_Ok; 541 542 char* result = NULL; 543 FT_String* r; 544 FT_Char* p; 545 FT_UInt len; 546 547 FT_UNUSED( error ); 548 549 550 if ( FT_ALLOC( result, entry->stringLength + 1 ) ) 551 return NULL; 552 553 if ( FT_STREAM_SEEK( entry->stringOffset ) || 554 FT_FRAME_ENTER( entry->stringLength ) ) 555 goto get_apple_string_error; 556 557 r = (FT_String*)result; 558 p = (FT_Char*)stream->cursor; 559 560 for ( len = entry->stringLength; len > 0; len--, p++ ) 561 { 562 if ( char_type( *p ) ) 563 *r++ = *p; 564 else 565 { 566 if ( report_invalid_characters ) 567 FT_TRACE0(( "get_apple_string:" 568 " Character `%c' (0x%X) invalid in PS name string\n", 569 *p, *p )); 570 break; 571 } 572 } 573 if ( !len ) 574 *r = '\0'; 575 576 FT_FRAME_EXIT(); 577 578 if ( !len ) 579 return result; 580 581 get_apple_string_error: 582 FT_FREE( result ); 583 584 entry->stringOffset = 0; 585 entry->stringLength = 0; 586 FT_FREE( entry->string ); 587 588 return NULL; 589 } 590 591 592 static FT_Bool 593 sfnt_get_name_id( TT_Face face, 594 FT_UShort id, 595 FT_Int *win, 596 FT_Int *apple ) 597 { 598 FT_Int n; 599 600 601 *win = -1; 602 *apple = -1; 603 604 for ( n = 0; n < face->num_names; n++ ) 605 { 606 TT_Name name = face->name_table.names + n; 607 608 609 if ( name->nameID == id && name->stringLength > 0 ) 610 { 611 if ( IS_WIN( name ) && ( name->languageID == 0x409 || *win == -1 ) ) 612 *win = n; 613 614 if ( IS_APPLE( name ) && ( name->languageID == 0 || *apple == -1 ) ) 615 *apple = n; 616 } 617 } 618 619 return ( *win >= 0 ) || ( *apple >= 0 ); 620 } 621 622 623 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 624 625 /* 626 The maximum length of an axis value descriptor. 627 628 We need 65536 different values for the decimal fraction; this fits 629 nicely into five decimal places. Consequently, it consists of 630 631 . the minus sign if the number is negative, 632 . up to five characters for the digits before the decimal point, 633 . the decimal point if there is a fractional part, and 634 . up to five characters for the digits after the decimal point. 635 636 We also need one byte for the leading `_' character and up to four 637 bytes for the axis tag. 638 */ 639 #define MAX_VALUE_DESCRIPTOR_LEN ( 1 + 5 + 1 + 5 + 1 + 4 ) 640 641 642 /* the maximum length of PostScript font names */ 643 #define MAX_PS_NAME_LEN 127 644 645 646 /* 647 * Find the shortest decimal representation of a 16.16 fixed point 648 * number. The function fills `buf' with the result, returning a pointer 649 * to the position after the representation's last byte. 650 */ 651 652 static char* 653 fixed2float( FT_Int fixed, 654 char* buf ) 655 { 656 char* p; 657 char* q; 658 char tmp[5]; 659 660 FT_Int int_part; 661 FT_Int frac_part; 662 663 FT_Int i; 664 665 666 p = buf; 667 668 if ( fixed == 0 ) 669 { 670 *p++ = '0'; 671 return p; 672 } 673 674 if ( fixed < 0 ) 675 { 676 *p++ = '-'; 677 fixed = NEG_INT( fixed ); 678 } 679 680 int_part = ( fixed >> 16 ) & 0xFFFF; 681 frac_part = fixed & 0xFFFF; 682 683 /* get digits of integer part (in reverse order) */ 684 q = tmp; 685 while ( int_part > 0 ) 686 { 687 *q++ = '0' + int_part % 10; 688 int_part /= 10; 689 } 690 691 /* copy digits in correct order to buffer */ 692 while ( q > tmp ) 693 *p++ = *--q; 694 695 if ( !frac_part ) 696 return p; 697 698 /* save position of point */ 699 q = p; 700 *p++ = '.'; 701 702 /* apply rounding */ 703 frac_part = frac_part * 10 + 5; 704 705 /* get digits of fractional part */ 706 for ( i = 0; i < 5; i++ ) 707 { 708 *p++ = '0' + (char)( frac_part / 0x10000L ); 709 710 frac_part %= 0x10000L; 711 if ( !frac_part ) 712 break; 713 714 frac_part *= 10; 715 } 716 717 /* 718 If the remainder stored in `frac_part' (after the last FOR loop) is 719 smaller than 34480*10, the resulting decimal value minus 0.00001 is 720 an equivalent representation of `fixed'. 721 722 The above FOR loop always finds the larger of the two values; I 723 verified this by iterating over all possible fixed point numbers. 724 725 If the remainder is 17232*10, both values are equally good, and we 726 take the next even number (following IEEE 754's `round to nearest, 727 ties to even' rounding rule). 728 729 If the remainder is smaller than 17232*10, the lower of the two 730 numbers is nearer to the exact result (values 17232 and 34480 were 731 also found by testing all possible fixed point values). 732 733 We use this to find a shorter decimal representation. If not ending 734 with digit zero, we take the representation with less error. 735 */ 736 p--; 737 if ( p - q == 5 ) /* five digits? */ 738 { 739 /* take the representation that has zero as the last digit */ 740 if ( frac_part < 34480 * 10 && 741 *p == '1' ) 742 *p = '0'; 743 744 /* otherwise use the one with less error */ 745 else if ( frac_part == 17232 * 10 && 746 *p & 1 ) 747 *p -= 1; 748 749 else if ( frac_part < 17232 * 10 && 750 *p != '0' ) 751 *p -= 1; 752 } 753 754 /* remove trailing zeros */ 755 while ( *p == '0' ) 756 *p-- = '\0'; 757 758 return p + 1; 759 } 760 761 762 static const char hexdigits[16] = 763 { 764 '0', '1', '2', '3', '4', '5', '6', '7', 765 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' 766 }; 767 768 769 static const char* 770 sfnt_get_var_ps_name( TT_Face face ) 771 { 772 FT_Error error; 773 FT_Memory memory = face->root.memory; 774 775 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; 776 777 FT_UInt num_coords; 778 FT_Fixed* coords; 779 FT_MM_Var* mm_var; 780 781 FT_Int found, win, apple; 782 FT_UInt i, j; 783 784 char* result = NULL; 785 char* p; 786 787 788 if ( !face->var_postscript_prefix ) 789 { 790 FT_UInt len; 791 792 793 /* check whether we have a Variations PostScript Name Prefix */ 794 found = sfnt_get_name_id( face, 795 TT_NAME_ID_VARIATIONS_PREFIX, 796 &win, 797 &apple ); 798 if ( !found ) 799 { 800 /* otherwise use the typographic family name */ 801 found = sfnt_get_name_id( face, 802 TT_NAME_ID_TYPOGRAPHIC_FAMILY, 803 &win, 804 &apple ); 805 } 806 807 if ( !found ) 808 { 809 /* as a last resort we try the family name; note that this is */ 810 /* not in the Adobe TechNote, but GX fonts (which predate the */ 811 /* TechNote) benefit from this behaviour */ 812 found = sfnt_get_name_id( face, 813 TT_NAME_ID_FONT_FAMILY, 814 &win, 815 &apple ); 816 } 817 818 if ( !found ) 819 { 820 FT_TRACE0(( "sfnt_get_var_ps_name:" 821 " Can't construct PS name prefix for font instances\n" )); 822 return NULL; 823 } 824 825 /* prefer Windows entries over Apple */ 826 if ( win != -1 ) 827 result = get_win_string( face->root.memory, 828 face->name_table.stream, 829 face->name_table.names + win, 830 sfnt_is_alphanumeric, 831 0 ); 832 if ( !result && apple != -1 ) 833 result = get_apple_string( face->root.memory, 834 face->name_table.stream, 835 face->name_table.names + apple, 836 sfnt_is_alphanumeric, 837 0 ); 838 839 if ( !result ) 840 { 841 FT_TRACE0(( "sfnt_get_var_ps_name:" 842 " No valid PS name prefix for font instances found\n" )); 843 return NULL; 844 } 845 846 len = ft_strlen( result ); 847 848 /* sanitize if necessary; we reserve space for 36 bytes (a 128bit */ 849 /* checksum as a hex number, preceded by `-' and followed by three */ 850 /* ASCII dots, to be used if the constructed PS name would be too */ 851 /* long); this is also sufficient for a single instance */ 852 if ( len > MAX_PS_NAME_LEN - ( 1 + 32 + 3 ) ) 853 { 854 len = MAX_PS_NAME_LEN - ( 1 + 32 + 3 ); 855 result[len] = '\0'; 856 857 FT_TRACE0(( "sfnt_get_var_ps_name:" 858 " Shortening variation PS name prefix\n" 859 " " 860 " to %d characters\n", len )); 861 } 862 863 face->var_postscript_prefix = result; 864 face->var_postscript_prefix_len = len; 865 } 866 867 mm->get_var_blend( FT_FACE( face ), 868 &num_coords, 869 &coords, 870 NULL, 871 &mm_var ); 872 873 if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) && 874 !FT_IS_VARIATION( FT_FACE( face ) ) ) 875 { 876 SFNT_Service sfnt = (SFNT_Service)face->sfnt; 877 878 FT_Long instance = ( ( face->root.face_index & 0x7FFF0000L ) >> 16 ) - 1; 879 FT_UInt psid = mm_var->namedstyle[instance].psid; 880 881 char* ps_name = NULL; 882 883 884 /* try first to load the name string with index `postScriptNameID' */ 885 if ( psid == 6 || 886 ( psid > 255 && psid < 32768 ) ) 887 (void)sfnt->get_name( face, (FT_UShort)psid, &ps_name ); 888 889 if ( ps_name ) 890 { 891 result = ps_name; 892 p = result + ft_strlen( result ) + 1; 893 894 goto check_length; 895 } 896 else 897 { 898 /* otherwise construct a name using `subfamilyNameID' */ 899 FT_UInt strid = mm_var->namedstyle[instance].strid; 900 901 char* subfamily_name; 902 char* s; 903 904 905 (void)sfnt->get_name( face, (FT_UShort)strid, &subfamily_name ); 906 907 if ( !subfamily_name ) 908 { 909 FT_TRACE1(( "sfnt_get_var_ps_name:" 910 " can't construct named instance PS name;\n" 911 " " 912 " trying to construct normal instance PS name\n" )); 913 goto construct_instance_name; 914 } 915 916 /* after the prefix we have character `-' followed by the */ 917 /* subfamily name (using only characters a-z, A-Z, and 0-9) */ 918 if ( FT_ALLOC( result, face->var_postscript_prefix_len + 919 1 + ft_strlen( subfamily_name ) + 1 ) ) 920 return NULL; 921 922 ft_strcpy( result, face->var_postscript_prefix ); 923 924 p = result + face->var_postscript_prefix_len; 925 *p++ = '-'; 926 927 s = subfamily_name; 928 while ( *s ) 929 { 930 if ( ft_isalnum( *s ) ) 931 *p++ = *s; 932 s++; 933 } 934 *p++ = '\0'; 935 936 FT_FREE( subfamily_name ); 937 } 938 } 939 else 940 { 941 FT_Var_Axis* axis; 942 943 944 construct_instance_name: 945 axis = mm_var->axis; 946 947 if ( FT_ALLOC( result, 948 face->var_postscript_prefix_len + 949 num_coords * MAX_VALUE_DESCRIPTOR_LEN + 1 ) ) 950 return NULL; 951 952 p = result; 953 954 ft_strcpy( p, face->var_postscript_prefix ); 955 p += face->var_postscript_prefix_len; 956 957 for ( i = 0; i < num_coords; i++, coords++, axis++ ) 958 { 959 char t; 960 961 962 /* omit axis value descriptor if it is identical */ 963 /* to the default axis value */ 964 if ( *coords == axis->def ) 965 continue; 966 967 *p++ = '_'; 968 p = fixed2float( *coords, p ); 969 970 t = (char)( axis->tag >> 24 ); 971 if ( t != ' ' && ft_isalnum( t ) ) 972 *p++ = t; 973 t = (char)( axis->tag >> 16 ); 974 if ( t != ' ' && ft_isalnum( t ) ) 975 *p++ = t; 976 t = (char)( axis->tag >> 8 ); 977 if ( t != ' ' && ft_isalnum( t ) ) 978 *p++ = t; 979 t = (char)axis->tag; 980 if ( t != ' ' && ft_isalnum( t ) ) 981 *p++ = t; 982 } 983 } 984 985 check_length: 986 if ( p - result > MAX_PS_NAME_LEN ) 987 { 988 /* the PS name is too long; replace the part after the prefix with */ 989 /* a checksum; we use MurmurHash 3 with a hash length of 128 bit */ 990 991 FT_UInt32 seed = 123456789; 992 993 FT_UInt32 hash[4]; 994 FT_UInt32* h; 995 996 997 murmur_hash_3_128( result, p - result, seed, hash ); 998 999 p = result + face->var_postscript_prefix_len; 1000 *p++ = '-'; 1001 1002 /* we convert the hash value to hex digits from back to front */ 1003 p += 32 + 3; 1004 h = hash + 3; 1005 1006 *p-- = '\0'; 1007 *p-- = '.'; 1008 *p-- = '.'; 1009 *p-- = '.'; 1010 1011 for ( i = 0; i < 4; i++, h-- ) 1012 { 1013 FT_UInt32 v = *h; 1014 1015 1016 for ( j = 0; j < 8; j++ ) 1017 { 1018 *p-- = hexdigits[v & 0xF]; 1019 v >>= 4; 1020 } 1021 } 1022 } 1023 1024 return result; 1025 } 1026 1027 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ 1028 1029 1030 static const char* 1031 sfnt_get_ps_name( TT_Face face ) 1032 { 1033 FT_Int found, win, apple; 1034 const char* result = NULL; 1035 1036 1037 if ( face->postscript_name ) 1038 return face->postscript_name; 1039 1040 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 1041 if ( face->blend && 1042 ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) || 1043 FT_IS_VARIATION( FT_FACE( face ) ) ) ) 1044 { 1045 face->postscript_name = sfnt_get_var_ps_name( face ); 1046 return face->postscript_name; 1047 } 1048 #endif 1049 1050 /* scan the name table to see whether we have a Postscript name here, */ 1051 /* either in Macintosh or Windows platform encodings */ 1052 found = sfnt_get_name_id( face, TT_NAME_ID_PS_NAME, &win, &apple ); 1053 if ( !found ) 1054 return NULL; 1055 1056 /* prefer Windows entries over Apple */ 1057 if ( win != -1 ) 1058 result = get_win_string( face->root.memory, 1059 face->name_table.stream, 1060 face->name_table.names + win, 1061 sfnt_is_postscript, 1062 1 ); 1063 if ( !result && apple != -1 ) 1064 result = get_apple_string( face->root.memory, 1065 face->name_table.stream, 1066 face->name_table.names + apple, 1067 sfnt_is_postscript, 1068 1 ); 1069 1070 face->postscript_name = result; 1071 1072 return result; 1073 } 1074 1075 1076 FT_DEFINE_SERVICE_PSFONTNAMEREC( 1077 sfnt_service_ps_name, 1078 1079 (FT_PsName_GetFunc)sfnt_get_ps_name /* get_ps_font_name */ 1080 ) 1081 1082 1083 /* 1084 * TT CMAP INFO 1085 */ 1086 FT_DEFINE_SERVICE_TTCMAPSREC( 1087 tt_service_get_cmap_info, 1088 1089 (TT_CMap_Info_GetFunc)tt_get_cmap_info /* get_cmap_info */ 1090 ) 1091 1092 1093 #ifdef TT_CONFIG_OPTION_BDF 1094 1095 static FT_Error 1096 sfnt_get_charset_id( TT_Face face, 1097 const char* *acharset_encoding, 1098 const char* *acharset_registry ) 1099 { 1100 BDF_PropertyRec encoding, registry; 1101 FT_Error error; 1102 1103 1104 /* XXX: I don't know whether this is correct, since 1105 * tt_face_find_bdf_prop only returns something correct if we have 1106 * previously selected a size that is listed in the BDF table. 1107 * Should we change the BDF table format to include single offsets 1108 * for `CHARSET_REGISTRY' and `CHARSET_ENCODING'? 1109 */ 1110 error = tt_face_find_bdf_prop( face, "CHARSET_REGISTRY", ®istry ); 1111 if ( !error ) 1112 { 1113 error = tt_face_find_bdf_prop( face, "CHARSET_ENCODING", &encoding ); 1114 if ( !error ) 1115 { 1116 if ( registry.type == BDF_PROPERTY_TYPE_ATOM && 1117 encoding.type == BDF_PROPERTY_TYPE_ATOM ) 1118 { 1119 *acharset_encoding = encoding.u.atom; 1120 *acharset_registry = registry.u.atom; 1121 } 1122 else 1123 error = FT_THROW( Invalid_Argument ); 1124 } 1125 } 1126 1127 return error; 1128 } 1129 1130 1131 FT_DEFINE_SERVICE_BDFRec( 1132 sfnt_service_bdf, 1133 1134 (FT_BDF_GetCharsetIdFunc)sfnt_get_charset_id, /* get_charset_id */ 1135 (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop /* get_property */ 1136 ) 1137 1138 1139 #endif /* TT_CONFIG_OPTION_BDF */ 1140 1141 1142 /* 1143 * SERVICE LIST 1144 */ 1145 1146 #if defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES && defined TT_CONFIG_OPTION_BDF 1147 FT_DEFINE_SERVICEDESCREC5( 1148 sfnt_services, 1149 1150 FT_SERVICE_ID_SFNT_TABLE, &sfnt_service_sfnt_table, 1151 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name, 1152 FT_SERVICE_ID_GLYPH_DICT, &sfnt_service_glyph_dict, 1153 FT_SERVICE_ID_BDF, &sfnt_service_bdf, 1154 FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info ) 1155 #elif defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES 1156 FT_DEFINE_SERVICEDESCREC4( 1157 sfnt_services, 1158 1159 FT_SERVICE_ID_SFNT_TABLE, &sfnt_service_sfnt_table, 1160 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name, 1161 FT_SERVICE_ID_GLYPH_DICT, &sfnt_service_glyph_dict, 1162 FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info ) 1163 #elif defined TT_CONFIG_OPTION_BDF 1164 FT_DEFINE_SERVICEDESCREC4( 1165 sfnt_services, 1166 1167 FT_SERVICE_ID_SFNT_TABLE, &sfnt_service_sfnt_table, 1168 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name, 1169 FT_SERVICE_ID_BDF, &sfnt_service_bdf, 1170 FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info ) 1171 #else 1172 FT_DEFINE_SERVICEDESCREC3( 1173 sfnt_services, 1174 1175 FT_SERVICE_ID_SFNT_TABLE, &sfnt_service_sfnt_table, 1176 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name, 1177 FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info ) 1178 #endif 1179 1180 1181 FT_CALLBACK_DEF( FT_Module_Interface ) 1182 sfnt_get_interface( FT_Module module, 1183 const char* module_interface ) 1184 { 1185 FT_UNUSED( module ); 1186 1187 return ft_service_list_lookup( sfnt_services, module_interface ); 1188 } 1189 1190 1191 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 1192 #define PUT_EMBEDDED_BITMAPS( a ) a 1193 #else 1194 #define PUT_EMBEDDED_BITMAPS( a ) NULL 1195 #endif 1196 1197 #ifdef TT_CONFIG_OPTION_COLOR_LAYERS 1198 #define PUT_COLOR_LAYERS( a ) a 1199 #else 1200 #define PUT_COLOR_LAYERS( a ) NULL 1201 #endif 1202 1203 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES 1204 #define PUT_PS_NAMES( a ) a 1205 #else 1206 #define PUT_PS_NAMES( a ) NULL 1207 #endif 1208 1209 FT_DEFINE_SFNT_INTERFACE( 1210 sfnt_interface, 1211 1212 tt_face_goto_table, /* TT_Loader_GotoTableFunc goto_table */ 1213 1214 sfnt_init_face, /* TT_Init_Face_Func init_face */ 1215 sfnt_load_face, /* TT_Load_Face_Func load_face */ 1216 sfnt_done_face, /* TT_Done_Face_Func done_face */ 1217 sfnt_get_interface, /* FT_Module_Requester get_interface */ 1218 1219 tt_face_load_any, /* TT_Load_Any_Func load_any */ 1220 1221 tt_face_load_head, /* TT_Load_Table_Func load_head */ 1222 tt_face_load_hhea, /* TT_Load_Metrics_Func load_hhea */ 1223 tt_face_load_cmap, /* TT_Load_Table_Func load_cmap */ 1224 tt_face_load_maxp, /* TT_Load_Table_Func load_maxp */ 1225 tt_face_load_os2, /* TT_Load_Table_Func load_os2 */ 1226 tt_face_load_post, /* TT_Load_Table_Func load_post */ 1227 1228 tt_face_load_name, /* TT_Load_Table_Func load_name */ 1229 tt_face_free_name, /* TT_Free_Table_Func free_name */ 1230 1231 tt_face_load_kern, /* TT_Load_Table_Func load_kern */ 1232 tt_face_load_gasp, /* TT_Load_Table_Func load_gasp */ 1233 tt_face_load_pclt, /* TT_Load_Table_Func load_init */ 1234 1235 /* see `ttload.h' */ 1236 PUT_EMBEDDED_BITMAPS( tt_face_load_bhed ), 1237 /* TT_Load_Table_Func load_bhed */ 1238 PUT_EMBEDDED_BITMAPS( tt_face_load_sbit_image ), 1239 /* TT_Load_SBit_Image_Func load_sbit_image */ 1240 1241 /* see `ttpost.h' */ 1242 PUT_PS_NAMES( tt_face_get_ps_name ), 1243 /* TT_Get_PS_Name_Func get_psname */ 1244 PUT_PS_NAMES( tt_face_free_ps_names ), 1245 /* TT_Free_Table_Func free_psnames */ 1246 1247 /* since version 2.1.8 */ 1248 tt_face_get_kerning, /* TT_Face_GetKerningFunc get_kerning */ 1249 1250 /* since version 2.2 */ 1251 tt_face_load_font_dir, /* TT_Load_Table_Func load_font_dir */ 1252 tt_face_load_hmtx, /* TT_Load_Metrics_Func load_hmtx */ 1253 1254 /* see `ttsbit.h' and `sfnt.h' */ 1255 PUT_EMBEDDED_BITMAPS( tt_face_load_sbit ), 1256 /* TT_Load_Table_Func load_eblc */ 1257 PUT_EMBEDDED_BITMAPS( tt_face_free_sbit ), 1258 /* TT_Free_Table_Func free_eblc */ 1259 1260 PUT_EMBEDDED_BITMAPS( tt_face_set_sbit_strike ), 1261 /* TT_Set_SBit_Strike_Func set_sbit_strike */ 1262 PUT_EMBEDDED_BITMAPS( tt_face_load_strike_metrics ), 1263 /* TT_Load_Strike_Metrics_Func load_strike_metrics */ 1264 1265 PUT_COLOR_LAYERS( tt_face_load_cpal ), 1266 /* TT_Load_Table_Func load_cpal */ 1267 PUT_COLOR_LAYERS( tt_face_load_colr ), 1268 /* TT_Load_Table_Func load_colr */ 1269 PUT_COLOR_LAYERS( tt_face_free_cpal ), 1270 /* TT_Free_Table_Func free_cpal */ 1271 PUT_COLOR_LAYERS( tt_face_free_colr ), 1272 /* TT_Free_Table_Func free_colr */ 1273 PUT_COLOR_LAYERS( tt_face_palette_set ), 1274 /* TT_Set_Palette_Func set_palette */ 1275 PUT_COLOR_LAYERS( tt_face_get_colr_layer ), 1276 /* TT_Get_Colr_Layer_Func get_colr_layer */ 1277 PUT_COLOR_LAYERS( tt_face_colr_blend_layer ), 1278 /* TT_Blend_Colr_Func colr_blend */ 1279 1280 tt_face_get_metrics, /* TT_Get_Metrics_Func get_metrics */ 1281 1282 tt_face_get_name, /* TT_Get_Name_Func get_name */ 1283 sfnt_get_name_id /* TT_Get_Name_ID_Func get_name_id */ 1284 ) 1285 1286 1287 FT_DEFINE_MODULE( 1288 sfnt_module_class, 1289 1290 0, /* not a font driver or renderer */ 1291 sizeof ( FT_ModuleRec ), 1292 1293 "sfnt", /* driver name */ 1294 0x10000L, /* driver version 1.0 */ 1295 0x20000L, /* driver requires FreeType 2.0 or higher */ 1296 1297 (const void*)&sfnt_interface, /* module specific interface */ 1298 1299 (FT_Module_Constructor)NULL, /* module_init */ 1300 (FT_Module_Destructor) NULL, /* module_done */ 1301 (FT_Module_Requester) sfnt_get_interface /* get_interface */ 1302 ) 1303 1304 1305 /* END */