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