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