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