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 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 trace_sfdriver 72 73 74 /* 75 * SFNT TABLE SERVICE 76 * 77 */ 78 79 static void* get_sfnt_table(TT_Face face,FT_Sfnt_Tag tag)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 sfnt_table_info(TT_Face face,FT_UInt idx,FT_ULong * tag,FT_ULong * offset,FT_ULong * length)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 sfnt_get_glyph_name(FT_Face face,FT_UInt glyph_index,FT_Pointer buffer,FT_UInt buffer_max)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 sfnt_get_name_index(FT_Face face,FT_String * glyph_name)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 sfnt_is_postscript(int c)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 sfnt_is_alphanumeric(int c)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 fmix32(FT_UInt32 h)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 murmur_hash_3_128(const void * key,const unsigned int len,FT_UInt32 seed,void * out)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 (n)->languageID == 0x409 ) 471 472 #define IS_APPLE( n ) ( (n)->platformID == 1 && \ 473 (n)->encodingID == 0 && \ 474 (n)->languageID == 0 ) 475 476 static char* get_win_string(FT_Memory memory,FT_Stream stream,TT_Name entry,char_type_func char_type,FT_Bool report_invalid_characters)477 get_win_string( FT_Memory memory, 478 FT_Stream stream, 479 TT_Name entry, 480 char_type_func char_type, 481 FT_Bool report_invalid_characters ) 482 { 483 FT_Error error = FT_Err_Ok; 484 485 char* result = NULL; 486 FT_String* r; 487 FT_Char* p; 488 FT_UInt len; 489 490 FT_UNUSED( error ); 491 492 493 if ( FT_ALLOC( result, entry->stringLength / 2 + 1 ) ) 494 return NULL; 495 496 if ( FT_STREAM_SEEK( entry->stringOffset ) || 497 FT_FRAME_ENTER( entry->stringLength ) ) 498 { 499 FT_FREE( result ); 500 entry->stringLength = 0; 501 entry->stringOffset = 0; 502 FT_FREE( entry->string ); 503 504 return NULL; 505 } 506 507 r = (FT_String*)result; 508 p = (FT_Char*)stream->cursor; 509 510 for ( len = entry->stringLength / 2; len > 0; len--, p += 2 ) 511 { 512 if ( p[0] == 0 ) 513 { 514 if ( char_type( p[1] ) ) 515 *r++ = p[1]; 516 else 517 { 518 if ( report_invalid_characters ) 519 { 520 FT_TRACE0(( "get_win_string:" 521 " Character `%c' (0x%X) invalid in PS name string\n", 522 p[1], p[1] )); 523 /* it's not the job of FreeType to correct PS names... */ 524 *r++ = p[1]; 525 } 526 } 527 } 528 } 529 *r = '\0'; 530 531 FT_FRAME_EXIT(); 532 533 return result; 534 } 535 536 537 static char* get_apple_string(FT_Memory memory,FT_Stream stream,TT_Name entry,char_type_func char_type,FT_Bool report_invalid_characters)538 get_apple_string( FT_Memory memory, 539 FT_Stream stream, 540 TT_Name entry, 541 char_type_func char_type, 542 FT_Bool report_invalid_characters ) 543 { 544 FT_Error error = FT_Err_Ok; 545 546 char* result = NULL; 547 FT_String* r; 548 FT_Char* p; 549 FT_UInt len; 550 551 FT_UNUSED( error ); 552 553 554 if ( FT_ALLOC( result, entry->stringLength + 1 ) ) 555 return NULL; 556 557 if ( FT_STREAM_SEEK( entry->stringOffset ) || 558 FT_FRAME_ENTER( entry->stringLength ) ) 559 { 560 FT_FREE( result ); 561 entry->stringOffset = 0; 562 entry->stringLength = 0; 563 FT_FREE( entry->string ); 564 565 return NULL; 566 } 567 568 r = (FT_String*)result; 569 p = (FT_Char*)stream->cursor; 570 571 for ( len = entry->stringLength; len > 0; len--, p++ ) 572 { 573 if ( char_type( *p ) ) 574 *r++ = *p; 575 else 576 { 577 if ( report_invalid_characters ) 578 { 579 FT_TRACE0(( "get_apple_string:" 580 " Character `%c' (0x%X) invalid in PS name string\n", 581 *p, *p )); 582 /* it's not the job of FreeType to correct PS names... */ 583 *r++ = *p; 584 } 585 } 586 } 587 *r = '\0'; 588 589 FT_FRAME_EXIT(); 590 591 return result; 592 } 593 594 595 static FT_Bool sfnt_get_name_id(TT_Face face,FT_UShort id,FT_Int * win,FT_Int * apple)596 sfnt_get_name_id( TT_Face face, 597 FT_UShort id, 598 FT_Int *win, 599 FT_Int *apple ) 600 { 601 FT_Int n; 602 603 604 *win = -1; 605 *apple = -1; 606 607 for ( n = 0; n < face->num_names; n++ ) 608 { 609 TT_Name name = face->name_table.names + n; 610 611 612 if ( name->nameID == id && name->stringLength > 0 ) 613 { 614 if ( IS_WIN( name ) ) 615 *win = n; 616 617 if ( IS_APPLE( name ) ) 618 *apple = n; 619 } 620 } 621 622 return ( *win >= 0 ) || ( *apple >= 0 ); 623 } 624 625 626 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 627 628 /* 629 The maximum length of an axis value descriptor. 630 631 We need 65536 different values for the decimal fraction; this fits 632 nicely into five decimal places. Consequently, it consists of 633 634 . the minus sign if the number is negative, 635 . up to five characters for the digits before the decimal point, 636 . the decimal point if there is a fractional part, and 637 . up to five characters for the digits after the decimal point. 638 639 We also need one byte for the leading `_' character and up to four 640 bytes for the axis tag. 641 */ 642 #define MAX_VALUE_DESCRIPTOR_LEN ( 1 + 5 + 1 + 5 + 1 + 4 ) 643 644 645 /* the maximum length of PostScript font names */ 646 #define MAX_PS_NAME_LEN 127 647 648 649 /* 650 * Find the shortest decimal representation of a 16.16 fixed point 651 * number. The function fills `buf' with the result, returning a pointer 652 * to the position after the representation's last byte. 653 */ 654 655 static char* fixed2float(FT_Int fixed,char * buf)656 fixed2float( FT_Int fixed, 657 char* buf ) 658 { 659 char* p; 660 char* q; 661 char tmp[5]; 662 663 FT_Int int_part; 664 FT_Int frac_part; 665 666 FT_Int i; 667 668 669 p = buf; 670 671 if ( fixed == 0 ) 672 { 673 *p++ = '0'; 674 return p; 675 } 676 677 if ( fixed < 0 ) 678 { 679 *p++ = '-'; 680 fixed = NEG_INT( fixed ); 681 } 682 683 int_part = ( fixed >> 16 ) & 0xFFFF; 684 frac_part = fixed & 0xFFFF; 685 686 /* get digits of integer part (in reverse order) */ 687 q = tmp; 688 while ( int_part > 0 ) 689 { 690 *q++ = '0' + int_part % 10; 691 int_part /= 10; 692 } 693 694 /* copy digits in correct order to buffer */ 695 while ( q > tmp ) 696 *p++ = *--q; 697 698 if ( !frac_part ) 699 return p; 700 701 /* save position of point */ 702 q = p; 703 *p++ = '.'; 704 705 /* apply rounding */ 706 frac_part = frac_part * 10 + 5; 707 708 /* get digits of fractional part */ 709 for ( i = 0; i < 5; i++ ) 710 { 711 *p++ = '0' + (char)( frac_part / 0x10000L ); 712 713 frac_part %= 0x10000L; 714 if ( !frac_part ) 715 break; 716 717 frac_part *= 10; 718 } 719 720 /* 721 If the remainder stored in `frac_part' (after the last FOR loop) is 722 smaller than 34480*10, the resulting decimal value minus 0.00001 is 723 an equivalent representation of `fixed'. 724 725 The above FOR loop always finds the larger of the two values; I 726 verified this by iterating over all possible fixed point numbers. 727 728 If the remainder is 17232*10, both values are equally good, and we 729 take the next even number (following IEEE 754's `round to nearest, 730 ties to even' rounding rule). 731 732 If the remainder is smaller than 17232*10, the lower of the two 733 numbers is nearer to the exact result (values 17232 and 34480 were 734 also found by testing all possible fixed point values). 735 736 We use this to find a shorter decimal representation. If not ending 737 with digit zero, we take the representation with less error. 738 */ 739 p--; 740 if ( p - q == 5 ) /* five digits? */ 741 { 742 /* take the representation that has zero as the last digit */ 743 if ( frac_part < 34480 * 10 && 744 *p == '1' ) 745 *p = '0'; 746 747 /* otherwise use the one with less error */ 748 else if ( frac_part == 17232 * 10 && 749 *p & 1 ) 750 *p -= 1; 751 752 else if ( frac_part < 17232 * 10 && 753 *p != '0' ) 754 *p -= 1; 755 } 756 757 /* remove trailing zeros */ 758 while ( *p == '0' ) 759 *p-- = '\0'; 760 761 return p + 1; 762 } 763 764 765 static const char hexdigits[16] = 766 { 767 '0', '1', '2', '3', '4', '5', '6', '7', 768 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' 769 }; 770 771 772 static const char* sfnt_get_var_ps_name(TT_Face face)773 sfnt_get_var_ps_name( TT_Face face ) 774 { 775 FT_Error error; 776 FT_Memory memory = face->root.memory; 777 778 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; 779 780 FT_UInt num_coords; 781 FT_Fixed* coords; 782 FT_MM_Var* mm_var; 783 784 FT_Int found, win, apple; 785 FT_UInt i, j; 786 787 char* result = NULL; 788 char* p; 789 790 791 if ( !face->var_postscript_prefix ) 792 { 793 FT_UInt len; 794 795 796 /* check whether we have a Variations PostScript Name Prefix */ 797 found = sfnt_get_name_id( face, 798 TT_NAME_ID_VARIATIONS_PREFIX, 799 &win, 800 &apple ); 801 if ( !found ) 802 { 803 /* otherwise use the typographic family name */ 804 found = sfnt_get_name_id( face, 805 TT_NAME_ID_TYPOGRAPHIC_FAMILY, 806 &win, 807 &apple ); 808 } 809 810 if ( !found ) 811 { 812 /* as a last resort we try the family name; note that this is */ 813 /* not in the Adobe TechNote, but GX fonts (which predate the */ 814 /* TechNote) benefit from this behaviour */ 815 found = sfnt_get_name_id( face, 816 TT_NAME_ID_FONT_FAMILY, 817 &win, 818 &apple ); 819 } 820 821 if ( !found ) 822 { 823 FT_TRACE0(( "sfnt_get_var_ps_name:" 824 " Can't construct PS name prefix for font instances\n" )); 825 return NULL; 826 } 827 828 /* prefer Windows entries over Apple */ 829 if ( win != -1 ) 830 result = get_win_string( face->root.memory, 831 face->name_table.stream, 832 face->name_table.names + win, 833 sfnt_is_alphanumeric, 834 0 ); 835 else 836 result = get_apple_string( face->root.memory, 837 face->name_table.stream, 838 face->name_table.names + apple, 839 sfnt_is_alphanumeric, 840 0 ); 841 842 len = ft_strlen( result ); 843 844 /* sanitize if necessary; we reserve space for 36 bytes (a 128bit */ 845 /* checksum as a hex number, preceded by `-' and followed by three */ 846 /* ASCII dots, to be used if the constructed PS name would be too */ 847 /* long); this is also sufficient for a single instance */ 848 if ( len > MAX_PS_NAME_LEN - ( 1 + 32 + 3 ) ) 849 { 850 len = MAX_PS_NAME_LEN - ( 1 + 32 + 3 ); 851 result[len] = '\0'; 852 853 FT_TRACE0(( "sfnt_get_var_ps_name:" 854 " Shortening variation PS name prefix\n" 855 " " 856 " to %d characters\n", len )); 857 } 858 859 face->var_postscript_prefix = result; 860 face->var_postscript_prefix_len = len; 861 } 862 863 mm->get_var_blend( FT_FACE( face ), 864 &num_coords, 865 &coords, 866 NULL, 867 &mm_var ); 868 869 if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) && 870 !FT_IS_VARIATION( FT_FACE( face ) ) ) 871 { 872 SFNT_Service sfnt = (SFNT_Service)face->sfnt; 873 874 FT_Long instance = ( ( face->root.face_index & 0x7FFF0000L ) >> 16 ) - 1; 875 FT_UInt psid = mm_var->namedstyle[instance].psid; 876 877 char* ps_name = NULL; 878 879 880 /* try first to load the name string with index `postScriptNameID' */ 881 if ( psid == 6 || 882 ( psid > 255 && psid < 32768 ) ) 883 (void)sfnt->get_name( face, (FT_UShort)psid, &ps_name ); 884 885 if ( ps_name ) 886 { 887 result = ps_name; 888 p = result + ft_strlen( result ) + 1; 889 890 goto check_length; 891 } 892 else 893 { 894 /* otherwise construct a name using `subfamilyNameID' */ 895 FT_UInt strid = mm_var->namedstyle[instance].strid; 896 897 char* subfamily_name; 898 char* s; 899 900 901 (void)sfnt->get_name( face, (FT_UShort)strid, &subfamily_name ); 902 903 if ( !subfamily_name ) 904 { 905 FT_TRACE1(( "sfnt_get_var_ps_name:" 906 " can't construct named instance PS name;\n" 907 " " 908 " trying to construct normal instance PS name\n" )); 909 goto construct_instance_name; 910 } 911 912 /* after the prefix we have character `-' followed by the */ 913 /* subfamily name (using only characters a-z, A-Z, and 0-9) */ 914 if ( FT_ALLOC( result, face->var_postscript_prefix_len + 915 1 + ft_strlen( subfamily_name ) + 1 ) ) 916 return NULL; 917 918 ft_strcpy( result, face->var_postscript_prefix ); 919 920 p = result + face->var_postscript_prefix_len; 921 *p++ = '-'; 922 923 s = subfamily_name; 924 while ( *s ) 925 { 926 if ( ft_isalnum( *s ) ) 927 *p++ = *s; 928 s++; 929 } 930 *p++ = '\0'; 931 932 FT_FREE( subfamily_name ); 933 } 934 } 935 else 936 { 937 FT_Var_Axis* axis; 938 939 940 construct_instance_name: 941 axis = mm_var->axis; 942 943 if ( FT_ALLOC( result, 944 face->var_postscript_prefix_len + 945 num_coords * MAX_VALUE_DESCRIPTOR_LEN + 1 ) ) 946 return NULL; 947 948 p = result; 949 950 ft_strcpy( p, face->var_postscript_prefix ); 951 p += face->var_postscript_prefix_len; 952 953 for ( i = 0; i < num_coords; i++, coords++, axis++ ) 954 { 955 char t; 956 957 958 /* omit axis value descriptor if it is identical */ 959 /* to the default axis value */ 960 if ( *coords == axis->def ) 961 continue; 962 963 *p++ = '_'; 964 p = fixed2float( *coords, p ); 965 966 t = (char)( axis->tag >> 24 ); 967 if ( t != ' ' && ft_isalnum( t ) ) 968 *p++ = t; 969 t = (char)( axis->tag >> 16 ); 970 if ( t != ' ' && ft_isalnum( t ) ) 971 *p++ = t; 972 t = (char)( axis->tag >> 8 ); 973 if ( t != ' ' && ft_isalnum( t ) ) 974 *p++ = t; 975 t = (char)axis->tag; 976 if ( t != ' ' && ft_isalnum( t ) ) 977 *p++ = t; 978 } 979 } 980 981 check_length: 982 if ( p - result > MAX_PS_NAME_LEN ) 983 { 984 /* the PS name is too long; replace the part after the prefix with */ 985 /* a checksum; we use MurmurHash 3 with a hash length of 128 bit */ 986 987 FT_UInt32 seed = 123456789; 988 989 FT_UInt32 hash[4]; 990 FT_UInt32* h; 991 992 993 murmur_hash_3_128( result, p - result, seed, hash ); 994 995 p = result + face->var_postscript_prefix_len; 996 *p++ = '-'; 997 998 /* we convert the hash value to hex digits from back to front */ 999 p += 32 + 3; 1000 h = hash + 3; 1001 1002 *p-- = '\0'; 1003 *p-- = '.'; 1004 *p-- = '.'; 1005 *p-- = '.'; 1006 1007 for ( i = 0; i < 4; i++, h-- ) 1008 { 1009 FT_UInt32 v = *h; 1010 1011 1012 for ( j = 0; j < 8; j++ ) 1013 { 1014 *p-- = hexdigits[v & 0xF]; 1015 v >>= 4; 1016 } 1017 } 1018 } 1019 1020 return result; 1021 } 1022 1023 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ 1024 1025 1026 static const char* sfnt_get_ps_name(TT_Face face)1027 sfnt_get_ps_name( TT_Face face ) 1028 { 1029 FT_Int found, win, apple; 1030 const char* result = NULL; 1031 1032 1033 if ( face->postscript_name ) 1034 return face->postscript_name; 1035 1036 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 1037 if ( face->blend && 1038 ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) || 1039 FT_IS_VARIATION( FT_FACE( face ) ) ) ) 1040 { 1041 face->postscript_name = sfnt_get_var_ps_name( face ); 1042 return face->postscript_name; 1043 } 1044 #endif 1045 1046 /* scan the name table to see whether we have a Postscript name here, */ 1047 /* either in Macintosh or Windows platform encodings */ 1048 found = sfnt_get_name_id( face, TT_NAME_ID_PS_NAME, &win, &apple ); 1049 if ( !found ) 1050 return NULL; 1051 1052 /* prefer Windows entries over Apple */ 1053 if ( win != -1 ) 1054 result = get_win_string( face->root.memory, 1055 face->name_table.stream, 1056 face->name_table.names + win, 1057 sfnt_is_postscript, 1058 1 ); 1059 else 1060 result = get_apple_string( face->root.memory, 1061 face->name_table.stream, 1062 face->name_table.names + apple, 1063 sfnt_is_postscript, 1064 1 ); 1065 1066 face->postscript_name = result; 1067 1068 return result; 1069 } 1070 1071 1072 FT_DEFINE_SERVICE_PSFONTNAMEREC( 1073 sfnt_service_ps_name, 1074 1075 (FT_PsName_GetFunc)sfnt_get_ps_name /* get_ps_font_name */ 1076 ) 1077 1078 1079 /* 1080 * TT CMAP INFO 1081 */ 1082 FT_DEFINE_SERVICE_TTCMAPSREC( 1083 tt_service_get_cmap_info, 1084 1085 (TT_CMap_Info_GetFunc)tt_get_cmap_info /* get_cmap_info */ 1086 ) 1087 1088 1089 #ifdef TT_CONFIG_OPTION_BDF 1090 1091 static FT_Error sfnt_get_charset_id(TT_Face face,const char ** acharset_encoding,const char ** acharset_registry)1092 sfnt_get_charset_id( TT_Face face, 1093 const char* *acharset_encoding, 1094 const char* *acharset_registry ) 1095 { 1096 BDF_PropertyRec encoding, registry; 1097 FT_Error error; 1098 1099 1100 /* XXX: I don't know whether this is correct, since 1101 * tt_face_find_bdf_prop only returns something correct if we have 1102 * previously selected a size that is listed in the BDF table. 1103 * Should we change the BDF table format to include single offsets 1104 * for `CHARSET_REGISTRY' and `CHARSET_ENCODING'? 1105 */ 1106 error = tt_face_find_bdf_prop( face, "CHARSET_REGISTRY", ®istry ); 1107 if ( !error ) 1108 { 1109 error = tt_face_find_bdf_prop( face, "CHARSET_ENCODING", &encoding ); 1110 if ( !error ) 1111 { 1112 if ( registry.type == BDF_PROPERTY_TYPE_ATOM && 1113 encoding.type == BDF_PROPERTY_TYPE_ATOM ) 1114 { 1115 *acharset_encoding = encoding.u.atom; 1116 *acharset_registry = registry.u.atom; 1117 } 1118 else 1119 error = FT_THROW( Invalid_Argument ); 1120 } 1121 } 1122 1123 return error; 1124 } 1125 1126 1127 FT_DEFINE_SERVICE_BDFRec( 1128 sfnt_service_bdf, 1129 1130 (FT_BDF_GetCharsetIdFunc)sfnt_get_charset_id, /* get_charset_id */ 1131 (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop /* get_property */ 1132 ) 1133 1134 1135 #endif /* TT_CONFIG_OPTION_BDF */ 1136 1137 1138 /* 1139 * SERVICE LIST 1140 */ 1141 1142 #if defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES && defined TT_CONFIG_OPTION_BDF 1143 FT_DEFINE_SERVICEDESCREC5( 1144 sfnt_services, 1145 1146 FT_SERVICE_ID_SFNT_TABLE, &sfnt_service_sfnt_table, 1147 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name, 1148 FT_SERVICE_ID_GLYPH_DICT, &sfnt_service_glyph_dict, 1149 FT_SERVICE_ID_BDF, &sfnt_service_bdf, 1150 FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info ) 1151 #elif defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES 1152 FT_DEFINE_SERVICEDESCREC4( 1153 sfnt_services, 1154 1155 FT_SERVICE_ID_SFNT_TABLE, &sfnt_service_sfnt_table, 1156 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name, 1157 FT_SERVICE_ID_GLYPH_DICT, &sfnt_service_glyph_dict, 1158 FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info ) 1159 #elif defined TT_CONFIG_OPTION_BDF 1160 FT_DEFINE_SERVICEDESCREC4( 1161 sfnt_services, 1162 1163 FT_SERVICE_ID_SFNT_TABLE, &sfnt_service_sfnt_table, 1164 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name, 1165 FT_SERVICE_ID_BDF, &sfnt_service_bdf, 1166 FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info ) 1167 #else 1168 FT_DEFINE_SERVICEDESCREC3( 1169 sfnt_services, 1170 1171 FT_SERVICE_ID_SFNT_TABLE, &sfnt_service_sfnt_table, 1172 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name, 1173 FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info ) 1174 #endif 1175 1176 FT_CALLBACK_DEF(FT_Module_Interface)1177 FT_CALLBACK_DEF( FT_Module_Interface ) 1178 sfnt_get_interface( FT_Module module, 1179 const char* module_interface ) 1180 { 1181 FT_UNUSED( module ); 1182 1183 return ft_service_list_lookup( sfnt_services, module_interface ); 1184 } 1185 1186 1187 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 1188 #define PUT_EMBEDDED_BITMAPS( a ) a 1189 #else 1190 #define PUT_EMBEDDED_BITMAPS( a ) NULL 1191 #endif 1192 1193 #ifdef TT_CONFIG_OPTION_COLOR_LAYERS 1194 #define PUT_COLOR_LAYERS( a ) a 1195 #else 1196 #define PUT_COLOR_LAYERS( a ) NULL 1197 #endif 1198 1199 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES 1200 #define PUT_PS_NAMES( a ) a 1201 #else 1202 #define PUT_PS_NAMES( a ) NULL 1203 #endif 1204 1205 FT_DEFINE_SFNT_INTERFACE( 1206 sfnt_interface, 1207 1208 tt_face_goto_table, /* TT_Loader_GotoTableFunc goto_table */ 1209 1210 sfnt_init_face, /* TT_Init_Face_Func init_face */ 1211 sfnt_load_face, /* TT_Load_Face_Func load_face */ 1212 sfnt_done_face, /* TT_Done_Face_Func done_face */ 1213 sfnt_get_interface, /* FT_Module_Requester get_interface */ 1214 1215 tt_face_load_any, /* TT_Load_Any_Func load_any */ 1216 1217 tt_face_load_head, /* TT_Load_Table_Func load_head */ 1218 tt_face_load_hhea, /* TT_Load_Metrics_Func load_hhea */ 1219 tt_face_load_cmap, /* TT_Load_Table_Func load_cmap */ 1220 tt_face_load_maxp, /* TT_Load_Table_Func load_maxp */ 1221 tt_face_load_os2, /* TT_Load_Table_Func load_os2 */ 1222 tt_face_load_post, /* TT_Load_Table_Func load_post */ 1223 1224 tt_face_load_name, /* TT_Load_Table_Func load_name */ 1225 tt_face_free_name, /* TT_Free_Table_Func free_name */ 1226 1227 tt_face_load_kern, /* TT_Load_Table_Func load_kern */ 1228 tt_face_load_gasp, /* TT_Load_Table_Func load_gasp */ 1229 tt_face_load_pclt, /* TT_Load_Table_Func load_init */ 1230 1231 /* see `ttload.h' */ 1232 PUT_EMBEDDED_BITMAPS( tt_face_load_bhed ), 1233 /* TT_Load_Table_Func load_bhed */ 1234 PUT_EMBEDDED_BITMAPS( tt_face_load_sbit_image ), 1235 /* TT_Load_SBit_Image_Func load_sbit_image */ 1236 1237 /* see `ttpost.h' */ 1238 PUT_PS_NAMES( tt_face_get_ps_name ), 1239 /* TT_Get_PS_Name_Func get_psname */ 1240 PUT_PS_NAMES( tt_face_free_ps_names ), 1241 /* TT_Free_Table_Func free_psnames */ 1242 1243 /* since version 2.1.8 */ 1244 tt_face_get_kerning, /* TT_Face_GetKerningFunc get_kerning */ 1245 1246 /* since version 2.2 */ 1247 tt_face_load_font_dir, /* TT_Load_Table_Func load_font_dir */ 1248 tt_face_load_hmtx, /* TT_Load_Metrics_Func load_hmtx */ 1249 1250 /* see `ttsbit.h' and `sfnt.h' */ 1251 PUT_EMBEDDED_BITMAPS( tt_face_load_sbit ), 1252 /* TT_Load_Table_Func load_eblc */ 1253 PUT_EMBEDDED_BITMAPS( tt_face_free_sbit ), 1254 /* TT_Free_Table_Func free_eblc */ 1255 1256 PUT_EMBEDDED_BITMAPS( tt_face_set_sbit_strike ), 1257 /* TT_Set_SBit_Strike_Func set_sbit_strike */ 1258 PUT_EMBEDDED_BITMAPS( tt_face_load_strike_metrics ), 1259 /* TT_Load_Strike_Metrics_Func load_strike_metrics */ 1260 1261 PUT_COLOR_LAYERS( tt_face_load_cpal ), 1262 /* TT_Load_Table_Func load_cpal */ 1263 PUT_COLOR_LAYERS( tt_face_load_colr ), 1264 /* TT_Load_Table_Func load_colr */ 1265 PUT_COLOR_LAYERS( tt_face_free_cpal ), 1266 /* TT_Free_Table_Func free_cpal */ 1267 PUT_COLOR_LAYERS( tt_face_free_colr ), 1268 /* TT_Free_Table_Func free_colr */ 1269 PUT_COLOR_LAYERS( tt_face_palette_set ), 1270 /* TT_Set_Palette_Func set_palette */ 1271 PUT_COLOR_LAYERS( tt_face_get_colr_layer ), 1272 /* TT_Get_Colr_Layer_Func get_colr_layer */ 1273 PUT_COLOR_LAYERS( tt_face_colr_blend_layer ), 1274 /* TT_Blend_Colr_Func colr_blend */ 1275 1276 tt_face_get_metrics, /* TT_Get_Metrics_Func get_metrics */ 1277 1278 tt_face_get_name, /* TT_Get_Name_Func get_name */ 1279 sfnt_get_name_id /* TT_Get_Name_ID_Func get_name_id */ 1280 ) 1281 1282 1283 FT_DEFINE_MODULE( 1284 sfnt_module_class, 1285 1286 0, /* not a font driver or renderer */ 1287 sizeof ( FT_ModuleRec ), 1288 1289 "sfnt", /* driver name */ 1290 0x10000L, /* driver version 1.0 */ 1291 0x20000L, /* driver requires FreeType 2.0 or higher */ 1292 1293 (const void*)&sfnt_interface, /* module specific interface */ 1294 1295 (FT_Module_Constructor)NULL, /* module_init */ 1296 (FT_Module_Destructor) NULL, /* module_done */ 1297 (FT_Module_Requester) sfnt_get_interface /* get_interface */ 1298 ) 1299 1300 1301 /* END */ 1302