1 /***************************************************************************/ 2 /* */ 3 /* cffload.c */ 4 /* */ 5 /* OpenType and CFF data/program tables loader (body). */ 6 /* */ 7 /* Copyright 1996-2018 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 #include FT_INTERNAL_POSTSCRIPT_AUX_H 26 27 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 28 #include FT_MULTIPLE_MASTERS_H 29 #include FT_SERVICE_MULTIPLE_MASTERS_H 30 #endif 31 32 #include "cffload.h" 33 #include "cffparse.h" 34 35 #include "cfferrs.h" 36 37 38 #define FT_FIXED_ONE ( (FT_Fixed)0x10000 ) 39 40 41 #if 1 42 43 static const FT_UShort cff_isoadobe_charset[229] = 44 { 45 0, 1, 2, 3, 4, 5, 6, 7, 46 8, 9, 10, 11, 12, 13, 14, 15, 47 16, 17, 18, 19, 20, 21, 22, 23, 48 24, 25, 26, 27, 28, 29, 30, 31, 49 32, 33, 34, 35, 36, 37, 38, 39, 50 40, 41, 42, 43, 44, 45, 46, 47, 51 48, 49, 50, 51, 52, 53, 54, 55, 52 56, 57, 58, 59, 60, 61, 62, 63, 53 64, 65, 66, 67, 68, 69, 70, 71, 54 72, 73, 74, 75, 76, 77, 78, 79, 55 80, 81, 82, 83, 84, 85, 86, 87, 56 88, 89, 90, 91, 92, 93, 94, 95, 57 96, 97, 98, 99, 100, 101, 102, 103, 58 104, 105, 106, 107, 108, 109, 110, 111, 59 112, 113, 114, 115, 116, 117, 118, 119, 60 120, 121, 122, 123, 124, 125, 126, 127, 61 128, 129, 130, 131, 132, 133, 134, 135, 62 136, 137, 138, 139, 140, 141, 142, 143, 63 144, 145, 146, 147, 148, 149, 150, 151, 64 152, 153, 154, 155, 156, 157, 158, 159, 65 160, 161, 162, 163, 164, 165, 166, 167, 66 168, 169, 170, 171, 172, 173, 174, 175, 67 176, 177, 178, 179, 180, 181, 182, 183, 68 184, 185, 186, 187, 188, 189, 190, 191, 69 192, 193, 194, 195, 196, 197, 198, 199, 70 200, 201, 202, 203, 204, 205, 206, 207, 71 208, 209, 210, 211, 212, 213, 214, 215, 72 216, 217, 218, 219, 220, 221, 222, 223, 73 224, 225, 226, 227, 228 74 }; 75 76 static const FT_UShort cff_expert_charset[166] = 77 { 78 0, 1, 229, 230, 231, 232, 233, 234, 79 235, 236, 237, 238, 13, 14, 15, 99, 80 239, 240, 241, 242, 243, 244, 245, 246, 81 247, 248, 27, 28, 249, 250, 251, 252, 82 253, 254, 255, 256, 257, 258, 259, 260, 83 261, 262, 263, 264, 265, 266, 109, 110, 84 267, 268, 269, 270, 271, 272, 273, 274, 85 275, 276, 277, 278, 279, 280, 281, 282, 86 283, 284, 285, 286, 287, 288, 289, 290, 87 291, 292, 293, 294, 295, 296, 297, 298, 88 299, 300, 301, 302, 303, 304, 305, 306, 89 307, 308, 309, 310, 311, 312, 313, 314, 90 315, 316, 317, 318, 158, 155, 163, 319, 91 320, 321, 322, 323, 324, 325, 326, 150, 92 164, 169, 327, 328, 329, 330, 331, 332, 93 333, 334, 335, 336, 337, 338, 339, 340, 94 341, 342, 343, 344, 345, 346, 347, 348, 95 349, 350, 351, 352, 353, 354, 355, 356, 96 357, 358, 359, 360, 361, 362, 363, 364, 97 365, 366, 367, 368, 369, 370, 371, 372, 98 373, 374, 375, 376, 377, 378 99 }; 100 101 static const FT_UShort cff_expertsubset_charset[87] = 102 { 103 0, 1, 231, 232, 235, 236, 237, 238, 104 13, 14, 15, 99, 239, 240, 241, 242, 105 243, 244, 245, 246, 247, 248, 27, 28, 106 249, 250, 251, 253, 254, 255, 256, 257, 107 258, 259, 260, 261, 262, 263, 264, 265, 108 266, 109, 110, 267, 268, 269, 270, 272, 109 300, 301, 302, 305, 314, 315, 158, 155, 110 163, 320, 321, 322, 323, 324, 325, 326, 111 150, 164, 169, 327, 328, 329, 330, 331, 112 332, 333, 334, 335, 336, 337, 338, 339, 113 340, 341, 342, 343, 344, 345, 346 114 }; 115 116 static const FT_UShort cff_standard_encoding[256] = 117 { 118 0, 0, 0, 0, 0, 0, 0, 0, 119 0, 0, 0, 0, 0, 0, 0, 0, 120 0, 0, 0, 0, 0, 0, 0, 0, 121 0, 0, 0, 0, 0, 0, 0, 0, 122 1, 2, 3, 4, 5, 6, 7, 8, 123 9, 10, 11, 12, 13, 14, 15, 16, 124 17, 18, 19, 20, 21, 22, 23, 24, 125 25, 26, 27, 28, 29, 30, 31, 32, 126 33, 34, 35, 36, 37, 38, 39, 40, 127 41, 42, 43, 44, 45, 46, 47, 48, 128 49, 50, 51, 52, 53, 54, 55, 56, 129 57, 58, 59, 60, 61, 62, 63, 64, 130 65, 66, 67, 68, 69, 70, 71, 72, 131 73, 74, 75, 76, 77, 78, 79, 80, 132 81, 82, 83, 84, 85, 86, 87, 88, 133 89, 90, 91, 92, 93, 94, 95, 0, 134 0, 0, 0, 0, 0, 0, 0, 0, 135 0, 0, 0, 0, 0, 0, 0, 0, 136 0, 0, 0, 0, 0, 0, 0, 0, 137 0, 0, 0, 0, 0, 0, 0, 0, 138 0, 96, 97, 98, 99, 100, 101, 102, 139 103, 104, 105, 106, 107, 108, 109, 110, 140 0, 111, 112, 113, 114, 0, 115, 116, 141 117, 118, 119, 120, 121, 122, 0, 123, 142 0, 124, 125, 126, 127, 128, 129, 130, 143 131, 0, 132, 133, 0, 134, 135, 136, 144 137, 0, 0, 0, 0, 0, 0, 0, 145 0, 0, 0, 0, 0, 0, 0, 0, 146 0, 138, 0, 139, 0, 0, 0, 0, 147 140, 141, 142, 143, 0, 0, 0, 0, 148 0, 144, 0, 0, 0, 145, 0, 0, 149 146, 147, 148, 149, 0, 0, 0, 0 150 }; 151 152 static const FT_UShort cff_expert_encoding[256] = 153 { 154 0, 0, 0, 0, 0, 0, 0, 0, 155 0, 0, 0, 0, 0, 0, 0, 0, 156 0, 0, 0, 0, 0, 0, 0, 0, 157 0, 0, 0, 0, 0, 0, 0, 0, 158 1, 229, 230, 0, 231, 232, 233, 234, 159 235, 236, 237, 238, 13, 14, 15, 99, 160 239, 240, 241, 242, 243, 244, 245, 246, 161 247, 248, 27, 28, 249, 250, 251, 252, 162 0, 253, 254, 255, 256, 257, 0, 0, 163 0, 258, 0, 0, 259, 260, 261, 262, 164 0, 0, 263, 264, 265, 0, 266, 109, 165 110, 267, 268, 269, 0, 270, 271, 272, 166 273, 274, 275, 276, 277, 278, 279, 280, 167 281, 282, 283, 284, 285, 286, 287, 288, 168 289, 290, 291, 292, 293, 294, 295, 296, 169 297, 298, 299, 300, 301, 302, 303, 0, 170 0, 0, 0, 0, 0, 0, 0, 0, 171 0, 0, 0, 0, 0, 0, 0, 0, 172 0, 0, 0, 0, 0, 0, 0, 0, 173 0, 0, 0, 0, 0, 0, 0, 0, 174 0, 304, 305, 306, 0, 0, 307, 308, 175 309, 310, 311, 0, 312, 0, 0, 312, 176 0, 0, 314, 315, 0, 0, 316, 317, 177 318, 0, 0, 0, 158, 155, 163, 319, 178 320, 321, 322, 323, 324, 325, 0, 0, 179 326, 150, 164, 169, 327, 328, 329, 330, 180 331, 332, 333, 334, 335, 336, 337, 338, 181 339, 340, 341, 342, 343, 344, 345, 346, 182 347, 348, 349, 350, 351, 352, 353, 354, 183 355, 356, 357, 358, 359, 360, 361, 362, 184 363, 364, 365, 366, 367, 368, 369, 370, 185 371, 372, 373, 374, 375, 376, 377, 378 186 }; 187 188 #endif /* 1 */ 189 190 191 FT_LOCAL_DEF( FT_UShort ) cff_get_standard_encoding(FT_UInt charcode)192 cff_get_standard_encoding( FT_UInt charcode ) 193 { 194 return (FT_UShort)( charcode < 256 ? cff_standard_encoding[charcode] 195 : 0 ); 196 } 197 198 199 /*************************************************************************/ 200 /* */ 201 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 202 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 203 /* messages during execution. */ 204 /* */ 205 #undef FT_COMPONENT 206 #define FT_COMPONENT trace_cffload 207 208 209 /* read an offset from the index's stream current position */ 210 static FT_ULong cff_index_read_offset(CFF_Index idx,FT_Error * errorp)211 cff_index_read_offset( CFF_Index idx, 212 FT_Error *errorp ) 213 { 214 FT_Error error; 215 FT_Stream stream = idx->stream; 216 FT_Byte tmp[4]; 217 FT_ULong result = 0; 218 219 220 if ( !FT_STREAM_READ( tmp, idx->off_size ) ) 221 { 222 FT_Int nn; 223 224 225 for ( nn = 0; nn < idx->off_size; nn++ ) 226 result = ( result << 8 ) | tmp[nn]; 227 } 228 229 *errorp = error; 230 return result; 231 } 232 233 234 static FT_Error cff_index_init(CFF_Index idx,FT_Stream stream,FT_Bool load,FT_Bool cff2)235 cff_index_init( CFF_Index idx, 236 FT_Stream stream, 237 FT_Bool load, 238 FT_Bool cff2 ) 239 { 240 FT_Error error; 241 FT_Memory memory = stream->memory; 242 FT_UInt count; 243 244 245 FT_ZERO( idx ); 246 247 idx->stream = stream; 248 idx->start = FT_STREAM_POS(); 249 250 if ( cff2 ) 251 { 252 if ( FT_READ_ULONG( count ) ) 253 goto Exit; 254 idx->hdr_size = 5; 255 } 256 else 257 { 258 if ( FT_READ_USHORT( count ) ) 259 goto Exit; 260 idx->hdr_size = 3; 261 } 262 263 if ( count > 0 ) 264 { 265 FT_Byte offsize; 266 FT_ULong size; 267 268 269 /* there is at least one element; read the offset size, */ 270 /* then access the offset table to compute the index's total size */ 271 if ( FT_READ_BYTE( offsize ) ) 272 goto Exit; 273 274 if ( offsize < 1 || offsize > 4 ) 275 { 276 error = FT_THROW( Invalid_Table ); 277 goto Exit; 278 } 279 280 idx->count = count; 281 idx->off_size = offsize; 282 size = (FT_ULong)( count + 1 ) * offsize; 283 284 idx->data_offset = idx->start + idx->hdr_size + size; 285 286 if ( FT_STREAM_SKIP( size - offsize ) ) 287 goto Exit; 288 289 size = cff_index_read_offset( idx, &error ); 290 if ( error ) 291 goto Exit; 292 293 if ( size == 0 ) 294 { 295 error = FT_THROW( Invalid_Table ); 296 goto Exit; 297 } 298 299 idx->data_size = --size; 300 301 if ( load ) 302 { 303 /* load the data */ 304 if ( FT_FRAME_EXTRACT( size, idx->bytes ) ) 305 goto Exit; 306 } 307 else 308 { 309 /* skip the data */ 310 if ( FT_STREAM_SKIP( size ) ) 311 goto Exit; 312 } 313 } 314 315 Exit: 316 if ( error ) 317 FT_FREE( idx->offsets ); 318 319 return error; 320 } 321 322 323 static void cff_index_done(CFF_Index idx)324 cff_index_done( CFF_Index idx ) 325 { 326 if ( idx->stream ) 327 { 328 FT_Stream stream = idx->stream; 329 FT_Memory memory = stream->memory; 330 331 332 if ( idx->bytes ) 333 FT_FRAME_RELEASE( idx->bytes ); 334 335 FT_FREE( idx->offsets ); 336 FT_ZERO( idx ); 337 } 338 } 339 340 341 static FT_Error cff_index_load_offsets(CFF_Index idx)342 cff_index_load_offsets( CFF_Index idx ) 343 { 344 FT_Error error = FT_Err_Ok; 345 FT_Stream stream = idx->stream; 346 FT_Memory memory = stream->memory; 347 348 349 if ( idx->count > 0 && !idx->offsets ) 350 { 351 FT_Byte offsize = idx->off_size; 352 FT_ULong data_size; 353 FT_Byte* p; 354 FT_Byte* p_end; 355 FT_ULong* poff; 356 357 358 data_size = (FT_ULong)( idx->count + 1 ) * offsize; 359 360 if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) || 361 FT_STREAM_SEEK( idx->start + idx->hdr_size ) || 362 FT_FRAME_ENTER( data_size ) ) 363 goto Exit; 364 365 poff = idx->offsets; 366 p = (FT_Byte*)stream->cursor; 367 p_end = p + data_size; 368 369 switch ( offsize ) 370 { 371 case 1: 372 for ( ; p < p_end; p++, poff++ ) 373 poff[0] = p[0]; 374 break; 375 376 case 2: 377 for ( ; p < p_end; p += 2, poff++ ) 378 poff[0] = FT_PEEK_USHORT( p ); 379 break; 380 381 case 3: 382 for ( ; p < p_end; p += 3, poff++ ) 383 poff[0] = FT_PEEK_UOFF3( p ); 384 break; 385 386 default: 387 for ( ; p < p_end; p += 4, poff++ ) 388 poff[0] = FT_PEEK_ULONG( p ); 389 } 390 391 FT_FRAME_EXIT(); 392 } 393 394 Exit: 395 if ( error ) 396 FT_FREE( idx->offsets ); 397 398 return error; 399 } 400 401 402 /* Allocate a table containing pointers to an index's elements. */ 403 /* The `pool' argument makes this function convert the index */ 404 /* entries to C-style strings (this is, NULL-terminated). */ 405 static FT_Error cff_index_get_pointers(CFF_Index idx,FT_Byte *** table,FT_Byte ** pool,FT_ULong * pool_size)406 cff_index_get_pointers( CFF_Index idx, 407 FT_Byte*** table, 408 FT_Byte** pool, 409 FT_ULong* pool_size ) 410 { 411 FT_Error error = FT_Err_Ok; 412 FT_Memory memory = idx->stream->memory; 413 414 FT_Byte** t = NULL; 415 FT_Byte* new_bytes = NULL; 416 FT_ULong new_size; 417 418 419 *table = NULL; 420 421 if ( !idx->offsets ) 422 { 423 error = cff_index_load_offsets( idx ); 424 if ( error ) 425 goto Exit; 426 } 427 428 new_size = idx->data_size + idx->count; 429 430 if ( idx->count > 0 && 431 !FT_NEW_ARRAY( t, idx->count + 1 ) && 432 ( !pool || !FT_ALLOC( new_bytes, new_size ) ) ) 433 { 434 FT_ULong n, cur_offset; 435 FT_ULong extra = 0; 436 FT_Byte* org_bytes = idx->bytes; 437 438 439 /* at this point, `idx->offsets' can't be NULL */ 440 cur_offset = idx->offsets[0] - 1; 441 442 /* sanity check */ 443 if ( cur_offset != 0 ) 444 { 445 FT_TRACE0(( "cff_index_get_pointers:" 446 " invalid first offset value %d set to zero\n", 447 cur_offset )); 448 cur_offset = 0; 449 } 450 451 if ( !pool ) 452 t[0] = org_bytes + cur_offset; 453 else 454 t[0] = new_bytes + cur_offset; 455 456 for ( n = 1; n <= idx->count; n++ ) 457 { 458 FT_ULong next_offset = idx->offsets[n] - 1; 459 460 461 /* two sanity checks for invalid offset tables */ 462 if ( next_offset < cur_offset ) 463 next_offset = cur_offset; 464 else if ( next_offset > idx->data_size ) 465 next_offset = idx->data_size; 466 467 if ( !pool ) 468 t[n] = org_bytes + next_offset; 469 else 470 { 471 t[n] = new_bytes + next_offset + extra; 472 473 if ( next_offset != cur_offset ) 474 { 475 FT_MEM_COPY( t[n - 1], org_bytes + cur_offset, t[n] - t[n - 1] ); 476 t[n][0] = '\0'; 477 t[n] += 1; 478 extra++; 479 } 480 } 481 482 cur_offset = next_offset; 483 } 484 *table = t; 485 486 if ( pool ) 487 *pool = new_bytes; 488 if ( pool_size ) 489 *pool_size = new_size; 490 } 491 492 Exit: 493 return error; 494 } 495 496 497 FT_LOCAL_DEF( FT_Error ) cff_index_access_element(CFF_Index idx,FT_UInt element,FT_Byte ** pbytes,FT_ULong * pbyte_len)498 cff_index_access_element( CFF_Index idx, 499 FT_UInt element, 500 FT_Byte** pbytes, 501 FT_ULong* pbyte_len ) 502 { 503 FT_Error error = FT_Err_Ok; 504 505 506 if ( idx && idx->count > element ) 507 { 508 /* compute start and end offsets */ 509 FT_Stream stream = idx->stream; 510 FT_ULong off1, off2 = 0; 511 512 513 /* load offsets from file or the offset table */ 514 if ( !idx->offsets ) 515 { 516 FT_ULong pos = element * idx->off_size; 517 518 519 if ( FT_STREAM_SEEK( idx->start + idx->hdr_size + pos ) ) 520 goto Exit; 521 522 off1 = cff_index_read_offset( idx, &error ); 523 if ( error ) 524 goto Exit; 525 526 if ( off1 != 0 ) 527 { 528 do 529 { 530 element++; 531 off2 = cff_index_read_offset( idx, &error ); 532 533 } while ( off2 == 0 && element < idx->count ); 534 } 535 } 536 else /* use offsets table */ 537 { 538 off1 = idx->offsets[element]; 539 if ( off1 ) 540 { 541 do 542 { 543 element++; 544 off2 = idx->offsets[element]; 545 546 } while ( off2 == 0 && element < idx->count ); 547 } 548 } 549 550 /* XXX: should check off2 does not exceed the end of this entry; */ 551 /* at present, only truncate off2 at the end of this stream */ 552 if ( off2 > stream->size + 1 || 553 idx->data_offset > stream->size - off2 + 1 ) 554 { 555 FT_ERROR(( "cff_index_access_element:" 556 " offset to next entry (%d)" 557 " exceeds the end of stream (%d)\n", 558 off2, stream->size - idx->data_offset + 1 )); 559 off2 = stream->size - idx->data_offset + 1; 560 } 561 562 /* access element */ 563 if ( off1 && off2 > off1 ) 564 { 565 *pbyte_len = off2 - off1; 566 567 if ( idx->bytes ) 568 { 569 /* this index was completely loaded in memory, that's easy */ 570 *pbytes = idx->bytes + off1 - 1; 571 } 572 else 573 { 574 /* this index is still on disk/file, access it through a frame */ 575 if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) || 576 FT_FRAME_EXTRACT( off2 - off1, *pbytes ) ) 577 goto Exit; 578 } 579 } 580 else 581 { 582 /* empty index element */ 583 *pbytes = 0; 584 *pbyte_len = 0; 585 } 586 } 587 else 588 error = FT_THROW( Invalid_Argument ); 589 590 Exit: 591 return error; 592 } 593 594 595 FT_LOCAL_DEF( void ) cff_index_forget_element(CFF_Index idx,FT_Byte ** pbytes)596 cff_index_forget_element( CFF_Index idx, 597 FT_Byte** pbytes ) 598 { 599 if ( idx->bytes == 0 ) 600 { 601 FT_Stream stream = idx->stream; 602 603 604 FT_FRAME_RELEASE( *pbytes ); 605 } 606 } 607 608 609 /* get an entry from Name INDEX */ 610 FT_LOCAL_DEF( FT_String* ) cff_index_get_name(CFF_Font font,FT_UInt element)611 cff_index_get_name( CFF_Font font, 612 FT_UInt element ) 613 { 614 CFF_Index idx = &font->name_index; 615 FT_Memory memory; 616 FT_Byte* bytes; 617 FT_ULong byte_len; 618 FT_Error error; 619 FT_String* name = 0; 620 621 622 if ( !idx->stream ) /* CFF2 does not include a name index */ 623 goto Exit; 624 625 memory = idx->stream->memory; 626 627 error = cff_index_access_element( idx, element, &bytes, &byte_len ); 628 if ( error ) 629 goto Exit; 630 631 if ( !FT_ALLOC( name, byte_len + 1 ) ) 632 { 633 if ( byte_len ) 634 FT_MEM_COPY( name, bytes, byte_len ); 635 name[byte_len] = 0; 636 } 637 cff_index_forget_element( idx, &bytes ); 638 639 Exit: 640 return name; 641 } 642 643 644 /* get an entry from String INDEX */ 645 FT_LOCAL_DEF( FT_String* ) cff_index_get_string(CFF_Font font,FT_UInt element)646 cff_index_get_string( CFF_Font font, 647 FT_UInt element ) 648 { 649 return ( element < font->num_strings ) 650 ? (FT_String*)font->strings[element] 651 : NULL; 652 } 653 654 655 FT_LOCAL_DEF( FT_String* ) cff_index_get_sid_string(CFF_Font font,FT_UInt sid)656 cff_index_get_sid_string( CFF_Font font, 657 FT_UInt sid ) 658 { 659 /* value 0xFFFFU indicates a missing dictionary entry */ 660 if ( sid == 0xFFFFU ) 661 return NULL; 662 663 /* if it is not a standard string, return it */ 664 if ( sid > 390 ) 665 return cff_index_get_string( font, sid - 391 ); 666 667 /* CID-keyed CFF fonts don't have glyph names */ 668 if ( !font->psnames ) 669 return NULL; 670 671 /* this is a standard string */ 672 return (FT_String *)font->psnames->adobe_std_strings( sid ); 673 } 674 675 676 /*************************************************************************/ 677 /*************************************************************************/ 678 /*** ***/ 679 /*** FD Select table support ***/ 680 /*** ***/ 681 /*************************************************************************/ 682 /*************************************************************************/ 683 684 685 static void CFF_Done_FD_Select(CFF_FDSelect fdselect,FT_Stream stream)686 CFF_Done_FD_Select( CFF_FDSelect fdselect, 687 FT_Stream stream ) 688 { 689 if ( fdselect->data ) 690 FT_FRAME_RELEASE( fdselect->data ); 691 692 fdselect->data_size = 0; 693 fdselect->format = 0; 694 fdselect->range_count = 0; 695 } 696 697 698 static FT_Error CFF_Load_FD_Select(CFF_FDSelect fdselect,FT_UInt num_glyphs,FT_Stream stream,FT_ULong offset)699 CFF_Load_FD_Select( CFF_FDSelect fdselect, 700 FT_UInt num_glyphs, 701 FT_Stream stream, 702 FT_ULong offset ) 703 { 704 FT_Error error; 705 FT_Byte format; 706 FT_UInt num_ranges; 707 708 709 /* read format */ 710 if ( FT_STREAM_SEEK( offset ) || FT_READ_BYTE( format ) ) 711 goto Exit; 712 713 fdselect->format = format; 714 fdselect->cache_count = 0; /* clear cache */ 715 716 switch ( format ) 717 { 718 case 0: /* format 0, that's simple */ 719 fdselect->data_size = num_glyphs; 720 goto Load_Data; 721 722 case 3: /* format 3, a tad more complex */ 723 if ( FT_READ_USHORT( num_ranges ) ) 724 goto Exit; 725 726 if ( !num_ranges ) 727 { 728 FT_TRACE0(( "CFF_Load_FD_Select: empty FDSelect array\n" )); 729 error = FT_THROW( Invalid_File_Format ); 730 goto Exit; 731 } 732 733 fdselect->data_size = num_ranges * 3 + 2; 734 735 Load_Data: 736 if ( FT_FRAME_EXTRACT( fdselect->data_size, fdselect->data ) ) 737 goto Exit; 738 break; 739 740 default: /* hmm... that's wrong */ 741 error = FT_THROW( Invalid_File_Format ); 742 } 743 744 Exit: 745 return error; 746 } 747 748 749 FT_LOCAL_DEF( FT_Byte ) cff_fd_select_get(CFF_FDSelect fdselect,FT_UInt glyph_index)750 cff_fd_select_get( CFF_FDSelect fdselect, 751 FT_UInt glyph_index ) 752 { 753 FT_Byte fd = 0; 754 755 756 /* if there is no FDSelect, return zero */ 757 /* Note: CFF2 with just one Font Dict has no FDSelect */ 758 if ( !fdselect->data ) 759 goto Exit; 760 761 switch ( fdselect->format ) 762 { 763 case 0: 764 fd = fdselect->data[glyph_index]; 765 break; 766 767 case 3: 768 /* first, compare to the cache */ 769 if ( (FT_UInt)( glyph_index - fdselect->cache_first ) < 770 fdselect->cache_count ) 771 { 772 fd = fdselect->cache_fd; 773 break; 774 } 775 776 /* then, look up the ranges array */ 777 { 778 FT_Byte* p = fdselect->data; 779 FT_Byte* p_limit = p + fdselect->data_size; 780 FT_Byte fd2; 781 FT_UInt first, limit; 782 783 784 first = FT_NEXT_USHORT( p ); 785 do 786 { 787 if ( glyph_index < first ) 788 break; 789 790 fd2 = *p++; 791 limit = FT_NEXT_USHORT( p ); 792 793 if ( glyph_index < limit ) 794 { 795 fd = fd2; 796 797 /* update cache */ 798 fdselect->cache_first = first; 799 fdselect->cache_count = limit - first; 800 fdselect->cache_fd = fd2; 801 break; 802 } 803 first = limit; 804 805 } while ( p < p_limit ); 806 } 807 break; 808 809 default: 810 ; 811 } 812 813 Exit: 814 return fd; 815 } 816 817 818 /*************************************************************************/ 819 /*************************************************************************/ 820 /*** ***/ 821 /*** CFF font support ***/ 822 /*** ***/ 823 /*************************************************************************/ 824 /*************************************************************************/ 825 826 static FT_Error cff_charset_compute_cids(CFF_Charset charset,FT_UInt num_glyphs,FT_Memory memory)827 cff_charset_compute_cids( CFF_Charset charset, 828 FT_UInt num_glyphs, 829 FT_Memory memory ) 830 { 831 FT_Error error = FT_Err_Ok; 832 FT_UInt i; 833 FT_Long j; 834 FT_UShort max_cid = 0; 835 836 837 if ( charset->max_cid > 0 ) 838 goto Exit; 839 840 for ( i = 0; i < num_glyphs; i++ ) 841 { 842 if ( charset->sids[i] > max_cid ) 843 max_cid = charset->sids[i]; 844 } 845 846 if ( FT_NEW_ARRAY( charset->cids, (FT_ULong)max_cid + 1 ) ) 847 goto Exit; 848 849 /* When multiple GIDs map to the same CID, we choose the lowest */ 850 /* GID. This is not described in any spec, but it matches the */ 851 /* behaviour of recent Acroread versions. */ 852 for ( j = (FT_Long)num_glyphs - 1; j >= 0; j-- ) 853 charset->cids[charset->sids[j]] = (FT_UShort)j; 854 855 charset->max_cid = max_cid; 856 charset->num_glyphs = num_glyphs; 857 858 Exit: 859 return error; 860 } 861 862 863 FT_LOCAL_DEF( FT_UInt ) cff_charset_cid_to_gindex(CFF_Charset charset,FT_UInt cid)864 cff_charset_cid_to_gindex( CFF_Charset charset, 865 FT_UInt cid ) 866 { 867 FT_UInt result = 0; 868 869 870 if ( cid <= charset->max_cid ) 871 result = charset->cids[cid]; 872 873 return result; 874 } 875 876 877 static void cff_charset_free_cids(CFF_Charset charset,FT_Memory memory)878 cff_charset_free_cids( CFF_Charset charset, 879 FT_Memory memory ) 880 { 881 FT_FREE( charset->cids ); 882 charset->max_cid = 0; 883 } 884 885 886 static void cff_charset_done(CFF_Charset charset,FT_Stream stream)887 cff_charset_done( CFF_Charset charset, 888 FT_Stream stream ) 889 { 890 FT_Memory memory = stream->memory; 891 892 893 cff_charset_free_cids( charset, memory ); 894 895 FT_FREE( charset->sids ); 896 charset->format = 0; 897 charset->offset = 0; 898 } 899 900 901 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)902 cff_charset_load( CFF_Charset charset, 903 FT_UInt num_glyphs, 904 FT_Stream stream, 905 FT_ULong base_offset, 906 FT_ULong offset, 907 FT_Bool invert ) 908 { 909 FT_Memory memory = stream->memory; 910 FT_Error error = FT_Err_Ok; 911 FT_UShort glyph_sid; 912 913 914 /* If the offset is greater than 2, we have to parse the charset */ 915 /* table. */ 916 if ( offset > 2 ) 917 { 918 FT_UInt j; 919 920 921 charset->offset = base_offset + offset; 922 923 /* Get the format of the table. */ 924 if ( FT_STREAM_SEEK( charset->offset ) || 925 FT_READ_BYTE( charset->format ) ) 926 goto Exit; 927 928 /* Allocate memory for sids. */ 929 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) 930 goto Exit; 931 932 /* assign the .notdef glyph */ 933 charset->sids[0] = 0; 934 935 switch ( charset->format ) 936 { 937 case 0: 938 if ( num_glyphs > 0 ) 939 { 940 if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) ) 941 goto Exit; 942 943 for ( j = 1; j < num_glyphs; j++ ) 944 charset->sids[j] = FT_GET_USHORT(); 945 946 FT_FRAME_EXIT(); 947 } 948 break; 949 950 case 1: 951 case 2: 952 { 953 FT_UInt nleft; 954 FT_UInt i; 955 956 957 j = 1; 958 959 while ( j < num_glyphs ) 960 { 961 /* Read the first glyph sid of the range. */ 962 if ( FT_READ_USHORT( glyph_sid ) ) 963 goto Exit; 964 965 /* Read the number of glyphs in the range. */ 966 if ( charset->format == 2 ) 967 { 968 if ( FT_READ_USHORT( nleft ) ) 969 goto Exit; 970 } 971 else 972 { 973 if ( FT_READ_BYTE( nleft ) ) 974 goto Exit; 975 } 976 977 /* try to rescue some of the SIDs if `nleft' is too large */ 978 if ( glyph_sid > 0xFFFFL - nleft ) 979 { 980 FT_ERROR(( "cff_charset_load: invalid SID range trimmed" 981 " nleft=%d -> %d\n", nleft, 0xFFFFL - glyph_sid )); 982 nleft = ( FT_UInt )( 0xFFFFL - glyph_sid ); 983 } 984 985 /* Fill in the range of sids -- `nleft + 1' glyphs. */ 986 for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ ) 987 charset->sids[j] = glyph_sid; 988 } 989 } 990 break; 991 992 default: 993 FT_ERROR(( "cff_charset_load: invalid table format\n" )); 994 error = FT_THROW( Invalid_File_Format ); 995 goto Exit; 996 } 997 } 998 else 999 { 1000 /* Parse default tables corresponding to offset == 0, 1, or 2. */ 1001 /* CFF specification intimates the following: */ 1002 /* */ 1003 /* In order to use a predefined charset, the following must be */ 1004 /* true: The charset constructed for the glyphs in the font's */ 1005 /* charstrings dictionary must match the predefined charset in */ 1006 /* the first num_glyphs. */ 1007 1008 charset->offset = offset; /* record charset type */ 1009 1010 switch ( (FT_UInt)offset ) 1011 { 1012 case 0: 1013 if ( num_glyphs > 229 ) 1014 { 1015 FT_ERROR(( "cff_charset_load: implicit charset larger than\n" 1016 "predefined charset (Adobe ISO-Latin)\n" )); 1017 error = FT_THROW( Invalid_File_Format ); 1018 goto Exit; 1019 } 1020 1021 /* Allocate memory for sids. */ 1022 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) 1023 goto Exit; 1024 1025 /* Copy the predefined charset into the allocated memory. */ 1026 FT_ARRAY_COPY( charset->sids, cff_isoadobe_charset, num_glyphs ); 1027 1028 break; 1029 1030 case 1: 1031 if ( num_glyphs > 166 ) 1032 { 1033 FT_ERROR(( "cff_charset_load: implicit charset larger than\n" 1034 "predefined charset (Adobe Expert)\n" )); 1035 error = FT_THROW( Invalid_File_Format ); 1036 goto Exit; 1037 } 1038 1039 /* Allocate memory for sids. */ 1040 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) 1041 goto Exit; 1042 1043 /* Copy the predefined charset into the allocated memory. */ 1044 FT_ARRAY_COPY( charset->sids, cff_expert_charset, num_glyphs ); 1045 1046 break; 1047 1048 case 2: 1049 if ( num_glyphs > 87 ) 1050 { 1051 FT_ERROR(( "cff_charset_load: implicit charset larger than\n" 1052 "predefined charset (Adobe Expert Subset)\n" )); 1053 error = FT_THROW( Invalid_File_Format ); 1054 goto Exit; 1055 } 1056 1057 /* Allocate memory for sids. */ 1058 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) 1059 goto Exit; 1060 1061 /* Copy the predefined charset into the allocated memory. */ 1062 FT_ARRAY_COPY( charset->sids, cff_expertsubset_charset, num_glyphs ); 1063 1064 break; 1065 1066 default: 1067 error = FT_THROW( Invalid_File_Format ); 1068 goto Exit; 1069 } 1070 } 1071 1072 /* we have to invert the `sids' array for subsetted CID-keyed fonts */ 1073 if ( invert ) 1074 error = cff_charset_compute_cids( charset, num_glyphs, memory ); 1075 1076 Exit: 1077 /* Clean up if there was an error. */ 1078 if ( error ) 1079 { 1080 FT_FREE( charset->sids ); 1081 FT_FREE( charset->cids ); 1082 charset->format = 0; 1083 charset->offset = 0; 1084 charset->sids = 0; 1085 } 1086 1087 return error; 1088 } 1089 1090 1091 static void cff_vstore_done(CFF_VStoreRec * vstore,FT_Memory memory)1092 cff_vstore_done( CFF_VStoreRec* vstore, 1093 FT_Memory memory ) 1094 { 1095 FT_UInt i; 1096 1097 1098 /* free regionList and axisLists */ 1099 if ( vstore->varRegionList ) 1100 { 1101 for ( i = 0; i < vstore->regionCount; i++ ) 1102 FT_FREE( vstore->varRegionList[i].axisList ); 1103 } 1104 FT_FREE( vstore->varRegionList ); 1105 1106 /* free varData and indices */ 1107 if ( vstore->varData ) 1108 { 1109 for ( i = 0; i < vstore->dataCount; i++ ) 1110 FT_FREE( vstore->varData[i].regionIndices ); 1111 } 1112 FT_FREE( vstore->varData ); 1113 } 1114 1115 1116 /* convert 2.14 to Fixed */ 1117 #define FT_fdot14ToFixed( x ) ( (FT_Fixed)( (FT_ULong)(x) << 2 ) ) 1118 1119 1120 static FT_Error cff_vstore_load(CFF_VStoreRec * vstore,FT_Stream stream,FT_ULong base_offset,FT_ULong offset)1121 cff_vstore_load( CFF_VStoreRec* vstore, 1122 FT_Stream stream, 1123 FT_ULong base_offset, 1124 FT_ULong offset ) 1125 { 1126 FT_Memory memory = stream->memory; 1127 FT_Error error = FT_ERR( Invalid_File_Format ); 1128 1129 FT_ULong* dataOffsetArray = NULL; 1130 FT_UInt i, j; 1131 1132 1133 /* no offset means no vstore to parse */ 1134 if ( offset ) 1135 { 1136 FT_UInt vsOffset; 1137 FT_UInt format; 1138 FT_ULong regionListOffset; 1139 1140 1141 /* we need to parse the table to determine its size; */ 1142 /* skip table length */ 1143 if ( FT_STREAM_SEEK( base_offset + offset ) || 1144 FT_STREAM_SKIP( 2 ) ) 1145 goto Exit; 1146 1147 /* actual variation store begins after the length */ 1148 vsOffset = FT_STREAM_POS(); 1149 1150 /* check the header */ 1151 if ( FT_READ_USHORT( format ) ) 1152 goto Exit; 1153 if ( format != 1 ) 1154 { 1155 error = FT_THROW( Invalid_File_Format ); 1156 goto Exit; 1157 } 1158 1159 /* read top level fields */ 1160 if ( FT_READ_ULONG( regionListOffset ) || 1161 FT_READ_USHORT( vstore->dataCount ) ) 1162 goto Exit; 1163 1164 /* make temporary copy of item variation data offsets; */ 1165 /* we'll parse region list first, then come back */ 1166 if ( FT_NEW_ARRAY( dataOffsetArray, vstore->dataCount ) ) 1167 goto Exit; 1168 1169 for ( i = 0; i < vstore->dataCount; i++ ) 1170 { 1171 if ( FT_READ_ULONG( dataOffsetArray[i] ) ) 1172 goto Exit; 1173 } 1174 1175 /* parse regionList and axisLists */ 1176 if ( FT_STREAM_SEEK( vsOffset + regionListOffset ) || 1177 FT_READ_USHORT( vstore->axisCount ) || 1178 FT_READ_USHORT( vstore->regionCount ) ) 1179 goto Exit; 1180 1181 if ( FT_NEW_ARRAY( vstore->varRegionList, vstore->regionCount ) ) 1182 goto Exit; 1183 1184 for ( i = 0; i < vstore->regionCount; i++ ) 1185 { 1186 CFF_VarRegion* region = &vstore->varRegionList[i]; 1187 1188 1189 if ( FT_NEW_ARRAY( region->axisList, vstore->axisCount ) ) 1190 goto Exit; 1191 1192 for ( j = 0; j < vstore->axisCount; j++ ) 1193 { 1194 CFF_AxisCoords* axis = ®ion->axisList[j]; 1195 1196 FT_Int16 start14, peak14, end14; 1197 1198 1199 if ( FT_READ_SHORT( start14 ) || 1200 FT_READ_SHORT( peak14 ) || 1201 FT_READ_SHORT( end14 ) ) 1202 goto Exit; 1203 1204 axis->startCoord = FT_fdot14ToFixed( start14 ); 1205 axis->peakCoord = FT_fdot14ToFixed( peak14 ); 1206 axis->endCoord = FT_fdot14ToFixed( end14 ); 1207 } 1208 } 1209 1210 /* use dataOffsetArray now to parse varData items */ 1211 if ( FT_NEW_ARRAY( vstore->varData, vstore->dataCount ) ) 1212 goto Exit; 1213 1214 for ( i = 0; i < vstore->dataCount; i++ ) 1215 { 1216 CFF_VarData* data = &vstore->varData[i]; 1217 1218 1219 if ( FT_STREAM_SEEK( vsOffset + dataOffsetArray[i] ) ) 1220 goto Exit; 1221 1222 /* ignore `itemCount' and `shortDeltaCount' */ 1223 /* because CFF2 has no delta sets */ 1224 if ( FT_STREAM_SKIP( 4 ) ) 1225 goto Exit; 1226 1227 /* Note: just record values; consistency is checked later */ 1228 /* by cff_blend_build_vector when it consumes `vstore' */ 1229 1230 if ( FT_READ_USHORT( data->regionIdxCount ) ) 1231 goto Exit; 1232 1233 if ( FT_NEW_ARRAY( data->regionIndices, data->regionIdxCount ) ) 1234 goto Exit; 1235 1236 for ( j = 0; j < data->regionIdxCount; j++ ) 1237 { 1238 if ( FT_READ_USHORT( data->regionIndices[j] ) ) 1239 goto Exit; 1240 } 1241 } 1242 } 1243 1244 error = FT_Err_Ok; 1245 1246 Exit: 1247 FT_FREE( dataOffsetArray ); 1248 if ( error ) 1249 cff_vstore_done( vstore, memory ); 1250 1251 return error; 1252 } 1253 1254 1255 /* Clear blend stack (after blend values are consumed). */ 1256 /* */ 1257 /* TODO: Should do this in cff_run_parse, but subFont */ 1258 /* ref is not available there. */ 1259 /* */ 1260 /* Allocation is not changed when stack is cleared. */ 1261 FT_LOCAL_DEF( void ) cff_blend_clear(CFF_SubFont subFont)1262 cff_blend_clear( CFF_SubFont subFont ) 1263 { 1264 subFont->blend_top = subFont->blend_stack; 1265 subFont->blend_used = 0; 1266 } 1267 1268 1269 /* Blend numOperands on the stack, */ 1270 /* store results into the first numBlends values, */ 1271 /* then pop remaining arguments. */ 1272 /* */ 1273 /* This is comparable to `cf2_doBlend' but */ 1274 /* the cffparse stack is different and can't be written. */ 1275 /* Blended values are written to a different buffer, */ 1276 /* using reserved operator 255. */ 1277 /* */ 1278 /* Blend calculation is done in 16.16 fixed point. */ 1279 FT_LOCAL_DEF( FT_Error ) cff_blend_doBlend(CFF_SubFont subFont,CFF_Parser parser,FT_UInt numBlends)1280 cff_blend_doBlend( CFF_SubFont subFont, 1281 CFF_Parser parser, 1282 FT_UInt numBlends ) 1283 { 1284 FT_UInt delta; 1285 FT_UInt base; 1286 FT_UInt i, j; 1287 FT_UInt size; 1288 1289 CFF_Blend blend = &subFont->blend; 1290 1291 FT_Memory memory = subFont->blend.font->memory; /* for FT_REALLOC */ 1292 FT_Error error = FT_Err_Ok; /* for FT_REALLOC */ 1293 1294 /* compute expected number of operands for this blend */ 1295 FT_UInt numOperands = (FT_UInt)( numBlends * blend->lenBV ); 1296 FT_UInt count = (FT_UInt)( parser->top - 1 - parser->stack ); 1297 1298 1299 if ( numOperands > count ) 1300 { 1301 FT_TRACE4(( " cff_blend_doBlend: Stack underflow %d argument%s\n", 1302 count, 1303 count == 1 ? "" : "s" )); 1304 1305 error = FT_THROW( Stack_Underflow ); 1306 goto Exit; 1307 } 1308 1309 /* check whether we have room for `numBlends' values at `blend_top' */ 1310 size = 5 * numBlends; /* add 5 bytes per entry */ 1311 if ( subFont->blend_used + size > subFont->blend_alloc ) 1312 { 1313 FT_Byte* blend_stack_old = subFont->blend_stack; 1314 FT_Byte* blend_top_old = subFont->blend_top; 1315 1316 1317 /* increase or allocate `blend_stack' and reset `blend_top'; */ 1318 /* prepare to append `numBlends' values to the buffer */ 1319 if ( FT_REALLOC( subFont->blend_stack, 1320 subFont->blend_alloc, 1321 subFont->blend_alloc + size ) ) 1322 goto Exit; 1323 1324 subFont->blend_top = subFont->blend_stack + subFont->blend_used; 1325 subFont->blend_alloc += size; 1326 1327 /* iterate over the parser stack and adjust pointers */ 1328 /* if the reallocated buffer has a different address */ 1329 if ( blend_stack_old && 1330 subFont->blend_stack != blend_stack_old ) 1331 { 1332 FT_PtrDist offset = subFont->blend_stack - blend_stack_old; 1333 FT_Byte** p; 1334 1335 1336 for ( p = parser->stack; p < parser->top; p++ ) 1337 { 1338 if ( *p >= blend_stack_old && *p < blend_top_old ) 1339 *p += offset; 1340 } 1341 } 1342 } 1343 subFont->blend_used += size; 1344 1345 base = count - numOperands; /* index of first blend arg */ 1346 delta = base + numBlends; /* index of first delta arg */ 1347 1348 for ( i = 0; i < numBlends; i++ ) 1349 { 1350 const FT_Int32* weight = &blend->BV[1]; 1351 FT_UInt32 sum; 1352 1353 1354 /* convert inputs to 16.16 fixed point */ 1355 sum = cff_parse_num( parser, &parser->stack[i + base] ) * 0x10000; 1356 1357 for ( j = 1; j < blend->lenBV; j++ ) 1358 sum += cff_parse_num( parser, &parser->stack[delta++] ) * *weight++; 1359 1360 /* point parser stack to new value on blend_stack */ 1361 parser->stack[i + base] = subFont->blend_top; 1362 1363 /* Push blended result as Type 2 5-byte fixed point number. This */ 1364 /* will not conflict with actual DICTs because 255 is a reserved */ 1365 /* opcode in both CFF and CFF2 DICTs. See `cff_parse_num' for */ 1366 /* decode of this, which rounds to an integer. */ 1367 *subFont->blend_top++ = 255; 1368 *subFont->blend_top++ = (FT_Byte)( sum >> 24 ); 1369 *subFont->blend_top++ = (FT_Byte)( sum >> 16 ); 1370 *subFont->blend_top++ = (FT_Byte)( sum >> 8 ); 1371 *subFont->blend_top++ = (FT_Byte)sum; 1372 } 1373 1374 /* leave only numBlends results on parser stack */ 1375 parser->top = &parser->stack[base + numBlends]; 1376 1377 Exit: 1378 return error; 1379 } 1380 1381 1382 /* Compute a blend vector from variation store index and normalized */ 1383 /* vector based on pseudo-code in OpenType Font Variations Overview. */ 1384 /* */ 1385 /* Note: lenNDV == 0 produces a default blend vector, (1,0,0,...). */ 1386 FT_LOCAL_DEF( FT_Error ) cff_blend_build_vector(CFF_Blend blend,FT_UInt vsindex,FT_UInt lenNDV,FT_Fixed * NDV)1387 cff_blend_build_vector( CFF_Blend blend, 1388 FT_UInt vsindex, 1389 FT_UInt lenNDV, 1390 FT_Fixed* NDV ) 1391 { 1392 FT_Error error = FT_Err_Ok; /* for FT_REALLOC */ 1393 FT_Memory memory = blend->font->memory; /* for FT_REALLOC */ 1394 1395 FT_UInt len; 1396 CFF_VStore vs; 1397 CFF_VarData* varData; 1398 FT_UInt master; 1399 1400 1401 FT_ASSERT( lenNDV == 0 || NDV ); 1402 1403 blend->builtBV = FALSE; 1404 1405 vs = &blend->font->vstore; 1406 1407 /* VStore and fvar must be consistent */ 1408 if ( lenNDV != 0 && lenNDV != vs->axisCount ) 1409 { 1410 FT_TRACE4(( " cff_blend_build_vector: Axis count mismatch\n" )); 1411 error = FT_THROW( Invalid_File_Format ); 1412 goto Exit; 1413 } 1414 1415 if ( vsindex >= vs->dataCount ) 1416 { 1417 FT_TRACE4(( " cff_blend_build_vector: vsindex out of range\n" )); 1418 error = FT_THROW( Invalid_File_Format ); 1419 goto Exit; 1420 } 1421 1422 /* select the item variation data structure */ 1423 varData = &vs->varData[vsindex]; 1424 1425 /* prepare buffer for the blend vector */ 1426 len = varData->regionIdxCount + 1; /* add 1 for default component */ 1427 if ( FT_REALLOC( blend->BV, 1428 blend->lenBV * sizeof( *blend->BV ), 1429 len * sizeof( *blend->BV ) ) ) 1430 goto Exit; 1431 1432 blend->lenBV = len; 1433 1434 /* outer loop steps through master designs to be blended */ 1435 for ( master = 0; master < len; master++ ) 1436 { 1437 FT_UInt j; 1438 FT_UInt idx; 1439 CFF_VarRegion* varRegion; 1440 1441 1442 /* default factor is always one */ 1443 if ( master == 0 ) 1444 { 1445 blend->BV[master] = FT_FIXED_ONE; 1446 FT_TRACE4(( " build blend vector len %d\n" 1447 " [ %f ", 1448 len, 1449 blend->BV[master] / 65536.0 )); 1450 continue; 1451 } 1452 1453 /* VStore array does not include default master, so subtract one */ 1454 idx = varData->regionIndices[master - 1]; 1455 varRegion = &vs->varRegionList[idx]; 1456 1457 if ( idx >= vs->regionCount ) 1458 { 1459 FT_TRACE4(( " cff_blend_build_vector:" 1460 " region index out of range\n" )); 1461 error = FT_THROW( Invalid_File_Format ); 1462 goto Exit; 1463 } 1464 1465 /* Note: `lenNDV' could be zero. */ 1466 /* In that case, build default blend vector (1,0,0...). */ 1467 if ( !lenNDV ) 1468 { 1469 blend->BV[master] = 0; 1470 continue; 1471 } 1472 1473 /* In the normal case, initialize each component to 1 */ 1474 /* before inner loop. */ 1475 blend->BV[master] = FT_FIXED_ONE; /* default */ 1476 1477 /* inner loop steps through axes in this region */ 1478 for ( j = 0; j < lenNDV; j++ ) 1479 { 1480 CFF_AxisCoords* axis = &varRegion->axisList[j]; 1481 FT_Fixed axisScalar; 1482 1483 1484 /* compute the scalar contribution of this axis; */ 1485 /* ignore invalid ranges */ 1486 if ( axis->startCoord > axis->peakCoord || 1487 axis->peakCoord > axis->endCoord ) 1488 axisScalar = FT_FIXED_ONE; 1489 1490 else if ( axis->startCoord < 0 && 1491 axis->endCoord > 0 && 1492 axis->peakCoord != 0 ) 1493 axisScalar = FT_FIXED_ONE; 1494 1495 /* peak of 0 means ignore this axis */ 1496 else if ( axis->peakCoord == 0 ) 1497 axisScalar = FT_FIXED_ONE; 1498 1499 /* ignore this region if coords are out of range */ 1500 else if ( NDV[j] < axis->startCoord || 1501 NDV[j] > axis->endCoord ) 1502 axisScalar = 0; 1503 1504 /* calculate a proportional factor */ 1505 else 1506 { 1507 if ( NDV[j] == axis->peakCoord ) 1508 axisScalar = FT_FIXED_ONE; 1509 else if ( NDV[j] < axis->peakCoord ) 1510 axisScalar = FT_DivFix( NDV[j] - axis->startCoord, 1511 axis->peakCoord - axis->startCoord ); 1512 else 1513 axisScalar = FT_DivFix( axis->endCoord - NDV[j], 1514 axis->endCoord - axis->peakCoord ); 1515 } 1516 1517 /* take product of all the axis scalars */ 1518 blend->BV[master] = FT_MulFix( blend->BV[master], axisScalar ); 1519 } 1520 1521 FT_TRACE4(( ", %f ", 1522 blend->BV[master] / 65536.0 )); 1523 } 1524 1525 FT_TRACE4(( "]\n" )); 1526 1527 /* record the parameters used to build the blend vector */ 1528 blend->lastVsindex = vsindex; 1529 1530 if ( lenNDV != 0 ) 1531 { 1532 /* user has set a normalized vector */ 1533 if ( FT_REALLOC( blend->lastNDV, 1534 blend->lenNDV * sizeof ( *NDV ), 1535 lenNDV * sizeof ( *NDV ) ) ) 1536 goto Exit; 1537 1538 FT_MEM_COPY( blend->lastNDV, 1539 NDV, 1540 lenNDV * sizeof ( *NDV ) ); 1541 } 1542 1543 blend->lenNDV = lenNDV; 1544 blend->builtBV = TRUE; 1545 1546 Exit: 1547 return error; 1548 } 1549 1550 1551 /* `lenNDV' is zero for default vector; */ 1552 /* return TRUE if blend vector needs to be built. */ 1553 FT_LOCAL_DEF( FT_Bool ) cff_blend_check_vector(CFF_Blend blend,FT_UInt vsindex,FT_UInt lenNDV,FT_Fixed * NDV)1554 cff_blend_check_vector( CFF_Blend blend, 1555 FT_UInt vsindex, 1556 FT_UInt lenNDV, 1557 FT_Fixed* NDV ) 1558 { 1559 if ( !blend->builtBV || 1560 blend->lastVsindex != vsindex || 1561 blend->lenNDV != lenNDV || 1562 ( lenNDV && 1563 ft_memcmp( NDV, 1564 blend->lastNDV, 1565 lenNDV * sizeof ( *NDV ) ) != 0 ) ) 1566 { 1567 /* need to build blend vector */ 1568 return TRUE; 1569 } 1570 1571 return FALSE; 1572 } 1573 1574 1575 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 1576 1577 FT_LOCAL_DEF( FT_Error ) cff_get_var_blend(CFF_Face face,FT_UInt * num_coords,FT_Fixed ** coords,FT_Fixed ** normalizedcoords,FT_MM_Var ** mm_var)1578 cff_get_var_blend( CFF_Face face, 1579 FT_UInt *num_coords, 1580 FT_Fixed* *coords, 1581 FT_Fixed* *normalizedcoords, 1582 FT_MM_Var* *mm_var ) 1583 { 1584 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; 1585 1586 1587 return mm->get_var_blend( FT_FACE( face ), 1588 num_coords, 1589 coords, 1590 normalizedcoords, 1591 mm_var ); 1592 } 1593 1594 1595 FT_LOCAL_DEF( void ) cff_done_blend(CFF_Face face)1596 cff_done_blend( CFF_Face face ) 1597 { 1598 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; 1599 1600 1601 if (mm) 1602 mm->done_blend( FT_FACE( face ) ); 1603 } 1604 1605 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ 1606 1607 1608 static void cff_encoding_done(CFF_Encoding encoding)1609 cff_encoding_done( CFF_Encoding encoding ) 1610 { 1611 encoding->format = 0; 1612 encoding->offset = 0; 1613 encoding->count = 0; 1614 } 1615 1616 1617 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)1618 cff_encoding_load( CFF_Encoding encoding, 1619 CFF_Charset charset, 1620 FT_UInt num_glyphs, 1621 FT_Stream stream, 1622 FT_ULong base_offset, 1623 FT_ULong offset ) 1624 { 1625 FT_Error error = FT_Err_Ok; 1626 FT_UInt count; 1627 FT_UInt j; 1628 FT_UShort glyph_sid; 1629 FT_UInt glyph_code; 1630 1631 1632 /* Check for charset->sids. If we do not have this, we fail. */ 1633 if ( !charset->sids ) 1634 { 1635 error = FT_THROW( Invalid_File_Format ); 1636 goto Exit; 1637 } 1638 1639 /* Zero out the code to gid/sid mappings. */ 1640 for ( j = 0; j < 256; j++ ) 1641 { 1642 encoding->sids [j] = 0; 1643 encoding->codes[j] = 0; 1644 } 1645 1646 /* Note: The encoding table in a CFF font is indexed by glyph index; */ 1647 /* the first encoded glyph index is 1. Hence, we read the character */ 1648 /* code (`glyph_code') at index j and make the assignment: */ 1649 /* */ 1650 /* encoding->codes[glyph_code] = j + 1 */ 1651 /* */ 1652 /* We also make the assignment: */ 1653 /* */ 1654 /* encoding->sids[glyph_code] = charset->sids[j + 1] */ 1655 /* */ 1656 /* This gives us both a code to GID and a code to SID mapping. */ 1657 1658 if ( offset > 1 ) 1659 { 1660 encoding->offset = base_offset + offset; 1661 1662 /* we need to parse the table to determine its size */ 1663 if ( FT_STREAM_SEEK( encoding->offset ) || 1664 FT_READ_BYTE( encoding->format ) || 1665 FT_READ_BYTE( count ) ) 1666 goto Exit; 1667 1668 switch ( encoding->format & 0x7F ) 1669 { 1670 case 0: 1671 { 1672 FT_Byte* p; 1673 1674 1675 /* By convention, GID 0 is always ".notdef" and is never */ 1676 /* coded in the font. Hence, the number of codes found */ 1677 /* in the table is `count+1'. */ 1678 /* */ 1679 encoding->count = count + 1; 1680 1681 if ( FT_FRAME_ENTER( count ) ) 1682 goto Exit; 1683 1684 p = (FT_Byte*)stream->cursor; 1685 1686 for ( j = 1; j <= count; j++ ) 1687 { 1688 glyph_code = *p++; 1689 1690 /* Make sure j is not too big. */ 1691 if ( j < num_glyphs ) 1692 { 1693 /* Assign code to GID mapping. */ 1694 encoding->codes[glyph_code] = (FT_UShort)j; 1695 1696 /* Assign code to SID mapping. */ 1697 encoding->sids[glyph_code] = charset->sids[j]; 1698 } 1699 } 1700 1701 FT_FRAME_EXIT(); 1702 } 1703 break; 1704 1705 case 1: 1706 { 1707 FT_UInt nleft; 1708 FT_UInt i = 1; 1709 FT_UInt k; 1710 1711 1712 encoding->count = 0; 1713 1714 /* Parse the Format1 ranges. */ 1715 for ( j = 0; j < count; j++, i += nleft ) 1716 { 1717 /* Read the first glyph code of the range. */ 1718 if ( FT_READ_BYTE( glyph_code ) ) 1719 goto Exit; 1720 1721 /* Read the number of codes in the range. */ 1722 if ( FT_READ_BYTE( nleft ) ) 1723 goto Exit; 1724 1725 /* Increment nleft, so we read `nleft + 1' codes/sids. */ 1726 nleft++; 1727 1728 /* compute max number of character codes */ 1729 if ( (FT_UInt)nleft > encoding->count ) 1730 encoding->count = nleft; 1731 1732 /* Fill in the range of codes/sids. */ 1733 for ( k = i; k < nleft + i; k++, glyph_code++ ) 1734 { 1735 /* Make sure k is not too big. */ 1736 if ( k < num_glyphs && glyph_code < 256 ) 1737 { 1738 /* Assign code to GID mapping. */ 1739 encoding->codes[glyph_code] = (FT_UShort)k; 1740 1741 /* Assign code to SID mapping. */ 1742 encoding->sids[glyph_code] = charset->sids[k]; 1743 } 1744 } 1745 } 1746 1747 /* simple check; one never knows what can be found in a font */ 1748 if ( encoding->count > 256 ) 1749 encoding->count = 256; 1750 } 1751 break; 1752 1753 default: 1754 FT_ERROR(( "cff_encoding_load: invalid table format\n" )); 1755 error = FT_THROW( Invalid_File_Format ); 1756 goto Exit; 1757 } 1758 1759 /* Parse supplemental encodings, if any. */ 1760 if ( encoding->format & 0x80 ) 1761 { 1762 FT_UInt gindex; 1763 1764 1765 /* count supplements */ 1766 if ( FT_READ_BYTE( count ) ) 1767 goto Exit; 1768 1769 for ( j = 0; j < count; j++ ) 1770 { 1771 /* Read supplemental glyph code. */ 1772 if ( FT_READ_BYTE( glyph_code ) ) 1773 goto Exit; 1774 1775 /* Read the SID associated with this glyph code. */ 1776 if ( FT_READ_USHORT( glyph_sid ) ) 1777 goto Exit; 1778 1779 /* Assign code to SID mapping. */ 1780 encoding->sids[glyph_code] = glyph_sid; 1781 1782 /* First, look up GID which has been assigned to */ 1783 /* SID glyph_sid. */ 1784 for ( gindex = 0; gindex < num_glyphs; gindex++ ) 1785 { 1786 if ( charset->sids[gindex] == glyph_sid ) 1787 { 1788 encoding->codes[glyph_code] = (FT_UShort)gindex; 1789 break; 1790 } 1791 } 1792 } 1793 } 1794 } 1795 else 1796 { 1797 /* We take into account the fact a CFF font can use a predefined */ 1798 /* encoding without containing all of the glyphs encoded by this */ 1799 /* encoding (see the note at the end of section 12 in the CFF */ 1800 /* specification). */ 1801 1802 switch ( (FT_UInt)offset ) 1803 { 1804 case 0: 1805 /* First, copy the code to SID mapping. */ 1806 FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 ); 1807 goto Populate; 1808 1809 case 1: 1810 /* First, copy the code to SID mapping. */ 1811 FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 ); 1812 1813 Populate: 1814 /* Construct code to GID mapping from code to SID mapping */ 1815 /* and charset. */ 1816 1817 encoding->count = 0; 1818 1819 error = cff_charset_compute_cids( charset, num_glyphs, 1820 stream->memory ); 1821 if ( error ) 1822 goto Exit; 1823 1824 for ( j = 0; j < 256; j++ ) 1825 { 1826 FT_UInt sid = encoding->sids[j]; 1827 FT_UInt gid = 0; 1828 1829 1830 if ( sid ) 1831 gid = cff_charset_cid_to_gindex( charset, sid ); 1832 1833 if ( gid != 0 ) 1834 { 1835 encoding->codes[j] = (FT_UShort)gid; 1836 encoding->count = j + 1; 1837 } 1838 else 1839 { 1840 encoding->codes[j] = 0; 1841 encoding->sids [j] = 0; 1842 } 1843 } 1844 break; 1845 1846 default: 1847 FT_ERROR(( "cff_encoding_load: invalid table format\n" )); 1848 error = FT_THROW( Invalid_File_Format ); 1849 goto Exit; 1850 } 1851 } 1852 1853 Exit: 1854 1855 /* Clean up if there was an error. */ 1856 return error; 1857 } 1858 1859 1860 /* Parse private dictionary; first call is always from `cff_face_init', */ 1861 /* so NDV has not been set for CFF2 variation. */ 1862 /* */ 1863 /* `cff_slot_load' must call this function each time NDV changes. */ 1864 FT_LOCAL_DEF( FT_Error ) cff_load_private_dict(CFF_Font font,CFF_SubFont subfont,FT_UInt lenNDV,FT_Fixed * NDV)1865 cff_load_private_dict( CFF_Font font, 1866 CFF_SubFont subfont, 1867 FT_UInt lenNDV, 1868 FT_Fixed* NDV ) 1869 { 1870 FT_Error error = FT_Err_Ok; 1871 CFF_ParserRec parser; 1872 CFF_FontRecDict top = &subfont->font_dict; 1873 CFF_Private priv = &subfont->private_dict; 1874 FT_Stream stream = font->stream; 1875 FT_UInt stackSize; 1876 1877 1878 /* store handle needed to access memory, vstore for blend; */ 1879 /* we need this for clean-up even if there is no private DICT */ 1880 subfont->blend.font = font; 1881 subfont->blend.usedBV = FALSE; /* clear state */ 1882 1883 if ( !top->private_offset || !top->private_size ) 1884 goto Exit2; /* no private DICT, do nothing */ 1885 1886 /* set defaults */ 1887 FT_ZERO( priv ); 1888 1889 priv->blue_shift = 7; 1890 priv->blue_fuzz = 1; 1891 priv->lenIV = -1; 1892 priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); 1893 priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 ); 1894 1895 /* provide inputs for blend calculations */ 1896 priv->subfont = subfont; 1897 subfont->lenNDV = lenNDV; 1898 subfont->NDV = NDV; 1899 1900 /* add 1 for the operator */ 1901 stackSize = font->cff2 ? font->top_font.font_dict.maxstack + 1 1902 : CFF_MAX_STACK_DEPTH + 1; 1903 1904 if ( cff_parser_init( &parser, 1905 font->cff2 ? CFF2_CODE_PRIVATE : CFF_CODE_PRIVATE, 1906 priv, 1907 font->library, 1908 stackSize, 1909 top->num_designs, 1910 top->num_axes ) ) 1911 goto Exit; 1912 1913 if ( FT_STREAM_SEEK( font->base_offset + top->private_offset ) || 1914 FT_FRAME_ENTER( top->private_size ) ) 1915 goto Exit; 1916 1917 FT_TRACE4(( " private dictionary:\n" )); 1918 error = cff_parser_run( &parser, 1919 (FT_Byte*)stream->cursor, 1920 (FT_Byte*)stream->limit ); 1921 FT_FRAME_EXIT(); 1922 1923 if ( error ) 1924 goto Exit; 1925 1926 /* ensure that `num_blue_values' is even */ 1927 priv->num_blue_values &= ~1; 1928 1929 /* sanitize `initialRandomSeed' to be a positive value, if necessary; */ 1930 /* this is not mandated by the specification but by our implementation */ 1931 if ( priv->initial_random_seed < 0 ) 1932 priv->initial_random_seed = -priv->initial_random_seed; 1933 else if ( priv->initial_random_seed == 0 ) 1934 priv->initial_random_seed = 987654321; 1935 1936 Exit: 1937 /* clean up */ 1938 cff_blend_clear( subfont ); /* clear blend stack */ 1939 cff_parser_done( &parser ); /* free parser stack */ 1940 1941 Exit2: 1942 /* no clean up (parser not initialized) */ 1943 return error; 1944 } 1945 1946 1947 /* There are 3 ways to call this function, distinguished by code. */ 1948 /* */ 1949 /* . CFF_CODE_TOPDICT for either a CFF Top DICT or a CFF Font DICT */ 1950 /* . CFF2_CODE_TOPDICT for CFF2 Top DICT */ 1951 /* . CFF2_CODE_FONTDICT for CFF2 Font DICT */ 1952 1953 static FT_Error cff_subfont_load(CFF_SubFont subfont,CFF_Index idx,FT_UInt font_index,FT_Stream stream,FT_ULong base_offset,FT_UInt code,CFF_Font font,CFF_Face face)1954 cff_subfont_load( CFF_SubFont subfont, 1955 CFF_Index idx, 1956 FT_UInt font_index, 1957 FT_Stream stream, 1958 FT_ULong base_offset, 1959 FT_UInt code, 1960 CFF_Font font, 1961 CFF_Face face ) 1962 { 1963 FT_Error error; 1964 CFF_ParserRec parser; 1965 FT_Byte* dict = NULL; 1966 FT_ULong dict_len; 1967 CFF_FontRecDict top = &subfont->font_dict; 1968 CFF_Private priv = &subfont->private_dict; 1969 1970 PSAux_Service psaux = (PSAux_Service)face->psaux; 1971 1972 FT_Bool cff2 = FT_BOOL( code == CFF2_CODE_TOPDICT || 1973 code == CFF2_CODE_FONTDICT ); 1974 FT_UInt stackSize = cff2 ? CFF2_DEFAULT_STACK 1975 : CFF_MAX_STACK_DEPTH; 1976 1977 1978 /* Note: We use default stack size for CFF2 Font DICT because */ 1979 /* Top and Font DICTs are not allowed to have blend operators. */ 1980 error = cff_parser_init( &parser, 1981 code, 1982 &subfont->font_dict, 1983 font->library, 1984 stackSize, 1985 0, 1986 0 ); 1987 if ( error ) 1988 goto Exit; 1989 1990 /* set defaults */ 1991 FT_ZERO( top ); 1992 1993 top->underline_position = -( 100L << 16 ); 1994 top->underline_thickness = 50L << 16; 1995 top->charstring_type = 2; 1996 top->font_matrix.xx = 0x10000L; 1997 top->font_matrix.yy = 0x10000L; 1998 top->cid_count = 8720; 1999 2000 /* we use the implementation specific SID value 0xFFFF to indicate */ 2001 /* missing entries */ 2002 top->version = 0xFFFFU; 2003 top->notice = 0xFFFFU; 2004 top->copyright = 0xFFFFU; 2005 top->full_name = 0xFFFFU; 2006 top->family_name = 0xFFFFU; 2007 top->weight = 0xFFFFU; 2008 top->embedded_postscript = 0xFFFFU; 2009 2010 top->cid_registry = 0xFFFFU; 2011 top->cid_ordering = 0xFFFFU; 2012 top->cid_font_name = 0xFFFFU; 2013 2014 /* set default stack size */ 2015 top->maxstack = cff2 ? CFF2_DEFAULT_STACK : 48; 2016 2017 if ( idx->count ) /* count is nonzero for a real index */ 2018 error = cff_index_access_element( idx, font_index, &dict, &dict_len ); 2019 else 2020 { 2021 /* CFF2 has a fake top dict index; */ 2022 /* simulate `cff_index_access_element' */ 2023 2024 /* Note: macros implicitly use `stream' and set `error' */ 2025 if ( FT_STREAM_SEEK( idx->data_offset ) || 2026 FT_FRAME_EXTRACT( idx->data_size, dict ) ) 2027 goto Exit; 2028 2029 dict_len = idx->data_size; 2030 } 2031 2032 if ( !error ) 2033 { 2034 FT_TRACE4(( " top dictionary:\n" )); 2035 error = cff_parser_run( &parser, dict, dict + dict_len ); 2036 } 2037 2038 /* clean up regardless of error */ 2039 if ( idx->count ) 2040 cff_index_forget_element( idx, &dict ); 2041 else 2042 FT_FRAME_RELEASE( dict ); 2043 2044 if ( error ) 2045 goto Exit; 2046 2047 /* if it is a CID font, we stop there */ 2048 if ( top->cid_registry != 0xFFFFU ) 2049 goto Exit; 2050 2051 /* Parse the private dictionary, if any. */ 2052 /* */ 2053 /* CFF2 does not have a private dictionary in the Top DICT */ 2054 /* but may have one in a Font DICT. We need to parse */ 2055 /* the latter here in order to load any local subrs. */ 2056 error = cff_load_private_dict( font, subfont, 0, 0 ); 2057 if ( error ) 2058 goto Exit; 2059 2060 if ( !cff2 ) 2061 { 2062 /* 2063 * Initialize the random number generator. 2064 * 2065 * . If we have a face-specific seed, use it. 2066 * If non-zero, update it to a positive value. 2067 * 2068 * . Otherwise, use the seed from the CFF driver. 2069 * If non-zero, update it to a positive value. 2070 * 2071 * . If the random value is zero, use the seed given by the subfont's 2072 * `initialRandomSeed' value. 2073 * 2074 */ 2075 if ( face->root.internal->random_seed == -1 ) 2076 { 2077 PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( face ); 2078 2079 2080 subfont->random = (FT_UInt32)driver->random_seed; 2081 if ( driver->random_seed ) 2082 { 2083 do 2084 { 2085 driver->random_seed = 2086 (FT_Int32)psaux->cff_random( (FT_UInt32)driver->random_seed ); 2087 2088 } while ( driver->random_seed < 0 ); 2089 } 2090 } 2091 else 2092 { 2093 subfont->random = (FT_UInt32)face->root.internal->random_seed; 2094 if ( face->root.internal->random_seed ) 2095 { 2096 do 2097 { 2098 face->root.internal->random_seed = 2099 (FT_Int32)psaux->cff_random( 2100 (FT_UInt32)face->root.internal->random_seed ); 2101 2102 } while ( face->root.internal->random_seed < 0 ); 2103 } 2104 } 2105 2106 if ( !subfont->random ) 2107 subfont->random = (FT_UInt32)priv->initial_random_seed; 2108 } 2109 2110 /* read the local subrs, if any */ 2111 if ( priv->local_subrs_offset ) 2112 { 2113 if ( FT_STREAM_SEEK( base_offset + top->private_offset + 2114 priv->local_subrs_offset ) ) 2115 goto Exit; 2116 2117 error = cff_index_init( &subfont->local_subrs_index, stream, 1, cff2 ); 2118 if ( error ) 2119 goto Exit; 2120 2121 error = cff_index_get_pointers( &subfont->local_subrs_index, 2122 &subfont->local_subrs, NULL, NULL ); 2123 if ( error ) 2124 goto Exit; 2125 } 2126 2127 Exit: 2128 cff_parser_done( &parser ); /* free parser stack */ 2129 2130 return error; 2131 } 2132 2133 2134 static void cff_subfont_done(FT_Memory memory,CFF_SubFont subfont)2135 cff_subfont_done( FT_Memory memory, 2136 CFF_SubFont subfont ) 2137 { 2138 if ( subfont ) 2139 { 2140 cff_index_done( &subfont->local_subrs_index ); 2141 FT_FREE( subfont->local_subrs ); 2142 2143 FT_FREE( subfont->blend.lastNDV ); 2144 FT_FREE( subfont->blend.BV ); 2145 FT_FREE( subfont->blend_stack ); 2146 } 2147 } 2148 2149 2150 FT_LOCAL_DEF( FT_Error ) cff_font_load(FT_Library library,FT_Stream stream,FT_Int face_index,CFF_Font font,CFF_Face face,FT_Bool pure_cff,FT_Bool cff2)2151 cff_font_load( FT_Library library, 2152 FT_Stream stream, 2153 FT_Int face_index, 2154 CFF_Font font, 2155 CFF_Face face, 2156 FT_Bool pure_cff, 2157 FT_Bool cff2 ) 2158 { 2159 static const FT_Frame_Field cff_header_fields[] = 2160 { 2161 #undef FT_STRUCTURE 2162 #define FT_STRUCTURE CFF_FontRec 2163 2164 FT_FRAME_START( 3 ), 2165 FT_FRAME_BYTE( version_major ), 2166 FT_FRAME_BYTE( version_minor ), 2167 FT_FRAME_BYTE( header_size ), 2168 FT_FRAME_END 2169 }; 2170 2171 FT_Error error; 2172 FT_Memory memory = stream->memory; 2173 FT_ULong base_offset; 2174 CFF_FontRecDict dict; 2175 CFF_IndexRec string_index; 2176 FT_UInt subfont_index; 2177 2178 2179 FT_ZERO( font ); 2180 FT_ZERO( &string_index ); 2181 2182 dict = &font->top_font.font_dict; 2183 base_offset = FT_STREAM_POS(); 2184 2185 font->library = library; 2186 font->stream = stream; 2187 font->memory = memory; 2188 font->cff2 = cff2; 2189 font->base_offset = base_offset; 2190 2191 /* read CFF font header */ 2192 if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) ) 2193 goto Exit; 2194 2195 if ( cff2 ) 2196 { 2197 if ( font->version_major != 2 || 2198 font->header_size < 5 ) 2199 { 2200 FT_TRACE2(( " not a CFF2 font header\n" )); 2201 error = FT_THROW( Unknown_File_Format ); 2202 goto Exit; 2203 } 2204 2205 if ( FT_READ_USHORT( font->top_dict_length ) ) 2206 goto Exit; 2207 } 2208 else 2209 { 2210 FT_Byte absolute_offset; 2211 2212 2213 if ( FT_READ_BYTE( absolute_offset ) ) 2214 goto Exit; 2215 2216 if ( font->version_major != 1 || 2217 font->header_size < 4 || 2218 absolute_offset > 4 ) 2219 { 2220 FT_TRACE2(( " not a CFF font header\n" )); 2221 error = FT_THROW( Unknown_File_Format ); 2222 goto Exit; 2223 } 2224 } 2225 2226 /* skip the rest of the header */ 2227 if ( FT_STREAM_SEEK( base_offset + font->header_size ) ) 2228 { 2229 /* For pure CFFs we have read only four bytes so far. Contrary to */ 2230 /* other formats like SFNT those bytes doesn't define a signature; */ 2231 /* it is thus possible that the font isn't a CFF at all. */ 2232 if ( pure_cff ) 2233 { 2234 FT_TRACE2(( " not a CFF file\n" )); 2235 error = FT_THROW( Unknown_File_Format ); 2236 } 2237 goto Exit; 2238 } 2239 2240 if ( cff2 ) 2241 { 2242 /* For CFF2, the top dict data immediately follow the header */ 2243 /* and the length is stored in the header `offSize' field; */ 2244 /* there is no index for it. */ 2245 /* */ 2246 /* Use the `font_dict_index' to save the current position */ 2247 /* and length of data, but leave count at zero as an indicator. */ 2248 FT_ZERO( &font->font_dict_index ); 2249 2250 font->font_dict_index.data_offset = FT_STREAM_POS(); 2251 font->font_dict_index.data_size = font->top_dict_length; 2252 2253 /* skip the top dict data for now, we will parse it later */ 2254 if ( FT_STREAM_SKIP( font->top_dict_length ) ) 2255 goto Exit; 2256 2257 /* next, read the global subrs index */ 2258 if ( FT_SET_ERROR( cff_index_init( &font->global_subrs_index, 2259 stream, 1, cff2 ) ) ) 2260 goto Exit; 2261 } 2262 else 2263 { 2264 /* for CFF, read the name, top dict, string and global subrs index */ 2265 if ( FT_SET_ERROR( cff_index_init( &font->name_index, 2266 stream, 0, cff2 ) ) ) 2267 { 2268 if ( pure_cff ) 2269 { 2270 FT_TRACE2(( " not a CFF file\n" )); 2271 error = FT_THROW( Unknown_File_Format ); 2272 } 2273 goto Exit; 2274 } 2275 2276 /* if we have an empty font name, */ 2277 /* it must be the only font in the CFF */ 2278 if ( font->name_index.count > 1 && 2279 font->name_index.data_size < font->name_index.count ) 2280 { 2281 /* for pure CFFs, we still haven't checked enough bytes */ 2282 /* to be sure that it is a CFF at all */ 2283 error = pure_cff ? FT_THROW( Unknown_File_Format ) 2284 : FT_THROW( Invalid_File_Format ); 2285 goto Exit; 2286 } 2287 2288 if ( FT_SET_ERROR( cff_index_init( &font->font_dict_index, 2289 stream, 0, cff2 ) ) || 2290 FT_SET_ERROR( cff_index_init( &string_index, 2291 stream, 1, cff2 ) ) || 2292 FT_SET_ERROR( cff_index_init( &font->global_subrs_index, 2293 stream, 1, cff2 ) ) || 2294 FT_SET_ERROR( cff_index_get_pointers( &string_index, 2295 &font->strings, 2296 &font->string_pool, 2297 &font->string_pool_size ) ) ) 2298 goto Exit; 2299 2300 /* there must be a Top DICT index entry for each name index entry */ 2301 if ( font->name_index.count > font->font_dict_index.count ) 2302 { 2303 FT_ERROR(( "cff_font_load:" 2304 " not enough entries in Top DICT index\n" )); 2305 error = FT_THROW( Invalid_File_Format ); 2306 goto Exit; 2307 } 2308 } 2309 2310 font->num_strings = string_index.count; 2311 2312 if ( pure_cff ) 2313 { 2314 /* well, we don't really forget the `disabled' fonts... */ 2315 subfont_index = (FT_UInt)( face_index & 0xFFFF ); 2316 2317 if ( face_index > 0 && subfont_index >= font->name_index.count ) 2318 { 2319 FT_ERROR(( "cff_font_load:" 2320 " invalid subfont index for pure CFF font (%d)\n", 2321 subfont_index )); 2322 error = FT_THROW( Invalid_Argument ); 2323 goto Exit; 2324 } 2325 2326 font->num_faces = font->name_index.count; 2327 } 2328 else 2329 { 2330 subfont_index = 0; 2331 2332 if ( font->name_index.count > 1 ) 2333 { 2334 FT_ERROR(( "cff_font_load:" 2335 " invalid CFF font with multiple subfonts\n" 2336 " " 2337 " in SFNT wrapper\n" )); 2338 error = FT_THROW( Invalid_File_Format ); 2339 goto Exit; 2340 } 2341 } 2342 2343 /* in case of a font format check, simply exit now */ 2344 if ( face_index < 0 ) 2345 goto Exit; 2346 2347 /* now, parse the top-level font dictionary */ 2348 FT_TRACE4(( "parsing top-level\n" )); 2349 error = cff_subfont_load( &font->top_font, 2350 &font->font_dict_index, 2351 subfont_index, 2352 stream, 2353 base_offset, 2354 cff2 ? CFF2_CODE_TOPDICT : CFF_CODE_TOPDICT, 2355 font, 2356 face ); 2357 if ( error ) 2358 goto Exit; 2359 2360 if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) ) 2361 goto Exit; 2362 2363 error = cff_index_init( &font->charstrings_index, stream, 0, cff2 ); 2364 if ( error ) 2365 goto Exit; 2366 2367 /* now, check for a CID or CFF2 font */ 2368 if ( dict->cid_registry != 0xFFFFU || 2369 cff2 ) 2370 { 2371 CFF_IndexRec fd_index; 2372 CFF_SubFont sub = NULL; 2373 FT_UInt idx; 2374 2375 2376 /* for CFF2, read the Variation Store if available; */ 2377 /* this must follow the Top DICT parse and precede any Private DICT */ 2378 error = cff_vstore_load( &font->vstore, 2379 stream, 2380 base_offset, 2381 dict->vstore_offset ); 2382 if ( error ) 2383 goto Exit; 2384 2385 /* this is a CID-keyed font, we must now allocate a table of */ 2386 /* sub-fonts, then load each of them separately */ 2387 if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) ) 2388 goto Exit; 2389 2390 error = cff_index_init( &fd_index, stream, 0, cff2 ); 2391 if ( error ) 2392 goto Exit; 2393 2394 /* Font Dicts are not limited to 256 for CFF2. */ 2395 /* TODO: support this for CFF2 */ 2396 if ( fd_index.count > CFF_MAX_CID_FONTS ) 2397 { 2398 FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" )); 2399 goto Fail_CID; 2400 } 2401 2402 /* allocate & read each font dict independently */ 2403 font->num_subfonts = fd_index.count; 2404 if ( FT_NEW_ARRAY( sub, fd_index.count ) ) 2405 goto Fail_CID; 2406 2407 /* set up pointer table */ 2408 for ( idx = 0; idx < fd_index.count; idx++ ) 2409 font->subfonts[idx] = sub + idx; 2410 2411 /* now load each subfont independently */ 2412 for ( idx = 0; idx < fd_index.count; idx++ ) 2413 { 2414 sub = font->subfonts[idx]; 2415 FT_TRACE4(( "parsing subfont %u\n", idx )); 2416 error = cff_subfont_load( sub, 2417 &fd_index, 2418 idx, 2419 stream, 2420 base_offset, 2421 cff2 ? CFF2_CODE_FONTDICT 2422 : CFF_CODE_TOPDICT, 2423 font, 2424 face ); 2425 if ( error ) 2426 goto Fail_CID; 2427 } 2428 2429 /* now load the FD Select array; */ 2430 /* CFF2 omits FDSelect if there is only one FD */ 2431 if ( !cff2 || fd_index.count > 1 ) 2432 error = CFF_Load_FD_Select( &font->fd_select, 2433 font->charstrings_index.count, 2434 stream, 2435 base_offset + dict->cid_fd_select_offset ); 2436 2437 Fail_CID: 2438 cff_index_done( &fd_index ); 2439 2440 if ( error ) 2441 goto Exit; 2442 } 2443 else 2444 font->num_subfonts = 0; 2445 2446 /* read the charstrings index now */ 2447 if ( dict->charstrings_offset == 0 ) 2448 { 2449 FT_ERROR(( "cff_font_load: no charstrings offset\n" )); 2450 error = FT_THROW( Invalid_File_Format ); 2451 goto Exit; 2452 } 2453 2454 font->num_glyphs = font->charstrings_index.count; 2455 2456 error = cff_index_get_pointers( &font->global_subrs_index, 2457 &font->global_subrs, NULL, NULL ); 2458 2459 if ( error ) 2460 goto Exit; 2461 2462 /* read the Charset and Encoding tables if available */ 2463 if ( !cff2 && font->num_glyphs > 0 ) 2464 { 2465 FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff ); 2466 2467 2468 error = cff_charset_load( &font->charset, font->num_glyphs, stream, 2469 base_offset, dict->charset_offset, invert ); 2470 if ( error ) 2471 goto Exit; 2472 2473 /* CID-keyed CFFs don't have an encoding */ 2474 if ( dict->cid_registry == 0xFFFFU ) 2475 { 2476 error = cff_encoding_load( &font->encoding, 2477 &font->charset, 2478 font->num_glyphs, 2479 stream, 2480 base_offset, 2481 dict->encoding_offset ); 2482 if ( error ) 2483 goto Exit; 2484 } 2485 } 2486 2487 /* get the font name (/CIDFontName for CID-keyed fonts, */ 2488 /* /FontName otherwise) */ 2489 font->font_name = cff_index_get_name( font, subfont_index ); 2490 2491 Exit: 2492 cff_index_done( &string_index ); 2493 2494 return error; 2495 } 2496 2497 2498 FT_LOCAL_DEF( void ) cff_font_done(CFF_Font font)2499 cff_font_done( CFF_Font font ) 2500 { 2501 FT_Memory memory = font->memory; 2502 FT_UInt idx; 2503 2504 2505 cff_index_done( &font->global_subrs_index ); 2506 cff_index_done( &font->font_dict_index ); 2507 cff_index_done( &font->name_index ); 2508 cff_index_done( &font->charstrings_index ); 2509 2510 /* release font dictionaries, but only if working with */ 2511 /* a CID keyed CFF font or a CFF2 font */ 2512 if ( font->num_subfonts > 0 ) 2513 { 2514 for ( idx = 0; idx < font->num_subfonts; idx++ ) 2515 cff_subfont_done( memory, font->subfonts[idx] ); 2516 2517 /* the subfonts array has been allocated as a single block */ 2518 FT_FREE( font->subfonts[0] ); 2519 } 2520 2521 cff_encoding_done( &font->encoding ); 2522 cff_charset_done( &font->charset, font->stream ); 2523 cff_vstore_done( &font->vstore, memory ); 2524 2525 cff_subfont_done( memory, &font->top_font ); 2526 2527 CFF_Done_FD_Select( &font->fd_select, font->stream ); 2528 2529 FT_FREE( font->font_info ); 2530 2531 FT_FREE( font->font_name ); 2532 FT_FREE( font->global_subrs ); 2533 FT_FREE( font->strings ); 2534 FT_FREE( font->string_pool ); 2535 2536 if ( font->cf2_instance.finalizer ) 2537 { 2538 font->cf2_instance.finalizer( font->cf2_instance.data ); 2539 FT_FREE( font->cf2_instance.data ); 2540 } 2541 2542 FT_FREE( font->font_extra ); 2543 } 2544 2545 2546 /* END */ 2547