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