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 /* protect against malformed fonts */ 1402 if ( !( lenNDV == 0 || NDV ) ) 1403 { 1404 FT_TRACE4(( " cff_blend_build_vector:" 1405 " Malformed Normalize Design Vector data\n" )); 1406 error = FT_THROW( Invalid_File_Format ); 1407 goto Exit; 1408 } 1409 1410 blend->builtBV = FALSE; 1411 1412 vs = &blend->font->vstore; 1413 1414 /* VStore and fvar must be consistent */ 1415 if ( lenNDV != 0 && lenNDV != vs->axisCount ) 1416 { 1417 FT_TRACE4(( " cff_blend_build_vector: Axis count mismatch\n" )); 1418 error = FT_THROW( Invalid_File_Format ); 1419 goto Exit; 1420 } 1421 1422 if ( vsindex >= vs->dataCount ) 1423 { 1424 FT_TRACE4(( " cff_blend_build_vector: vsindex out of range\n" )); 1425 error = FT_THROW( Invalid_File_Format ); 1426 goto Exit; 1427 } 1428 1429 /* select the item variation data structure */ 1430 varData = &vs->varData[vsindex]; 1431 1432 /* prepare buffer for the blend vector */ 1433 len = varData->regionIdxCount + 1; /* add 1 for default component */ 1434 if ( FT_REALLOC( blend->BV, 1435 blend->lenBV * sizeof( *blend->BV ), 1436 len * sizeof( *blend->BV ) ) ) 1437 goto Exit; 1438 1439 blend->lenBV = len; 1440 1441 /* outer loop steps through master designs to be blended */ 1442 for ( master = 0; master < len; master++ ) 1443 { 1444 FT_UInt j; 1445 FT_UInt idx; 1446 CFF_VarRegion* varRegion; 1447 1448 1449 /* default factor is always one */ 1450 if ( master == 0 ) 1451 { 1452 blend->BV[master] = FT_FIXED_ONE; 1453 FT_TRACE4(( " build blend vector len %d\n" 1454 " [ %f ", 1455 len, 1456 blend->BV[master] / 65536.0 )); 1457 continue; 1458 } 1459 1460 /* VStore array does not include default master, so subtract one */ 1461 idx = varData->regionIndices[master - 1]; 1462 varRegion = &vs->varRegionList[idx]; 1463 1464 if ( idx >= vs->regionCount ) 1465 { 1466 FT_TRACE4(( " cff_blend_build_vector:" 1467 " region index out of range\n" )); 1468 error = FT_THROW( Invalid_File_Format ); 1469 goto Exit; 1470 } 1471 1472 /* Note: `lenNDV' could be zero. */ 1473 /* In that case, build default blend vector (1,0,0...). */ 1474 if ( !lenNDV ) 1475 { 1476 blend->BV[master] = 0; 1477 continue; 1478 } 1479 1480 /* In the normal case, initialize each component to 1 */ 1481 /* before inner loop. */ 1482 blend->BV[master] = FT_FIXED_ONE; /* default */ 1483 1484 /* inner loop steps through axes in this region */ 1485 for ( j = 0; j < lenNDV; j++ ) 1486 { 1487 CFF_AxisCoords* axis = &varRegion->axisList[j]; 1488 FT_Fixed axisScalar; 1489 1490 1491 /* compute the scalar contribution of this axis; */ 1492 /* ignore invalid ranges */ 1493 if ( axis->startCoord > axis->peakCoord || 1494 axis->peakCoord > axis->endCoord ) 1495 axisScalar = FT_FIXED_ONE; 1496 1497 else if ( axis->startCoord < 0 && 1498 axis->endCoord > 0 && 1499 axis->peakCoord != 0 ) 1500 axisScalar = FT_FIXED_ONE; 1501 1502 /* peak of 0 means ignore this axis */ 1503 else if ( axis->peakCoord == 0 ) 1504 axisScalar = FT_FIXED_ONE; 1505 1506 /* ignore this region if coords are out of range */ 1507 else if ( NDV[j] < axis->startCoord || 1508 NDV[j] > axis->endCoord ) 1509 axisScalar = 0; 1510 1511 /* calculate a proportional factor */ 1512 else 1513 { 1514 if ( NDV[j] == axis->peakCoord ) 1515 axisScalar = FT_FIXED_ONE; 1516 else if ( NDV[j] < axis->peakCoord ) 1517 axisScalar = FT_DivFix( NDV[j] - axis->startCoord, 1518 axis->peakCoord - axis->startCoord ); 1519 else 1520 axisScalar = FT_DivFix( axis->endCoord - NDV[j], 1521 axis->endCoord - axis->peakCoord ); 1522 } 1523 1524 /* take product of all the axis scalars */ 1525 blend->BV[master] = FT_MulFix( blend->BV[master], axisScalar ); 1526 } 1527 1528 FT_TRACE4(( ", %f ", 1529 blend->BV[master] / 65536.0 )); 1530 } 1531 1532 FT_TRACE4(( "]\n" )); 1533 1534 /* record the parameters used to build the blend vector */ 1535 blend->lastVsindex = vsindex; 1536 1537 if ( lenNDV != 0 ) 1538 { 1539 /* user has set a normalized vector */ 1540 if ( FT_REALLOC( blend->lastNDV, 1541 blend->lenNDV * sizeof ( *NDV ), 1542 lenNDV * sizeof ( *NDV ) ) ) 1543 goto Exit; 1544 1545 FT_MEM_COPY( blend->lastNDV, 1546 NDV, 1547 lenNDV * sizeof ( *NDV ) ); 1548 } 1549 1550 blend->lenNDV = lenNDV; 1551 blend->builtBV = TRUE; 1552 1553 Exit: 1554 return error; 1555 } 1556 1557 1558 /* `lenNDV' is zero for default vector; */ 1559 /* return TRUE if blend vector needs to be built. */ 1560 FT_LOCAL_DEF( FT_Bool ) cff_blend_check_vector(CFF_Blend blend,FT_UInt vsindex,FT_UInt lenNDV,FT_Fixed * NDV)1561 cff_blend_check_vector( CFF_Blend blend, 1562 FT_UInt vsindex, 1563 FT_UInt lenNDV, 1564 FT_Fixed* NDV ) 1565 { 1566 if ( !blend->builtBV || 1567 blend->lastVsindex != vsindex || 1568 blend->lenNDV != lenNDV || 1569 ( lenNDV && 1570 ft_memcmp( NDV, 1571 blend->lastNDV, 1572 lenNDV * sizeof ( *NDV ) ) != 0 ) ) 1573 { 1574 /* need to build blend vector */ 1575 return TRUE; 1576 } 1577 1578 return FALSE; 1579 } 1580 1581 1582 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 1583 1584 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)1585 cff_get_var_blend( CFF_Face face, 1586 FT_UInt *num_coords, 1587 FT_Fixed* *coords, 1588 FT_Fixed* *normalizedcoords, 1589 FT_MM_Var* *mm_var ) 1590 { 1591 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; 1592 1593 1594 return mm->get_var_blend( FT_FACE( face ), 1595 num_coords, 1596 coords, 1597 normalizedcoords, 1598 mm_var ); 1599 } 1600 1601 1602 FT_LOCAL_DEF( void ) cff_done_blend(CFF_Face face)1603 cff_done_blend( CFF_Face face ) 1604 { 1605 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; 1606 1607 1608 if (mm) 1609 mm->done_blend( FT_FACE( face ) ); 1610 } 1611 1612 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ 1613 1614 1615 static void cff_encoding_done(CFF_Encoding encoding)1616 cff_encoding_done( CFF_Encoding encoding ) 1617 { 1618 encoding->format = 0; 1619 encoding->offset = 0; 1620 encoding->count = 0; 1621 } 1622 1623 1624 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)1625 cff_encoding_load( CFF_Encoding encoding, 1626 CFF_Charset charset, 1627 FT_UInt num_glyphs, 1628 FT_Stream stream, 1629 FT_ULong base_offset, 1630 FT_ULong offset ) 1631 { 1632 FT_Error error = FT_Err_Ok; 1633 FT_UInt count; 1634 FT_UInt j; 1635 FT_UShort glyph_sid; 1636 FT_UInt glyph_code; 1637 1638 1639 /* Check for charset->sids. If we do not have this, we fail. */ 1640 if ( !charset->sids ) 1641 { 1642 error = FT_THROW( Invalid_File_Format ); 1643 goto Exit; 1644 } 1645 1646 /* Zero out the code to gid/sid mappings. */ 1647 for ( j = 0; j < 256; j++ ) 1648 { 1649 encoding->sids [j] = 0; 1650 encoding->codes[j] = 0; 1651 } 1652 1653 /* Note: The encoding table in a CFF font is indexed by glyph index; */ 1654 /* the first encoded glyph index is 1. Hence, we read the character */ 1655 /* code (`glyph_code') at index j and make the assignment: */ 1656 /* */ 1657 /* encoding->codes[glyph_code] = j + 1 */ 1658 /* */ 1659 /* We also make the assignment: */ 1660 /* */ 1661 /* encoding->sids[glyph_code] = charset->sids[j + 1] */ 1662 /* */ 1663 /* This gives us both a code to GID and a code to SID mapping. */ 1664 1665 if ( offset > 1 ) 1666 { 1667 encoding->offset = base_offset + offset; 1668 1669 /* we need to parse the table to determine its size */ 1670 if ( FT_STREAM_SEEK( encoding->offset ) || 1671 FT_READ_BYTE( encoding->format ) || 1672 FT_READ_BYTE( count ) ) 1673 goto Exit; 1674 1675 switch ( encoding->format & 0x7F ) 1676 { 1677 case 0: 1678 { 1679 FT_Byte* p; 1680 1681 1682 /* By convention, GID 0 is always ".notdef" and is never */ 1683 /* coded in the font. Hence, the number of codes found */ 1684 /* in the table is `count+1'. */ 1685 /* */ 1686 encoding->count = count + 1; 1687 1688 if ( FT_FRAME_ENTER( count ) ) 1689 goto Exit; 1690 1691 p = (FT_Byte*)stream->cursor; 1692 1693 for ( j = 1; j <= count; j++ ) 1694 { 1695 glyph_code = *p++; 1696 1697 /* Make sure j is not too big. */ 1698 if ( j < num_glyphs ) 1699 { 1700 /* Assign code to GID mapping. */ 1701 encoding->codes[glyph_code] = (FT_UShort)j; 1702 1703 /* Assign code to SID mapping. */ 1704 encoding->sids[glyph_code] = charset->sids[j]; 1705 } 1706 } 1707 1708 FT_FRAME_EXIT(); 1709 } 1710 break; 1711 1712 case 1: 1713 { 1714 FT_UInt nleft; 1715 FT_UInt i = 1; 1716 FT_UInt k; 1717 1718 1719 encoding->count = 0; 1720 1721 /* Parse the Format1 ranges. */ 1722 for ( j = 0; j < count; j++, i += nleft ) 1723 { 1724 /* Read the first glyph code of the range. */ 1725 if ( FT_READ_BYTE( glyph_code ) ) 1726 goto Exit; 1727 1728 /* Read the number of codes in the range. */ 1729 if ( FT_READ_BYTE( nleft ) ) 1730 goto Exit; 1731 1732 /* Increment nleft, so we read `nleft + 1' codes/sids. */ 1733 nleft++; 1734 1735 /* compute max number of character codes */ 1736 if ( (FT_UInt)nleft > encoding->count ) 1737 encoding->count = nleft; 1738 1739 /* Fill in the range of codes/sids. */ 1740 for ( k = i; k < nleft + i; k++, glyph_code++ ) 1741 { 1742 /* Make sure k is not too big. */ 1743 if ( k < num_glyphs && glyph_code < 256 ) 1744 { 1745 /* Assign code to GID mapping. */ 1746 encoding->codes[glyph_code] = (FT_UShort)k; 1747 1748 /* Assign code to SID mapping. */ 1749 encoding->sids[glyph_code] = charset->sids[k]; 1750 } 1751 } 1752 } 1753 1754 /* simple check; one never knows what can be found in a font */ 1755 if ( encoding->count > 256 ) 1756 encoding->count = 256; 1757 } 1758 break; 1759 1760 default: 1761 FT_ERROR(( "cff_encoding_load: invalid table format\n" )); 1762 error = FT_THROW( Invalid_File_Format ); 1763 goto Exit; 1764 } 1765 1766 /* Parse supplemental encodings, if any. */ 1767 if ( encoding->format & 0x80 ) 1768 { 1769 FT_UInt gindex; 1770 1771 1772 /* count supplements */ 1773 if ( FT_READ_BYTE( count ) ) 1774 goto Exit; 1775 1776 for ( j = 0; j < count; j++ ) 1777 { 1778 /* Read supplemental glyph code. */ 1779 if ( FT_READ_BYTE( glyph_code ) ) 1780 goto Exit; 1781 1782 /* Read the SID associated with this glyph code. */ 1783 if ( FT_READ_USHORT( glyph_sid ) ) 1784 goto Exit; 1785 1786 /* Assign code to SID mapping. */ 1787 encoding->sids[glyph_code] = glyph_sid; 1788 1789 /* First, look up GID which has been assigned to */ 1790 /* SID glyph_sid. */ 1791 for ( gindex = 0; gindex < num_glyphs; gindex++ ) 1792 { 1793 if ( charset->sids[gindex] == glyph_sid ) 1794 { 1795 encoding->codes[glyph_code] = (FT_UShort)gindex; 1796 break; 1797 } 1798 } 1799 } 1800 } 1801 } 1802 else 1803 { 1804 /* We take into account the fact a CFF font can use a predefined */ 1805 /* encoding without containing all of the glyphs encoded by this */ 1806 /* encoding (see the note at the end of section 12 in the CFF */ 1807 /* specification). */ 1808 1809 switch ( (FT_UInt)offset ) 1810 { 1811 case 0: 1812 /* First, copy the code to SID mapping. */ 1813 FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 ); 1814 goto Populate; 1815 1816 case 1: 1817 /* First, copy the code to SID mapping. */ 1818 FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 ); 1819 1820 Populate: 1821 /* Construct code to GID mapping from code to SID mapping */ 1822 /* and charset. */ 1823 1824 encoding->count = 0; 1825 1826 error = cff_charset_compute_cids( charset, num_glyphs, 1827 stream->memory ); 1828 if ( error ) 1829 goto Exit; 1830 1831 for ( j = 0; j < 256; j++ ) 1832 { 1833 FT_UInt sid = encoding->sids[j]; 1834 FT_UInt gid = 0; 1835 1836 1837 if ( sid ) 1838 gid = cff_charset_cid_to_gindex( charset, sid ); 1839 1840 if ( gid != 0 ) 1841 { 1842 encoding->codes[j] = (FT_UShort)gid; 1843 encoding->count = j + 1; 1844 } 1845 else 1846 { 1847 encoding->codes[j] = 0; 1848 encoding->sids [j] = 0; 1849 } 1850 } 1851 break; 1852 1853 default: 1854 FT_ERROR(( "cff_encoding_load: invalid table format\n" )); 1855 error = FT_THROW( Invalid_File_Format ); 1856 goto Exit; 1857 } 1858 } 1859 1860 Exit: 1861 1862 /* Clean up if there was an error. */ 1863 return error; 1864 } 1865 1866 1867 /* Parse private dictionary; first call is always from `cff_face_init', */ 1868 /* so NDV has not been set for CFF2 variation. */ 1869 /* */ 1870 /* `cff_slot_load' must call this function each time NDV changes. */ 1871 FT_LOCAL_DEF( FT_Error ) cff_load_private_dict(CFF_Font font,CFF_SubFont subfont,FT_UInt lenNDV,FT_Fixed * NDV)1872 cff_load_private_dict( CFF_Font font, 1873 CFF_SubFont subfont, 1874 FT_UInt lenNDV, 1875 FT_Fixed* NDV ) 1876 { 1877 FT_Error error = FT_Err_Ok; 1878 CFF_ParserRec parser; 1879 CFF_FontRecDict top = &subfont->font_dict; 1880 CFF_Private priv = &subfont->private_dict; 1881 FT_Stream stream = font->stream; 1882 FT_UInt stackSize; 1883 1884 1885 /* store handle needed to access memory, vstore for blend; */ 1886 /* we need this for clean-up even if there is no private DICT */ 1887 subfont->blend.font = font; 1888 subfont->blend.usedBV = FALSE; /* clear state */ 1889 1890 if ( !top->private_offset || !top->private_size ) 1891 goto Exit2; /* no private DICT, do nothing */ 1892 1893 /* set defaults */ 1894 FT_ZERO( priv ); 1895 1896 priv->blue_shift = 7; 1897 priv->blue_fuzz = 1; 1898 priv->lenIV = -1; 1899 priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); 1900 priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 ); 1901 1902 /* provide inputs for blend calculations */ 1903 priv->subfont = subfont; 1904 subfont->lenNDV = lenNDV; 1905 subfont->NDV = NDV; 1906 1907 /* add 1 for the operator */ 1908 stackSize = font->cff2 ? font->top_font.font_dict.maxstack + 1 1909 : CFF_MAX_STACK_DEPTH + 1; 1910 1911 if ( cff_parser_init( &parser, 1912 font->cff2 ? CFF2_CODE_PRIVATE : CFF_CODE_PRIVATE, 1913 priv, 1914 font->library, 1915 stackSize, 1916 top->num_designs, 1917 top->num_axes ) ) 1918 goto Exit; 1919 1920 if ( FT_STREAM_SEEK( font->base_offset + top->private_offset ) || 1921 FT_FRAME_ENTER( top->private_size ) ) 1922 goto Exit; 1923 1924 FT_TRACE4(( " private dictionary:\n" )); 1925 error = cff_parser_run( &parser, 1926 (FT_Byte*)stream->cursor, 1927 (FT_Byte*)stream->limit ); 1928 FT_FRAME_EXIT(); 1929 1930 if ( error ) 1931 goto Exit; 1932 1933 /* ensure that `num_blue_values' is even */ 1934 priv->num_blue_values &= ~1; 1935 1936 /* sanitize `initialRandomSeed' to be a positive value, if necessary; */ 1937 /* this is not mandated by the specification but by our implementation */ 1938 if ( priv->initial_random_seed < 0 ) 1939 priv->initial_random_seed = -priv->initial_random_seed; 1940 else if ( priv->initial_random_seed == 0 ) 1941 priv->initial_random_seed = 987654321; 1942 1943 /* some sanitizing to avoid overflows later on; */ 1944 /* the upper limits are ad-hoc values */ 1945 if ( priv->blue_shift > 1000 || priv->blue_shift < 0 ) 1946 { 1947 FT_TRACE2(( "cff_load_private_dict:" 1948 " setting unlikely BlueShift value %d to default (7)\n", 1949 priv->blue_shift )); 1950 priv->blue_shift = 7; 1951 } 1952 1953 if ( priv->blue_fuzz > 1000 || priv->blue_fuzz < 0 ) 1954 { 1955 FT_TRACE2(( "cff_load_private_dict:" 1956 " setting unlikely BlueFuzz value %d to default (1)\n", 1957 priv->blue_fuzz )); 1958 priv->blue_fuzz = 1; 1959 } 1960 1961 Exit: 1962 /* clean up */ 1963 cff_blend_clear( subfont ); /* clear blend stack */ 1964 cff_parser_done( &parser ); /* free parser stack */ 1965 1966 Exit2: 1967 /* no clean up (parser not initialized) */ 1968 return error; 1969 } 1970 1971 1972 /* There are 3 ways to call this function, distinguished by code. */ 1973 /* */ 1974 /* . CFF_CODE_TOPDICT for either a CFF Top DICT or a CFF Font DICT */ 1975 /* . CFF2_CODE_TOPDICT for CFF2 Top DICT */ 1976 /* . CFF2_CODE_FONTDICT for CFF2 Font DICT */ 1977 1978 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)1979 cff_subfont_load( CFF_SubFont subfont, 1980 CFF_Index idx, 1981 FT_UInt font_index, 1982 FT_Stream stream, 1983 FT_ULong base_offset, 1984 FT_UInt code, 1985 CFF_Font font, 1986 CFF_Face face ) 1987 { 1988 FT_Error error; 1989 CFF_ParserRec parser; 1990 FT_Byte* dict = NULL; 1991 FT_ULong dict_len; 1992 CFF_FontRecDict top = &subfont->font_dict; 1993 CFF_Private priv = &subfont->private_dict; 1994 1995 PSAux_Service psaux = (PSAux_Service)face->psaux; 1996 1997 FT_Bool cff2 = FT_BOOL( code == CFF2_CODE_TOPDICT || 1998 code == CFF2_CODE_FONTDICT ); 1999 FT_UInt stackSize = cff2 ? CFF2_DEFAULT_STACK 2000 : CFF_MAX_STACK_DEPTH; 2001 2002 2003 /* Note: We use default stack size for CFF2 Font DICT because */ 2004 /* Top and Font DICTs are not allowed to have blend operators. */ 2005 error = cff_parser_init( &parser, 2006 code, 2007 &subfont->font_dict, 2008 font->library, 2009 stackSize, 2010 0, 2011 0 ); 2012 if ( error ) 2013 goto Exit; 2014 2015 /* set defaults */ 2016 FT_ZERO( top ); 2017 2018 top->underline_position = -( 100L << 16 ); 2019 top->underline_thickness = 50L << 16; 2020 top->charstring_type = 2; 2021 top->font_matrix.xx = 0x10000L; 2022 top->font_matrix.yy = 0x10000L; 2023 top->cid_count = 8720; 2024 2025 /* we use the implementation specific SID value 0xFFFF to indicate */ 2026 /* missing entries */ 2027 top->version = 0xFFFFU; 2028 top->notice = 0xFFFFU; 2029 top->copyright = 0xFFFFU; 2030 top->full_name = 0xFFFFU; 2031 top->family_name = 0xFFFFU; 2032 top->weight = 0xFFFFU; 2033 top->embedded_postscript = 0xFFFFU; 2034 2035 top->cid_registry = 0xFFFFU; 2036 top->cid_ordering = 0xFFFFU; 2037 top->cid_font_name = 0xFFFFU; 2038 2039 /* set default stack size */ 2040 top->maxstack = cff2 ? CFF2_DEFAULT_STACK : 48; 2041 2042 if ( idx->count ) /* count is nonzero for a real index */ 2043 error = cff_index_access_element( idx, font_index, &dict, &dict_len ); 2044 else 2045 { 2046 /* CFF2 has a fake top dict index; */ 2047 /* simulate `cff_index_access_element' */ 2048 2049 /* Note: macros implicitly use `stream' and set `error' */ 2050 if ( FT_STREAM_SEEK( idx->data_offset ) || 2051 FT_FRAME_EXTRACT( idx->data_size, dict ) ) 2052 goto Exit; 2053 2054 dict_len = idx->data_size; 2055 } 2056 2057 if ( !error ) 2058 { 2059 FT_TRACE4(( " top dictionary:\n" )); 2060 error = cff_parser_run( &parser, dict, dict + dict_len ); 2061 } 2062 2063 /* clean up regardless of error */ 2064 if ( idx->count ) 2065 cff_index_forget_element( idx, &dict ); 2066 else 2067 FT_FRAME_RELEASE( dict ); 2068 2069 if ( error ) 2070 goto Exit; 2071 2072 /* if it is a CID font, we stop there */ 2073 if ( top->cid_registry != 0xFFFFU ) 2074 goto Exit; 2075 2076 /* Parse the private dictionary, if any. */ 2077 /* */ 2078 /* CFF2 does not have a private dictionary in the Top DICT */ 2079 /* but may have one in a Font DICT. We need to parse */ 2080 /* the latter here in order to load any local subrs. */ 2081 error = cff_load_private_dict( font, subfont, 0, 0 ); 2082 if ( error ) 2083 goto Exit; 2084 2085 if ( !cff2 ) 2086 { 2087 /* 2088 * Initialize the random number generator. 2089 * 2090 * - If we have a face-specific seed, use it. 2091 * If non-zero, update it to a positive value. 2092 * 2093 * - Otherwise, use the seed from the CFF driver. 2094 * If non-zero, update it to a positive value. 2095 * 2096 * - If the random value is zero, use the seed given by the subfont's 2097 * `initialRandomSeed' value. 2098 * 2099 */ 2100 if ( face->root.internal->random_seed == -1 ) 2101 { 2102 PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( face ); 2103 2104 2105 subfont->random = (FT_UInt32)driver->random_seed; 2106 if ( driver->random_seed ) 2107 { 2108 do 2109 { 2110 driver->random_seed = 2111 (FT_Int32)psaux->cff_random( (FT_UInt32)driver->random_seed ); 2112 2113 } while ( driver->random_seed < 0 ); 2114 } 2115 } 2116 else 2117 { 2118 subfont->random = (FT_UInt32)face->root.internal->random_seed; 2119 if ( face->root.internal->random_seed ) 2120 { 2121 do 2122 { 2123 face->root.internal->random_seed = 2124 (FT_Int32)psaux->cff_random( 2125 (FT_UInt32)face->root.internal->random_seed ); 2126 2127 } while ( face->root.internal->random_seed < 0 ); 2128 } 2129 } 2130 2131 if ( !subfont->random ) 2132 subfont->random = (FT_UInt32)priv->initial_random_seed; 2133 } 2134 2135 /* read the local subrs, if any */ 2136 if ( priv->local_subrs_offset ) 2137 { 2138 if ( FT_STREAM_SEEK( base_offset + top->private_offset + 2139 priv->local_subrs_offset ) ) 2140 goto Exit; 2141 2142 error = cff_index_init( &subfont->local_subrs_index, stream, 1, cff2 ); 2143 if ( error ) 2144 goto Exit; 2145 2146 error = cff_index_get_pointers( &subfont->local_subrs_index, 2147 &subfont->local_subrs, NULL, NULL ); 2148 if ( error ) 2149 goto Exit; 2150 } 2151 2152 Exit: 2153 cff_parser_done( &parser ); /* free parser stack */ 2154 2155 return error; 2156 } 2157 2158 2159 static void cff_subfont_done(FT_Memory memory,CFF_SubFont subfont)2160 cff_subfont_done( FT_Memory memory, 2161 CFF_SubFont subfont ) 2162 { 2163 if ( subfont ) 2164 { 2165 cff_index_done( &subfont->local_subrs_index ); 2166 FT_FREE( subfont->local_subrs ); 2167 2168 FT_FREE( subfont->blend.lastNDV ); 2169 FT_FREE( subfont->blend.BV ); 2170 FT_FREE( subfont->blend_stack ); 2171 } 2172 } 2173 2174 2175 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)2176 cff_font_load( FT_Library library, 2177 FT_Stream stream, 2178 FT_Int face_index, 2179 CFF_Font font, 2180 CFF_Face face, 2181 FT_Bool pure_cff, 2182 FT_Bool cff2 ) 2183 { 2184 static const FT_Frame_Field cff_header_fields[] = 2185 { 2186 #undef FT_STRUCTURE 2187 #define FT_STRUCTURE CFF_FontRec 2188 2189 FT_FRAME_START( 3 ), 2190 FT_FRAME_BYTE( version_major ), 2191 FT_FRAME_BYTE( version_minor ), 2192 FT_FRAME_BYTE( header_size ), 2193 FT_FRAME_END 2194 }; 2195 2196 FT_Error error; 2197 FT_Memory memory = stream->memory; 2198 FT_ULong base_offset; 2199 CFF_FontRecDict dict; 2200 CFF_IndexRec string_index; 2201 FT_UInt subfont_index; 2202 2203 2204 FT_ZERO( font ); 2205 FT_ZERO( &string_index ); 2206 2207 dict = &font->top_font.font_dict; 2208 base_offset = FT_STREAM_POS(); 2209 2210 font->library = library; 2211 font->stream = stream; 2212 font->memory = memory; 2213 font->cff2 = cff2; 2214 font->base_offset = base_offset; 2215 2216 /* read CFF font header */ 2217 if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) ) 2218 goto Exit; 2219 2220 if ( cff2 ) 2221 { 2222 if ( font->version_major != 2 || 2223 font->header_size < 5 ) 2224 { 2225 FT_TRACE2(( " not a CFF2 font header\n" )); 2226 error = FT_THROW( Unknown_File_Format ); 2227 goto Exit; 2228 } 2229 2230 if ( FT_READ_USHORT( font->top_dict_length ) ) 2231 goto Exit; 2232 } 2233 else 2234 { 2235 FT_Byte absolute_offset; 2236 2237 2238 if ( FT_READ_BYTE( absolute_offset ) ) 2239 goto Exit; 2240 2241 if ( font->version_major != 1 || 2242 font->header_size < 4 || 2243 absolute_offset > 4 ) 2244 { 2245 FT_TRACE2(( " not a CFF font header\n" )); 2246 error = FT_THROW( Unknown_File_Format ); 2247 goto Exit; 2248 } 2249 } 2250 2251 /* skip the rest of the header */ 2252 if ( FT_STREAM_SEEK( base_offset + font->header_size ) ) 2253 { 2254 /* For pure CFFs we have read only four bytes so far. Contrary to */ 2255 /* other formats like SFNT those bytes doesn't define a signature; */ 2256 /* it is thus possible that the font isn't a CFF at all. */ 2257 if ( pure_cff ) 2258 { 2259 FT_TRACE2(( " not a CFF file\n" )); 2260 error = FT_THROW( Unknown_File_Format ); 2261 } 2262 goto Exit; 2263 } 2264 2265 if ( cff2 ) 2266 { 2267 /* For CFF2, the top dict data immediately follow the header */ 2268 /* and the length is stored in the header `offSize' field; */ 2269 /* there is no index for it. */ 2270 /* */ 2271 /* Use the `font_dict_index' to save the current position */ 2272 /* and length of data, but leave count at zero as an indicator. */ 2273 FT_ZERO( &font->font_dict_index ); 2274 2275 font->font_dict_index.data_offset = FT_STREAM_POS(); 2276 font->font_dict_index.data_size = font->top_dict_length; 2277 2278 /* skip the top dict data for now, we will parse it later */ 2279 if ( FT_STREAM_SKIP( font->top_dict_length ) ) 2280 goto Exit; 2281 2282 /* next, read the global subrs index */ 2283 if ( FT_SET_ERROR( cff_index_init( &font->global_subrs_index, 2284 stream, 1, cff2 ) ) ) 2285 goto Exit; 2286 } 2287 else 2288 { 2289 /* for CFF, read the name, top dict, string and global subrs index */ 2290 if ( FT_SET_ERROR( cff_index_init( &font->name_index, 2291 stream, 0, cff2 ) ) ) 2292 { 2293 if ( pure_cff ) 2294 { 2295 FT_TRACE2(( " not a CFF file\n" )); 2296 error = FT_THROW( Unknown_File_Format ); 2297 } 2298 goto Exit; 2299 } 2300 2301 /* if we have an empty font name, */ 2302 /* it must be the only font in the CFF */ 2303 if ( font->name_index.count > 1 && 2304 font->name_index.data_size < font->name_index.count ) 2305 { 2306 /* for pure CFFs, we still haven't checked enough bytes */ 2307 /* to be sure that it is a CFF at all */ 2308 error = pure_cff ? FT_THROW( Unknown_File_Format ) 2309 : FT_THROW( Invalid_File_Format ); 2310 goto Exit; 2311 } 2312 2313 if ( FT_SET_ERROR( cff_index_init( &font->font_dict_index, 2314 stream, 0, cff2 ) ) || 2315 FT_SET_ERROR( cff_index_init( &string_index, 2316 stream, 1, cff2 ) ) || 2317 FT_SET_ERROR( cff_index_init( &font->global_subrs_index, 2318 stream, 1, cff2 ) ) || 2319 FT_SET_ERROR( cff_index_get_pointers( &string_index, 2320 &font->strings, 2321 &font->string_pool, 2322 &font->string_pool_size ) ) ) 2323 goto Exit; 2324 2325 /* there must be a Top DICT index entry for each name index entry */ 2326 if ( font->name_index.count > font->font_dict_index.count ) 2327 { 2328 FT_ERROR(( "cff_font_load:" 2329 " not enough entries in Top DICT index\n" )); 2330 error = FT_THROW( Invalid_File_Format ); 2331 goto Exit; 2332 } 2333 } 2334 2335 font->num_strings = string_index.count; 2336 2337 if ( pure_cff ) 2338 { 2339 /* well, we don't really forget the `disabled' fonts... */ 2340 subfont_index = (FT_UInt)( face_index & 0xFFFF ); 2341 2342 if ( face_index > 0 && subfont_index >= font->name_index.count ) 2343 { 2344 FT_ERROR(( "cff_font_load:" 2345 " invalid subfont index for pure CFF font (%d)\n", 2346 subfont_index )); 2347 error = FT_THROW( Invalid_Argument ); 2348 goto Exit; 2349 } 2350 2351 font->num_faces = font->name_index.count; 2352 } 2353 else 2354 { 2355 subfont_index = 0; 2356 2357 if ( font->name_index.count > 1 ) 2358 { 2359 FT_ERROR(( "cff_font_load:" 2360 " invalid CFF font with multiple subfonts\n" 2361 " " 2362 " in SFNT wrapper\n" )); 2363 error = FT_THROW( Invalid_File_Format ); 2364 goto Exit; 2365 } 2366 } 2367 2368 /* in case of a font format check, simply exit now */ 2369 if ( face_index < 0 ) 2370 goto Exit; 2371 2372 /* now, parse the top-level font dictionary */ 2373 FT_TRACE4(( "parsing top-level\n" )); 2374 error = cff_subfont_load( &font->top_font, 2375 &font->font_dict_index, 2376 subfont_index, 2377 stream, 2378 base_offset, 2379 cff2 ? CFF2_CODE_TOPDICT : CFF_CODE_TOPDICT, 2380 font, 2381 face ); 2382 if ( error ) 2383 goto Exit; 2384 2385 if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) ) 2386 goto Exit; 2387 2388 error = cff_index_init( &font->charstrings_index, stream, 0, cff2 ); 2389 if ( error ) 2390 goto Exit; 2391 2392 /* now, check for a CID or CFF2 font */ 2393 if ( dict->cid_registry != 0xFFFFU || 2394 cff2 ) 2395 { 2396 CFF_IndexRec fd_index; 2397 CFF_SubFont sub = NULL; 2398 FT_UInt idx; 2399 2400 2401 /* for CFF2, read the Variation Store if available; */ 2402 /* this must follow the Top DICT parse and precede any Private DICT */ 2403 error = cff_vstore_load( &font->vstore, 2404 stream, 2405 base_offset, 2406 dict->vstore_offset ); 2407 if ( error ) 2408 goto Exit; 2409 2410 /* this is a CID-keyed font, we must now allocate a table of */ 2411 /* sub-fonts, then load each of them separately */ 2412 if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) ) 2413 goto Exit; 2414 2415 error = cff_index_init( &fd_index, stream, 0, cff2 ); 2416 if ( error ) 2417 goto Exit; 2418 2419 /* Font Dicts are not limited to 256 for CFF2. */ 2420 /* TODO: support this for CFF2 */ 2421 if ( fd_index.count > CFF_MAX_CID_FONTS ) 2422 { 2423 FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" )); 2424 goto Fail_CID; 2425 } 2426 2427 /* allocate & read each font dict independently */ 2428 font->num_subfonts = fd_index.count; 2429 if ( FT_NEW_ARRAY( sub, fd_index.count ) ) 2430 goto Fail_CID; 2431 2432 /* set up pointer table */ 2433 for ( idx = 0; idx < fd_index.count; idx++ ) 2434 font->subfonts[idx] = sub + idx; 2435 2436 /* now load each subfont independently */ 2437 for ( idx = 0; idx < fd_index.count; idx++ ) 2438 { 2439 sub = font->subfonts[idx]; 2440 FT_TRACE4(( "parsing subfont %u\n", idx )); 2441 error = cff_subfont_load( sub, 2442 &fd_index, 2443 idx, 2444 stream, 2445 base_offset, 2446 cff2 ? CFF2_CODE_FONTDICT 2447 : CFF_CODE_TOPDICT, 2448 font, 2449 face ); 2450 if ( error ) 2451 goto Fail_CID; 2452 } 2453 2454 /* now load the FD Select array; */ 2455 /* CFF2 omits FDSelect if there is only one FD */ 2456 if ( !cff2 || fd_index.count > 1 ) 2457 error = CFF_Load_FD_Select( &font->fd_select, 2458 font->charstrings_index.count, 2459 stream, 2460 base_offset + dict->cid_fd_select_offset ); 2461 2462 Fail_CID: 2463 cff_index_done( &fd_index ); 2464 2465 if ( error ) 2466 goto Exit; 2467 } 2468 else 2469 font->num_subfonts = 0; 2470 2471 /* read the charstrings index now */ 2472 if ( dict->charstrings_offset == 0 ) 2473 { 2474 FT_ERROR(( "cff_font_load: no charstrings offset\n" )); 2475 error = FT_THROW( Invalid_File_Format ); 2476 goto Exit; 2477 } 2478 2479 font->num_glyphs = font->charstrings_index.count; 2480 2481 error = cff_index_get_pointers( &font->global_subrs_index, 2482 &font->global_subrs, NULL, NULL ); 2483 2484 if ( error ) 2485 goto Exit; 2486 2487 /* read the Charset and Encoding tables if available */ 2488 if ( !cff2 && font->num_glyphs > 0 ) 2489 { 2490 FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff ); 2491 2492 2493 error = cff_charset_load( &font->charset, font->num_glyphs, stream, 2494 base_offset, dict->charset_offset, invert ); 2495 if ( error ) 2496 goto Exit; 2497 2498 /* CID-keyed CFFs don't have an encoding */ 2499 if ( dict->cid_registry == 0xFFFFU ) 2500 { 2501 error = cff_encoding_load( &font->encoding, 2502 &font->charset, 2503 font->num_glyphs, 2504 stream, 2505 base_offset, 2506 dict->encoding_offset ); 2507 if ( error ) 2508 goto Exit; 2509 } 2510 } 2511 2512 /* get the font name (/CIDFontName for CID-keyed fonts, */ 2513 /* /FontName otherwise) */ 2514 font->font_name = cff_index_get_name( font, subfont_index ); 2515 2516 Exit: 2517 cff_index_done( &string_index ); 2518 2519 return error; 2520 } 2521 2522 2523 FT_LOCAL_DEF( void ) cff_font_done(CFF_Font font)2524 cff_font_done( CFF_Font font ) 2525 { 2526 FT_Memory memory = font->memory; 2527 FT_UInt idx; 2528 2529 2530 cff_index_done( &font->global_subrs_index ); 2531 cff_index_done( &font->font_dict_index ); 2532 cff_index_done( &font->name_index ); 2533 cff_index_done( &font->charstrings_index ); 2534 2535 /* release font dictionaries, but only if working with */ 2536 /* a CID keyed CFF font or a CFF2 font */ 2537 if ( font->num_subfonts > 0 ) 2538 { 2539 for ( idx = 0; idx < font->num_subfonts; idx++ ) 2540 cff_subfont_done( memory, font->subfonts[idx] ); 2541 2542 /* the subfonts array has been allocated as a single block */ 2543 FT_FREE( font->subfonts[0] ); 2544 } 2545 2546 cff_encoding_done( &font->encoding ); 2547 cff_charset_done( &font->charset, font->stream ); 2548 cff_vstore_done( &font->vstore, memory ); 2549 2550 cff_subfont_done( memory, &font->top_font ); 2551 2552 CFF_Done_FD_Select( &font->fd_select, font->stream ); 2553 2554 FT_FREE( font->font_info ); 2555 2556 FT_FREE( font->font_name ); 2557 FT_FREE( font->global_subrs ); 2558 FT_FREE( font->strings ); 2559 FT_FREE( font->string_pool ); 2560 2561 if ( font->cf2_instance.finalizer ) 2562 { 2563 font->cf2_instance.finalizer( font->cf2_instance.data ); 2564 FT_FREE( font->cf2_instance.data ); 2565 } 2566 2567 FT_FREE( font->font_extra ); 2568 } 2569 2570 2571 /* END */ 2572