1 /**************************************************************************** 2 * 3 * cffload.c 4 * 5 * OpenType and CFF data/program tables loader (body). 6 * 7 * Copyright (C) 1996-2023 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 ) cff_get_standard_encoding(FT_UInt charcode)191 cff_get_standard_encoding( FT_UInt charcode ) 192 { 193 return (FT_UShort)( charcode < 256 ? cff_standard_encoding[charcode] 194 : 0 ); 195 } 196 197 198 /************************************************************************** 199 * 200 * The macro FT_COMPONENT is used in trace mode. It is an implicit 201 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log 202 * messages during execution. 203 */ 204 #undef FT_COMPONENT 205 #define FT_COMPONENT cffload 206 207 208 /* read an offset from the index's stream current position */ 209 static FT_ULong cff_index_read_offset(CFF_Index idx,FT_Error * errorp)210 cff_index_read_offset( CFF_Index idx, 211 FT_Error *errorp ) 212 { 213 FT_Error error; 214 FT_Stream stream = idx->stream; 215 FT_Byte tmp[4]; 216 FT_ULong result = 0; 217 218 219 if ( !FT_STREAM_READ( tmp, idx->off_size ) ) 220 { 221 FT_Int nn; 222 223 224 for ( nn = 0; nn < idx->off_size; nn++ ) 225 result = ( result << 8 ) | tmp[nn]; 226 } 227 228 *errorp = error; 229 return result; 230 } 231 232 233 static FT_Error cff_index_init(CFF_Index idx,FT_Stream stream,FT_Bool load,FT_Bool cff2)234 cff_index_init( CFF_Index idx, 235 FT_Stream stream, 236 FT_Bool load, 237 FT_Bool cff2 ) 238 { 239 FT_Error error; 240 FT_Memory memory = stream->memory; 241 FT_UInt count; 242 243 244 FT_ZERO( idx ); 245 246 idx->stream = stream; 247 idx->start = FT_STREAM_POS(); 248 249 if ( cff2 ) 250 { 251 if ( FT_READ_ULONG( count ) ) 252 goto Exit; 253 idx->hdr_size = 5; 254 } 255 else 256 { 257 if ( FT_READ_USHORT( count ) ) 258 goto Exit; 259 idx->hdr_size = 3; 260 } 261 262 if ( count > 0 ) 263 { 264 FT_Byte offsize; 265 FT_ULong size; 266 267 268 /* there is at least one element; read the offset size, */ 269 /* then access the offset table to compute the index's total size */ 270 if ( FT_READ_BYTE( offsize ) ) 271 goto Exit; 272 273 if ( offsize < 1 || offsize > 4 ) 274 { 275 error = FT_THROW( Invalid_Table ); 276 goto Exit; 277 } 278 279 idx->count = count; 280 idx->off_size = offsize; 281 size = (FT_ULong)( count + 1 ) * offsize; 282 283 idx->data_offset = idx->start + idx->hdr_size + size; 284 285 if ( FT_STREAM_SKIP( size - offsize ) ) 286 goto Exit; 287 288 size = cff_index_read_offset( idx, &error ); 289 if ( error ) 290 goto Exit; 291 292 if ( size == 0 ) 293 { 294 error = FT_THROW( Invalid_Table ); 295 goto Exit; 296 } 297 298 idx->data_size = --size; 299 300 if ( load ) 301 { 302 /* load the data */ 303 if ( FT_FRAME_EXTRACT( size, idx->bytes ) ) 304 goto Exit; 305 } 306 else 307 { 308 /* skip the data */ 309 if ( FT_STREAM_SKIP( size ) ) 310 goto Exit; 311 } 312 } 313 314 Exit: 315 if ( error ) 316 FT_FREE( idx->offsets ); 317 318 return error; 319 } 320 321 322 static void cff_index_done(CFF_Index idx)323 cff_index_done( CFF_Index idx ) 324 { 325 if ( idx->stream ) 326 { 327 FT_Stream stream = idx->stream; 328 FT_Memory memory = stream->memory; 329 330 331 if ( idx->bytes ) 332 FT_FRAME_RELEASE( idx->bytes ); 333 334 FT_FREE( idx->offsets ); 335 FT_ZERO( idx ); 336 } 337 } 338 339 340 static FT_Error cff_index_load_offsets(CFF_Index idx)341 cff_index_load_offsets( CFF_Index idx ) 342 { 343 FT_Error error = FT_Err_Ok; 344 FT_Stream stream = idx->stream; 345 FT_Memory memory = stream->memory; 346 347 348 if ( idx->count > 0 && !idx->offsets ) 349 { 350 FT_Byte offsize = idx->off_size; 351 FT_ULong data_size; 352 FT_Byte* p; 353 FT_Byte* p_end; 354 FT_ULong* poff; 355 356 357 data_size = (FT_ULong)( idx->count + 1 ) * offsize; 358 359 if ( FT_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 cff_index_get_pointers(CFF_Index idx,FT_Byte *** table,FT_Byte ** pool,FT_ULong * pool_size)405 cff_index_get_pointers( CFF_Index idx, 406 FT_Byte*** table, 407 FT_Byte** pool, 408 FT_ULong* pool_size ) 409 { 410 FT_Error error = FT_Err_Ok; 411 FT_Memory memory = idx->stream->memory; 412 413 FT_Byte** 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 %ld 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 ) cff_index_access_element(CFF_Index idx,FT_UInt element,FT_Byte ** pbytes,FT_ULong * pbyte_len)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 (%ld)" 563 " exceeds the end of stream (%ld)\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 ) cff_index_forget_element(CFF_Index idx,FT_Byte ** pbytes)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* ) cff_index_get_name(CFF_Font font,FT_UInt element)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* ) cff_index_get_string(CFF_Font font,FT_UInt element)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* ) cff_index_get_sid_string(CFF_Font font,FT_UInt sid)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 CFF_Done_FD_Select(CFF_FDSelect fdselect,FT_Stream stream)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 CFF_Load_FD_Select(CFF_FDSelect fdselect,FT_UInt num_glyphs,FT_Stream stream,FT_ULong offset)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 ) cff_fd_select_get(CFF_FDSelect fdselect,FT_UInt glyph_index)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 cff_charset_compute_cids(CFF_Charset charset,FT_UInt num_glyphs,FT_Memory memory)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 ) cff_charset_cid_to_gindex(CFF_Charset charset,FT_UInt cid)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 cff_charset_free_cids(CFF_Charset charset,FT_Memory memory)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 cff_charset_done(CFF_Charset charset,FT_Stream stream)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 cff_charset_load(CFF_Charset charset,FT_UInt num_glyphs,FT_Stream stream,FT_ULong base_offset,FT_ULong offset,FT_Bool invert)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=%d -> %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 cff_vstore_done(CFF_VStoreRec * vstore,FT_Memory memory)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 cff_vstore_load(CFF_VStoreRec * vstore,FT_Stream stream,FT_ULong base_offset,FT_ULong offset)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_Int16 start14, peak14, end14; 1206 1207 1208 if ( FT_READ_SHORT( start14 ) || 1209 FT_READ_SHORT( peak14 ) || 1210 FT_READ_SHORT( end14 ) ) 1211 goto Exit; 1212 1213 axis->startCoord = FT_fdot14ToFixed( start14 ); 1214 axis->peakCoord = FT_fdot14ToFixed( peak14 ); 1215 axis->endCoord = FT_fdot14ToFixed( end14 ); 1216 } 1217 } 1218 1219 /* use dataOffsetArray now to parse varData items */ 1220 vstore->dataCount = 0; 1221 if ( FT_QNEW_ARRAY( vstore->varData, dataCount ) ) 1222 goto Exit; 1223 1224 for ( i = 0; i < dataCount; i++ ) 1225 { 1226 CFF_VarData* data = &vstore->varData[i]; 1227 1228 1229 if ( FT_STREAM_SEEK( vsOffset + dataOffsetArray[i] ) ) 1230 goto Exit; 1231 1232 /* ignore `itemCount' and `shortDeltaCount' */ 1233 /* because CFF2 has no delta sets */ 1234 if ( FT_STREAM_SKIP( 4 ) ) 1235 goto Exit; 1236 1237 /* Note: just record values; consistency is checked later */ 1238 /* by cff_blend_build_vector when it consumes `vstore' */ 1239 1240 if ( FT_READ_USHORT( data->regionIdxCount ) ) 1241 goto Exit; 1242 1243 if ( FT_QNEW_ARRAY( data->regionIndices, data->regionIdxCount ) ) 1244 goto Exit; 1245 1246 /* keep track of how many regionIndices to deallocate on error */ 1247 vstore->dataCount++; 1248 1249 for ( j = 0; j < data->regionIdxCount; j++ ) 1250 { 1251 if ( FT_READ_USHORT( data->regionIndices[j] ) ) 1252 goto Exit; 1253 } 1254 } 1255 } 1256 1257 error = FT_Err_Ok; 1258 1259 Exit: 1260 FT_FREE( dataOffsetArray ); 1261 if ( error ) 1262 cff_vstore_done( vstore, memory ); 1263 1264 return error; 1265 } 1266 1267 1268 /* Clear blend stack (after blend values are consumed). */ 1269 /* */ 1270 /* TODO: Should do this in cff_run_parse, but subFont */ 1271 /* ref is not available there. */ 1272 /* */ 1273 /* Allocation is not changed when stack is cleared. */ 1274 FT_LOCAL_DEF( void ) cff_blend_clear(CFF_SubFont subFont)1275 cff_blend_clear( CFF_SubFont subFont ) 1276 { 1277 subFont->blend_top = subFont->blend_stack; 1278 subFont->blend_used = 0; 1279 } 1280 1281 1282 /* Blend numOperands on the stack, */ 1283 /* store results into the first numBlends values, */ 1284 /* then pop remaining arguments. */ 1285 /* */ 1286 /* This is comparable to `cf2_doBlend' but */ 1287 /* the cffparse stack is different and can't be written. */ 1288 /* Blended values are written to a different buffer, */ 1289 /* using reserved operator 255. */ 1290 /* */ 1291 /* Blend calculation is done in 16.16 fixed-point. */ 1292 FT_LOCAL_DEF( FT_Error ) cff_blend_doBlend(CFF_SubFont subFont,CFF_Parser parser,FT_UInt numBlends)1293 cff_blend_doBlend( CFF_SubFont subFont, 1294 CFF_Parser parser, 1295 FT_UInt numBlends ) 1296 { 1297 FT_UInt delta; 1298 FT_UInt base; 1299 FT_UInt i, j; 1300 FT_UInt size; 1301 1302 CFF_Blend blend = &subFont->blend; 1303 1304 FT_Memory memory = subFont->blend.font->memory; /* for FT_REALLOC */ 1305 FT_Error error = FT_Err_Ok; /* for FT_REALLOC */ 1306 1307 /* compute expected number of operands for this blend */ 1308 FT_UInt numOperands = (FT_UInt)( numBlends * blend->lenBV ); 1309 FT_UInt count = (FT_UInt)( parser->top - 1 - parser->stack ); 1310 1311 1312 if ( numOperands > count ) 1313 { 1314 FT_TRACE4(( " cff_blend_doBlend: Stack underflow %d argument%s\n", 1315 count, 1316 count == 1 ? "" : "s" )); 1317 1318 error = FT_THROW( Stack_Underflow ); 1319 goto Exit; 1320 } 1321 1322 /* check whether we have room for `numBlends' values at `blend_top' */ 1323 size = 5 * numBlends; /* add 5 bytes per entry */ 1324 if ( subFont->blend_used + size > subFont->blend_alloc ) 1325 { 1326 FT_Byte* blend_stack_old = subFont->blend_stack; 1327 FT_Byte* blend_top_old = subFont->blend_top; 1328 1329 1330 /* increase or allocate `blend_stack' and reset `blend_top'; */ 1331 /* prepare to append `numBlends' values to the buffer */ 1332 if ( FT_QREALLOC( subFont->blend_stack, 1333 subFont->blend_alloc, 1334 subFont->blend_alloc + size ) ) 1335 goto Exit; 1336 1337 subFont->blend_top = subFont->blend_stack + subFont->blend_used; 1338 subFont->blend_alloc += size; 1339 1340 /* iterate over the parser stack and adjust pointers */ 1341 /* if the reallocated buffer has a different address */ 1342 if ( blend_stack_old && 1343 subFont->blend_stack != blend_stack_old ) 1344 { 1345 FT_PtrDist offset = subFont->blend_stack - blend_stack_old; 1346 FT_Byte** p; 1347 1348 1349 for ( p = parser->stack; p < parser->top; p++ ) 1350 { 1351 if ( *p >= blend_stack_old && *p < blend_top_old ) 1352 *p += offset; 1353 } 1354 } 1355 } 1356 subFont->blend_used += size; 1357 1358 base = count - numOperands; /* index of first blend arg */ 1359 delta = base + numBlends; /* index of first delta arg */ 1360 1361 for ( i = 0; i < numBlends; i++ ) 1362 { 1363 const FT_Int32* weight = &blend->BV[1]; 1364 FT_Fixed sum; 1365 1366 1367 /* convert inputs to 16.16 fixed point */ 1368 sum = cff_parse_fixed( parser, &parser->stack[i + base] ); 1369 1370 for ( j = 1; j < blend->lenBV; j++ ) 1371 sum += FT_MulFix( cff_parse_fixed( parser, &parser->stack[delta++] ), 1372 *weight++ ); 1373 1374 /* point parser stack to new value on blend_stack */ 1375 parser->stack[i + base] = subFont->blend_top; 1376 1377 /* Push blended result as Type 2 5-byte fixed-point number. This */ 1378 /* will not conflict with actual DICTs because 255 is a reserved */ 1379 /* opcode in both CFF and CFF2 DICTs. See `cff_parse_num' for */ 1380 /* decode of this, which rounds to an integer. */ 1381 *subFont->blend_top++ = 255; 1382 *subFont->blend_top++ = (FT_Byte)( sum >> 24 ); 1383 *subFont->blend_top++ = (FT_Byte)( sum >> 16 ); 1384 *subFont->blend_top++ = (FT_Byte)( sum >> 8 ); 1385 *subFont->blend_top++ = (FT_Byte)sum; 1386 } 1387 1388 /* leave only numBlends results on parser stack */ 1389 parser->top = &parser->stack[base + numBlends]; 1390 1391 Exit: 1392 return error; 1393 } 1394 1395 1396 /* Compute a blend vector from variation store index and normalized */ 1397 /* vector based on pseudo-code in OpenType Font Variations Overview. */ 1398 /* */ 1399 /* Note: lenNDV == 0 produces a default blend vector, (1,0,0,...). */ 1400 FT_LOCAL_DEF( FT_Error ) cff_blend_build_vector(CFF_Blend blend,FT_UInt vsindex,FT_UInt lenNDV,FT_Fixed * NDV)1401 cff_blend_build_vector( CFF_Blend blend, 1402 FT_UInt vsindex, 1403 FT_UInt lenNDV, 1404 FT_Fixed* NDV ) 1405 { 1406 FT_Error error = FT_Err_Ok; /* for FT_REALLOC */ 1407 FT_Memory memory = blend->font->memory; /* for FT_REALLOC */ 1408 1409 FT_UInt len; 1410 CFF_VStore vs; 1411 CFF_VarData* varData; 1412 FT_UInt master; 1413 1414 1415 /* protect against malformed fonts */ 1416 if ( !( lenNDV == 0 || NDV ) ) 1417 { 1418 FT_TRACE4(( " cff_blend_build_vector:" 1419 " Malformed Normalize Design Vector data\n" )); 1420 error = FT_THROW( Invalid_File_Format ); 1421 goto Exit; 1422 } 1423 1424 blend->builtBV = FALSE; 1425 1426 vs = &blend->font->vstore; 1427 1428 /* VStore and fvar must be consistent */ 1429 if ( lenNDV != 0 && lenNDV != vs->axisCount ) 1430 { 1431 FT_TRACE4(( " cff_blend_build_vector: Axis count mismatch\n" )); 1432 error = FT_THROW( Invalid_File_Format ); 1433 goto Exit; 1434 } 1435 1436 if ( vsindex >= vs->dataCount ) 1437 { 1438 FT_TRACE4(( " cff_blend_build_vector: vsindex out of range\n" )); 1439 error = FT_THROW( Invalid_File_Format ); 1440 goto Exit; 1441 } 1442 1443 /* select the item variation data structure */ 1444 varData = &vs->varData[vsindex]; 1445 1446 /* prepare buffer for the blend vector */ 1447 len = varData->regionIdxCount + 1; /* add 1 for default component */ 1448 if ( FT_QRENEW_ARRAY( blend->BV, blend->lenBV, len ) ) 1449 goto Exit; 1450 1451 blend->lenBV = len; 1452 1453 /* outer loop steps through master designs to be blended */ 1454 for ( master = 0; master < len; master++ ) 1455 { 1456 FT_UInt j; 1457 FT_UInt idx; 1458 CFF_VarRegion* varRegion; 1459 1460 1461 /* default factor is always one */ 1462 if ( master == 0 ) 1463 { 1464 blend->BV[master] = FT_FIXED_ONE; 1465 FT_TRACE4(( " build blend vector len %d\n", len )); 1466 FT_TRACE4(( " [ %f ", blend->BV[master] / 65536.0 )); 1467 continue; 1468 } 1469 1470 /* VStore array does not include default master, so subtract one */ 1471 idx = varData->regionIndices[master - 1]; 1472 varRegion = &vs->varRegionList[idx]; 1473 1474 if ( idx >= vs->regionCount ) 1475 { 1476 FT_TRACE4(( " cff_blend_build_vector:" 1477 " region index out of range\n" )); 1478 error = FT_THROW( Invalid_File_Format ); 1479 goto Exit; 1480 } 1481 1482 /* Note: `lenNDV' could be zero. */ 1483 /* In that case, build default blend vector (1,0,0...). */ 1484 if ( !lenNDV ) 1485 { 1486 blend->BV[master] = 0; 1487 continue; 1488 } 1489 1490 /* In the normal case, initialize each component to 1 */ 1491 /* before inner loop. */ 1492 blend->BV[master] = FT_FIXED_ONE; /* default */ 1493 1494 /* inner loop steps through axes in this region */ 1495 for ( j = 0; j < lenNDV; j++ ) 1496 { 1497 CFF_AxisCoords* axis = &varRegion->axisList[j]; 1498 FT_Fixed axisScalar; 1499 1500 1501 /* compute the scalar contribution of this axis; */ 1502 /* ignore invalid ranges */ 1503 if ( axis->startCoord > axis->peakCoord || 1504 axis->peakCoord > axis->endCoord ) 1505 axisScalar = FT_FIXED_ONE; 1506 1507 else if ( axis->startCoord < 0 && 1508 axis->endCoord > 0 && 1509 axis->peakCoord != 0 ) 1510 axisScalar = FT_FIXED_ONE; 1511 1512 /* peak of 0 means ignore this axis */ 1513 else if ( axis->peakCoord == 0 ) 1514 axisScalar = FT_FIXED_ONE; 1515 1516 /* ignore this region if coords are out of range */ 1517 else if ( NDV[j] < axis->startCoord || 1518 NDV[j] > axis->endCoord ) 1519 axisScalar = 0; 1520 1521 /* calculate a proportional factor */ 1522 else 1523 { 1524 if ( NDV[j] == axis->peakCoord ) 1525 axisScalar = FT_FIXED_ONE; 1526 else if ( NDV[j] < axis->peakCoord ) 1527 axisScalar = FT_DivFix( NDV[j] - axis->startCoord, 1528 axis->peakCoord - axis->startCoord ); 1529 else 1530 axisScalar = FT_DivFix( axis->endCoord - NDV[j], 1531 axis->endCoord - axis->peakCoord ); 1532 } 1533 1534 /* take product of all the axis scalars */ 1535 blend->BV[master] = FT_MulFix( blend->BV[master], axisScalar ); 1536 } 1537 1538 FT_TRACE4(( ", %f ", 1539 blend->BV[master] / 65536.0 )); 1540 } 1541 1542 FT_TRACE4(( "]\n" )); 1543 1544 /* record the parameters used to build the blend vector */ 1545 blend->lastVsindex = vsindex; 1546 1547 if ( lenNDV != 0 ) 1548 { 1549 /* user has set a normalized vector */ 1550 if ( FT_QRENEW_ARRAY( blend->lastNDV, blend->lenNDV, lenNDV ) ) 1551 goto Exit; 1552 1553 FT_MEM_COPY( blend->lastNDV, 1554 NDV, 1555 lenNDV * sizeof ( *NDV ) ); 1556 } 1557 1558 blend->lenNDV = lenNDV; 1559 blend->builtBV = TRUE; 1560 1561 Exit: 1562 return error; 1563 } 1564 1565 1566 /* `lenNDV' is zero for default vector; */ 1567 /* return TRUE if blend vector needs to be built. */ 1568 FT_LOCAL_DEF( FT_Bool ) cff_blend_check_vector(CFF_Blend blend,FT_UInt vsindex,FT_UInt lenNDV,FT_Fixed * NDV)1569 cff_blend_check_vector( CFF_Blend blend, 1570 FT_UInt vsindex, 1571 FT_UInt lenNDV, 1572 FT_Fixed* NDV ) 1573 { 1574 if ( !blend->builtBV || 1575 blend->lastVsindex != vsindex || 1576 blend->lenNDV != lenNDV || 1577 ( lenNDV && 1578 ft_memcmp( NDV, 1579 blend->lastNDV, 1580 lenNDV * sizeof ( *NDV ) ) != 0 ) ) 1581 { 1582 /* need to build blend vector */ 1583 return TRUE; 1584 } 1585 1586 return FALSE; 1587 } 1588 1589 1590 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT 1591 1592 FT_LOCAL_DEF( FT_Error ) cff_get_var_blend(FT_Face face,FT_UInt * num_coords,FT_Fixed ** coords,FT_Fixed ** normalizedcoords,FT_MM_Var ** mm_var)1593 cff_get_var_blend( FT_Face face, /* CFF_Face */ 1594 FT_UInt *num_coords, 1595 FT_Fixed* *coords, 1596 FT_Fixed* *normalizedcoords, 1597 FT_MM_Var* *mm_var ) 1598 { 1599 CFF_Face cffface = (CFF_Face)face; 1600 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; 1601 1602 1603 return mm->get_var_blend( face, 1604 num_coords, 1605 coords, 1606 normalizedcoords, 1607 mm_var ); 1608 } 1609 1610 1611 FT_LOCAL_DEF( void ) cff_done_blend(FT_Face face)1612 cff_done_blend( FT_Face face ) /* CFF_Face */ 1613 { 1614 CFF_Face cffface = (CFF_Face)face; 1615 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm; 1616 1617 1618 if ( mm ) 1619 mm->done_blend( face ); 1620 } 1621 1622 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ 1623 1624 1625 static void cff_encoding_done(CFF_Encoding encoding)1626 cff_encoding_done( CFF_Encoding encoding ) 1627 { 1628 encoding->format = 0; 1629 encoding->offset = 0; 1630 encoding->count = 0; 1631 } 1632 1633 1634 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)1635 cff_encoding_load( CFF_Encoding encoding, 1636 CFF_Charset charset, 1637 FT_UInt num_glyphs, 1638 FT_Stream stream, 1639 FT_ULong base_offset, 1640 FT_ULong offset ) 1641 { 1642 FT_Error error = FT_Err_Ok; 1643 FT_UInt count; 1644 FT_UInt j; 1645 FT_UShort glyph_sid; 1646 FT_UInt glyph_code; 1647 1648 1649 /* Check for charset->sids. If we do not have this, we fail. */ 1650 if ( !charset->sids ) 1651 { 1652 error = FT_THROW( Invalid_File_Format ); 1653 goto Exit; 1654 } 1655 1656 /* Note: The encoding table in a CFF font is indexed by glyph index; */ 1657 /* the first encoded glyph index is 1. Hence, we read the character */ 1658 /* code (`glyph_code') at index j and make the assignment: */ 1659 /* */ 1660 /* encoding->codes[glyph_code] = j + 1 */ 1661 /* */ 1662 /* We also make the assignment: */ 1663 /* */ 1664 /* encoding->sids[glyph_code] = charset->sids[j + 1] */ 1665 /* */ 1666 /* This gives us both a code to GID and a code to SID mapping. */ 1667 1668 if ( offset > 1 ) 1669 { 1670 /* Zero out the code to gid/sid mappings. */ 1671 FT_ARRAY_ZERO( encoding->sids, 256 ); 1672 FT_ARRAY_ZERO( encoding->codes, 256 ); 1673 1674 encoding->offset = base_offset + offset; 1675 1676 /* we need to parse the table to determine its size */ 1677 if ( FT_STREAM_SEEK( encoding->offset ) || 1678 FT_READ_BYTE( encoding->format ) || 1679 FT_READ_BYTE( count ) ) 1680 goto Exit; 1681 1682 switch ( encoding->format & 0x7F ) 1683 { 1684 case 0: 1685 { 1686 FT_Byte* p; 1687 1688 1689 /* By convention, GID 0 is always ".notdef" and is never */ 1690 /* coded in the font. Hence, the number of codes found */ 1691 /* in the table is `count+1'. */ 1692 /* */ 1693 encoding->count = count + 1; 1694 1695 if ( FT_FRAME_ENTER( count ) ) 1696 goto Exit; 1697 1698 p = (FT_Byte*)stream->cursor; 1699 1700 for ( j = 1; j <= count; j++ ) 1701 { 1702 glyph_code = *p++; 1703 1704 /* Make sure j is not too big. */ 1705 if ( j < num_glyphs ) 1706 { 1707 /* Assign code to GID mapping. */ 1708 encoding->codes[glyph_code] = (FT_UShort)j; 1709 1710 /* Assign code to SID mapping. */ 1711 encoding->sids[glyph_code] = charset->sids[j]; 1712 } 1713 } 1714 1715 FT_FRAME_EXIT(); 1716 } 1717 break; 1718 1719 case 1: 1720 { 1721 FT_UInt nleft; 1722 FT_UInt i = 1; 1723 FT_UInt k; 1724 1725 1726 encoding->count = 0; 1727 1728 /* Parse the Format1 ranges. */ 1729 for ( j = 0; j < count; j++, i += nleft ) 1730 { 1731 /* Read the first glyph code of the range. */ 1732 if ( FT_READ_BYTE( glyph_code ) ) 1733 goto Exit; 1734 1735 /* Read the number of codes in the range. */ 1736 if ( FT_READ_BYTE( nleft ) ) 1737 goto Exit; 1738 1739 /* Increment nleft, so we read `nleft + 1' codes/sids. */ 1740 nleft++; 1741 1742 /* compute max number of character codes */ 1743 if ( (FT_UInt)nleft > encoding->count ) 1744 encoding->count = nleft; 1745 1746 /* Fill in the range of codes/sids. */ 1747 for ( k = i; k < nleft + i; k++, glyph_code++ ) 1748 { 1749 /* Make sure k is not too big. */ 1750 if ( k < num_glyphs && glyph_code < 256 ) 1751 { 1752 /* Assign code to GID mapping. */ 1753 encoding->codes[glyph_code] = (FT_UShort)k; 1754 1755 /* Assign code to SID mapping. */ 1756 encoding->sids[glyph_code] = charset->sids[k]; 1757 } 1758 } 1759 } 1760 1761 /* simple check; one never knows what can be found in a font */ 1762 if ( encoding->count > 256 ) 1763 encoding->count = 256; 1764 } 1765 break; 1766 1767 default: 1768 FT_ERROR(( "cff_encoding_load: invalid table format\n" )); 1769 error = FT_THROW( Invalid_File_Format ); 1770 goto Exit; 1771 } 1772 1773 /* Parse supplemental encodings, if any. */ 1774 if ( encoding->format & 0x80 ) 1775 { 1776 FT_UInt gindex; 1777 1778 1779 /* count supplements */ 1780 if ( FT_READ_BYTE( count ) ) 1781 goto Exit; 1782 1783 for ( j = 0; j < count; j++ ) 1784 { 1785 /* Read supplemental glyph code. */ 1786 if ( FT_READ_BYTE( glyph_code ) ) 1787 goto Exit; 1788 1789 /* Read the SID associated with this glyph code. */ 1790 if ( FT_READ_USHORT( glyph_sid ) ) 1791 goto Exit; 1792 1793 /* Assign code to SID mapping. */ 1794 encoding->sids[glyph_code] = glyph_sid; 1795 1796 /* First, look up GID which has been assigned to */ 1797 /* SID glyph_sid. */ 1798 for ( gindex = 0; gindex < num_glyphs; gindex++ ) 1799 { 1800 if ( charset->sids[gindex] == glyph_sid ) 1801 { 1802 encoding->codes[glyph_code] = (FT_UShort)gindex; 1803 break; 1804 } 1805 } 1806 } 1807 } 1808 } 1809 else 1810 { 1811 /* We take into account the fact a CFF font can use a predefined */ 1812 /* encoding without containing all of the glyphs encoded by this */ 1813 /* encoding (see the note at the end of section 12 in the CFF */ 1814 /* specification). */ 1815 1816 switch ( (FT_UInt)offset ) 1817 { 1818 case 0: 1819 /* First, copy the code to SID mapping. */ 1820 FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 ); 1821 goto Populate; 1822 1823 case 1: 1824 /* First, copy the code to SID mapping. */ 1825 FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 ); 1826 1827 Populate: 1828 /* Construct code to GID mapping from code to SID mapping */ 1829 /* and charset. */ 1830 1831 encoding->offset = offset; /* used in cff_face_init */ 1832 encoding->count = 0; 1833 1834 error = cff_charset_compute_cids( charset, num_glyphs, 1835 stream->memory ); 1836 if ( error ) 1837 goto Exit; 1838 1839 for ( j = 0; j < 256; j++ ) 1840 { 1841 FT_UInt sid = encoding->sids[j]; 1842 FT_UInt gid = 0; 1843 1844 1845 if ( sid ) 1846 gid = cff_charset_cid_to_gindex( charset, sid ); 1847 1848 if ( gid != 0 ) 1849 { 1850 encoding->codes[j] = (FT_UShort)gid; 1851 encoding->count = j + 1; 1852 } 1853 else 1854 { 1855 encoding->codes[j] = 0; 1856 encoding->sids [j] = 0; 1857 } 1858 } 1859 break; 1860 1861 default: 1862 FT_ERROR(( "cff_encoding_load: invalid table format\n" )); 1863 error = FT_THROW( Invalid_File_Format ); 1864 goto Exit; 1865 } 1866 } 1867 1868 Exit: 1869 1870 /* Clean up if there was an error. */ 1871 return error; 1872 } 1873 1874 1875 /* Parse private dictionary; first call is always from `cff_face_init', */ 1876 /* so NDV has not been set for CFF2 variation. */ 1877 /* */ 1878 /* `cff_slot_load' must call this function each time NDV changes. */ 1879 FT_LOCAL_DEF( FT_Error ) cff_load_private_dict(CFF_Font font,CFF_SubFont subfont,FT_UInt lenNDV,FT_Fixed * NDV)1880 cff_load_private_dict( CFF_Font font, 1881 CFF_SubFont subfont, 1882 FT_UInt lenNDV, 1883 FT_Fixed* NDV ) 1884 { 1885 FT_Error error = FT_Err_Ok; 1886 CFF_ParserRec parser; 1887 CFF_FontRecDict top = &subfont->font_dict; 1888 CFF_Private priv = &subfont->private_dict; 1889 FT_Stream stream = font->stream; 1890 FT_UInt stackSize; 1891 1892 1893 /* store handle needed to access memory, vstore for blend; */ 1894 /* we need this for clean-up even if there is no private DICT */ 1895 subfont->blend.font = font; 1896 subfont->blend.usedBV = FALSE; /* clear state */ 1897 1898 if ( !top->private_offset || !top->private_size ) 1899 goto Exit2; /* no private DICT, do nothing */ 1900 1901 /* set defaults */ 1902 FT_ZERO( priv ); 1903 1904 priv->blue_shift = 7; 1905 priv->blue_fuzz = 1; 1906 priv->lenIV = -1; 1907 priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); 1908 priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 ); 1909 1910 /* provide inputs for blend calculations */ 1911 priv->subfont = subfont; 1912 subfont->lenNDV = lenNDV; 1913 subfont->NDV = NDV; 1914 1915 /* add 1 for the operator */ 1916 stackSize = font->cff2 ? font->top_font.font_dict.maxstack + 1 1917 : CFF_MAX_STACK_DEPTH + 1; 1918 1919 if ( cff_parser_init( &parser, 1920 font->cff2 ? CFF2_CODE_PRIVATE : CFF_CODE_PRIVATE, 1921 priv, 1922 font->library, 1923 stackSize, 1924 top->num_designs, 1925 top->num_axes ) ) 1926 goto Exit; 1927 1928 if ( FT_STREAM_SEEK( font->base_offset + top->private_offset ) || 1929 FT_FRAME_ENTER( top->private_size ) ) 1930 goto Exit; 1931 1932 FT_TRACE4(( " private dictionary:\n" )); 1933 error = cff_parser_run( &parser, 1934 (FT_Byte*)stream->cursor, 1935 (FT_Byte*)stream->limit ); 1936 FT_FRAME_EXIT(); 1937 1938 if ( error ) 1939 goto Exit; 1940 1941 /* ensure that `num_blue_values' is even */ 1942 priv->num_blue_values &= ~1; 1943 1944 /* sanitize `initialRandomSeed' to be a positive value, if necessary; */ 1945 /* this is not mandated by the specification but by our implementation */ 1946 if ( priv->initial_random_seed < 0 ) 1947 priv->initial_random_seed = -priv->initial_random_seed; 1948 else if ( priv->initial_random_seed == 0 ) 1949 priv->initial_random_seed = 987654321; 1950 1951 /* some sanitizing to avoid overflows later on; */ 1952 /* the upper limits are ad-hoc values */ 1953 if ( priv->blue_shift > 1000 || priv->blue_shift < 0 ) 1954 { 1955 FT_TRACE2(( "cff_load_private_dict:" 1956 " setting unlikely BlueShift value %ld to default (7)\n", 1957 priv->blue_shift )); 1958 priv->blue_shift = 7; 1959 } 1960 1961 if ( priv->blue_fuzz > 1000 || priv->blue_fuzz < 0 ) 1962 { 1963 FT_TRACE2(( "cff_load_private_dict:" 1964 " setting unlikely BlueFuzz value %ld to default (1)\n", 1965 priv->blue_fuzz )); 1966 priv->blue_fuzz = 1; 1967 } 1968 1969 Exit: 1970 /* clean up */ 1971 cff_blend_clear( subfont ); /* clear blend stack */ 1972 cff_parser_done( &parser ); /* free parser stack */ 1973 1974 Exit2: 1975 /* no clean up (parser not initialized) */ 1976 return error; 1977 } 1978 1979 1980 /* There are 3 ways to call this function, distinguished by code. */ 1981 /* */ 1982 /* . CFF_CODE_TOPDICT for either a CFF Top DICT or a CFF Font DICT */ 1983 /* . CFF2_CODE_TOPDICT for CFF2 Top DICT */ 1984 /* . CFF2_CODE_FONTDICT for CFF2 Font DICT */ 1985 1986 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)1987 cff_subfont_load( CFF_SubFont subfont, 1988 CFF_Index idx, 1989 FT_UInt font_index, 1990 FT_Stream stream, 1991 FT_ULong base_offset, 1992 FT_UInt code, 1993 CFF_Font font, 1994 CFF_Face face ) 1995 { 1996 FT_Error error; 1997 CFF_ParserRec parser; 1998 FT_Byte* dict = NULL; 1999 FT_ULong dict_len; 2000 CFF_FontRecDict top = &subfont->font_dict; 2001 CFF_Private priv = &subfont->private_dict; 2002 2003 PSAux_Service psaux = (PSAux_Service)face->psaux; 2004 2005 FT_Bool cff2 = FT_BOOL( code == CFF2_CODE_TOPDICT || 2006 code == CFF2_CODE_FONTDICT ); 2007 FT_UInt stackSize = cff2 ? CFF2_DEFAULT_STACK 2008 : CFF_MAX_STACK_DEPTH; 2009 2010 2011 /* Note: We use default stack size for CFF2 Font DICT because */ 2012 /* Top and Font DICTs are not allowed to have blend operators. */ 2013 error = cff_parser_init( &parser, 2014 code, 2015 top, 2016 font->library, 2017 stackSize, 2018 0, 2019 0 ); 2020 if ( error ) 2021 goto Exit; 2022 2023 /* set defaults */ 2024 FT_ZERO( top ); 2025 2026 top->underline_position = -( 100L << 16 ); 2027 top->underline_thickness = 50L << 16; 2028 top->charstring_type = 2; 2029 top->font_matrix.xx = 0x10000L; 2030 top->font_matrix.yy = 0x10000L; 2031 top->cid_count = 8720; 2032 2033 /* we use the implementation specific SID value 0xFFFF to indicate */ 2034 /* missing entries */ 2035 top->version = 0xFFFFU; 2036 top->notice = 0xFFFFU; 2037 top->copyright = 0xFFFFU; 2038 top->full_name = 0xFFFFU; 2039 top->family_name = 0xFFFFU; 2040 top->weight = 0xFFFFU; 2041 top->embedded_postscript = 0xFFFFU; 2042 2043 top->cid_registry = 0xFFFFU; 2044 top->cid_ordering = 0xFFFFU; 2045 top->cid_font_name = 0xFFFFU; 2046 2047 /* set default stack size */ 2048 top->maxstack = cff2 ? CFF2_DEFAULT_STACK : 48; 2049 2050 if ( idx->count ) /* count is nonzero for a real index */ 2051 error = cff_index_access_element( idx, font_index, &dict, &dict_len ); 2052 else 2053 { 2054 /* CFF2 has a fake top dict index; */ 2055 /* simulate `cff_index_access_element' */ 2056 2057 /* Note: macros implicitly use `stream' and set `error' */ 2058 if ( FT_STREAM_SEEK( idx->data_offset ) || 2059 FT_FRAME_EXTRACT( idx->data_size, dict ) ) 2060 goto Exit; 2061 2062 dict_len = idx->data_size; 2063 } 2064 2065 if ( !error ) 2066 { 2067 FT_TRACE4(( " top dictionary:\n" )); 2068 error = cff_parser_run( &parser, dict, FT_OFFSET( dict, dict_len ) ); 2069 } 2070 2071 /* clean up regardless of error */ 2072 if ( idx->count ) 2073 cff_index_forget_element( idx, &dict ); 2074 else 2075 FT_FRAME_RELEASE( dict ); 2076 2077 if ( error ) 2078 goto Exit; 2079 2080 /* if it is a CID font, we stop there */ 2081 if ( top->cid_registry != 0xFFFFU ) 2082 goto Exit; 2083 2084 /* Parse the private dictionary, if any. */ 2085 /* */ 2086 /* CFF2 does not have a private dictionary in the Top DICT */ 2087 /* but may have one in a Font DICT. We need to parse */ 2088 /* the latter here in order to load any local subrs. */ 2089 error = cff_load_private_dict( font, subfont, 0, 0 ); 2090 if ( error ) 2091 goto Exit; 2092 2093 if ( !cff2 ) 2094 { 2095 /* 2096 * Initialize the random number generator. 2097 * 2098 * - If we have a face-specific seed, use it. 2099 * If non-zero, update it to a positive value. 2100 * 2101 * - Otherwise, use the seed from the CFF driver. 2102 * If non-zero, update it to a positive value. 2103 * 2104 * - If the random value is zero, use the seed given by the subfont's 2105 * `initialRandomSeed' value. 2106 * 2107 */ 2108 if ( face->root.internal->random_seed == -1 ) 2109 { 2110 PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( face ); 2111 2112 2113 subfont->random = (FT_UInt32)driver->random_seed; 2114 if ( driver->random_seed ) 2115 { 2116 do 2117 { 2118 driver->random_seed = 2119 (FT_Int32)psaux->cff_random( (FT_UInt32)driver->random_seed ); 2120 2121 } while ( driver->random_seed < 0 ); 2122 } 2123 } 2124 else 2125 { 2126 subfont->random = (FT_UInt32)face->root.internal->random_seed; 2127 if ( face->root.internal->random_seed ) 2128 { 2129 do 2130 { 2131 face->root.internal->random_seed = 2132 (FT_Int32)psaux->cff_random( 2133 (FT_UInt32)face->root.internal->random_seed ); 2134 2135 } while ( face->root.internal->random_seed < 0 ); 2136 } 2137 } 2138 2139 if ( !subfont->random ) 2140 subfont->random = (FT_UInt32)priv->initial_random_seed; 2141 } 2142 2143 /* read the local subrs, if any */ 2144 if ( priv->local_subrs_offset ) 2145 { 2146 if ( FT_STREAM_SEEK( base_offset + top->private_offset + 2147 priv->local_subrs_offset ) ) 2148 goto Exit; 2149 2150 error = cff_index_init( &subfont->local_subrs_index, stream, 1, cff2 ); 2151 if ( error ) 2152 goto Exit; 2153 2154 error = cff_index_get_pointers( &subfont->local_subrs_index, 2155 &subfont->local_subrs, NULL, NULL ); 2156 if ( error ) 2157 goto Exit; 2158 } 2159 2160 Exit: 2161 cff_parser_done( &parser ); /* free parser stack */ 2162 2163 return error; 2164 } 2165 2166 2167 static void cff_subfont_done(FT_Memory memory,CFF_SubFont subfont)2168 cff_subfont_done( FT_Memory memory, 2169 CFF_SubFont subfont ) 2170 { 2171 if ( subfont ) 2172 { 2173 cff_index_done( &subfont->local_subrs_index ); 2174 FT_FREE( subfont->local_subrs ); 2175 2176 FT_FREE( subfont->blend.lastNDV ); 2177 FT_FREE( subfont->blend.BV ); 2178 FT_FREE( subfont->blend_stack ); 2179 } 2180 } 2181 2182 2183 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)2184 cff_font_load( FT_Library library, 2185 FT_Stream stream, 2186 FT_Int face_index, 2187 CFF_Font font, 2188 CFF_Face face, 2189 FT_Bool pure_cff, 2190 FT_Bool cff2 ) 2191 { 2192 static const FT_Frame_Field cff_header_fields[] = 2193 { 2194 #undef FT_STRUCTURE 2195 #define FT_STRUCTURE CFF_FontRec 2196 2197 FT_FRAME_START( 3 ), 2198 FT_FRAME_BYTE( version_major ), 2199 FT_FRAME_BYTE( version_minor ), 2200 FT_FRAME_BYTE( header_size ), 2201 FT_FRAME_END 2202 }; 2203 2204 FT_Error error; 2205 FT_Memory memory = stream->memory; 2206 FT_ULong base_offset; 2207 CFF_FontRecDict dict; 2208 CFF_IndexRec string_index; 2209 FT_UInt subfont_index; 2210 2211 2212 FT_ZERO( font ); 2213 FT_ZERO( &string_index ); 2214 2215 dict = &font->top_font.font_dict; 2216 base_offset = FT_STREAM_POS(); 2217 2218 font->library = library; 2219 font->stream = stream; 2220 font->memory = memory; 2221 font->cff2 = cff2; 2222 font->base_offset = base_offset; 2223 2224 /* read CFF font header */ 2225 if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) ) 2226 goto Exit; 2227 2228 if ( cff2 ) 2229 { 2230 if ( font->version_major != 2 || 2231 font->header_size < 5 ) 2232 { 2233 FT_TRACE2(( " not a CFF2 font header\n" )); 2234 error = FT_THROW( Unknown_File_Format ); 2235 goto Exit; 2236 } 2237 2238 if ( FT_READ_USHORT( font->top_dict_length ) ) 2239 goto Exit; 2240 } 2241 else 2242 { 2243 FT_Byte absolute_offset; 2244 2245 2246 if ( FT_READ_BYTE( absolute_offset ) ) 2247 goto Exit; 2248 2249 if ( font->version_major != 1 || 2250 font->header_size < 4 || 2251 absolute_offset > 4 ) 2252 { 2253 FT_TRACE2(( " not a CFF font header\n" )); 2254 error = FT_THROW( Unknown_File_Format ); 2255 goto Exit; 2256 } 2257 } 2258 2259 /* skip the rest of the header */ 2260 if ( FT_STREAM_SEEK( base_offset + font->header_size ) ) 2261 { 2262 /* For pure CFFs we have read only four bytes so far. Contrary to */ 2263 /* other formats like SFNT those bytes doesn't define a signature; */ 2264 /* it is thus possible that the font isn't a CFF at all. */ 2265 if ( pure_cff ) 2266 { 2267 FT_TRACE2(( " not a CFF file\n" )); 2268 error = FT_THROW( Unknown_File_Format ); 2269 } 2270 goto Exit; 2271 } 2272 2273 if ( cff2 ) 2274 { 2275 /* For CFF2, the top dict data immediately follow the header */ 2276 /* and the length is stored in the header `offSize' field; */ 2277 /* there is no index for it. */ 2278 /* */ 2279 /* Use the `font_dict_index' to save the current position */ 2280 /* and length of data, but leave count at zero as an indicator. */ 2281 FT_ZERO( &font->font_dict_index ); 2282 2283 font->font_dict_index.data_offset = FT_STREAM_POS(); 2284 font->font_dict_index.data_size = font->top_dict_length; 2285 2286 /* skip the top dict data for now, we will parse it later */ 2287 if ( FT_STREAM_SKIP( font->top_dict_length ) ) 2288 goto Exit; 2289 2290 /* next, read the global subrs index */ 2291 if ( FT_SET_ERROR( cff_index_init( &font->global_subrs_index, 2292 stream, 1, cff2 ) ) ) 2293 goto Exit; 2294 } 2295 else 2296 { 2297 /* for CFF, read the name, top dict, string and global subrs index */ 2298 if ( FT_SET_ERROR( cff_index_init( &font->name_index, 2299 stream, 0, cff2 ) ) ) 2300 { 2301 if ( pure_cff ) 2302 { 2303 FT_TRACE2(( " not a CFF file\n" )); 2304 error = FT_THROW( Unknown_File_Format ); 2305 } 2306 goto Exit; 2307 } 2308 2309 /* if we have an empty font name, */ 2310 /* it must be the only font in the CFF */ 2311 if ( font->name_index.count > 1 && 2312 font->name_index.data_size < font->name_index.count ) 2313 { 2314 /* for pure CFFs, we still haven't checked enough bytes */ 2315 /* to be sure that it is a CFF at all */ 2316 error = pure_cff ? FT_THROW( Unknown_File_Format ) 2317 : FT_THROW( Invalid_File_Format ); 2318 goto Exit; 2319 } 2320 2321 if ( FT_SET_ERROR( cff_index_init( &font->font_dict_index, 2322 stream, 0, cff2 ) ) || 2323 FT_SET_ERROR( cff_index_init( &string_index, 2324 stream, 1, cff2 ) ) || 2325 FT_SET_ERROR( cff_index_init( &font->global_subrs_index, 2326 stream, 1, cff2 ) ) || 2327 FT_SET_ERROR( cff_index_get_pointers( &string_index, 2328 &font->strings, 2329 &font->string_pool, 2330 &font->string_pool_size ) ) ) 2331 goto Exit; 2332 2333 /* there must be a Top DICT index entry for each name index entry */ 2334 if ( font->name_index.count > font->font_dict_index.count ) 2335 { 2336 FT_ERROR(( "cff_font_load:" 2337 " not enough entries in Top DICT index\n" )); 2338 error = FT_THROW( Invalid_File_Format ); 2339 goto Exit; 2340 } 2341 } 2342 2343 font->num_strings = string_index.count; 2344 2345 if ( pure_cff ) 2346 { 2347 /* well, we don't really forget the `disabled' fonts... */ 2348 subfont_index = (FT_UInt)( face_index & 0xFFFF ); 2349 2350 if ( face_index > 0 && subfont_index >= font->name_index.count ) 2351 { 2352 FT_ERROR(( "cff_font_load:" 2353 " invalid subfont index for pure CFF font (%d)\n", 2354 subfont_index )); 2355 error = FT_THROW( Invalid_Argument ); 2356 goto Exit; 2357 } 2358 2359 font->num_faces = font->name_index.count; 2360 } 2361 else 2362 { 2363 subfont_index = 0; 2364 2365 if ( font->name_index.count > 1 ) 2366 { 2367 FT_ERROR(( "cff_font_load:" 2368 " invalid CFF font with multiple subfonts\n" )); 2369 FT_ERROR(( " " 2370 " in SFNT wrapper\n" )); 2371 error = FT_THROW( Invalid_File_Format ); 2372 goto Exit; 2373 } 2374 } 2375 2376 /* in case of a font format check, simply exit now */ 2377 if ( face_index < 0 ) 2378 goto Exit; 2379 2380 /* now, parse the top-level font dictionary */ 2381 FT_TRACE4(( "parsing top-level\n" )); 2382 error = cff_subfont_load( &font->top_font, 2383 &font->font_dict_index, 2384 subfont_index, 2385 stream, 2386 base_offset, 2387 cff2 ? CFF2_CODE_TOPDICT : CFF_CODE_TOPDICT, 2388 font, 2389 face ); 2390 if ( error ) 2391 goto Exit; 2392 2393 if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) ) 2394 goto Exit; 2395 2396 error = cff_index_init( &font->charstrings_index, stream, 0, cff2 ); 2397 if ( error ) 2398 goto Exit; 2399 2400 /* now, check for a CID or CFF2 font */ 2401 if ( dict->cid_registry != 0xFFFFU || 2402 cff2 ) 2403 { 2404 CFF_IndexRec fd_index; 2405 CFF_SubFont sub = NULL; 2406 FT_UInt idx; 2407 2408 2409 /* for CFF2, read the Variation Store if available; */ 2410 /* this must follow the Top DICT parse and precede any Private DICT */ 2411 error = cff_vstore_load( &font->vstore, 2412 stream, 2413 base_offset, 2414 dict->vstore_offset ); 2415 if ( error ) 2416 goto Exit; 2417 2418 /* this is a CID-keyed font, we must now allocate a table of */ 2419 /* sub-fonts, then load each of them separately */ 2420 if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) ) 2421 goto Exit; 2422 2423 error = cff_index_init( &fd_index, stream, 0, cff2 ); 2424 if ( error ) 2425 goto Exit; 2426 2427 /* Font Dicts are not limited to 256 for CFF2. */ 2428 /* TODO: support this for CFF2 */ 2429 if ( fd_index.count > CFF_MAX_CID_FONTS ) 2430 { 2431 FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" )); 2432 goto Fail_CID; 2433 } 2434 2435 /* allocate & read each font dict independently */ 2436 font->num_subfonts = fd_index.count; 2437 if ( FT_NEW_ARRAY( sub, fd_index.count ) ) 2438 goto Fail_CID; 2439 2440 /* set up pointer table */ 2441 for ( idx = 0; idx < fd_index.count; idx++ ) 2442 font->subfonts[idx] = sub + idx; 2443 2444 /* now load each subfont independently */ 2445 for ( idx = 0; idx < fd_index.count; idx++ ) 2446 { 2447 sub = font->subfonts[idx]; 2448 FT_TRACE4(( "parsing subfont %u\n", idx )); 2449 error = cff_subfont_load( sub, 2450 &fd_index, 2451 idx, 2452 stream, 2453 base_offset, 2454 cff2 ? CFF2_CODE_FONTDICT 2455 : CFF_CODE_TOPDICT, 2456 font, 2457 face ); 2458 if ( error ) 2459 goto Fail_CID; 2460 } 2461 2462 /* now load the FD Select array; */ 2463 /* CFF2 omits FDSelect if there is only one FD */ 2464 if ( !cff2 || fd_index.count > 1 ) 2465 error = CFF_Load_FD_Select( &font->fd_select, 2466 font->charstrings_index.count, 2467 stream, 2468 base_offset + dict->cid_fd_select_offset ); 2469 2470 Fail_CID: 2471 cff_index_done( &fd_index ); 2472 2473 if ( error ) 2474 goto Exit; 2475 } 2476 else 2477 font->num_subfonts = 0; 2478 2479 /* read the charstrings index now */ 2480 if ( dict->charstrings_offset == 0 ) 2481 { 2482 FT_ERROR(( "cff_font_load: no charstrings offset\n" )); 2483 error = FT_THROW( Invalid_File_Format ); 2484 goto Exit; 2485 } 2486 2487 font->num_glyphs = font->charstrings_index.count; 2488 2489 error = cff_index_get_pointers( &font->global_subrs_index, 2490 &font->global_subrs, NULL, NULL ); 2491 2492 if ( error ) 2493 goto Exit; 2494 2495 /* read the Charset and Encoding tables if available */ 2496 if ( !cff2 && font->num_glyphs > 0 ) 2497 { 2498 FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff ); 2499 2500 2501 error = cff_charset_load( &font->charset, font->num_glyphs, stream, 2502 base_offset, dict->charset_offset, invert ); 2503 if ( error ) 2504 goto Exit; 2505 2506 /* CID-keyed CFFs don't have an encoding */ 2507 if ( dict->cid_registry == 0xFFFFU ) 2508 { 2509 error = cff_encoding_load( &font->encoding, 2510 &font->charset, 2511 font->num_glyphs, 2512 stream, 2513 base_offset, 2514 dict->encoding_offset ); 2515 if ( error ) 2516 goto Exit; 2517 } 2518 } 2519 2520 /* get the font name (/CIDFontName for CID-keyed fonts, */ 2521 /* /FontName otherwise) */ 2522 font->font_name = cff_index_get_name( font, subfont_index ); 2523 2524 Exit: 2525 cff_index_done( &string_index ); 2526 2527 return error; 2528 } 2529 2530 2531 FT_LOCAL_DEF( void ) cff_font_done(CFF_Font font)2532 cff_font_done( CFF_Font font ) 2533 { 2534 FT_Memory memory = font->memory; 2535 FT_UInt idx; 2536 2537 2538 cff_index_done( &font->global_subrs_index ); 2539 cff_index_done( &font->font_dict_index ); 2540 cff_index_done( &font->name_index ); 2541 cff_index_done( &font->charstrings_index ); 2542 2543 /* release font dictionaries, but only if working with */ 2544 /* a CID keyed CFF font or a CFF2 font */ 2545 if ( font->num_subfonts > 0 ) 2546 { 2547 for ( idx = 0; idx < font->num_subfonts; idx++ ) 2548 cff_subfont_done( memory, font->subfonts[idx] ); 2549 2550 /* the subfonts array has been allocated as a single block */ 2551 FT_FREE( font->subfonts[0] ); 2552 } 2553 2554 cff_encoding_done( &font->encoding ); 2555 cff_charset_done( &font->charset, font->stream ); 2556 cff_vstore_done( &font->vstore, memory ); 2557 2558 cff_subfont_done( memory, &font->top_font ); 2559 2560 CFF_Done_FD_Select( &font->fd_select, font->stream ); 2561 2562 FT_FREE( font->font_info ); 2563 2564 FT_FREE( font->font_name ); 2565 FT_FREE( font->global_subrs ); 2566 FT_FREE( font->strings ); 2567 FT_FREE( font->string_pool ); 2568 2569 if ( font->cf2_instance.finalizer ) 2570 { 2571 font->cf2_instance.finalizer( font->cf2_instance.data ); 2572 FT_FREE( font->cf2_instance.data ); 2573 } 2574 2575 FT_FREE( font->font_extra ); 2576 } 2577 2578 2579 /* END */ 2580