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