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