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