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