1 /**************************************************************************** 2 * 3 * cffdecode.c 4 * 5 * PostScript CFF (Type 2) decoding routines (body). 6 * 7 * Copyright (C) 2017-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/freetype.h> 20 #include <freetype/internal/ftdebug.h> 21 #include <freetype/internal/ftserv.h> 22 #include <freetype/internal/services/svcfftl.h> 23 24 #include "cffdecode.h" 25 #include "psobjs.h" 26 27 #include "psauxerr.h" 28 29 30 /************************************************************************** 31 * 32 * The macro FT_COMPONENT is used in trace mode. It is an implicit 33 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log 34 * messages during execution. 35 */ 36 #undef FT_COMPONENT 37 #define FT_COMPONENT cffdecode 38 39 40 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE 41 42 typedef enum CFF_Operator_ 43 { 44 cff_op_unknown = 0, 45 46 cff_op_rmoveto, 47 cff_op_hmoveto, 48 cff_op_vmoveto, 49 50 cff_op_rlineto, 51 cff_op_hlineto, 52 cff_op_vlineto, 53 54 cff_op_rrcurveto, 55 cff_op_hhcurveto, 56 cff_op_hvcurveto, 57 cff_op_rcurveline, 58 cff_op_rlinecurve, 59 cff_op_vhcurveto, 60 cff_op_vvcurveto, 61 62 cff_op_flex, 63 cff_op_hflex, 64 cff_op_hflex1, 65 cff_op_flex1, 66 67 cff_op_endchar, 68 69 cff_op_hstem, 70 cff_op_vstem, 71 cff_op_hstemhm, 72 cff_op_vstemhm, 73 74 cff_op_hintmask, 75 cff_op_cntrmask, 76 cff_op_dotsection, /* deprecated, acts as no-op */ 77 78 cff_op_abs, 79 cff_op_add, 80 cff_op_sub, 81 cff_op_div, 82 cff_op_neg, 83 cff_op_random, 84 cff_op_mul, 85 cff_op_sqrt, 86 87 cff_op_blend, 88 89 cff_op_drop, 90 cff_op_exch, 91 cff_op_index, 92 cff_op_roll, 93 cff_op_dup, 94 95 cff_op_put, 96 cff_op_get, 97 cff_op_store, 98 cff_op_load, 99 100 cff_op_and, 101 cff_op_or, 102 cff_op_not, 103 cff_op_eq, 104 cff_op_ifelse, 105 106 cff_op_callsubr, 107 cff_op_callgsubr, 108 cff_op_return, 109 110 /* Type 1 opcodes: invalid but seen in real life */ 111 cff_op_hsbw, 112 cff_op_closepath, 113 cff_op_callothersubr, 114 cff_op_pop, 115 cff_op_seac, 116 cff_op_sbw, 117 cff_op_setcurrentpoint, 118 119 /* do not remove */ 120 cff_op_max 121 122 } CFF_Operator; 123 124 125 #define CFF_COUNT_CHECK_WIDTH 0x80 126 #define CFF_COUNT_EXACT 0x40 127 #define CFF_COUNT_CLEAR_STACK 0x20 128 129 /* count values which have the `CFF_COUNT_CHECK_WIDTH' flag set are */ 130 /* used for checking the width and requested numbers of arguments */ 131 /* only; they are set to zero afterwards */ 132 133 /* the other two flags are informative only and unused currently */ 134 135 static const FT_Byte cff_argument_counts[] = 136 { 137 0, /* unknown */ 138 139 2 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, /* rmoveto */ 140 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, 141 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, 142 143 0 | CFF_COUNT_CLEAR_STACK, /* rlineto */ 144 0 | CFF_COUNT_CLEAR_STACK, 145 0 | CFF_COUNT_CLEAR_STACK, 146 147 0 | CFF_COUNT_CLEAR_STACK, /* rrcurveto */ 148 0 | CFF_COUNT_CLEAR_STACK, 149 0 | CFF_COUNT_CLEAR_STACK, 150 0 | CFF_COUNT_CLEAR_STACK, 151 0 | CFF_COUNT_CLEAR_STACK, 152 0 | CFF_COUNT_CLEAR_STACK, 153 0 | CFF_COUNT_CLEAR_STACK, 154 155 13, /* flex */ 156 7, 157 9, 158 11, 159 160 0 | CFF_COUNT_CHECK_WIDTH, /* endchar */ 161 162 2 | CFF_COUNT_CHECK_WIDTH, /* hstem */ 163 2 | CFF_COUNT_CHECK_WIDTH, 164 2 | CFF_COUNT_CHECK_WIDTH, 165 2 | CFF_COUNT_CHECK_WIDTH, 166 167 0 | CFF_COUNT_CHECK_WIDTH, /* hintmask */ 168 0 | CFF_COUNT_CHECK_WIDTH, /* cntrmask */ 169 0, /* dotsection */ 170 171 1, /* abs */ 172 2, 173 2, 174 2, 175 1, 176 0, 177 2, 178 1, 179 180 1, /* blend */ 181 182 1, /* drop */ 183 2, 184 1, 185 2, 186 1, 187 188 2, /* put */ 189 1, 190 4, 191 3, 192 193 2, /* and */ 194 2, 195 1, 196 2, 197 4, 198 199 1, /* callsubr */ 200 1, 201 0, 202 203 2, /* hsbw */ 204 0, 205 0, 206 0, 207 5, /* seac */ 208 4, /* sbw */ 209 2 /* setcurrentpoint */ 210 }; 211 212 213 static FT_Error cff_operator_seac(CFF_Decoder * decoder,FT_Pos asb,FT_Pos adx,FT_Pos ady,FT_Int bchar,FT_Int achar)214 cff_operator_seac( CFF_Decoder* decoder, 215 FT_Pos asb, 216 FT_Pos adx, 217 FT_Pos ady, 218 FT_Int bchar, 219 FT_Int achar ) 220 { 221 FT_Error error; 222 CFF_Builder* builder = &decoder->builder; 223 FT_Int bchar_index, achar_index; 224 TT_Face face = decoder->builder.face; 225 FT_Vector left_bearing, advance; 226 FT_Byte* charstring; 227 FT_ULong charstring_len; 228 FT_Pos glyph_width; 229 230 231 if ( decoder->seac ) 232 { 233 FT_ERROR(( "cff_operator_seac: invalid nested seac\n" )); 234 return FT_THROW( Syntax_Error ); 235 } 236 237 adx = ADD_LONG( adx, decoder->builder.left_bearing.x ); 238 ady = ADD_LONG( ady, decoder->builder.left_bearing.y ); 239 240 #ifdef FT_CONFIG_OPTION_INCREMENTAL 241 /* Incremental fonts don't necessarily have valid charsets. */ 242 /* They use the character code, not the glyph index, in this case. */ 243 if ( face->root.internal->incremental_interface ) 244 { 245 bchar_index = bchar; 246 achar_index = achar; 247 } 248 else 249 #endif /* FT_CONFIG_OPTION_INCREMENTAL */ 250 { 251 CFF_Font cff = (CFF_Font)( face->extra.data ); 252 253 254 bchar_index = cff_lookup_glyph_by_stdcharcode( cff, bchar ); 255 achar_index = cff_lookup_glyph_by_stdcharcode( cff, achar ); 256 } 257 258 if ( bchar_index < 0 || achar_index < 0 ) 259 { 260 FT_ERROR(( "cff_operator_seac:" 261 " invalid seac character code arguments\n" )); 262 return FT_THROW( Syntax_Error ); 263 } 264 265 /* If we are trying to load a composite glyph, do not load the */ 266 /* accent character and return the array of subglyphs. */ 267 if ( builder->no_recurse ) 268 { 269 FT_GlyphSlot glyph = (FT_GlyphSlot)builder->glyph; 270 FT_GlyphLoader loader = glyph->internal->loader; 271 FT_SubGlyph subg; 272 273 274 /* reallocate subglyph array if necessary */ 275 error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 ); 276 if ( error ) 277 goto Exit; 278 279 subg = loader->current.subglyphs; 280 281 /* subglyph 0 = base character */ 282 subg->index = bchar_index; 283 subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES | 284 FT_SUBGLYPH_FLAG_USE_MY_METRICS; 285 subg->arg1 = 0; 286 subg->arg2 = 0; 287 subg++; 288 289 /* subglyph 1 = accent character */ 290 subg->index = achar_index; 291 subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; 292 subg->arg1 = (FT_Int)( adx >> 16 ); 293 subg->arg2 = (FT_Int)( ady >> 16 ); 294 295 /* set up remaining glyph fields */ 296 glyph->num_subglyphs = 2; 297 glyph->subglyphs = loader->base.subglyphs; 298 glyph->format = FT_GLYPH_FORMAT_COMPOSITE; 299 300 loader->current.num_subglyphs = 2; 301 } 302 303 FT_GlyphLoader_Prepare( builder->loader ); 304 305 /* First load `bchar' in builder */ 306 error = decoder->get_glyph_callback( face, (FT_UInt)bchar_index, 307 &charstring, &charstring_len ); 308 if ( !error ) 309 { 310 /* the seac operator must not be nested */ 311 decoder->seac = TRUE; 312 error = cff_decoder_parse_charstrings( decoder, charstring, 313 charstring_len, 0 ); 314 decoder->seac = FALSE; 315 316 decoder->free_glyph_callback( face, &charstring, charstring_len ); 317 318 if ( error ) 319 goto Exit; 320 } 321 322 /* Save the left bearing, advance and glyph width of the base */ 323 /* character as they will be erased by the next load. */ 324 325 left_bearing = builder->left_bearing; 326 advance = builder->advance; 327 glyph_width = decoder->glyph_width; 328 329 builder->left_bearing.x = 0; 330 builder->left_bearing.y = 0; 331 332 builder->pos_x = SUB_LONG( adx, asb ); 333 builder->pos_y = ady; 334 335 /* Now load `achar' on top of the base outline. */ 336 error = decoder->get_glyph_callback( face, (FT_UInt)achar_index, 337 &charstring, &charstring_len ); 338 if ( !error ) 339 { 340 /* the seac operator must not be nested */ 341 decoder->seac = TRUE; 342 error = cff_decoder_parse_charstrings( decoder, charstring, 343 charstring_len, 0 ); 344 decoder->seac = FALSE; 345 346 decoder->free_glyph_callback( face, &charstring, charstring_len ); 347 348 if ( error ) 349 goto Exit; 350 } 351 352 /* Restore the left side bearing, advance and glyph width */ 353 /* of the base character. */ 354 builder->left_bearing = left_bearing; 355 builder->advance = advance; 356 decoder->glyph_width = glyph_width; 357 358 builder->pos_x = 0; 359 builder->pos_y = 0; 360 361 Exit: 362 return error; 363 } 364 365 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ 366 367 368 /*************************************************************************/ 369 /*************************************************************************/ 370 /*************************************************************************/ 371 /********** *********/ 372 /********** *********/ 373 /********** GENERIC CHARSTRING PARSING *********/ 374 /********** *********/ 375 /********** *********/ 376 /*************************************************************************/ 377 /*************************************************************************/ 378 /*************************************************************************/ 379 380 /************************************************************************** 381 * 382 * @Function: 383 * cff_compute_bias 384 * 385 * @Description: 386 * Computes the bias value in dependence of the number of glyph 387 * subroutines. 388 * 389 * @Input: 390 * in_charstring_type :: 391 * The `CharstringType' value of the top DICT 392 * dictionary. 393 * 394 * num_subrs :: 395 * The number of glyph subroutines. 396 * 397 * @Return: 398 * The bias value. 399 */ 400 static FT_Int cff_compute_bias(FT_Int in_charstring_type,FT_UInt num_subrs)401 cff_compute_bias( FT_Int in_charstring_type, 402 FT_UInt num_subrs ) 403 { 404 FT_Int result; 405 406 407 if ( in_charstring_type == 1 ) 408 result = 0; 409 else if ( num_subrs < 1240 ) 410 result = 107; 411 else if ( num_subrs < 33900U ) 412 result = 1131; 413 else 414 result = 32768U; 415 416 return result; 417 } 418 419 420 FT_LOCAL_DEF( FT_Int ) cff_lookup_glyph_by_stdcharcode(CFF_Font cff,FT_Int charcode)421 cff_lookup_glyph_by_stdcharcode( CFF_Font cff, 422 FT_Int charcode ) 423 { 424 FT_UInt n; 425 FT_UShort glyph_sid; 426 427 FT_Service_CFFLoad cffload; 428 429 430 /* CID-keyed fonts don't have glyph names */ 431 if ( !cff->charset.sids ) 432 return -1; 433 434 /* check range of standard char code */ 435 if ( charcode < 0 || charcode > 255 ) 436 return -1; 437 438 #if 0 439 /* retrieve cffload from list of current modules */ 440 FT_Service_CFFLoad cffload; 441 442 443 FT_FACE_FIND_GLOBAL_SERVICE( face, cffload, CFF_LOAD ); 444 if ( !cffload ) 445 { 446 FT_ERROR(( "cff_lookup_glyph_by_stdcharcode:" 447 " the `cffload' module is not available\n" )); 448 return FT_THROW( Unimplemented_Feature ); 449 } 450 #endif 451 452 cffload = (FT_Service_CFFLoad)cff->cffload; 453 454 /* Get code to SID mapping from `cff_standard_encoding'. */ 455 glyph_sid = cffload->get_standard_encoding( (FT_UInt)charcode ); 456 457 for ( n = 0; n < cff->num_glyphs; n++ ) 458 { 459 if ( cff->charset.sids[n] == glyph_sid ) 460 return (FT_Int)n; 461 } 462 463 return -1; 464 } 465 466 467 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE 468 469 /************************************************************************** 470 * 471 * @Function: 472 * cff_decoder_parse_charstrings 473 * 474 * @Description: 475 * Parses a given Type 2 charstrings program. 476 * 477 * @InOut: 478 * decoder :: 479 * The current Type 1 decoder. 480 * 481 * @Input: 482 * charstring_base :: 483 * The base of the charstring stream. 484 * 485 * charstring_len :: 486 * The length in bytes of the charstring stream. 487 * 488 * in_dict :: 489 * Set to 1 if function is called from top or 490 * private DICT (needed for Multiple Master CFFs). 491 * 492 * @Return: 493 * FreeType error code. 0 means success. 494 */ 495 FT_LOCAL_DEF( FT_Error ) cff_decoder_parse_charstrings(CFF_Decoder * decoder,FT_Byte * charstring_base,FT_ULong charstring_len,FT_Bool in_dict)496 cff_decoder_parse_charstrings( CFF_Decoder* decoder, 497 FT_Byte* charstring_base, 498 FT_ULong charstring_len, 499 FT_Bool in_dict ) 500 { 501 FT_Error error; 502 CFF_Decoder_Zone* zone; 503 FT_Byte* ip; 504 FT_Byte* limit; 505 CFF_Builder* builder = &decoder->builder; 506 FT_Pos x, y; 507 FT_Fixed* stack; 508 FT_Int charstring_type = 509 decoder->cff->top_font.font_dict.charstring_type; 510 FT_UShort num_designs = 511 decoder->cff->top_font.font_dict.num_designs; 512 FT_UShort num_axes = 513 decoder->cff->top_font.font_dict.num_axes; 514 515 T2_Hints_Funcs hinter; 516 517 518 /* set default width */ 519 decoder->num_hints = 0; 520 decoder->read_width = 1; 521 522 /* initialize the decoder */ 523 decoder->top = decoder->stack; 524 decoder->zone = decoder->zones; 525 zone = decoder->zones; 526 stack = decoder->top; 527 528 hinter = (T2_Hints_Funcs)builder->hints_funcs; 529 530 builder->path_begun = 0; 531 532 if ( !charstring_base ) 533 return FT_Err_Ok; 534 535 zone->base = charstring_base; 536 limit = zone->limit = charstring_base + charstring_len; 537 ip = zone->cursor = zone->base; 538 539 error = FT_Err_Ok; 540 541 x = builder->pos_x; 542 y = builder->pos_y; 543 544 /* begin hints recording session, if any */ 545 if ( hinter ) 546 hinter->open( hinter->hints ); 547 548 /* now execute loop */ 549 while ( ip < limit ) 550 { 551 CFF_Operator op; 552 FT_Byte v; 553 554 555 /********************************************************************* 556 * 557 * Decode operator or operand 558 */ 559 v = *ip++; 560 if ( v >= 32 || v == 28 ) 561 { 562 FT_Int shift = 16; 563 FT_Int32 val; 564 565 566 /* this is an operand, push it on the stack */ 567 568 /* if we use shifts, all computations are done with unsigned */ 569 /* values; the conversion to a signed value is the last step */ 570 if ( v == 28 ) 571 { 572 if ( ip + 1 >= limit ) 573 goto Syntax_Error; 574 val = (FT_Short)( ( (FT_UShort)ip[0] << 8 ) | ip[1] ); 575 ip += 2; 576 } 577 else if ( v < 247 ) 578 val = (FT_Int32)v - 139; 579 else if ( v < 251 ) 580 { 581 if ( ip >= limit ) 582 goto Syntax_Error; 583 val = ( (FT_Int32)v - 247 ) * 256 + *ip++ + 108; 584 } 585 else if ( v < 255 ) 586 { 587 if ( ip >= limit ) 588 goto Syntax_Error; 589 val = -( (FT_Int32)v - 251 ) * 256 - *ip++ - 108; 590 } 591 else 592 { 593 if ( ip + 3 >= limit ) 594 goto Syntax_Error; 595 val = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) | 596 ( (FT_UInt32)ip[1] << 16 ) | 597 ( (FT_UInt32)ip[2] << 8 ) | 598 (FT_UInt32)ip[3] ); 599 ip += 4; 600 if ( charstring_type == 2 ) 601 shift = 0; 602 } 603 if ( decoder->top - stack >= CFF_MAX_OPERANDS ) 604 goto Stack_Overflow; 605 606 val = (FT_Int32)( (FT_UInt32)val << shift ); 607 *decoder->top++ = val; 608 609 #ifdef FT_DEBUG_LEVEL_TRACE 610 if ( !( val & 0xFFFFL ) ) 611 FT_TRACE4(( " %hd", (FT_Short)( (FT_UInt32)val >> 16 ) )); 612 else 613 FT_TRACE4(( " %.5f", val / 65536.0 )); 614 #endif 615 616 } 617 else 618 { 619 /* The specification says that normally arguments are to be taken */ 620 /* from the bottom of the stack. However, this seems not to be */ 621 /* correct, at least for Acroread 7.0.8 on GNU/Linux: It pops the */ 622 /* arguments similar to a PS interpreter. */ 623 624 FT_Fixed* args = decoder->top; 625 FT_Int num_args = (FT_Int)( args - decoder->stack ); 626 FT_Int req_args; 627 628 629 /* find operator */ 630 op = cff_op_unknown; 631 632 switch ( v ) 633 { 634 case 1: 635 op = cff_op_hstem; 636 break; 637 case 3: 638 op = cff_op_vstem; 639 break; 640 case 4: 641 op = cff_op_vmoveto; 642 break; 643 case 5: 644 op = cff_op_rlineto; 645 break; 646 case 6: 647 op = cff_op_hlineto; 648 break; 649 case 7: 650 op = cff_op_vlineto; 651 break; 652 case 8: 653 op = cff_op_rrcurveto; 654 break; 655 case 9: 656 op = cff_op_closepath; 657 break; 658 case 10: 659 op = cff_op_callsubr; 660 break; 661 case 11: 662 op = cff_op_return; 663 break; 664 case 12: 665 if ( ip >= limit ) 666 goto Syntax_Error; 667 v = *ip++; 668 669 switch ( v ) 670 { 671 case 0: 672 op = cff_op_dotsection; 673 break; 674 case 1: /* this is actually the Type1 vstem3 operator */ 675 op = cff_op_vstem; 676 break; 677 case 2: /* this is actually the Type1 hstem3 operator */ 678 op = cff_op_hstem; 679 break; 680 case 3: 681 op = cff_op_and; 682 break; 683 case 4: 684 op = cff_op_or; 685 break; 686 case 5: 687 op = cff_op_not; 688 break; 689 case 6: 690 op = cff_op_seac; 691 break; 692 case 7: 693 op = cff_op_sbw; 694 break; 695 case 8: 696 op = cff_op_store; 697 break; 698 case 9: 699 op = cff_op_abs; 700 break; 701 case 10: 702 op = cff_op_add; 703 break; 704 case 11: 705 op = cff_op_sub; 706 break; 707 case 12: 708 op = cff_op_div; 709 break; 710 case 13: 711 op = cff_op_load; 712 break; 713 case 14: 714 op = cff_op_neg; 715 break; 716 case 15: 717 op = cff_op_eq; 718 break; 719 case 16: 720 op = cff_op_callothersubr; 721 break; 722 case 17: 723 op = cff_op_pop; 724 break; 725 case 18: 726 op = cff_op_drop; 727 break; 728 case 20: 729 op = cff_op_put; 730 break; 731 case 21: 732 op = cff_op_get; 733 break; 734 case 22: 735 op = cff_op_ifelse; 736 break; 737 case 23: 738 op = cff_op_random; 739 break; 740 case 24: 741 op = cff_op_mul; 742 break; 743 case 26: 744 op = cff_op_sqrt; 745 break; 746 case 27: 747 op = cff_op_dup; 748 break; 749 case 28: 750 op = cff_op_exch; 751 break; 752 case 29: 753 op = cff_op_index; 754 break; 755 case 30: 756 op = cff_op_roll; 757 break; 758 case 33: 759 op = cff_op_setcurrentpoint; 760 break; 761 case 34: 762 op = cff_op_hflex; 763 break; 764 case 35: 765 op = cff_op_flex; 766 break; 767 case 36: 768 op = cff_op_hflex1; 769 break; 770 case 37: 771 op = cff_op_flex1; 772 break; 773 default: 774 FT_TRACE4(( " unknown op (12, %d)\n", v )); 775 break; 776 } 777 break; 778 case 13: 779 op = cff_op_hsbw; 780 break; 781 case 14: 782 op = cff_op_endchar; 783 break; 784 case 16: 785 op = cff_op_blend; 786 break; 787 case 18: 788 op = cff_op_hstemhm; 789 break; 790 case 19: 791 op = cff_op_hintmask; 792 break; 793 case 20: 794 op = cff_op_cntrmask; 795 break; 796 case 21: 797 op = cff_op_rmoveto; 798 break; 799 case 22: 800 op = cff_op_hmoveto; 801 break; 802 case 23: 803 op = cff_op_vstemhm; 804 break; 805 case 24: 806 op = cff_op_rcurveline; 807 break; 808 case 25: 809 op = cff_op_rlinecurve; 810 break; 811 case 26: 812 op = cff_op_vvcurveto; 813 break; 814 case 27: 815 op = cff_op_hhcurveto; 816 break; 817 case 29: 818 op = cff_op_callgsubr; 819 break; 820 case 30: 821 op = cff_op_vhcurveto; 822 break; 823 case 31: 824 op = cff_op_hvcurveto; 825 break; 826 default: 827 FT_TRACE4(( " unknown op (%d)\n", v )); 828 break; 829 } 830 831 if ( op == cff_op_unknown ) 832 continue; 833 834 /* in Multiple Master CFFs, T2 charstrings can appear in */ 835 /* dictionaries, but some operators are prohibited */ 836 if ( in_dict ) 837 { 838 switch ( op ) 839 { 840 case cff_op_hstem: 841 case cff_op_vstem: 842 case cff_op_vmoveto: 843 case cff_op_rlineto: 844 case cff_op_hlineto: 845 case cff_op_vlineto: 846 case cff_op_rrcurveto: 847 case cff_op_hstemhm: 848 case cff_op_hintmask: 849 case cff_op_cntrmask: 850 case cff_op_rmoveto: 851 case cff_op_hmoveto: 852 case cff_op_vstemhm: 853 case cff_op_rcurveline: 854 case cff_op_rlinecurve: 855 case cff_op_vvcurveto: 856 case cff_op_hhcurveto: 857 case cff_op_vhcurveto: 858 case cff_op_hvcurveto: 859 case cff_op_hflex: 860 case cff_op_flex: 861 case cff_op_hflex1: 862 case cff_op_flex1: 863 case cff_op_callsubr: 864 case cff_op_callgsubr: 865 /* deprecated opcodes */ 866 case cff_op_dotsection: 867 /* invalid Type 1 opcodes */ 868 case cff_op_hsbw: 869 case cff_op_closepath: 870 case cff_op_callothersubr: 871 case cff_op_seac: 872 case cff_op_sbw: 873 case cff_op_setcurrentpoint: 874 goto MM_Error; 875 876 default: 877 break; 878 } 879 } 880 881 /* check arguments */ 882 req_args = cff_argument_counts[op]; 883 if ( req_args & CFF_COUNT_CHECK_WIDTH ) 884 { 885 if ( num_args > 0 && decoder->read_width ) 886 { 887 /* If `nominal_width' is non-zero, the number is really a */ 888 /* difference against `nominal_width'. Else, the number here */ 889 /* is truly a width, not a difference against `nominal_width'. */ 890 /* If the font does not set `nominal_width', then */ 891 /* `nominal_width' defaults to zero, and so we can set */ 892 /* `glyph_width' to `nominal_width' plus number on the stack */ 893 /* -- for either case. */ 894 895 FT_Int set_width_ok; 896 897 898 switch ( op ) 899 { 900 case cff_op_hmoveto: 901 case cff_op_vmoveto: 902 set_width_ok = num_args & 2; 903 break; 904 905 case cff_op_hstem: 906 case cff_op_vstem: 907 case cff_op_hstemhm: 908 case cff_op_vstemhm: 909 case cff_op_rmoveto: 910 case cff_op_hintmask: 911 case cff_op_cntrmask: 912 set_width_ok = num_args & 1; 913 break; 914 915 case cff_op_endchar: 916 /* If there is a width specified for endchar, we either have */ 917 /* 1 argument or 5 arguments. We like to argue. */ 918 set_width_ok = in_dict 919 ? 0 920 : ( ( num_args == 5 ) || ( num_args == 1 ) ); 921 break; 922 923 default: 924 set_width_ok = 0; 925 break; 926 } 927 928 if ( set_width_ok ) 929 { 930 decoder->glyph_width = decoder->nominal_width + 931 ( stack[0] >> 16 ); 932 933 if ( decoder->width_only ) 934 { 935 /* we only want the advance width; stop here */ 936 break; 937 } 938 939 /* Consumed an argument. */ 940 num_args--; 941 } 942 } 943 944 decoder->read_width = 0; 945 req_args = 0; 946 } 947 948 req_args &= 0x000F; 949 if ( num_args < req_args ) 950 goto Stack_Underflow; 951 args -= req_args; 952 num_args -= req_args; 953 954 /* At this point, `args' points to the first argument of the */ 955 /* operand in case `req_args' isn't zero. Otherwise, we have */ 956 /* to adjust `args' manually. */ 957 958 /* Note that we only pop arguments from the stack which we */ 959 /* really need and can digest so that we can continue in case */ 960 /* of superfluous stack elements. */ 961 962 switch ( op ) 963 { 964 case cff_op_hstem: 965 case cff_op_vstem: 966 case cff_op_hstemhm: 967 case cff_op_vstemhm: 968 /* the number of arguments is always even here */ 969 FT_TRACE4(( "%s\n", 970 op == cff_op_hstem ? " hstem" : 971 ( op == cff_op_vstem ? " vstem" : 972 ( op == cff_op_hstemhm ? " hstemhm" : " vstemhm" ) ) )); 973 974 if ( hinter ) 975 hinter->stems( hinter->hints, 976 ( op == cff_op_hstem || op == cff_op_hstemhm ), 977 num_args / 2, 978 args - ( num_args & ~1 ) ); 979 980 decoder->num_hints += num_args / 2; 981 args = stack; 982 break; 983 984 case cff_op_hintmask: 985 case cff_op_cntrmask: 986 FT_TRACE4(( "%s", op == cff_op_hintmask ? " hintmask" 987 : " cntrmask" )); 988 989 /* implement vstem when needed -- */ 990 /* the specification doesn't say it, but this also works */ 991 /* with the 'cntrmask' operator */ 992 /* */ 993 if ( num_args > 0 ) 994 { 995 if ( hinter ) 996 hinter->stems( hinter->hints, 997 0, 998 num_args / 2, 999 args - ( num_args & ~1 ) ); 1000 1001 decoder->num_hints += num_args / 2; 1002 } 1003 1004 /* In a valid charstring there must be at least one byte */ 1005 /* after `hintmask' or `cntrmask' (e.g., for a `return' */ 1006 /* instruction). Additionally, there must be space for */ 1007 /* `num_hints' bits. */ 1008 1009 if ( ( ip + ( ( decoder->num_hints + 7 ) >> 3 ) ) >= limit ) 1010 goto Syntax_Error; 1011 1012 if ( hinter ) 1013 { 1014 if ( op == cff_op_hintmask ) 1015 hinter->hintmask( hinter->hints, 1016 (FT_UInt)builder->current->n_points, 1017 (FT_UInt)decoder->num_hints, 1018 ip ); 1019 else 1020 hinter->counter( hinter->hints, 1021 (FT_UInt)decoder->num_hints, 1022 ip ); 1023 } 1024 1025 #ifdef FT_DEBUG_LEVEL_TRACE 1026 { 1027 FT_UInt maskbyte; 1028 1029 1030 FT_TRACE4(( " (maskbytes:" )); 1031 1032 for ( maskbyte = 0; 1033 maskbyte < (FT_UInt)( ( decoder->num_hints + 7 ) >> 3 ); 1034 maskbyte++, ip++ ) 1035 FT_TRACE4(( " 0x%02X", *ip )); 1036 1037 FT_TRACE4(( ")\n" )); 1038 } 1039 #else 1040 ip += ( decoder->num_hints + 7 ) >> 3; 1041 #endif 1042 args = stack; 1043 break; 1044 1045 case cff_op_rmoveto: 1046 FT_TRACE4(( " rmoveto\n" )); 1047 1048 cff_builder_close_contour( builder ); 1049 builder->path_begun = 0; 1050 x = ADD_LONG( x, args[-2] ); 1051 y = ADD_LONG( y, args[-1] ); 1052 args = stack; 1053 break; 1054 1055 case cff_op_vmoveto: 1056 FT_TRACE4(( " vmoveto\n" )); 1057 1058 cff_builder_close_contour( builder ); 1059 builder->path_begun = 0; 1060 y = ADD_LONG( y, args[-1] ); 1061 args = stack; 1062 break; 1063 1064 case cff_op_hmoveto: 1065 FT_TRACE4(( " hmoveto\n" )); 1066 1067 cff_builder_close_contour( builder ); 1068 builder->path_begun = 0; 1069 x = ADD_LONG( x, args[-1] ); 1070 args = stack; 1071 break; 1072 1073 case cff_op_rlineto: 1074 FT_TRACE4(( " rlineto\n" )); 1075 1076 if ( cff_builder_start_point( builder, x, y ) || 1077 cff_check_points( builder, num_args / 2 ) ) 1078 goto Fail; 1079 1080 if ( num_args < 2 ) 1081 goto Stack_Underflow; 1082 1083 args -= num_args & ~1; 1084 while ( args < decoder->top ) 1085 { 1086 x = ADD_LONG( x, args[0] ); 1087 y = ADD_LONG( y, args[1] ); 1088 cff_builder_add_point( builder, x, y, 1 ); 1089 args += 2; 1090 } 1091 args = stack; 1092 break; 1093 1094 case cff_op_hlineto: 1095 case cff_op_vlineto: 1096 { 1097 FT_Int phase = ( op == cff_op_hlineto ); 1098 1099 1100 FT_TRACE4(( "%s\n", op == cff_op_hlineto ? " hlineto" 1101 : " vlineto" )); 1102 1103 if ( num_args < 0 ) 1104 goto Stack_Underflow; 1105 1106 /* there exist subsetted fonts (found in PDFs) */ 1107 /* which call `hlineto' without arguments */ 1108 if ( num_args == 0 ) 1109 break; 1110 1111 if ( cff_builder_start_point( builder, x, y ) || 1112 cff_check_points( builder, num_args ) ) 1113 goto Fail; 1114 1115 args = stack; 1116 while ( args < decoder->top ) 1117 { 1118 if ( phase ) 1119 x = ADD_LONG( x, args[0] ); 1120 else 1121 y = ADD_LONG( y, args[0] ); 1122 1123 if ( cff_builder_add_point1( builder, x, y ) ) 1124 goto Fail; 1125 1126 args++; 1127 phase ^= 1; 1128 } 1129 args = stack; 1130 } 1131 break; 1132 1133 case cff_op_rrcurveto: 1134 { 1135 FT_Int nargs; 1136 1137 1138 FT_TRACE4(( " rrcurveto\n" )); 1139 1140 if ( num_args < 6 ) 1141 goto Stack_Underflow; 1142 1143 nargs = num_args - num_args % 6; 1144 1145 if ( cff_builder_start_point( builder, x, y ) || 1146 cff_check_points( builder, nargs / 2 ) ) 1147 goto Fail; 1148 1149 args -= nargs; 1150 while ( args < decoder->top ) 1151 { 1152 x = ADD_LONG( x, args[0] ); 1153 y = ADD_LONG( y, args[1] ); 1154 cff_builder_add_point( builder, x, y, 0 ); 1155 1156 x = ADD_LONG( x, args[2] ); 1157 y = ADD_LONG( y, args[3] ); 1158 cff_builder_add_point( builder, x, y, 0 ); 1159 1160 x = ADD_LONG( x, args[4] ); 1161 y = ADD_LONG( y, args[5] ); 1162 cff_builder_add_point( builder, x, y, 1 ); 1163 1164 args += 6; 1165 } 1166 args = stack; 1167 } 1168 break; 1169 1170 case cff_op_vvcurveto: 1171 { 1172 FT_Int nargs; 1173 1174 1175 FT_TRACE4(( " vvcurveto\n" )); 1176 1177 if ( num_args < 4 ) 1178 goto Stack_Underflow; 1179 1180 /* if num_args isn't of the form 4n or 4n+1, */ 1181 /* we enforce it by clearing the second bit */ 1182 1183 nargs = num_args & ~2; 1184 1185 if ( cff_builder_start_point( builder, x, y ) ) 1186 goto Fail; 1187 1188 args -= nargs; 1189 1190 if ( nargs & 1 ) 1191 { 1192 x = ADD_LONG( x, args[0] ); 1193 args++; 1194 nargs--; 1195 } 1196 1197 if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) ) 1198 goto Fail; 1199 1200 while ( args < decoder->top ) 1201 { 1202 y = ADD_LONG( y, args[0] ); 1203 cff_builder_add_point( builder, x, y, 0 ); 1204 1205 x = ADD_LONG( x, args[1] ); 1206 y = ADD_LONG( y, args[2] ); 1207 cff_builder_add_point( builder, x, y, 0 ); 1208 1209 y = ADD_LONG( y, args[3] ); 1210 cff_builder_add_point( builder, x, y, 1 ); 1211 1212 args += 4; 1213 } 1214 args = stack; 1215 } 1216 break; 1217 1218 case cff_op_hhcurveto: 1219 { 1220 FT_Int nargs; 1221 1222 1223 FT_TRACE4(( " hhcurveto\n" )); 1224 1225 if ( num_args < 4 ) 1226 goto Stack_Underflow; 1227 1228 /* if num_args isn't of the form 4n or 4n+1, */ 1229 /* we enforce it by clearing the second bit */ 1230 1231 nargs = num_args & ~2; 1232 1233 if ( cff_builder_start_point( builder, x, y ) ) 1234 goto Fail; 1235 1236 args -= nargs; 1237 if ( nargs & 1 ) 1238 { 1239 y = ADD_LONG( y, args[0] ); 1240 args++; 1241 nargs--; 1242 } 1243 1244 if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) ) 1245 goto Fail; 1246 1247 while ( args < decoder->top ) 1248 { 1249 x = ADD_LONG( x, args[0] ); 1250 cff_builder_add_point( builder, x, y, 0 ); 1251 1252 x = ADD_LONG( x, args[1] ); 1253 y = ADD_LONG( y, args[2] ); 1254 cff_builder_add_point( builder, x, y, 0 ); 1255 1256 x = ADD_LONG( x, args[3] ); 1257 cff_builder_add_point( builder, x, y, 1 ); 1258 1259 args += 4; 1260 } 1261 args = stack; 1262 } 1263 break; 1264 1265 case cff_op_vhcurveto: 1266 case cff_op_hvcurveto: 1267 { 1268 FT_Int phase; 1269 FT_Int nargs; 1270 1271 1272 FT_TRACE4(( "%s\n", op == cff_op_vhcurveto ? " vhcurveto" 1273 : " hvcurveto" )); 1274 1275 if ( cff_builder_start_point( builder, x, y ) ) 1276 goto Fail; 1277 1278 if ( num_args < 4 ) 1279 goto Stack_Underflow; 1280 1281 /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */ 1282 /* we enforce it by clearing the second bit */ 1283 1284 nargs = num_args & ~2; 1285 1286 args -= nargs; 1287 if ( cff_check_points( builder, ( nargs / 4 ) * 3 ) ) 1288 goto Stack_Underflow; 1289 1290 phase = ( op == cff_op_hvcurveto ); 1291 1292 while ( nargs >= 4 ) 1293 { 1294 nargs -= 4; 1295 if ( phase ) 1296 { 1297 x = ADD_LONG( x, args[0] ); 1298 cff_builder_add_point( builder, x, y, 0 ); 1299 1300 x = ADD_LONG( x, args[1] ); 1301 y = ADD_LONG( y, args[2] ); 1302 cff_builder_add_point( builder, x, y, 0 ); 1303 1304 y = ADD_LONG( y, args[3] ); 1305 if ( nargs == 1 ) 1306 x = ADD_LONG( x, args[4] ); 1307 cff_builder_add_point( builder, x, y, 1 ); 1308 } 1309 else 1310 { 1311 y = ADD_LONG( y, args[0] ); 1312 cff_builder_add_point( builder, x, y, 0 ); 1313 1314 x = ADD_LONG( x, args[1] ); 1315 y = ADD_LONG( y, args[2] ); 1316 cff_builder_add_point( builder, x, y, 0 ); 1317 1318 x = ADD_LONG( x, args[3] ); 1319 if ( nargs == 1 ) 1320 y = ADD_LONG( y, args[4] ); 1321 cff_builder_add_point( builder, x, y, 1 ); 1322 } 1323 args += 4; 1324 phase ^= 1; 1325 } 1326 args = stack; 1327 } 1328 break; 1329 1330 case cff_op_rlinecurve: 1331 { 1332 FT_Int num_lines; 1333 FT_Int nargs; 1334 1335 1336 FT_TRACE4(( " rlinecurve\n" )); 1337 1338 if ( num_args < 8 ) 1339 goto Stack_Underflow; 1340 1341 nargs = num_args & ~1; 1342 num_lines = ( nargs - 6 ) / 2; 1343 1344 if ( cff_builder_start_point( builder, x, y ) || 1345 cff_check_points( builder, num_lines + 3 ) ) 1346 goto Fail; 1347 1348 args -= nargs; 1349 1350 /* first, add the line segments */ 1351 while ( num_lines > 0 ) 1352 { 1353 x = ADD_LONG( x, args[0] ); 1354 y = ADD_LONG( y, args[1] ); 1355 cff_builder_add_point( builder, x, y, 1 ); 1356 1357 args += 2; 1358 num_lines--; 1359 } 1360 1361 /* then the curve */ 1362 x = ADD_LONG( x, args[0] ); 1363 y = ADD_LONG( y, args[1] ); 1364 cff_builder_add_point( builder, x, y, 0 ); 1365 1366 x = ADD_LONG( x, args[2] ); 1367 y = ADD_LONG( y, args[3] ); 1368 cff_builder_add_point( builder, x, y, 0 ); 1369 1370 x = ADD_LONG( x, args[4] ); 1371 y = ADD_LONG( y, args[5] ); 1372 cff_builder_add_point( builder, x, y, 1 ); 1373 1374 args = stack; 1375 } 1376 break; 1377 1378 case cff_op_rcurveline: 1379 { 1380 FT_Int num_curves; 1381 FT_Int nargs; 1382 1383 1384 FT_TRACE4(( " rcurveline\n" )); 1385 1386 if ( num_args < 8 ) 1387 goto Stack_Underflow; 1388 1389 nargs = num_args - 2; 1390 nargs = nargs - nargs % 6 + 2; 1391 num_curves = ( nargs - 2 ) / 6; 1392 1393 if ( cff_builder_start_point( builder, x, y ) || 1394 cff_check_points( builder, num_curves * 3 + 2 ) ) 1395 goto Fail; 1396 1397 args -= nargs; 1398 1399 /* first, add the curves */ 1400 while ( num_curves > 0 ) 1401 { 1402 x = ADD_LONG( x, args[0] ); 1403 y = ADD_LONG( y, args[1] ); 1404 cff_builder_add_point( builder, x, y, 0 ); 1405 1406 x = ADD_LONG( x, args[2] ); 1407 y = ADD_LONG( y, args[3] ); 1408 cff_builder_add_point( builder, x, y, 0 ); 1409 1410 x = ADD_LONG( x, args[4] ); 1411 y = ADD_LONG( y, args[5] ); 1412 cff_builder_add_point( builder, x, y, 1 ); 1413 1414 args += 6; 1415 num_curves--; 1416 } 1417 1418 /* then the final line */ 1419 x = ADD_LONG( x, args[0] ); 1420 y = ADD_LONG( y, args[1] ); 1421 cff_builder_add_point( builder, x, y, 1 ); 1422 1423 args = stack; 1424 } 1425 break; 1426 1427 case cff_op_hflex1: 1428 { 1429 FT_Pos start_y; 1430 1431 1432 FT_TRACE4(( " hflex1\n" )); 1433 1434 /* adding five more points: 4 control points, 1 on-curve point */ 1435 /* -- make sure we have enough space for the start point if it */ 1436 /* needs to be added */ 1437 if ( cff_builder_start_point( builder, x, y ) || 1438 cff_check_points( builder, 6 ) ) 1439 goto Fail; 1440 1441 /* record the starting point's y position for later use */ 1442 start_y = y; 1443 1444 /* first control point */ 1445 x = ADD_LONG( x, args[0] ); 1446 y = ADD_LONG( y, args[1] ); 1447 cff_builder_add_point( builder, x, y, 0 ); 1448 1449 /* second control point */ 1450 x = ADD_LONG( x, args[2] ); 1451 y = ADD_LONG( y, args[3] ); 1452 cff_builder_add_point( builder, x, y, 0 ); 1453 1454 /* join point; on curve, with y-value the same as the last */ 1455 /* control point's y-value */ 1456 x = ADD_LONG( x, args[4] ); 1457 cff_builder_add_point( builder, x, y, 1 ); 1458 1459 /* third control point, with y-value the same as the join */ 1460 /* point's y-value */ 1461 x = ADD_LONG( x, args[5] ); 1462 cff_builder_add_point( builder, x, y, 0 ); 1463 1464 /* fourth control point */ 1465 x = ADD_LONG( x, args[6] ); 1466 y = ADD_LONG( y, args[7] ); 1467 cff_builder_add_point( builder, x, y, 0 ); 1468 1469 /* ending point, with y-value the same as the start */ 1470 x = ADD_LONG( x, args[8] ); 1471 y = start_y; 1472 cff_builder_add_point( builder, x, y, 1 ); 1473 1474 args = stack; 1475 break; 1476 } 1477 1478 case cff_op_hflex: 1479 { 1480 FT_Pos start_y; 1481 1482 1483 FT_TRACE4(( " hflex\n" )); 1484 1485 /* adding six more points; 4 control points, 2 on-curve points */ 1486 if ( cff_builder_start_point( builder, x, y ) || 1487 cff_check_points( builder, 6 ) ) 1488 goto Fail; 1489 1490 /* record the starting point's y-position for later use */ 1491 start_y = y; 1492 1493 /* first control point */ 1494 x = ADD_LONG( x, args[0] ); 1495 cff_builder_add_point( builder, x, y, 0 ); 1496 1497 /* second control point */ 1498 x = ADD_LONG( x, args[1] ); 1499 y = ADD_LONG( y, args[2] ); 1500 cff_builder_add_point( builder, x, y, 0 ); 1501 1502 /* join point; on curve, with y-value the same as the last */ 1503 /* control point's y-value */ 1504 x = ADD_LONG( x, args[3] ); 1505 cff_builder_add_point( builder, x, y, 1 ); 1506 1507 /* third control point, with y-value the same as the join */ 1508 /* point's y-value */ 1509 x = ADD_LONG( x, args[4] ); 1510 cff_builder_add_point( builder, x, y, 0 ); 1511 1512 /* fourth control point */ 1513 x = ADD_LONG( x, args[5] ); 1514 y = start_y; 1515 cff_builder_add_point( builder, x, y, 0 ); 1516 1517 /* ending point, with y-value the same as the start point's */ 1518 /* y-value -- we don't add this point, though */ 1519 x = ADD_LONG( x, args[6] ); 1520 cff_builder_add_point( builder, x, y, 1 ); 1521 1522 args = stack; 1523 break; 1524 } 1525 1526 case cff_op_flex1: 1527 { 1528 FT_Pos start_x, start_y; /* record start x, y values for */ 1529 /* alter use */ 1530 FT_Fixed dx = 0, dy = 0; /* used in horizontal/vertical */ 1531 /* algorithm below */ 1532 FT_Int horizontal, count; 1533 FT_Fixed* temp; 1534 1535 1536 FT_TRACE4(( " flex1\n" )); 1537 1538 /* adding six more points; 4 control points, 2 on-curve points */ 1539 if ( cff_builder_start_point( builder, x, y ) || 1540 cff_check_points( builder, 6 ) ) 1541 goto Fail; 1542 1543 /* record the starting point's x, y position for later use */ 1544 start_x = x; 1545 start_y = y; 1546 1547 /* XXX: figure out whether this is supposed to be a horizontal */ 1548 /* or vertical flex; the Type 2 specification is vague... */ 1549 1550 temp = args; 1551 1552 /* grab up to the last argument */ 1553 for ( count = 5; count > 0; count-- ) 1554 { 1555 dx = ADD_LONG( dx, temp[0] ); 1556 dy = ADD_LONG( dy, temp[1] ); 1557 temp += 2; 1558 } 1559 1560 if ( dx < 0 ) 1561 dx = NEG_LONG( dx ); 1562 if ( dy < 0 ) 1563 dy = NEG_LONG( dy ); 1564 1565 /* strange test, but here it is... */ 1566 horizontal = ( dx > dy ); 1567 1568 for ( count = 5; count > 0; count-- ) 1569 { 1570 x = ADD_LONG( x, args[0] ); 1571 y = ADD_LONG( y, args[1] ); 1572 cff_builder_add_point( builder, x, y, 1573 FT_BOOL( count == 3 ) ); 1574 args += 2; 1575 } 1576 1577 /* is last operand an x- or y-delta? */ 1578 if ( horizontal ) 1579 { 1580 x = ADD_LONG( x, args[0] ); 1581 y = start_y; 1582 } 1583 else 1584 { 1585 x = start_x; 1586 y = ADD_LONG( y, args[0] ); 1587 } 1588 1589 cff_builder_add_point( builder, x, y, 1 ); 1590 1591 args = stack; 1592 break; 1593 } 1594 1595 case cff_op_flex: 1596 { 1597 FT_UInt count; 1598 1599 1600 FT_TRACE4(( " flex\n" )); 1601 1602 if ( cff_builder_start_point( builder, x, y ) || 1603 cff_check_points( builder, 6 ) ) 1604 goto Fail; 1605 1606 for ( count = 6; count > 0; count-- ) 1607 { 1608 x = ADD_LONG( x, args[0] ); 1609 y = ADD_LONG( y, args[1] ); 1610 cff_builder_add_point( builder, x, y, 1611 FT_BOOL( count == 4 || count == 1 ) ); 1612 args += 2; 1613 } 1614 1615 args = stack; 1616 } 1617 break; 1618 1619 case cff_op_seac: 1620 FT_TRACE4(( " seac\n" )); 1621 1622 error = cff_operator_seac( decoder, 1623 args[0], args[1], args[2], 1624 (FT_Int)( args[3] >> 16 ), 1625 (FT_Int)( args[4] >> 16 ) ); 1626 1627 /* add current outline to the glyph slot */ 1628 FT_GlyphLoader_Add( builder->loader ); 1629 1630 /* return now! */ 1631 FT_TRACE4(( "\n" )); 1632 return error; 1633 1634 case cff_op_endchar: 1635 /* in dictionaries, `endchar' simply indicates end of data */ 1636 if ( in_dict ) 1637 return error; 1638 1639 FT_TRACE4(( " endchar\n" )); 1640 1641 /* We are going to emulate the seac operator. */ 1642 if ( num_args >= 4 ) 1643 { 1644 /* Save glyph width so that the subglyphs don't overwrite it. */ 1645 FT_Pos glyph_width = decoder->glyph_width; 1646 1647 1648 error = cff_operator_seac( decoder, 1649 0L, args[-4], args[-3], 1650 (FT_Int)( args[-2] >> 16 ), 1651 (FT_Int)( args[-1] >> 16 ) ); 1652 1653 decoder->glyph_width = glyph_width; 1654 } 1655 else 1656 { 1657 cff_builder_close_contour( builder ); 1658 1659 /* close hints recording session */ 1660 if ( hinter ) 1661 { 1662 if ( hinter->close( hinter->hints, 1663 (FT_UInt)builder->current->n_points ) ) 1664 goto Syntax_Error; 1665 1666 /* apply hints to the loaded glyph outline now */ 1667 error = hinter->apply( hinter->hints, 1668 builder->current, 1669 (PSH_Globals)builder->hints_globals, 1670 decoder->hint_mode ); 1671 if ( error ) 1672 goto Fail; 1673 } 1674 1675 /* add current outline to the glyph slot */ 1676 FT_GlyphLoader_Add( builder->loader ); 1677 } 1678 1679 /* return now! */ 1680 FT_TRACE4(( "\n" )); 1681 return error; 1682 1683 case cff_op_abs: 1684 FT_TRACE4(( " abs\n" )); 1685 1686 if ( args[0] < 0 ) 1687 { 1688 if ( args[0] == FT_LONG_MIN ) 1689 args[0] = FT_LONG_MAX; 1690 else 1691 args[0] = -args[0]; 1692 } 1693 args++; 1694 break; 1695 1696 case cff_op_add: 1697 FT_TRACE4(( " add\n" )); 1698 1699 args[0] = ADD_LONG( args[0], args[1] ); 1700 args++; 1701 break; 1702 1703 case cff_op_sub: 1704 FT_TRACE4(( " sub\n" )); 1705 1706 args[0] = SUB_LONG( args[0], args[1] ); 1707 args++; 1708 break; 1709 1710 case cff_op_div: 1711 FT_TRACE4(( " div\n" )); 1712 1713 args[0] = FT_DivFix( args[0], args[1] ); 1714 args++; 1715 break; 1716 1717 case cff_op_neg: 1718 FT_TRACE4(( " neg\n" )); 1719 1720 if ( args[0] == FT_LONG_MIN ) 1721 args[0] = FT_LONG_MAX; 1722 args[0] = -args[0]; 1723 args++; 1724 break; 1725 1726 case cff_op_random: 1727 { 1728 FT_UInt32* randval = in_dict ? &decoder->cff->top_font.random 1729 : &decoder->current_subfont->random; 1730 1731 1732 FT_TRACE4(( " random\n" )); 1733 1734 /* only use the lower 16 bits of `random' */ 1735 /* to generate a number in the range (0;1] */ 1736 args[0] = (FT_Fixed)( ( *randval & 0xFFFF ) + 1 ); 1737 args++; 1738 1739 *randval = cff_random( *randval ); 1740 } 1741 break; 1742 1743 case cff_op_mul: 1744 FT_TRACE4(( " mul\n" )); 1745 1746 args[0] = FT_MulFix( args[0], args[1] ); 1747 args++; 1748 break; 1749 1750 case cff_op_sqrt: 1751 FT_TRACE4(( " sqrt\n" )); 1752 1753 /* without upper limit the loop below might not finish */ 1754 if ( args[0] > 0x7FFFFFFFL ) 1755 args[0] = 46341; 1756 else if ( args[0] > 0 ) 1757 { 1758 FT_Fixed root = args[0]; 1759 FT_Fixed new_root; 1760 1761 1762 for (;;) 1763 { 1764 new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1; 1765 if ( new_root == root ) 1766 break; 1767 root = new_root; 1768 } 1769 args[0] = new_root; 1770 } 1771 else 1772 args[0] = 0; 1773 args++; 1774 break; 1775 1776 case cff_op_drop: 1777 /* nothing */ 1778 FT_TRACE4(( " drop\n" )); 1779 1780 break; 1781 1782 case cff_op_exch: 1783 { 1784 FT_Fixed tmp; 1785 1786 1787 FT_TRACE4(( " exch\n" )); 1788 1789 tmp = args[0]; 1790 args[0] = args[1]; 1791 args[1] = tmp; 1792 args += 2; 1793 } 1794 break; 1795 1796 case cff_op_index: 1797 { 1798 FT_Int idx = (FT_Int)( args[0] >> 16 ); 1799 1800 1801 FT_TRACE4(( " index\n" )); 1802 1803 if ( idx < 0 ) 1804 idx = 0; 1805 else if ( idx > num_args - 2 ) 1806 idx = num_args - 2; 1807 args[0] = args[-( idx + 1 )]; 1808 args++; 1809 } 1810 break; 1811 1812 case cff_op_roll: 1813 { 1814 FT_Int count = (FT_Int)( args[0] >> 16 ); 1815 FT_Int idx = (FT_Int)( args[1] >> 16 ); 1816 1817 1818 FT_TRACE4(( " roll\n" )); 1819 1820 if ( count <= 0 ) 1821 count = 1; 1822 1823 args -= count; 1824 if ( args < stack ) 1825 goto Stack_Underflow; 1826 1827 if ( idx >= 0 ) 1828 { 1829 idx = idx % count; 1830 while ( idx > 0 ) 1831 { 1832 FT_Fixed tmp = args[count - 1]; 1833 FT_Int i; 1834 1835 1836 for ( i = count - 2; i >= 0; i-- ) 1837 args[i + 1] = args[i]; 1838 args[0] = tmp; 1839 idx--; 1840 } 1841 } 1842 else 1843 { 1844 /* before C99 it is implementation-defined whether */ 1845 /* the result of `%' is negative if the first operand */ 1846 /* is negative */ 1847 idx = -( NEG_INT( idx ) % count ); 1848 while ( idx < 0 ) 1849 { 1850 FT_Fixed tmp = args[0]; 1851 FT_Int i; 1852 1853 1854 for ( i = 0; i < count - 1; i++ ) 1855 args[i] = args[i + 1]; 1856 args[count - 1] = tmp; 1857 idx++; 1858 } 1859 } 1860 args += count; 1861 } 1862 break; 1863 1864 case cff_op_dup: 1865 FT_TRACE4(( " dup\n" )); 1866 1867 args[1] = args[0]; 1868 args += 2; 1869 break; 1870 1871 case cff_op_put: 1872 { 1873 FT_Fixed val = args[0]; 1874 FT_UInt idx = (FT_UInt)( args[1] >> 16 ); 1875 1876 1877 FT_TRACE4(( " put\n" )); 1878 1879 /* the Type2 specification before version 16-March-2000 */ 1880 /* didn't give a hard-coded size limit of the temporary */ 1881 /* storage array; instead, an argument of the */ 1882 /* `MultipleMaster' operator set the size */ 1883 if ( idx < CFF_MAX_TRANS_ELEMENTS ) 1884 decoder->buildchar[idx] = val; 1885 } 1886 break; 1887 1888 case cff_op_get: 1889 { 1890 FT_UInt idx = (FT_UInt)( args[0] >> 16 ); 1891 FT_Fixed val = 0; 1892 1893 1894 FT_TRACE4(( " get\n" )); 1895 1896 if ( idx < CFF_MAX_TRANS_ELEMENTS ) 1897 val = decoder->buildchar[idx]; 1898 1899 args[0] = val; 1900 args++; 1901 } 1902 break; 1903 1904 case cff_op_store: 1905 /* this operator was removed from the Type2 specification */ 1906 /* in version 16-March-2000 */ 1907 1908 /* since we currently don't handle interpolation of multiple */ 1909 /* master fonts, this is a no-op */ 1910 FT_TRACE4(( " store\n" )); 1911 break; 1912 1913 case cff_op_load: 1914 /* this operator was removed from the Type2 specification */ 1915 /* in version 16-March-2000 */ 1916 { 1917 FT_UInt reg_idx = (FT_UInt)args[0]; 1918 FT_UInt idx = (FT_UInt)args[1]; 1919 FT_UInt count = (FT_UInt)args[2]; 1920 1921 1922 FT_TRACE4(( " load\n" )); 1923 1924 /* since we currently don't handle interpolation of multiple */ 1925 /* master fonts, we store a vector [1 0 0 ...] in the */ 1926 /* temporary storage array regardless of the Registry index */ 1927 if ( reg_idx <= 2 && 1928 idx < CFF_MAX_TRANS_ELEMENTS && 1929 count <= num_axes ) 1930 { 1931 FT_UInt end, i; 1932 1933 1934 end = FT_MIN( idx + count, CFF_MAX_TRANS_ELEMENTS ); 1935 1936 if ( idx < end ) 1937 decoder->buildchar[idx] = 1 << 16; 1938 1939 for ( i = idx + 1; i < end; i++ ) 1940 decoder->buildchar[i] = 0; 1941 } 1942 } 1943 break; 1944 1945 case cff_op_blend: 1946 /* this operator was removed from the Type2 specification */ 1947 /* in version 16-March-2000 */ 1948 if ( num_designs ) 1949 { 1950 FT_Int num_results = (FT_Int)( args[0] >> 16 ); 1951 1952 1953 FT_TRACE4(( " blend\n" )); 1954 1955 if ( num_results < 0 ) 1956 goto Syntax_Error; 1957 1958 if ( num_results > num_args || 1959 num_results * (FT_Int)num_designs > num_args ) 1960 goto Stack_Underflow; 1961 1962 /* since we currently don't handle interpolation of multiple */ 1963 /* master fonts, return the `num_results' values of the */ 1964 /* first master */ 1965 args -= num_results * ( num_designs - 1 ); 1966 num_args -= num_results * ( num_designs - 1 ); 1967 } 1968 else 1969 goto Syntax_Error; 1970 break; 1971 1972 case cff_op_dotsection: 1973 /* this operator is deprecated and ignored by the parser */ 1974 FT_TRACE4(( " dotsection\n" )); 1975 break; 1976 1977 case cff_op_closepath: 1978 /* this is an invalid Type 2 operator; however, there */ 1979 /* exist fonts which are incorrectly converted from probably */ 1980 /* Type 1 to CFF, and some parsers seem to accept it */ 1981 1982 FT_TRACE4(( " closepath (invalid op)\n" )); 1983 1984 args = stack; 1985 break; 1986 1987 case cff_op_hsbw: 1988 /* this is an invalid Type 2 operator; however, there */ 1989 /* exist fonts which are incorrectly converted from probably */ 1990 /* Type 1 to CFF, and some parsers seem to accept it */ 1991 1992 FT_TRACE4(( " hsbw (invalid op)\n" )); 1993 1994 decoder->glyph_width = 1995 ADD_LONG( decoder->nominal_width, ( args[1] >> 16 ) ); 1996 1997 decoder->builder.left_bearing.x = args[0]; 1998 decoder->builder.left_bearing.y = 0; 1999 2000 x = ADD_LONG( decoder->builder.pos_x, args[0] ); 2001 y = decoder->builder.pos_y; 2002 args = stack; 2003 break; 2004 2005 case cff_op_sbw: 2006 /* this is an invalid Type 2 operator; however, there */ 2007 /* exist fonts which are incorrectly converted from probably */ 2008 /* Type 1 to CFF, and some parsers seem to accept it */ 2009 2010 FT_TRACE4(( " sbw (invalid op)\n" )); 2011 2012 decoder->glyph_width = 2013 ADD_LONG( decoder->nominal_width, ( args[2] >> 16 ) ); 2014 2015 decoder->builder.left_bearing.x = args[0]; 2016 decoder->builder.left_bearing.y = args[1]; 2017 2018 x = ADD_LONG( decoder->builder.pos_x, args[0] ); 2019 y = ADD_LONG( decoder->builder.pos_y, args[1] ); 2020 args = stack; 2021 break; 2022 2023 case cff_op_setcurrentpoint: 2024 /* this is an invalid Type 2 operator; however, there */ 2025 /* exist fonts which are incorrectly converted from probably */ 2026 /* Type 1 to CFF, and some parsers seem to accept it */ 2027 2028 FT_TRACE4(( " setcurrentpoint (invalid op)\n" )); 2029 2030 x = ADD_LONG( decoder->builder.pos_x, args[0] ); 2031 y = ADD_LONG( decoder->builder.pos_y, args[1] ); 2032 args = stack; 2033 break; 2034 2035 case cff_op_callothersubr: 2036 { 2037 FT_Fixed arg; 2038 2039 2040 /* this is an invalid Type 2 operator; however, there */ 2041 /* exist fonts which are incorrectly converted from */ 2042 /* probably Type 1 to CFF, and some parsers seem to accept */ 2043 /* it */ 2044 2045 FT_TRACE4(( " callothersubr (invalid op)\n" )); 2046 2047 /* subsequent `pop' operands should add the arguments, */ 2048 /* this is the implementation described for `unknown' */ 2049 /* other subroutines in the Type1 spec. */ 2050 /* */ 2051 /* XXX Fix return arguments (see discussion below). */ 2052 2053 arg = 2 + ( args[-2] >> 16 ); 2054 if ( arg >= CFF_MAX_OPERANDS ) 2055 goto Stack_Underflow; 2056 2057 args -= arg; 2058 if ( args < stack ) 2059 goto Stack_Underflow; 2060 } 2061 break; 2062 2063 case cff_op_pop: 2064 /* this is an invalid Type 2 operator; however, there */ 2065 /* exist fonts which are incorrectly converted from probably */ 2066 /* Type 1 to CFF, and some parsers seem to accept it */ 2067 2068 FT_TRACE4(( " pop (invalid op)\n" )); 2069 2070 /* XXX Increasing `args' is wrong: After a certain number of */ 2071 /* `pop's we get a stack overflow. Reason for doing it is */ 2072 /* code like this (actually found in a CFF font): */ 2073 /* */ 2074 /* 17 1 3 callothersubr */ 2075 /* pop */ 2076 /* callsubr */ 2077 /* */ 2078 /* Since we handle `callothersubr' as a no-op, and */ 2079 /* `callsubr' needs at least one argument, `pop' can't be a */ 2080 /* no-op too as it basically should be. */ 2081 /* */ 2082 /* The right solution would be to provide real support for */ 2083 /* `callothersubr' as done in `t1decode.c', however, given */ 2084 /* the fact that CFF fonts with `pop' are invalid, it is */ 2085 /* questionable whether it is worth the time. */ 2086 args++; 2087 break; 2088 2089 case cff_op_and: 2090 { 2091 FT_Fixed cond = ( args[0] && args[1] ); 2092 2093 2094 FT_TRACE4(( " and\n" )); 2095 2096 args[0] = cond ? 0x10000L : 0; 2097 args++; 2098 } 2099 break; 2100 2101 case cff_op_or: 2102 { 2103 FT_Fixed cond = ( args[0] || args[1] ); 2104 2105 2106 FT_TRACE4(( " or\n" )); 2107 2108 args[0] = cond ? 0x10000L : 0; 2109 args++; 2110 } 2111 break; 2112 2113 case cff_op_not: 2114 { 2115 FT_Fixed cond = !args[0]; 2116 2117 2118 FT_TRACE4(( " not\n" )); 2119 2120 args[0] = cond ? 0x10000L : 0; 2121 args++; 2122 } 2123 break; 2124 2125 case cff_op_eq: 2126 { 2127 FT_Fixed cond = ( args[0] == args[1] ); 2128 2129 2130 FT_TRACE4(( " eq\n" )); 2131 2132 args[0] = cond ? 0x10000L : 0; 2133 args++; 2134 } 2135 break; 2136 2137 case cff_op_ifelse: 2138 { 2139 FT_Fixed cond = ( args[2] <= args[3] ); 2140 2141 2142 FT_TRACE4(( " ifelse\n" )); 2143 2144 if ( !cond ) 2145 args[0] = args[1]; 2146 args++; 2147 } 2148 break; 2149 2150 case cff_op_callsubr: 2151 { 2152 FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) + 2153 decoder->locals_bias ); 2154 2155 2156 FT_TRACE4(( " callsubr (idx %d, entering level %ld)\n", 2157 idx, 2158 zone - decoder->zones + 1 )); 2159 2160 if ( idx >= decoder->num_locals ) 2161 { 2162 FT_ERROR(( "cff_decoder_parse_charstrings:" 2163 " invalid local subr index\n" )); 2164 goto Syntax_Error; 2165 } 2166 2167 if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS ) 2168 { 2169 FT_ERROR(( "cff_decoder_parse_charstrings:" 2170 " too many nested subrs\n" )); 2171 goto Syntax_Error; 2172 } 2173 2174 zone->cursor = ip; /* save current instruction pointer */ 2175 2176 zone++; 2177 zone->base = decoder->locals[idx]; 2178 zone->limit = decoder->locals[idx + 1]; 2179 zone->cursor = zone->base; 2180 2181 if ( !zone->base || zone->limit == zone->base ) 2182 { 2183 FT_ERROR(( "cff_decoder_parse_charstrings:" 2184 " invoking empty subrs\n" )); 2185 goto Syntax_Error; 2186 } 2187 2188 decoder->zone = zone; 2189 ip = zone->base; 2190 limit = zone->limit; 2191 } 2192 break; 2193 2194 case cff_op_callgsubr: 2195 { 2196 FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) + 2197 decoder->globals_bias ); 2198 2199 2200 FT_TRACE4(( " callgsubr (idx %d, entering level %ld)\n", 2201 idx, 2202 zone - decoder->zones + 1 )); 2203 2204 if ( idx >= decoder->num_globals ) 2205 { 2206 FT_ERROR(( "cff_decoder_parse_charstrings:" 2207 " invalid global subr index\n" )); 2208 goto Syntax_Error; 2209 } 2210 2211 if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS ) 2212 { 2213 FT_ERROR(( "cff_decoder_parse_charstrings:" 2214 " too many nested subrs\n" )); 2215 goto Syntax_Error; 2216 } 2217 2218 zone->cursor = ip; /* save current instruction pointer */ 2219 2220 zone++; 2221 zone->base = decoder->globals[idx]; 2222 zone->limit = decoder->globals[idx + 1]; 2223 zone->cursor = zone->base; 2224 2225 if ( !zone->base || zone->limit == zone->base ) 2226 { 2227 FT_ERROR(( "cff_decoder_parse_charstrings:" 2228 " invoking empty subrs\n" )); 2229 goto Syntax_Error; 2230 } 2231 2232 decoder->zone = zone; 2233 ip = zone->base; 2234 limit = zone->limit; 2235 } 2236 break; 2237 2238 case cff_op_return: 2239 FT_TRACE4(( " return (leaving level %ld)\n", 2240 decoder->zone - decoder->zones )); 2241 2242 if ( decoder->zone <= decoder->zones ) 2243 { 2244 FT_ERROR(( "cff_decoder_parse_charstrings:" 2245 " unexpected return\n" )); 2246 goto Syntax_Error; 2247 } 2248 2249 decoder->zone--; 2250 zone = decoder->zone; 2251 ip = zone->cursor; 2252 limit = zone->limit; 2253 break; 2254 2255 default: 2256 FT_ERROR(( "Unimplemented opcode: %d", ip[-1] )); 2257 2258 if ( ip[-1] == 12 ) 2259 FT_ERROR(( " %d", ip[0] )); 2260 FT_ERROR(( "\n" )); 2261 2262 return FT_THROW( Unimplemented_Feature ); 2263 } 2264 2265 decoder->top = args; 2266 2267 if ( decoder->top - stack >= CFF_MAX_OPERANDS ) 2268 goto Stack_Overflow; 2269 2270 } /* general operator processing */ 2271 2272 } /* while ip < limit */ 2273 2274 FT_TRACE4(( "..end..\n" )); 2275 FT_TRACE4(( "\n" )); 2276 2277 Fail: 2278 return error; 2279 2280 MM_Error: 2281 FT_TRACE4(( "cff_decoder_parse_charstrings:" 2282 " invalid opcode found in top DICT charstring\n")); 2283 return FT_THROW( Invalid_File_Format ); 2284 2285 Syntax_Error: 2286 FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" )); 2287 return FT_THROW( Invalid_File_Format ); 2288 2289 Stack_Underflow: 2290 FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" )); 2291 return FT_THROW( Too_Few_Arguments ); 2292 2293 Stack_Overflow: 2294 FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" )); 2295 return FT_THROW( Stack_Overflow ); 2296 } 2297 2298 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ 2299 2300 2301 /************************************************************************** 2302 * 2303 * @Function: 2304 * cff_decoder_init 2305 * 2306 * @Description: 2307 * Initializes a given glyph decoder. 2308 * 2309 * @InOut: 2310 * decoder :: 2311 * A pointer to the glyph builder to initialize. 2312 * 2313 * @Input: 2314 * face :: 2315 * The current face object. 2316 * 2317 * size :: 2318 * The current size object. 2319 * 2320 * slot :: 2321 * The current glyph object. 2322 * 2323 * hinting :: 2324 * Whether hinting is active. 2325 * 2326 * hint_mode :: 2327 * The hinting mode. 2328 */ 2329 FT_LOCAL_DEF( void ) cff_decoder_init(CFF_Decoder * decoder,TT_Face face,CFF_Size size,CFF_GlyphSlot slot,FT_Bool hinting,FT_Render_Mode hint_mode,CFF_Decoder_Get_Glyph_Callback get_callback,CFF_Decoder_Free_Glyph_Callback free_callback)2330 cff_decoder_init( CFF_Decoder* decoder, 2331 TT_Face face, 2332 CFF_Size size, 2333 CFF_GlyphSlot slot, 2334 FT_Bool hinting, 2335 FT_Render_Mode hint_mode, 2336 CFF_Decoder_Get_Glyph_Callback get_callback, 2337 CFF_Decoder_Free_Glyph_Callback free_callback ) 2338 { 2339 CFF_Font cff = (CFF_Font)face->extra.data; 2340 2341 2342 /* clear everything */ 2343 FT_ZERO( decoder ); 2344 2345 /* initialize builder */ 2346 cff_builder_init( &decoder->builder, face, size, slot, hinting ); 2347 2348 /* initialize Type2 decoder */ 2349 decoder->cff = cff; 2350 decoder->num_globals = cff->global_subrs_index.count; 2351 decoder->globals = cff->global_subrs; 2352 decoder->globals_bias = cff_compute_bias( 2353 cff->top_font.font_dict.charstring_type, 2354 decoder->num_globals ); 2355 2356 decoder->hint_mode = hint_mode; 2357 2358 decoder->get_glyph_callback = get_callback; 2359 decoder->free_glyph_callback = free_callback; 2360 } 2361 2362 2363 /* this function is used to select the subfont */ 2364 /* and the locals subrs array */ 2365 FT_LOCAL_DEF( FT_Error ) cff_decoder_prepare(CFF_Decoder * decoder,CFF_Size size,FT_UInt glyph_index)2366 cff_decoder_prepare( CFF_Decoder* decoder, 2367 CFF_Size size, 2368 FT_UInt glyph_index ) 2369 { 2370 CFF_Builder *builder = &decoder->builder; 2371 CFF_Font cff = (CFF_Font)builder->face->extra.data; 2372 CFF_SubFont sub = &cff->top_font; 2373 FT_Error error = FT_Err_Ok; 2374 2375 FT_Service_CFFLoad cffload = (FT_Service_CFFLoad)cff->cffload; 2376 2377 2378 /* manage CID fonts */ 2379 if ( cff->num_subfonts ) 2380 { 2381 FT_Byte fd_index = cffload->fd_select_get( &cff->fd_select, 2382 glyph_index ); 2383 2384 2385 if ( fd_index >= cff->num_subfonts ) 2386 { 2387 FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" )); 2388 error = FT_THROW( Invalid_File_Format ); 2389 goto Exit; 2390 } 2391 2392 FT_TRACE3(( " in subfont %d:\n", fd_index )); 2393 2394 sub = cff->subfonts[fd_index]; 2395 2396 if ( builder->hints_funcs && size ) 2397 { 2398 FT_Size ftsize = FT_SIZE( size ); 2399 CFF_Internal internal = (CFF_Internal)ftsize->internal->module_data; 2400 2401 2402 /* for CFFs without subfonts, this value has already been set */ 2403 builder->hints_globals = (void *)internal->subfonts[fd_index]; 2404 } 2405 } 2406 2407 decoder->num_locals = sub->local_subrs_index.count; 2408 decoder->locals = sub->local_subrs; 2409 decoder->locals_bias = cff_compute_bias( 2410 decoder->cff->top_font.font_dict.charstring_type, 2411 decoder->num_locals ); 2412 2413 decoder->glyph_width = sub->private_dict.default_width; 2414 decoder->nominal_width = sub->private_dict.nominal_width; 2415 2416 decoder->current_subfont = sub; 2417 2418 Exit: 2419 return error; 2420 } 2421 2422 2423 /* END */ 2424