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