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