1 /***************************************************************************/ 2 /* */ 3 /* cffload.c */ 4 /* */ 5 /* OpenType and CFF data/program tables loader (body). */ 6 /* */ 7 /* Copyright 1996-2016 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_OBJECTS_H 22 #include FT_INTERNAL_STREAM_H 23 #include FT_TRUETYPE_TAGS_H 24 #include FT_TYPE1_TABLES_H 25 26 #include "cffload.h" 27 #include "cffparse.h" 28 29 #include "cfferrs.h" 30 31 32 #if 1 33 34 static const FT_UShort cff_isoadobe_charset[229] = 35 { 36 0, 1, 2, 3, 4, 5, 6, 7, 37 8, 9, 10, 11, 12, 13, 14, 15, 38 16, 17, 18, 19, 20, 21, 22, 23, 39 24, 25, 26, 27, 28, 29, 30, 31, 40 32, 33, 34, 35, 36, 37, 38, 39, 41 40, 41, 42, 43, 44, 45, 46, 47, 42 48, 49, 50, 51, 52, 53, 54, 55, 43 56, 57, 58, 59, 60, 61, 62, 63, 44 64, 65, 66, 67, 68, 69, 70, 71, 45 72, 73, 74, 75, 76, 77, 78, 79, 46 80, 81, 82, 83, 84, 85, 86, 87, 47 88, 89, 90, 91, 92, 93, 94, 95, 48 96, 97, 98, 99, 100, 101, 102, 103, 49 104, 105, 106, 107, 108, 109, 110, 111, 50 112, 113, 114, 115, 116, 117, 118, 119, 51 120, 121, 122, 123, 124, 125, 126, 127, 52 128, 129, 130, 131, 132, 133, 134, 135, 53 136, 137, 138, 139, 140, 141, 142, 143, 54 144, 145, 146, 147, 148, 149, 150, 151, 55 152, 153, 154, 155, 156, 157, 158, 159, 56 160, 161, 162, 163, 164, 165, 166, 167, 57 168, 169, 170, 171, 172, 173, 174, 175, 58 176, 177, 178, 179, 180, 181, 182, 183, 59 184, 185, 186, 187, 188, 189, 190, 191, 60 192, 193, 194, 195, 196, 197, 198, 199, 61 200, 201, 202, 203, 204, 205, 206, 207, 62 208, 209, 210, 211, 212, 213, 214, 215, 63 216, 217, 218, 219, 220, 221, 222, 223, 64 224, 225, 226, 227, 228 65 }; 66 67 static const FT_UShort cff_expert_charset[166] = 68 { 69 0, 1, 229, 230, 231, 232, 233, 234, 70 235, 236, 237, 238, 13, 14, 15, 99, 71 239, 240, 241, 242, 243, 244, 245, 246, 72 247, 248, 27, 28, 249, 250, 251, 252, 73 253, 254, 255, 256, 257, 258, 259, 260, 74 261, 262, 263, 264, 265, 266, 109, 110, 75 267, 268, 269, 270, 271, 272, 273, 274, 76 275, 276, 277, 278, 279, 280, 281, 282, 77 283, 284, 285, 286, 287, 288, 289, 290, 78 291, 292, 293, 294, 295, 296, 297, 298, 79 299, 300, 301, 302, 303, 304, 305, 306, 80 307, 308, 309, 310, 311, 312, 313, 314, 81 315, 316, 317, 318, 158, 155, 163, 319, 82 320, 321, 322, 323, 324, 325, 326, 150, 83 164, 169, 327, 328, 329, 330, 331, 332, 84 333, 334, 335, 336, 337, 338, 339, 340, 85 341, 342, 343, 344, 345, 346, 347, 348, 86 349, 350, 351, 352, 353, 354, 355, 356, 87 357, 358, 359, 360, 361, 362, 363, 364, 88 365, 366, 367, 368, 369, 370, 371, 372, 89 373, 374, 375, 376, 377, 378 90 }; 91 92 static const FT_UShort cff_expertsubset_charset[87] = 93 { 94 0, 1, 231, 232, 235, 236, 237, 238, 95 13, 14, 15, 99, 239, 240, 241, 242, 96 243, 244, 245, 246, 247, 248, 27, 28, 97 249, 250, 251, 253, 254, 255, 256, 257, 98 258, 259, 260, 261, 262, 263, 264, 265, 99 266, 109, 110, 267, 268, 269, 270, 272, 100 300, 301, 302, 305, 314, 315, 158, 155, 101 163, 320, 321, 322, 323, 324, 325, 326, 102 150, 164, 169, 327, 328, 329, 330, 331, 103 332, 333, 334, 335, 336, 337, 338, 339, 104 340, 341, 342, 343, 344, 345, 346 105 }; 106 107 static const FT_UShort cff_standard_encoding[256] = 108 { 109 0, 0, 0, 0, 0, 0, 0, 0, 110 0, 0, 0, 0, 0, 0, 0, 0, 111 0, 0, 0, 0, 0, 0, 0, 0, 112 0, 0, 0, 0, 0, 0, 0, 0, 113 1, 2, 3, 4, 5, 6, 7, 8, 114 9, 10, 11, 12, 13, 14, 15, 16, 115 17, 18, 19, 20, 21, 22, 23, 24, 116 25, 26, 27, 28, 29, 30, 31, 32, 117 33, 34, 35, 36, 37, 38, 39, 40, 118 41, 42, 43, 44, 45, 46, 47, 48, 119 49, 50, 51, 52, 53, 54, 55, 56, 120 57, 58, 59, 60, 61, 62, 63, 64, 121 65, 66, 67, 68, 69, 70, 71, 72, 122 73, 74, 75, 76, 77, 78, 79, 80, 123 81, 82, 83, 84, 85, 86, 87, 88, 124 89, 90, 91, 92, 93, 94, 95, 0, 125 0, 0, 0, 0, 0, 0, 0, 0, 126 0, 0, 0, 0, 0, 0, 0, 0, 127 0, 0, 0, 0, 0, 0, 0, 0, 128 0, 0, 0, 0, 0, 0, 0, 0, 129 0, 96, 97, 98, 99, 100, 101, 102, 130 103, 104, 105, 106, 107, 108, 109, 110, 131 0, 111, 112, 113, 114, 0, 115, 116, 132 117, 118, 119, 120, 121, 122, 0, 123, 133 0, 124, 125, 126, 127, 128, 129, 130, 134 131, 0, 132, 133, 0, 134, 135, 136, 135 137, 0, 0, 0, 0, 0, 0, 0, 136 0, 0, 0, 0, 0, 0, 0, 0, 137 0, 138, 0, 139, 0, 0, 0, 0, 138 140, 141, 142, 143, 0, 0, 0, 0, 139 0, 144, 0, 0, 0, 145, 0, 0, 140 146, 147, 148, 149, 0, 0, 0, 0 141 }; 142 143 static const FT_UShort cff_expert_encoding[256] = 144 { 145 0, 0, 0, 0, 0, 0, 0, 0, 146 0, 0, 0, 0, 0, 0, 0, 0, 147 0, 0, 0, 0, 0, 0, 0, 0, 148 0, 0, 0, 0, 0, 0, 0, 0, 149 1, 229, 230, 0, 231, 232, 233, 234, 150 235, 236, 237, 238, 13, 14, 15, 99, 151 239, 240, 241, 242, 243, 244, 245, 246, 152 247, 248, 27, 28, 249, 250, 251, 252, 153 0, 253, 254, 255, 256, 257, 0, 0, 154 0, 258, 0, 0, 259, 260, 261, 262, 155 0, 0, 263, 264, 265, 0, 266, 109, 156 110, 267, 268, 269, 0, 270, 271, 272, 157 273, 274, 275, 276, 277, 278, 279, 280, 158 281, 282, 283, 284, 285, 286, 287, 288, 159 289, 290, 291, 292, 293, 294, 295, 296, 160 297, 298, 299, 300, 301, 302, 303, 0, 161 0, 0, 0, 0, 0, 0, 0, 0, 162 0, 0, 0, 0, 0, 0, 0, 0, 163 0, 0, 0, 0, 0, 0, 0, 0, 164 0, 0, 0, 0, 0, 0, 0, 0, 165 0, 304, 305, 306, 0, 0, 307, 308, 166 309, 310, 311, 0, 312, 0, 0, 312, 167 0, 0, 314, 315, 0, 0, 316, 317, 168 318, 0, 0, 0, 158, 155, 163, 319, 169 320, 321, 322, 323, 324, 325, 0, 0, 170 326, 150, 164, 169, 327, 328, 329, 330, 171 331, 332, 333, 334, 335, 336, 337, 338, 172 339, 340, 341, 342, 343, 344, 345, 346, 173 347, 348, 349, 350, 351, 352, 353, 354, 174 355, 356, 357, 358, 359, 360, 361, 362, 175 363, 364, 365, 366, 367, 368, 369, 370, 176 371, 372, 373, 374, 375, 376, 377, 378 177 }; 178 179 #endif /* 1 */ 180 181 182 FT_LOCAL_DEF( FT_UShort ) 183 cff_get_standard_encoding( FT_UInt charcode ) 184 { 185 return (FT_UShort)( charcode < 256 ? cff_standard_encoding[charcode] 186 : 0 ); 187 } 188 189 190 /*************************************************************************/ 191 /* */ 192 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 193 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 194 /* messages during execution. */ 195 /* */ 196 #undef FT_COMPONENT 197 #define FT_COMPONENT trace_cffload 198 199 200 /* read an offset from the index's stream current position */ 201 static FT_ULong 202 cff_index_read_offset( CFF_Index idx, 203 FT_Error *errorp ) 204 { 205 FT_Error error; 206 FT_Stream stream = idx->stream; 207 FT_Byte tmp[4]; 208 FT_ULong result = 0; 209 210 211 if ( !FT_STREAM_READ( tmp, idx->off_size ) ) 212 { 213 FT_Int nn; 214 215 216 for ( nn = 0; nn < idx->off_size; nn++ ) 217 result = ( result << 8 ) | tmp[nn]; 218 } 219 220 *errorp = error; 221 return result; 222 } 223 224 225 static FT_Error 226 cff_index_init( CFF_Index idx, 227 FT_Stream stream, 228 FT_Bool load ) 229 { 230 FT_Error error; 231 FT_Memory memory = stream->memory; 232 FT_UShort count; 233 234 235 FT_MEM_ZERO( idx, sizeof ( *idx ) ); 236 237 idx->stream = stream; 238 idx->start = FT_STREAM_POS(); 239 if ( !FT_READ_USHORT( count ) && 240 count > 0 ) 241 { 242 FT_Byte offsize; 243 FT_ULong size; 244 245 246 /* there is at least one element; read the offset size, */ 247 /* then access the offset table to compute the index's total size */ 248 if ( FT_READ_BYTE( offsize ) ) 249 goto Exit; 250 251 if ( offsize < 1 || offsize > 4 ) 252 { 253 error = FT_THROW( Invalid_Table ); 254 goto Exit; 255 } 256 257 idx->count = count; 258 idx->off_size = offsize; 259 size = (FT_ULong)( count + 1 ) * offsize; 260 261 idx->data_offset = idx->start + 3 + size; 262 263 if ( FT_STREAM_SKIP( size - offsize ) ) 264 goto Exit; 265 266 size = cff_index_read_offset( idx, &error ); 267 if ( error ) 268 goto Exit; 269 270 if ( size == 0 ) 271 { 272 error = FT_THROW( Invalid_Table ); 273 goto Exit; 274 } 275 276 idx->data_size = --size; 277 278 if ( load ) 279 { 280 /* load the data */ 281 if ( FT_FRAME_EXTRACT( size, idx->bytes ) ) 282 goto Exit; 283 } 284 else 285 { 286 /* skip the data */ 287 if ( FT_STREAM_SKIP( size ) ) 288 goto Exit; 289 } 290 } 291 292 Exit: 293 if ( error ) 294 FT_FREE( idx->offsets ); 295 296 return error; 297 } 298 299 300 static void 301 cff_index_done( CFF_Index idx ) 302 { 303 if ( idx->stream ) 304 { 305 FT_Stream stream = idx->stream; 306 FT_Memory memory = stream->memory; 307 308 309 if ( idx->bytes ) 310 FT_FRAME_RELEASE( idx->bytes ); 311 312 FT_FREE( idx->offsets ); 313 FT_MEM_ZERO( idx, sizeof ( *idx ) ); 314 } 315 } 316 317 318 static FT_Error 319 cff_index_load_offsets( CFF_Index idx ) 320 { 321 FT_Error error = FT_Err_Ok; 322 FT_Stream stream = idx->stream; 323 FT_Memory memory = stream->memory; 324 325 326 if ( idx->count > 0 && idx->offsets == NULL ) 327 { 328 FT_Byte offsize = idx->off_size; 329 FT_ULong data_size; 330 FT_Byte* p; 331 FT_Byte* p_end; 332 FT_ULong* poff; 333 334 335 data_size = (FT_ULong)( idx->count + 1 ) * offsize; 336 337 if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) || 338 FT_STREAM_SEEK( idx->start + 3 ) || 339 FT_FRAME_ENTER( data_size ) ) 340 goto Exit; 341 342 poff = idx->offsets; 343 p = (FT_Byte*)stream->cursor; 344 p_end = p + data_size; 345 346 switch ( offsize ) 347 { 348 case 1: 349 for ( ; p < p_end; p++, poff++ ) 350 poff[0] = p[0]; 351 break; 352 353 case 2: 354 for ( ; p < p_end; p += 2, poff++ ) 355 poff[0] = FT_PEEK_USHORT( p ); 356 break; 357 358 case 3: 359 for ( ; p < p_end; p += 3, poff++ ) 360 poff[0] = FT_PEEK_UOFF3( p ); 361 break; 362 363 default: 364 for ( ; p < p_end; p += 4, poff++ ) 365 poff[0] = FT_PEEK_ULONG( p ); 366 } 367 368 FT_FRAME_EXIT(); 369 } 370 371 Exit: 372 if ( error ) 373 FT_FREE( idx->offsets ); 374 375 return error; 376 } 377 378 379 /* Allocate a table containing pointers to an index's elements. */ 380 /* The `pool' argument makes this function convert the index */ 381 /* entries to C-style strings (this is, NULL-terminated). */ 382 static FT_Error 383 cff_index_get_pointers( CFF_Index idx, 384 FT_Byte*** table, 385 FT_Byte** pool, 386 FT_ULong* pool_size ) 387 { 388 FT_Error error = FT_Err_Ok; 389 FT_Memory memory = idx->stream->memory; 390 391 FT_Byte** t = NULL; 392 FT_Byte* new_bytes = NULL; 393 FT_ULong new_size; 394 395 396 *table = NULL; 397 398 if ( idx->offsets == NULL ) 399 { 400 error = cff_index_load_offsets( idx ); 401 if ( error ) 402 goto Exit; 403 } 404 405 new_size = idx->data_size + idx->count; 406 407 if ( idx->count > 0 && 408 !FT_NEW_ARRAY( t, idx->count + 1 ) && 409 ( !pool || !FT_ALLOC( new_bytes, new_size ) ) ) 410 { 411 FT_ULong n, cur_offset; 412 FT_ULong extra = 0; 413 FT_Byte* org_bytes = idx->bytes; 414 415 416 /* at this point, `idx->offsets' can't be NULL */ 417 cur_offset = idx->offsets[0] - 1; 418 419 /* sanity check */ 420 if ( cur_offset != 0 ) 421 { 422 FT_TRACE0(( "cff_index_get_pointers:" 423 " invalid first offset value %d set to zero\n", 424 cur_offset )); 425 cur_offset = 0; 426 } 427 428 if ( !pool ) 429 t[0] = org_bytes + cur_offset; 430 else 431 t[0] = new_bytes + cur_offset; 432 433 for ( n = 1; n <= idx->count; n++ ) 434 { 435 FT_ULong next_offset = idx->offsets[n] - 1; 436 437 438 /* two sanity checks for invalid offset tables */ 439 if ( next_offset < cur_offset ) 440 next_offset = cur_offset; 441 else if ( next_offset > idx->data_size ) 442 next_offset = idx->data_size; 443 444 if ( !pool ) 445 t[n] = org_bytes + next_offset; 446 else 447 { 448 t[n] = new_bytes + next_offset + extra; 449 450 if ( next_offset != cur_offset ) 451 { 452 FT_MEM_COPY( t[n - 1], org_bytes + cur_offset, t[n] - t[n - 1] ); 453 t[n][0] = '\0'; 454 t[n] += 1; 455 extra++; 456 } 457 } 458 459 cur_offset = next_offset; 460 } 461 *table = t; 462 463 if ( pool ) 464 *pool = new_bytes; 465 if ( pool_size ) 466 *pool_size = new_size; 467 } 468 469 Exit: 470 return error; 471 } 472 473 474 FT_LOCAL_DEF( FT_Error ) 475 cff_index_access_element( CFF_Index idx, 476 FT_UInt element, 477 FT_Byte** pbytes, 478 FT_ULong* pbyte_len ) 479 { 480 FT_Error error = FT_Err_Ok; 481 482 483 if ( idx && idx->count > element ) 484 { 485 /* compute start and end offsets */ 486 FT_Stream stream = idx->stream; 487 FT_ULong off1, off2 = 0; 488 489 490 /* load offsets from file or the offset table */ 491 if ( !idx->offsets ) 492 { 493 FT_ULong pos = element * idx->off_size; 494 495 496 if ( FT_STREAM_SEEK( idx->start + 3 + pos ) ) 497 goto Exit; 498 499 off1 = cff_index_read_offset( idx, &error ); 500 if ( error ) 501 goto Exit; 502 503 if ( off1 != 0 ) 504 { 505 do 506 { 507 element++; 508 off2 = cff_index_read_offset( idx, &error ); 509 510 } while ( off2 == 0 && element < idx->count ); 511 } 512 } 513 else /* use offsets table */ 514 { 515 off1 = idx->offsets[element]; 516 if ( off1 ) 517 { 518 do 519 { 520 element++; 521 off2 = idx->offsets[element]; 522 523 } while ( off2 == 0 && element < idx->count ); 524 } 525 } 526 527 /* XXX: should check off2 does not exceed the end of this entry; */ 528 /* at present, only truncate off2 at the end of this stream */ 529 if ( off2 > stream->size + 1 || 530 idx->data_offset > stream->size - off2 + 1 ) 531 { 532 FT_ERROR(( "cff_index_access_element:" 533 " offset to next entry (%d)" 534 " exceeds the end of stream (%d)\n", 535 off2, stream->size - idx->data_offset + 1 )); 536 off2 = stream->size - idx->data_offset + 1; 537 } 538 539 /* access element */ 540 if ( off1 && off2 > off1 ) 541 { 542 *pbyte_len = off2 - off1; 543 544 if ( idx->bytes ) 545 { 546 /* this index was completely loaded in memory, that's easy */ 547 *pbytes = idx->bytes + off1 - 1; 548 } 549 else 550 { 551 /* this index is still on disk/file, access it through a frame */ 552 if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) || 553 FT_FRAME_EXTRACT( off2 - off1, *pbytes ) ) 554 goto Exit; 555 } 556 } 557 else 558 { 559 /* empty index element */ 560 *pbytes = 0; 561 *pbyte_len = 0; 562 } 563 } 564 else 565 error = FT_THROW( Invalid_Argument ); 566 567 Exit: 568 return error; 569 } 570 571 572 FT_LOCAL_DEF( void ) 573 cff_index_forget_element( CFF_Index idx, 574 FT_Byte** pbytes ) 575 { 576 if ( idx->bytes == 0 ) 577 { 578 FT_Stream stream = idx->stream; 579 580 581 FT_FRAME_RELEASE( *pbytes ); 582 } 583 } 584 585 586 /* get an entry from Name INDEX */ 587 FT_LOCAL_DEF( FT_String* ) 588 cff_index_get_name( CFF_Font font, 589 FT_UInt element ) 590 { 591 CFF_Index idx = &font->name_index; 592 FT_Memory memory = idx->stream->memory; 593 FT_Byte* bytes; 594 FT_ULong byte_len; 595 FT_Error error; 596 FT_String* name = 0; 597 598 599 error = cff_index_access_element( idx, element, &bytes, &byte_len ); 600 if ( error ) 601 goto Exit; 602 603 if ( !FT_ALLOC( name, byte_len + 1 ) ) 604 { 605 if ( byte_len ) 606 FT_MEM_COPY( name, bytes, byte_len ); 607 name[byte_len] = 0; 608 } 609 cff_index_forget_element( idx, &bytes ); 610 611 Exit: 612 return name; 613 } 614 615 616 /* get an entry from String INDEX */ 617 FT_LOCAL_DEF( FT_String* ) 618 cff_index_get_string( CFF_Font font, 619 FT_UInt element ) 620 { 621 return ( element < font->num_strings ) 622 ? (FT_String*)font->strings[element] 623 : NULL; 624 } 625 626 627 FT_LOCAL_DEF( FT_String* ) 628 cff_index_get_sid_string( CFF_Font font, 629 FT_UInt sid ) 630 { 631 /* value 0xFFFFU indicates a missing dictionary entry */ 632 if ( sid == 0xFFFFU ) 633 return NULL; 634 635 /* if it is not a standard string, return it */ 636 if ( sid > 390 ) 637 return cff_index_get_string( font, sid - 391 ); 638 639 /* CID-keyed CFF fonts don't have glyph names */ 640 if ( !font->psnames ) 641 return NULL; 642 643 /* this is a standard string */ 644 return (FT_String *)font->psnames->adobe_std_strings( sid ); 645 } 646 647 648 /*************************************************************************/ 649 /*************************************************************************/ 650 /*** ***/ 651 /*** FD Select table support ***/ 652 /*** ***/ 653 /*************************************************************************/ 654 /*************************************************************************/ 655 656 657 static void 658 CFF_Done_FD_Select( CFF_FDSelect fdselect, 659 FT_Stream stream ) 660 { 661 if ( fdselect->data ) 662 FT_FRAME_RELEASE( fdselect->data ); 663 664 fdselect->data_size = 0; 665 fdselect->format = 0; 666 fdselect->range_count = 0; 667 } 668 669 670 static FT_Error 671 CFF_Load_FD_Select( CFF_FDSelect fdselect, 672 FT_UInt num_glyphs, 673 FT_Stream stream, 674 FT_ULong offset ) 675 { 676 FT_Error error; 677 FT_Byte format; 678 FT_UInt num_ranges; 679 680 681 /* read format */ 682 if ( FT_STREAM_SEEK( offset ) || FT_READ_BYTE( format ) ) 683 goto Exit; 684 685 fdselect->format = format; 686 fdselect->cache_count = 0; /* clear cache */ 687 688 switch ( format ) 689 { 690 case 0: /* format 0, that's simple */ 691 fdselect->data_size = num_glyphs; 692 goto Load_Data; 693 694 case 3: /* format 3, a tad more complex */ 695 if ( FT_READ_USHORT( num_ranges ) ) 696 goto Exit; 697 698 if ( !num_ranges ) 699 { 700 FT_TRACE0(( "CFF_Load_FD_Select: empty FDSelect array\n" )); 701 error = FT_THROW( Invalid_File_Format ); 702 goto Exit; 703 } 704 705 fdselect->data_size = num_ranges * 3 + 2; 706 707 Load_Data: 708 if ( FT_FRAME_EXTRACT( fdselect->data_size, fdselect->data ) ) 709 goto Exit; 710 break; 711 712 default: /* hmm... that's wrong */ 713 error = FT_THROW( Invalid_File_Format ); 714 } 715 716 Exit: 717 return error; 718 } 719 720 721 FT_LOCAL_DEF( FT_Byte ) 722 cff_fd_select_get( CFF_FDSelect fdselect, 723 FT_UInt glyph_index ) 724 { 725 FT_Byte fd = 0; 726 727 728 switch ( fdselect->format ) 729 { 730 case 0: 731 fd = fdselect->data[glyph_index]; 732 break; 733 734 case 3: 735 /* first, compare to the cache */ 736 if ( (FT_UInt)( glyph_index - fdselect->cache_first ) < 737 fdselect->cache_count ) 738 { 739 fd = fdselect->cache_fd; 740 break; 741 } 742 743 /* then, look up the ranges array */ 744 { 745 FT_Byte* p = fdselect->data; 746 FT_Byte* p_limit = p + fdselect->data_size; 747 FT_Byte fd2; 748 FT_UInt first, limit; 749 750 751 first = FT_NEXT_USHORT( p ); 752 do 753 { 754 if ( glyph_index < first ) 755 break; 756 757 fd2 = *p++; 758 limit = FT_NEXT_USHORT( p ); 759 760 if ( glyph_index < limit ) 761 { 762 fd = fd2; 763 764 /* update cache */ 765 fdselect->cache_first = first; 766 fdselect->cache_count = limit - first; 767 fdselect->cache_fd = fd2; 768 break; 769 } 770 first = limit; 771 772 } while ( p < p_limit ); 773 } 774 break; 775 776 default: 777 ; 778 } 779 780 return fd; 781 } 782 783 784 /*************************************************************************/ 785 /*************************************************************************/ 786 /*** ***/ 787 /*** CFF font support ***/ 788 /*** ***/ 789 /*************************************************************************/ 790 /*************************************************************************/ 791 792 static FT_Error 793 cff_charset_compute_cids( CFF_Charset charset, 794 FT_UInt num_glyphs, 795 FT_Memory memory ) 796 { 797 FT_Error error = FT_Err_Ok; 798 FT_UInt i; 799 FT_Long j; 800 FT_UShort max_cid = 0; 801 802 803 if ( charset->max_cid > 0 ) 804 goto Exit; 805 806 for ( i = 0; i < num_glyphs; i++ ) 807 { 808 if ( charset->sids[i] > max_cid ) 809 max_cid = charset->sids[i]; 810 } 811 812 if ( FT_NEW_ARRAY( charset->cids, (FT_ULong)max_cid + 1 ) ) 813 goto Exit; 814 815 /* When multiple GIDs map to the same CID, we choose the lowest */ 816 /* GID. This is not described in any spec, but it matches the */ 817 /* behaviour of recent Acroread versions. */ 818 for ( j = (FT_Long)num_glyphs - 1; j >= 0; j-- ) 819 charset->cids[charset->sids[j]] = (FT_UShort)j; 820 821 charset->max_cid = max_cid; 822 charset->num_glyphs = num_glyphs; 823 824 Exit: 825 return error; 826 } 827 828 829 FT_LOCAL_DEF( FT_UInt ) 830 cff_charset_cid_to_gindex( CFF_Charset charset, 831 FT_UInt cid ) 832 { 833 FT_UInt result = 0; 834 835 836 if ( cid <= charset->max_cid ) 837 result = charset->cids[cid]; 838 839 return result; 840 } 841 842 843 static void 844 cff_charset_free_cids( CFF_Charset charset, 845 FT_Memory memory ) 846 { 847 FT_FREE( charset->cids ); 848 charset->max_cid = 0; 849 } 850 851 852 static void 853 cff_charset_done( CFF_Charset charset, 854 FT_Stream stream ) 855 { 856 FT_Memory memory = stream->memory; 857 858 859 cff_charset_free_cids( charset, memory ); 860 861 FT_FREE( charset->sids ); 862 charset->format = 0; 863 charset->offset = 0; 864 } 865 866 867 static FT_Error 868 cff_charset_load( CFF_Charset charset, 869 FT_UInt num_glyphs, 870 FT_Stream stream, 871 FT_ULong base_offset, 872 FT_ULong offset, 873 FT_Bool invert ) 874 { 875 FT_Memory memory = stream->memory; 876 FT_Error error = FT_Err_Ok; 877 FT_UShort glyph_sid; 878 879 880 /* If the offset is greater than 2, we have to parse the charset */ 881 /* table. */ 882 if ( offset > 2 ) 883 { 884 FT_UInt j; 885 886 887 charset->offset = base_offset + offset; 888 889 /* Get the format of the table. */ 890 if ( FT_STREAM_SEEK( charset->offset ) || 891 FT_READ_BYTE( charset->format ) ) 892 goto Exit; 893 894 /* Allocate memory for sids. */ 895 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) 896 goto Exit; 897 898 /* assign the .notdef glyph */ 899 charset->sids[0] = 0; 900 901 switch ( charset->format ) 902 { 903 case 0: 904 if ( num_glyphs > 0 ) 905 { 906 if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) ) 907 goto Exit; 908 909 for ( j = 1; j < num_glyphs; j++ ) 910 charset->sids[j] = FT_GET_USHORT(); 911 912 FT_FRAME_EXIT(); 913 } 914 break; 915 916 case 1: 917 case 2: 918 { 919 FT_UInt nleft; 920 FT_UInt i; 921 922 923 j = 1; 924 925 while ( j < num_glyphs ) 926 { 927 /* Read the first glyph sid of the range. */ 928 if ( FT_READ_USHORT( glyph_sid ) ) 929 goto Exit; 930 931 /* Read the number of glyphs in the range. */ 932 if ( charset->format == 2 ) 933 { 934 if ( FT_READ_USHORT( nleft ) ) 935 goto Exit; 936 } 937 else 938 { 939 if ( FT_READ_BYTE( nleft ) ) 940 goto Exit; 941 } 942 943 /* try to rescue some of the SIDs if `nleft' is too large */ 944 if ( glyph_sid > 0xFFFFL - nleft ) 945 { 946 FT_ERROR(( "cff_charset_load: invalid SID range trimmed" 947 " nleft=%d -> %d\n", nleft, 0xFFFFL - glyph_sid )); 948 nleft = ( FT_UInt )( 0xFFFFL - glyph_sid ); 949 } 950 951 /* Fill in the range of sids -- `nleft + 1' glyphs. */ 952 for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ ) 953 charset->sids[j] = glyph_sid; 954 } 955 } 956 break; 957 958 default: 959 FT_ERROR(( "cff_charset_load: invalid table format\n" )); 960 error = FT_THROW( Invalid_File_Format ); 961 goto Exit; 962 } 963 } 964 else 965 { 966 /* Parse default tables corresponding to offset == 0, 1, or 2. */ 967 /* CFF specification intimates the following: */ 968 /* */ 969 /* In order to use a predefined charset, the following must be */ 970 /* true: The charset constructed for the glyphs in the font's */ 971 /* charstrings dictionary must match the predefined charset in */ 972 /* the first num_glyphs. */ 973 974 charset->offset = offset; /* record charset type */ 975 976 switch ( (FT_UInt)offset ) 977 { 978 case 0: 979 if ( num_glyphs > 229 ) 980 { 981 FT_ERROR(( "cff_charset_load: implicit charset larger than\n" 982 "predefined charset (Adobe ISO-Latin)\n" )); 983 error = FT_THROW( Invalid_File_Format ); 984 goto Exit; 985 } 986 987 /* Allocate memory for sids. */ 988 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) 989 goto Exit; 990 991 /* Copy the predefined charset into the allocated memory. */ 992 FT_ARRAY_COPY( charset->sids, cff_isoadobe_charset, num_glyphs ); 993 994 break; 995 996 case 1: 997 if ( num_glyphs > 166 ) 998 { 999 FT_ERROR(( "cff_charset_load: implicit charset larger than\n" 1000 "predefined charset (Adobe Expert)\n" )); 1001 error = FT_THROW( Invalid_File_Format ); 1002 goto Exit; 1003 } 1004 1005 /* Allocate memory for sids. */ 1006 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) 1007 goto Exit; 1008 1009 /* Copy the predefined charset into the allocated memory. */ 1010 FT_ARRAY_COPY( charset->sids, cff_expert_charset, num_glyphs ); 1011 1012 break; 1013 1014 case 2: 1015 if ( num_glyphs > 87 ) 1016 { 1017 FT_ERROR(( "cff_charset_load: implicit charset larger than\n" 1018 "predefined charset (Adobe Expert Subset)\n" )); 1019 error = FT_THROW( Invalid_File_Format ); 1020 goto Exit; 1021 } 1022 1023 /* Allocate memory for sids. */ 1024 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) 1025 goto Exit; 1026 1027 /* Copy the predefined charset into the allocated memory. */ 1028 FT_ARRAY_COPY( charset->sids, cff_expertsubset_charset, num_glyphs ); 1029 1030 break; 1031 1032 default: 1033 error = FT_THROW( Invalid_File_Format ); 1034 goto Exit; 1035 } 1036 } 1037 1038 /* we have to invert the `sids' array for subsetted CID-keyed fonts */ 1039 if ( invert ) 1040 error = cff_charset_compute_cids( charset, num_glyphs, memory ); 1041 1042 Exit: 1043 /* Clean up if there was an error. */ 1044 if ( error ) 1045 { 1046 FT_FREE( charset->sids ); 1047 FT_FREE( charset->cids ); 1048 charset->format = 0; 1049 charset->offset = 0; 1050 charset->sids = 0; 1051 } 1052 1053 return error; 1054 } 1055 1056 1057 static void 1058 cff_encoding_done( CFF_Encoding encoding ) 1059 { 1060 encoding->format = 0; 1061 encoding->offset = 0; 1062 encoding->count = 0; 1063 } 1064 1065 1066 static FT_Error 1067 cff_encoding_load( CFF_Encoding encoding, 1068 CFF_Charset charset, 1069 FT_UInt num_glyphs, 1070 FT_Stream stream, 1071 FT_ULong base_offset, 1072 FT_ULong offset ) 1073 { 1074 FT_Error error = FT_Err_Ok; 1075 FT_UInt count; 1076 FT_UInt j; 1077 FT_UShort glyph_sid; 1078 FT_UInt glyph_code; 1079 1080 1081 /* Check for charset->sids. If we do not have this, we fail. */ 1082 if ( !charset->sids ) 1083 { 1084 error = FT_THROW( Invalid_File_Format ); 1085 goto Exit; 1086 } 1087 1088 /* Zero out the code to gid/sid mappings. */ 1089 for ( j = 0; j < 256; j++ ) 1090 { 1091 encoding->sids [j] = 0; 1092 encoding->codes[j] = 0; 1093 } 1094 1095 /* Note: The encoding table in a CFF font is indexed by glyph index; */ 1096 /* the first encoded glyph index is 1. Hence, we read the character */ 1097 /* code (`glyph_code') at index j and make the assignment: */ 1098 /* */ 1099 /* encoding->codes[glyph_code] = j + 1 */ 1100 /* */ 1101 /* We also make the assignment: */ 1102 /* */ 1103 /* encoding->sids[glyph_code] = charset->sids[j + 1] */ 1104 /* */ 1105 /* This gives us both a code to GID and a code to SID mapping. */ 1106 1107 if ( offset > 1 ) 1108 { 1109 encoding->offset = base_offset + offset; 1110 1111 /* we need to parse the table to determine its size */ 1112 if ( FT_STREAM_SEEK( encoding->offset ) || 1113 FT_READ_BYTE( encoding->format ) || 1114 FT_READ_BYTE( count ) ) 1115 goto Exit; 1116 1117 switch ( encoding->format & 0x7F ) 1118 { 1119 case 0: 1120 { 1121 FT_Byte* p; 1122 1123 1124 /* By convention, GID 0 is always ".notdef" and is never */ 1125 /* coded in the font. Hence, the number of codes found */ 1126 /* in the table is `count+1'. */ 1127 /* */ 1128 encoding->count = count + 1; 1129 1130 if ( FT_FRAME_ENTER( count ) ) 1131 goto Exit; 1132 1133 p = (FT_Byte*)stream->cursor; 1134 1135 for ( j = 1; j <= count; j++ ) 1136 { 1137 glyph_code = *p++; 1138 1139 /* Make sure j is not too big. */ 1140 if ( j < num_glyphs ) 1141 { 1142 /* Assign code to GID mapping. */ 1143 encoding->codes[glyph_code] = (FT_UShort)j; 1144 1145 /* Assign code to SID mapping. */ 1146 encoding->sids[glyph_code] = charset->sids[j]; 1147 } 1148 } 1149 1150 FT_FRAME_EXIT(); 1151 } 1152 break; 1153 1154 case 1: 1155 { 1156 FT_UInt nleft; 1157 FT_UInt i = 1; 1158 FT_UInt k; 1159 1160 1161 encoding->count = 0; 1162 1163 /* Parse the Format1 ranges. */ 1164 for ( j = 0; j < count; j++, i += nleft ) 1165 { 1166 /* Read the first glyph code of the range. */ 1167 if ( FT_READ_BYTE( glyph_code ) ) 1168 goto Exit; 1169 1170 /* Read the number of codes in the range. */ 1171 if ( FT_READ_BYTE( nleft ) ) 1172 goto Exit; 1173 1174 /* Increment nleft, so we read `nleft + 1' codes/sids. */ 1175 nleft++; 1176 1177 /* compute max number of character codes */ 1178 if ( (FT_UInt)nleft > encoding->count ) 1179 encoding->count = nleft; 1180 1181 /* Fill in the range of codes/sids. */ 1182 for ( k = i; k < nleft + i; k++, glyph_code++ ) 1183 { 1184 /* Make sure k is not too big. */ 1185 if ( k < num_glyphs && glyph_code < 256 ) 1186 { 1187 /* Assign code to GID mapping. */ 1188 encoding->codes[glyph_code] = (FT_UShort)k; 1189 1190 /* Assign code to SID mapping. */ 1191 encoding->sids[glyph_code] = charset->sids[k]; 1192 } 1193 } 1194 } 1195 1196 /* simple check; one never knows what can be found in a font */ 1197 if ( encoding->count > 256 ) 1198 encoding->count = 256; 1199 } 1200 break; 1201 1202 default: 1203 FT_ERROR(( "cff_encoding_load: invalid table format\n" )); 1204 error = FT_THROW( Invalid_File_Format ); 1205 goto Exit; 1206 } 1207 1208 /* Parse supplemental encodings, if any. */ 1209 if ( encoding->format & 0x80 ) 1210 { 1211 FT_UInt gindex; 1212 1213 1214 /* count supplements */ 1215 if ( FT_READ_BYTE( count ) ) 1216 goto Exit; 1217 1218 for ( j = 0; j < count; j++ ) 1219 { 1220 /* Read supplemental glyph code. */ 1221 if ( FT_READ_BYTE( glyph_code ) ) 1222 goto Exit; 1223 1224 /* Read the SID associated with this glyph code. */ 1225 if ( FT_READ_USHORT( glyph_sid ) ) 1226 goto Exit; 1227 1228 /* Assign code to SID mapping. */ 1229 encoding->sids[glyph_code] = glyph_sid; 1230 1231 /* First, look up GID which has been assigned to */ 1232 /* SID glyph_sid. */ 1233 for ( gindex = 0; gindex < num_glyphs; gindex++ ) 1234 { 1235 if ( charset->sids[gindex] == glyph_sid ) 1236 { 1237 encoding->codes[glyph_code] = (FT_UShort)gindex; 1238 break; 1239 } 1240 } 1241 } 1242 } 1243 } 1244 else 1245 { 1246 /* We take into account the fact a CFF font can use a predefined */ 1247 /* encoding without containing all of the glyphs encoded by this */ 1248 /* encoding (see the note at the end of section 12 in the CFF */ 1249 /* specification). */ 1250 1251 switch ( (FT_UInt)offset ) 1252 { 1253 case 0: 1254 /* First, copy the code to SID mapping. */ 1255 FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 ); 1256 goto Populate; 1257 1258 case 1: 1259 /* First, copy the code to SID mapping. */ 1260 FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 ); 1261 1262 Populate: 1263 /* Construct code to GID mapping from code to SID mapping */ 1264 /* and charset. */ 1265 1266 encoding->count = 0; 1267 1268 error = cff_charset_compute_cids( charset, num_glyphs, 1269 stream->memory ); 1270 if ( error ) 1271 goto Exit; 1272 1273 for ( j = 0; j < 256; j++ ) 1274 { 1275 FT_UInt sid = encoding->sids[j]; 1276 FT_UInt gid = 0; 1277 1278 1279 if ( sid ) 1280 gid = cff_charset_cid_to_gindex( charset, sid ); 1281 1282 if ( gid != 0 ) 1283 { 1284 encoding->codes[j] = (FT_UShort)gid; 1285 encoding->count = j + 1; 1286 } 1287 else 1288 { 1289 encoding->codes[j] = 0; 1290 encoding->sids [j] = 0; 1291 } 1292 } 1293 break; 1294 1295 default: 1296 FT_ERROR(( "cff_encoding_load: invalid table format\n" )); 1297 error = FT_THROW( Invalid_File_Format ); 1298 goto Exit; 1299 } 1300 } 1301 1302 Exit: 1303 1304 /* Clean up if there was an error. */ 1305 return error; 1306 } 1307 1308 1309 static FT_Error 1310 cff_subfont_load( CFF_SubFont font, 1311 CFF_Index idx, 1312 FT_UInt font_index, 1313 FT_Stream stream, 1314 FT_ULong base_offset, 1315 FT_Library library ) 1316 { 1317 FT_Error error; 1318 CFF_ParserRec parser; 1319 FT_Byte* dict = NULL; 1320 FT_ULong dict_len; 1321 CFF_FontRecDict top = &font->font_dict; 1322 CFF_Private priv = &font->private_dict; 1323 1324 1325 cff_parser_init( &parser, 1326 CFF_CODE_TOPDICT, 1327 &font->font_dict, 1328 library, 1329 0, 1330 0 ); 1331 1332 /* set defaults */ 1333 FT_MEM_ZERO( top, sizeof ( *top ) ); 1334 1335 top->underline_position = -( 100L << 16 ); 1336 top->underline_thickness = 50L << 16; 1337 top->charstring_type = 2; 1338 top->font_matrix.xx = 0x10000L; 1339 top->font_matrix.yy = 0x10000L; 1340 top->cid_count = 8720; 1341 1342 /* we use the implementation specific SID value 0xFFFF to indicate */ 1343 /* missing entries */ 1344 top->version = 0xFFFFU; 1345 top->notice = 0xFFFFU; 1346 top->copyright = 0xFFFFU; 1347 top->full_name = 0xFFFFU; 1348 top->family_name = 0xFFFFU; 1349 top->weight = 0xFFFFU; 1350 top->embedded_postscript = 0xFFFFU; 1351 1352 top->cid_registry = 0xFFFFU; 1353 top->cid_ordering = 0xFFFFU; 1354 top->cid_font_name = 0xFFFFU; 1355 1356 error = cff_index_access_element( idx, font_index, &dict, &dict_len ); 1357 if ( !error ) 1358 { 1359 FT_TRACE4(( " top dictionary:\n" )); 1360 error = cff_parser_run( &parser, dict, dict + dict_len ); 1361 } 1362 1363 cff_index_forget_element( idx, &dict ); 1364 1365 if ( error ) 1366 goto Exit; 1367 1368 /* if it is a CID font, we stop there */ 1369 if ( top->cid_registry != 0xFFFFU ) 1370 goto Exit; 1371 1372 /* parse the private dictionary, if any */ 1373 if ( top->private_offset && top->private_size ) 1374 { 1375 /* set defaults */ 1376 FT_MEM_ZERO( priv, sizeof ( *priv ) ); 1377 1378 priv->blue_shift = 7; 1379 priv->blue_fuzz = 1; 1380 priv->lenIV = -1; 1381 priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); 1382 priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 ); 1383 1384 cff_parser_init( &parser, 1385 CFF_CODE_PRIVATE, 1386 priv, 1387 library, 1388 top->num_designs, 1389 top->num_axes ); 1390 1391 if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) || 1392 FT_FRAME_ENTER( font->font_dict.private_size ) ) 1393 goto Exit; 1394 1395 FT_TRACE4(( " private dictionary:\n" )); 1396 error = cff_parser_run( &parser, 1397 (FT_Byte*)stream->cursor, 1398 (FT_Byte*)stream->limit ); 1399 FT_FRAME_EXIT(); 1400 if ( error ) 1401 goto Exit; 1402 1403 /* ensure that `num_blue_values' is even */ 1404 priv->num_blue_values &= ~1; 1405 } 1406 1407 /* read the local subrs, if any */ 1408 if ( priv->local_subrs_offset ) 1409 { 1410 if ( FT_STREAM_SEEK( base_offset + top->private_offset + 1411 priv->local_subrs_offset ) ) 1412 goto Exit; 1413 1414 error = cff_index_init( &font->local_subrs_index, stream, 1 ); 1415 if ( error ) 1416 goto Exit; 1417 1418 error = cff_index_get_pointers( &font->local_subrs_index, 1419 &font->local_subrs, NULL, NULL ); 1420 if ( error ) 1421 goto Exit; 1422 } 1423 1424 Exit: 1425 return error; 1426 } 1427 1428 1429 static void 1430 cff_subfont_done( FT_Memory memory, 1431 CFF_SubFont subfont ) 1432 { 1433 if ( subfont ) 1434 { 1435 cff_index_done( &subfont->local_subrs_index ); 1436 FT_FREE( subfont->local_subrs ); 1437 } 1438 } 1439 1440 1441 FT_LOCAL_DEF( FT_Error ) 1442 cff_font_load( FT_Library library, 1443 FT_Stream stream, 1444 FT_Int face_index, 1445 CFF_Font font, 1446 FT_Bool pure_cff ) 1447 { 1448 static const FT_Frame_Field cff_header_fields[] = 1449 { 1450 #undef FT_STRUCTURE 1451 #define FT_STRUCTURE CFF_FontRec 1452 1453 FT_FRAME_START( 4 ), 1454 FT_FRAME_BYTE( version_major ), 1455 FT_FRAME_BYTE( version_minor ), 1456 FT_FRAME_BYTE( header_size ), 1457 FT_FRAME_BYTE( absolute_offsize ), 1458 FT_FRAME_END 1459 }; 1460 1461 FT_Error error; 1462 FT_Memory memory = stream->memory; 1463 FT_ULong base_offset; 1464 CFF_FontRecDict dict; 1465 CFF_IndexRec string_index; 1466 FT_UInt subfont_index; 1467 1468 1469 FT_ZERO( font ); 1470 FT_ZERO( &string_index ); 1471 1472 font->stream = stream; 1473 font->memory = memory; 1474 dict = &font->top_font.font_dict; 1475 base_offset = FT_STREAM_POS(); 1476 1477 /* read CFF font header */ 1478 if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) ) 1479 goto Exit; 1480 1481 /* check format */ 1482 if ( font->version_major != 1 || 1483 font->header_size < 4 || 1484 font->absolute_offsize > 4 ) 1485 { 1486 FT_TRACE2(( " not a CFF font header\n" )); 1487 error = FT_THROW( Unknown_File_Format ); 1488 goto Exit; 1489 } 1490 1491 /* skip the rest of the header */ 1492 if ( FT_STREAM_SKIP( font->header_size - 4 ) ) 1493 goto Exit; 1494 1495 /* read the name, top dict, string and global subrs index */ 1496 if ( FT_SET_ERROR( cff_index_init( &font->name_index, 1497 stream, 0 ) ) || 1498 FT_SET_ERROR( cff_index_init( &font->font_dict_index, 1499 stream, 0 ) ) || 1500 FT_SET_ERROR( cff_index_init( &string_index, 1501 stream, 1 ) ) || 1502 FT_SET_ERROR( cff_index_init( &font->global_subrs_index, 1503 stream, 1 ) ) || 1504 FT_SET_ERROR( cff_index_get_pointers( &string_index, 1505 &font->strings, 1506 &font->string_pool, 1507 &font->string_pool_size ) ) ) 1508 goto Exit; 1509 1510 font->num_strings = string_index.count; 1511 1512 if ( pure_cff ) 1513 { 1514 /* well, we don't really forget the `disabled' fonts... */ 1515 subfont_index = (FT_UInt)( face_index & 0xFFFF ); 1516 1517 if ( face_index > 0 && subfont_index >= font->name_index.count ) 1518 { 1519 FT_ERROR(( "cff_font_load:" 1520 " invalid subfont index for pure CFF font (%d)\n", 1521 subfont_index )); 1522 error = FT_THROW( Invalid_Argument ); 1523 goto Exit; 1524 } 1525 1526 font->num_faces = font->name_index.count; 1527 } 1528 else 1529 { 1530 subfont_index = 0; 1531 1532 if ( font->name_index.count > 1 ) 1533 { 1534 FT_ERROR(( "cff_font_load:" 1535 " invalid CFF font with multiple subfonts\n" 1536 " " 1537 " in SFNT wrapper\n" )); 1538 error = FT_THROW( Invalid_File_Format ); 1539 goto Exit; 1540 } 1541 } 1542 1543 /* in case of a font format check, simply exit now */ 1544 if ( face_index < 0 ) 1545 goto Exit; 1546 1547 /* now, parse the top-level font dictionary */ 1548 FT_TRACE4(( "parsing top-level\n" )); 1549 error = cff_subfont_load( &font->top_font, 1550 &font->font_dict_index, 1551 subfont_index, 1552 stream, 1553 base_offset, 1554 library ); 1555 if ( error ) 1556 goto Exit; 1557 1558 if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) ) 1559 goto Exit; 1560 1561 error = cff_index_init( &font->charstrings_index, stream, 0 ); 1562 if ( error ) 1563 goto Exit; 1564 1565 /* now, check for a CID font */ 1566 if ( dict->cid_registry != 0xFFFFU ) 1567 { 1568 CFF_IndexRec fd_index; 1569 CFF_SubFont sub = NULL; 1570 FT_UInt idx; 1571 1572 1573 /* this is a CID-keyed font, we must now allocate a table of */ 1574 /* sub-fonts, then load each of them separately */ 1575 if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) ) 1576 goto Exit; 1577 1578 error = cff_index_init( &fd_index, stream, 0 ); 1579 if ( error ) 1580 goto Exit; 1581 1582 if ( fd_index.count > CFF_MAX_CID_FONTS ) 1583 { 1584 FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" )); 1585 goto Fail_CID; 1586 } 1587 1588 /* allocate & read each font dict independently */ 1589 font->num_subfonts = fd_index.count; 1590 if ( FT_NEW_ARRAY( sub, fd_index.count ) ) 1591 goto Fail_CID; 1592 1593 /* set up pointer table */ 1594 for ( idx = 0; idx < fd_index.count; idx++ ) 1595 font->subfonts[idx] = sub + idx; 1596 1597 /* now load each subfont independently */ 1598 for ( idx = 0; idx < fd_index.count; idx++ ) 1599 { 1600 sub = font->subfonts[idx]; 1601 FT_TRACE4(( "parsing subfont %u\n", idx )); 1602 error = cff_subfont_load( sub, &fd_index, idx, 1603 stream, base_offset, library ); 1604 if ( error ) 1605 goto Fail_CID; 1606 } 1607 1608 /* now load the FD Select array */ 1609 error = CFF_Load_FD_Select( &font->fd_select, 1610 font->charstrings_index.count, 1611 stream, 1612 base_offset + dict->cid_fd_select_offset ); 1613 1614 Fail_CID: 1615 cff_index_done( &fd_index ); 1616 1617 if ( error ) 1618 goto Exit; 1619 } 1620 else 1621 font->num_subfonts = 0; 1622 1623 /* read the charstrings index now */ 1624 if ( dict->charstrings_offset == 0 ) 1625 { 1626 FT_ERROR(( "cff_font_load: no charstrings offset\n" )); 1627 error = FT_THROW( Invalid_File_Format ); 1628 goto Exit; 1629 } 1630 1631 font->num_glyphs = font->charstrings_index.count; 1632 1633 error = cff_index_get_pointers( &font->global_subrs_index, 1634 &font->global_subrs, NULL, NULL ); 1635 1636 if ( error ) 1637 goto Exit; 1638 1639 /* read the Charset and Encoding tables if available */ 1640 if ( font->num_glyphs > 0 ) 1641 { 1642 FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff ); 1643 1644 1645 error = cff_charset_load( &font->charset, font->num_glyphs, stream, 1646 base_offset, dict->charset_offset, invert ); 1647 if ( error ) 1648 goto Exit; 1649 1650 /* CID-keyed CFFs don't have an encoding */ 1651 if ( dict->cid_registry == 0xFFFFU ) 1652 { 1653 error = cff_encoding_load( &font->encoding, 1654 &font->charset, 1655 font->num_glyphs, 1656 stream, 1657 base_offset, 1658 dict->encoding_offset ); 1659 if ( error ) 1660 goto Exit; 1661 } 1662 } 1663 1664 /* get the font name (/CIDFontName for CID-keyed fonts, */ 1665 /* /FontName otherwise) */ 1666 font->font_name = cff_index_get_name( font, subfont_index ); 1667 1668 Exit: 1669 cff_index_done( &string_index ); 1670 1671 return error; 1672 } 1673 1674 1675 FT_LOCAL_DEF( void ) 1676 cff_font_done( CFF_Font font ) 1677 { 1678 FT_Memory memory = font->memory; 1679 FT_UInt idx; 1680 1681 1682 cff_index_done( &font->global_subrs_index ); 1683 cff_index_done( &font->font_dict_index ); 1684 cff_index_done( &font->name_index ); 1685 cff_index_done( &font->charstrings_index ); 1686 1687 /* release font dictionaries, but only if working with */ 1688 /* a CID keyed CFF font */ 1689 if ( font->num_subfonts > 0 ) 1690 { 1691 for ( idx = 0; idx < font->num_subfonts; idx++ ) 1692 cff_subfont_done( memory, font->subfonts[idx] ); 1693 1694 /* the subfonts array has been allocated as a single block */ 1695 FT_FREE( font->subfonts[0] ); 1696 } 1697 1698 cff_encoding_done( &font->encoding ); 1699 cff_charset_done( &font->charset, font->stream ); 1700 1701 cff_subfont_done( memory, &font->top_font ); 1702 1703 CFF_Done_FD_Select( &font->fd_select, font->stream ); 1704 1705 FT_FREE( font->font_info ); 1706 1707 FT_FREE( font->font_name ); 1708 FT_FREE( font->global_subrs ); 1709 FT_FREE( font->strings ); 1710 FT_FREE( font->string_pool ); 1711 1712 if ( font->cf2_instance.finalizer ) 1713 { 1714 font->cf2_instance.finalizer( font->cf2_instance.data ); 1715 FT_FREE( font->cf2_instance.data ); 1716 } 1717 } 1718 1719 1720 /* END */ 1721