1 /**************************************************************************** 2 * 3 * cffdecode.c 4 * 5 * PostScript CFF (Type 2) decoding routines (body). 6 * 7 * Copyright 2017-2018 by 8 * David Turner, Robert Wilhelm, and Werner Lemberg. 9 * 10 * This file is part of the FreeType project, and may only be used, 11 * modified, and distributed under the terms of the FreeType project 12 * license, LICENSE.TXT. By continuing to use, modify, or distribute 13 * this file you indicate that you have read the license and 14 * understand and accept it fully. 15 * 16 */ 17 18 19 #include <ft2build.h> 20 #include FT_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 trace_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 cff_operator_seac(CFF_Decoder * decoder,FT_Pos asb,FT_Pos adx,FT_Pos ady,FT_Int bchar,FT_Int achar)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 += decoder->builder.left_bearing.x; 239 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 = 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 cff_compute_bias(FT_Int in_charstring_type,FT_UInt num_subrs)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 ) cff_lookup_glyph_by_stdcharcode(CFF_Font cff,FT_Int charcode)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 ) cff_decoder_parse_charstrings(CFF_Decoder * decoder,FT_Byte * charstring_base,FT_ULong charstring_len,FT_Bool in_dict)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 zone->base = charstring_base; 534 limit = zone->limit = charstring_base + charstring_len; 535 ip = zone->cursor = zone->base; 536 537 error = FT_Err_Ok; 538 539 x = builder->pos_x; 540 y = builder->pos_y; 541 542 /* begin hints recording session, if any */ 543 if ( hinter ) 544 hinter->open( hinter->hints ); 545 546 /* now execute loop */ 547 while ( ip < limit ) 548 { 549 CFF_Operator op; 550 FT_Byte v; 551 552 553 /********************************************************************* 554 * 555 * Decode operator or operand 556 */ 557 v = *ip++; 558 if ( v >= 32 || v == 28 ) 559 { 560 FT_Int shift = 16; 561 FT_Int32 val; 562 563 564 /* this is an operand, push it on the stack */ 565 566 /* if we use shifts, all computations are done with unsigned */ 567 /* values; the conversion to a signed value is the last step */ 568 if ( v == 28 ) 569 { 570 if ( ip + 1 >= limit ) 571 goto Syntax_Error; 572 val = (FT_Short)( ( (FT_UShort)ip[0] << 8 ) | ip[1] ); 573 ip += 2; 574 } 575 else if ( v < 247 ) 576 val = (FT_Int32)v - 139; 577 else if ( v < 251 ) 578 { 579 if ( ip >= limit ) 580 goto Syntax_Error; 581 val = ( (FT_Int32)v - 247 ) * 256 + *ip++ + 108; 582 } 583 else if ( v < 255 ) 584 { 585 if ( ip >= limit ) 586 goto Syntax_Error; 587 val = -( (FT_Int32)v - 251 ) * 256 - *ip++ - 108; 588 } 589 else 590 { 591 if ( ip + 3 >= limit ) 592 goto Syntax_Error; 593 val = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) | 594 ( (FT_UInt32)ip[1] << 16 ) | 595 ( (FT_UInt32)ip[2] << 8 ) | 596 (FT_UInt32)ip[3] ); 597 ip += 4; 598 if ( charstring_type == 2 ) 599 shift = 0; 600 } 601 if ( decoder->top - stack >= CFF_MAX_OPERANDS ) 602 goto Stack_Overflow; 603 604 val = (FT_Int32)( (FT_UInt32)val << shift ); 605 *decoder->top++ = val; 606 607 #ifdef FT_DEBUG_LEVEL_TRACE 608 if ( !( val & 0xFFFFL ) ) 609 FT_TRACE4(( " %hd", (FT_Short)( (FT_UInt32)val >> 16 ) )); 610 else 611 FT_TRACE4(( " %.5f", val / 65536.0 )); 612 #endif 613 614 } 615 else 616 { 617 /* The specification says that normally arguments are to be taken */ 618 /* from the bottom of the stack. However, this seems not to be */ 619 /* correct, at least for Acroread 7.0.8 on GNU/Linux: It pops the */ 620 /* arguments similar to a PS interpreter. */ 621 622 FT_Fixed* args = decoder->top; 623 FT_Int num_args = (FT_Int)( args - decoder->stack ); 624 FT_Int req_args; 625 626 627 /* find operator */ 628 op = cff_op_unknown; 629 630 switch ( v ) 631 { 632 case 1: 633 op = cff_op_hstem; 634 break; 635 case 3: 636 op = cff_op_vstem; 637 break; 638 case 4: 639 op = cff_op_vmoveto; 640 break; 641 case 5: 642 op = cff_op_rlineto; 643 break; 644 case 6: 645 op = cff_op_hlineto; 646 break; 647 case 7: 648 op = cff_op_vlineto; 649 break; 650 case 8: 651 op = cff_op_rrcurveto; 652 break; 653 case 9: 654 op = cff_op_closepath; 655 break; 656 case 10: 657 op = cff_op_callsubr; 658 break; 659 case 11: 660 op = cff_op_return; 661 break; 662 case 12: 663 if ( ip >= limit ) 664 goto Syntax_Error; 665 v = *ip++; 666 667 switch ( v ) 668 { 669 case 0: 670 op = cff_op_dotsection; 671 break; 672 case 1: /* this is actually the Type1 vstem3 operator */ 673 op = cff_op_vstem; 674 break; 675 case 2: /* this is actually the Type1 hstem3 operator */ 676 op = cff_op_hstem; 677 break; 678 case 3: 679 op = cff_op_and; 680 break; 681 case 4: 682 op = cff_op_or; 683 break; 684 case 5: 685 op = cff_op_not; 686 break; 687 case 6: 688 op = cff_op_seac; 689 break; 690 case 7: 691 op = cff_op_sbw; 692 break; 693 case 8: 694 op = cff_op_store; 695 break; 696 case 9: 697 op = cff_op_abs; 698 break; 699 case 10: 700 op = cff_op_add; 701 break; 702 case 11: 703 op = cff_op_sub; 704 break; 705 case 12: 706 op = cff_op_div; 707 break; 708 case 13: 709 op = cff_op_load; 710 break; 711 case 14: 712 op = cff_op_neg; 713 break; 714 case 15: 715 op = cff_op_eq; 716 break; 717 case 16: 718 op = cff_op_callothersubr; 719 break; 720 case 17: 721 op = cff_op_pop; 722 break; 723 case 18: 724 op = cff_op_drop; 725 break; 726 case 20: 727 op = cff_op_put; 728 break; 729 case 21: 730 op = cff_op_get; 731 break; 732 case 22: 733 op = cff_op_ifelse; 734 break; 735 case 23: 736 op = cff_op_random; 737 break; 738 case 24: 739 op = cff_op_mul; 740 break; 741 case 26: 742 op = cff_op_sqrt; 743 break; 744 case 27: 745 op = cff_op_dup; 746 break; 747 case 28: 748 op = cff_op_exch; 749 break; 750 case 29: 751 op = cff_op_index; 752 break; 753 case 30: 754 op = cff_op_roll; 755 break; 756 case 33: 757 op = cff_op_setcurrentpoint; 758 break; 759 case 34: 760 op = cff_op_hflex; 761 break; 762 case 35: 763 op = cff_op_flex; 764 break; 765 case 36: 766 op = cff_op_hflex1; 767 break; 768 case 37: 769 op = cff_op_flex1; 770 break; 771 default: 772 FT_TRACE4(( " unknown op (12, %d)\n", v )); 773 break; 774 } 775 break; 776 case 13: 777 op = cff_op_hsbw; 778 break; 779 case 14: 780 op = cff_op_endchar; 781 break; 782 case 16: 783 op = cff_op_blend; 784 break; 785 case 18: 786 op = cff_op_hstemhm; 787 break; 788 case 19: 789 op = cff_op_hintmask; 790 break; 791 case 20: 792 op = cff_op_cntrmask; 793 break; 794 case 21: 795 op = cff_op_rmoveto; 796 break; 797 case 22: 798 op = cff_op_hmoveto; 799 break; 800 case 23: 801 op = cff_op_vstemhm; 802 break; 803 case 24: 804 op = cff_op_rcurveline; 805 break; 806 case 25: 807 op = cff_op_rlinecurve; 808 break; 809 case 26: 810 op = cff_op_vvcurveto; 811 break; 812 case 27: 813 op = cff_op_hhcurveto; 814 break; 815 case 29: 816 op = cff_op_callgsubr; 817 break; 818 case 30: 819 op = cff_op_vhcurveto; 820 break; 821 case 31: 822 op = cff_op_hvcurveto; 823 break; 824 default: 825 FT_TRACE4(( " unknown op (%d)\n", v )); 826 break; 827 } 828 829 if ( op == cff_op_unknown ) 830 continue; 831 832 /* in Multiple Master CFFs, T2 charstrings can appear in */ 833 /* dictionaries, but some operators are prohibited */ 834 if ( in_dict ) 835 { 836 switch ( op ) 837 { 838 case cff_op_hstem: 839 case cff_op_vstem: 840 case cff_op_vmoveto: 841 case cff_op_rlineto: 842 case cff_op_hlineto: 843 case cff_op_vlineto: 844 case cff_op_rrcurveto: 845 case cff_op_hstemhm: 846 case cff_op_hintmask: 847 case cff_op_cntrmask: 848 case cff_op_rmoveto: 849 case cff_op_hmoveto: 850 case cff_op_vstemhm: 851 case cff_op_rcurveline: 852 case cff_op_rlinecurve: 853 case cff_op_vvcurveto: 854 case cff_op_hhcurveto: 855 case cff_op_vhcurveto: 856 case cff_op_hvcurveto: 857 case cff_op_hflex: 858 case cff_op_flex: 859 case cff_op_hflex1: 860 case cff_op_flex1: 861 case cff_op_callsubr: 862 case cff_op_callgsubr: 863 goto MM_Error; 864 865 default: 866 break; 867 } 868 } 869 870 /* check arguments */ 871 req_args = cff_argument_counts[op]; 872 if ( req_args & CFF_COUNT_CHECK_WIDTH ) 873 { 874 if ( num_args > 0 && decoder->read_width ) 875 { 876 /* If `nominal_width' is non-zero, the number is really a */ 877 /* difference against `nominal_width'. Else, the number here */ 878 /* is truly a width, not a difference against `nominal_width'. */ 879 /* If the font does not set `nominal_width', then */ 880 /* `nominal_width' defaults to zero, and so we can set */ 881 /* `glyph_width' to `nominal_width' plus number on the stack */ 882 /* -- for either case. */ 883 884 FT_Int set_width_ok; 885 886 887 switch ( op ) 888 { 889 case cff_op_hmoveto: 890 case cff_op_vmoveto: 891 set_width_ok = num_args & 2; 892 break; 893 894 case cff_op_hstem: 895 case cff_op_vstem: 896 case cff_op_hstemhm: 897 case cff_op_vstemhm: 898 case cff_op_rmoveto: 899 case cff_op_hintmask: 900 case cff_op_cntrmask: 901 set_width_ok = num_args & 1; 902 break; 903 904 case cff_op_endchar: 905 /* If there is a width specified for endchar, we either have */ 906 /* 1 argument or 5 arguments. We like to argue. */ 907 set_width_ok = in_dict 908 ? 0 909 : ( ( num_args == 5 ) || ( num_args == 1 ) ); 910 break; 911 912 default: 913 set_width_ok = 0; 914 break; 915 } 916 917 if ( set_width_ok ) 918 { 919 decoder->glyph_width = decoder->nominal_width + 920 ( stack[0] >> 16 ); 921 922 if ( decoder->width_only ) 923 { 924 /* we only want the advance width; stop here */ 925 break; 926 } 927 928 /* Consumed an argument. */ 929 num_args--; 930 } 931 } 932 933 decoder->read_width = 0; 934 req_args = 0; 935 } 936 937 req_args &= 0x000F; 938 if ( num_args < req_args ) 939 goto Stack_Underflow; 940 args -= req_args; 941 num_args -= req_args; 942 943 /* At this point, `args' points to the first argument of the */ 944 /* operand in case `req_args' isn't zero. Otherwise, we have */ 945 /* to adjust `args' manually. */ 946 947 /* Note that we only pop arguments from the stack which we */ 948 /* really need and can digest so that we can continue in case */ 949 /* of superfluous stack elements. */ 950 951 switch ( op ) 952 { 953 case cff_op_hstem: 954 case cff_op_vstem: 955 case cff_op_hstemhm: 956 case cff_op_vstemhm: 957 /* the number of arguments is always even here */ 958 FT_TRACE4(( 959 op == cff_op_hstem ? " hstem\n" : 960 ( op == cff_op_vstem ? " vstem\n" : 961 ( op == cff_op_hstemhm ? " hstemhm\n" : " vstemhm\n" ) ) )); 962 963 if ( hinter ) 964 hinter->stems( hinter->hints, 965 ( op == cff_op_hstem || op == cff_op_hstemhm ), 966 num_args / 2, 967 args - ( num_args & ~1 ) ); 968 969 decoder->num_hints += num_args / 2; 970 args = stack; 971 break; 972 973 case cff_op_hintmask: 974 case cff_op_cntrmask: 975 FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" )); 976 977 /* implement vstem when needed -- */ 978 /* the specification doesn't say it, but this also works */ 979 /* with the 'cntrmask' operator */ 980 /* */ 981 if ( num_args > 0 ) 982 { 983 if ( hinter ) 984 hinter->stems( hinter->hints, 985 0, 986 num_args / 2, 987 args - ( num_args & ~1 ) ); 988 989 decoder->num_hints += num_args / 2; 990 } 991 992 /* In a valid charstring there must be at least one byte */ 993 /* after `hintmask' or `cntrmask' (e.g., for a `return' */ 994 /* instruction). Additionally, there must be space for */ 995 /* `num_hints' bits. */ 996 997 if ( ( ip + ( ( decoder->num_hints + 7 ) >> 3 ) ) >= limit ) 998 goto Syntax_Error; 999 1000 if ( hinter ) 1001 { 1002 if ( op == cff_op_hintmask ) 1003 hinter->hintmask( hinter->hints, 1004 (FT_UInt)builder->current->n_points, 1005 (FT_UInt)decoder->num_hints, 1006 ip ); 1007 else 1008 hinter->counter( hinter->hints, 1009 (FT_UInt)decoder->num_hints, 1010 ip ); 1011 } 1012 1013 #ifdef FT_DEBUG_LEVEL_TRACE 1014 { 1015 FT_UInt maskbyte; 1016 1017 1018 FT_TRACE4(( " (maskbytes:" )); 1019 1020 for ( maskbyte = 0; 1021 maskbyte < (FT_UInt)( ( decoder->num_hints + 7 ) >> 3 ); 1022 maskbyte++, ip++ ) 1023 FT_TRACE4(( " 0x%02X", *ip )); 1024 1025 FT_TRACE4(( ")\n" )); 1026 } 1027 #else 1028 ip += ( decoder->num_hints + 7 ) >> 3; 1029 #endif 1030 args = stack; 1031 break; 1032 1033 case cff_op_rmoveto: 1034 FT_TRACE4(( " rmoveto\n" )); 1035 1036 cff_builder_close_contour( builder ); 1037 builder->path_begun = 0; 1038 x = ADD_LONG( x, args[-2] ); 1039 y = ADD_LONG( y, args[-1] ); 1040 args = stack; 1041 break; 1042 1043 case cff_op_vmoveto: 1044 FT_TRACE4(( " vmoveto\n" )); 1045 1046 cff_builder_close_contour( builder ); 1047 builder->path_begun = 0; 1048 y = ADD_LONG( y, args[-1] ); 1049 args = stack; 1050 break; 1051 1052 case cff_op_hmoveto: 1053 FT_TRACE4(( " hmoveto\n" )); 1054 1055 cff_builder_close_contour( builder ); 1056 builder->path_begun = 0; 1057 x = ADD_LONG( x, args[-1] ); 1058 args = stack; 1059 break; 1060 1061 case cff_op_rlineto: 1062 FT_TRACE4(( " rlineto\n" )); 1063 1064 if ( cff_builder_start_point( builder, x, y ) || 1065 cff_check_points( builder, num_args / 2 ) ) 1066 goto Fail; 1067 1068 if ( num_args < 2 ) 1069 goto Stack_Underflow; 1070 1071 args -= num_args & ~1; 1072 while ( args < decoder->top ) 1073 { 1074 x = ADD_LONG( x, args[0] ); 1075 y = ADD_LONG( y, args[1] ); 1076 cff_builder_add_point( builder, x, y, 1 ); 1077 args += 2; 1078 } 1079 args = stack; 1080 break; 1081 1082 case cff_op_hlineto: 1083 case cff_op_vlineto: 1084 { 1085 FT_Int phase = ( op == cff_op_hlineto ); 1086 1087 1088 FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n" 1089 : " vlineto\n" )); 1090 1091 if ( num_args < 0 ) 1092 goto Stack_Underflow; 1093 1094 /* there exist subsetted fonts (found in PDFs) */ 1095 /* which call `hlineto' without arguments */ 1096 if ( num_args == 0 ) 1097 break; 1098 1099 if ( cff_builder_start_point( builder, x, y ) || 1100 cff_check_points( builder, num_args ) ) 1101 goto Fail; 1102 1103 args = stack; 1104 while ( args < decoder->top ) 1105 { 1106 if ( phase ) 1107 x = ADD_LONG( x, args[0] ); 1108 else 1109 y = ADD_LONG( y, args[0] ); 1110 1111 if ( cff_builder_add_point1( builder, x, y ) ) 1112 goto Fail; 1113 1114 args++; 1115 phase ^= 1; 1116 } 1117 args = stack; 1118 } 1119 break; 1120 1121 case cff_op_rrcurveto: 1122 { 1123 FT_Int nargs; 1124 1125 1126 FT_TRACE4(( " rrcurveto\n" )); 1127 1128 if ( num_args < 6 ) 1129 goto Stack_Underflow; 1130 1131 nargs = num_args - num_args % 6; 1132 1133 if ( cff_builder_start_point( builder, x, y ) || 1134 cff_check_points( builder, nargs / 2 ) ) 1135 goto Fail; 1136 1137 args -= nargs; 1138 while ( args < decoder->top ) 1139 { 1140 x = ADD_LONG( x, args[0] ); 1141 y = ADD_LONG( y, args[1] ); 1142 cff_builder_add_point( builder, x, y, 0 ); 1143 1144 x = ADD_LONG( x, args[2] ); 1145 y = ADD_LONG( y, args[3] ); 1146 cff_builder_add_point( builder, x, y, 0 ); 1147 1148 x = ADD_LONG( x, args[4] ); 1149 y = ADD_LONG( y, args[5] ); 1150 cff_builder_add_point( builder, x, y, 1 ); 1151 1152 args += 6; 1153 } 1154 args = stack; 1155 } 1156 break; 1157 1158 case cff_op_vvcurveto: 1159 { 1160 FT_Int nargs; 1161 1162 1163 FT_TRACE4(( " vvcurveto\n" )); 1164 1165 if ( num_args < 4 ) 1166 goto Stack_Underflow; 1167 1168 /* if num_args isn't of the form 4n or 4n+1, */ 1169 /* we enforce it by clearing the second bit */ 1170 1171 nargs = num_args & ~2; 1172 1173 if ( cff_builder_start_point( builder, x, y ) ) 1174 goto Fail; 1175 1176 args -= nargs; 1177 1178 if ( nargs & 1 ) 1179 { 1180 x = ADD_LONG( x, args[0] ); 1181 args++; 1182 nargs--; 1183 } 1184 1185 if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) ) 1186 goto Fail; 1187 1188 while ( args < decoder->top ) 1189 { 1190 y = ADD_LONG( y, args[0] ); 1191 cff_builder_add_point( builder, x, y, 0 ); 1192 1193 x = ADD_LONG( x, args[1] ); 1194 y = ADD_LONG( y, args[2] ); 1195 cff_builder_add_point( builder, x, y, 0 ); 1196 1197 y = ADD_LONG( y, args[3] ); 1198 cff_builder_add_point( builder, x, y, 1 ); 1199 1200 args += 4; 1201 } 1202 args = stack; 1203 } 1204 break; 1205 1206 case cff_op_hhcurveto: 1207 { 1208 FT_Int nargs; 1209 1210 1211 FT_TRACE4(( " hhcurveto\n" )); 1212 1213 if ( num_args < 4 ) 1214 goto Stack_Underflow; 1215 1216 /* if num_args isn't of the form 4n or 4n+1, */ 1217 /* we enforce it by clearing the second bit */ 1218 1219 nargs = num_args & ~2; 1220 1221 if ( cff_builder_start_point( builder, x, y ) ) 1222 goto Fail; 1223 1224 args -= nargs; 1225 if ( nargs & 1 ) 1226 { 1227 y = ADD_LONG( y, args[0] ); 1228 args++; 1229 nargs--; 1230 } 1231 1232 if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) ) 1233 goto Fail; 1234 1235 while ( args < decoder->top ) 1236 { 1237 x = ADD_LONG( x, args[0] ); 1238 cff_builder_add_point( builder, x, y, 0 ); 1239 1240 x = ADD_LONG( x, args[1] ); 1241 y = ADD_LONG( y, args[2] ); 1242 cff_builder_add_point( builder, x, y, 0 ); 1243 1244 x = ADD_LONG( x, args[3] ); 1245 cff_builder_add_point( builder, x, y, 1 ); 1246 1247 args += 4; 1248 } 1249 args = stack; 1250 } 1251 break; 1252 1253 case cff_op_vhcurveto: 1254 case cff_op_hvcurveto: 1255 { 1256 FT_Int phase; 1257 FT_Int nargs; 1258 1259 1260 FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto\n" 1261 : " hvcurveto\n" )); 1262 1263 if ( cff_builder_start_point( builder, x, y ) ) 1264 goto Fail; 1265 1266 if ( num_args < 4 ) 1267 goto Stack_Underflow; 1268 1269 /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */ 1270 /* we enforce it by clearing the second bit */ 1271 1272 nargs = num_args & ~2; 1273 1274 args -= nargs; 1275 if ( cff_check_points( builder, ( nargs / 4 ) * 3 ) ) 1276 goto Stack_Underflow; 1277 1278 phase = ( op == cff_op_hvcurveto ); 1279 1280 while ( nargs >= 4 ) 1281 { 1282 nargs -= 4; 1283 if ( phase ) 1284 { 1285 x = ADD_LONG( x, args[0] ); 1286 cff_builder_add_point( builder, x, y, 0 ); 1287 1288 x = ADD_LONG( x, args[1] ); 1289 y = ADD_LONG( y, args[2] ); 1290 cff_builder_add_point( builder, x, y, 0 ); 1291 1292 y = ADD_LONG( y, args[3] ); 1293 if ( nargs == 1 ) 1294 x = ADD_LONG( x, args[4] ); 1295 cff_builder_add_point( builder, x, y, 1 ); 1296 } 1297 else 1298 { 1299 y = ADD_LONG( y, args[0] ); 1300 cff_builder_add_point( builder, x, y, 0 ); 1301 1302 x = ADD_LONG( x, args[1] ); 1303 y = ADD_LONG( y, args[2] ); 1304 cff_builder_add_point( builder, x, y, 0 ); 1305 1306 x = ADD_LONG( x, args[3] ); 1307 if ( nargs == 1 ) 1308 y = ADD_LONG( y, args[4] ); 1309 cff_builder_add_point( builder, x, y, 1 ); 1310 } 1311 args += 4; 1312 phase ^= 1; 1313 } 1314 args = stack; 1315 } 1316 break; 1317 1318 case cff_op_rlinecurve: 1319 { 1320 FT_Int num_lines; 1321 FT_Int nargs; 1322 1323 1324 FT_TRACE4(( " rlinecurve\n" )); 1325 1326 if ( num_args < 8 ) 1327 goto Stack_Underflow; 1328 1329 nargs = num_args & ~1; 1330 num_lines = ( nargs - 6 ) / 2; 1331 1332 if ( cff_builder_start_point( builder, x, y ) || 1333 cff_check_points( builder, num_lines + 3 ) ) 1334 goto Fail; 1335 1336 args -= nargs; 1337 1338 /* first, add the line segments */ 1339 while ( num_lines > 0 ) 1340 { 1341 x = ADD_LONG( x, args[0] ); 1342 y = ADD_LONG( y, args[1] ); 1343 cff_builder_add_point( builder, x, y, 1 ); 1344 1345 args += 2; 1346 num_lines--; 1347 } 1348 1349 /* then the curve */ 1350 x = ADD_LONG( x, args[0] ); 1351 y = ADD_LONG( y, args[1] ); 1352 cff_builder_add_point( builder, x, y, 0 ); 1353 1354 x = ADD_LONG( x, args[2] ); 1355 y = ADD_LONG( y, args[3] ); 1356 cff_builder_add_point( builder, x, y, 0 ); 1357 1358 x = ADD_LONG( x, args[4] ); 1359 y = ADD_LONG( y, args[5] ); 1360 cff_builder_add_point( builder, x, y, 1 ); 1361 1362 args = stack; 1363 } 1364 break; 1365 1366 case cff_op_rcurveline: 1367 { 1368 FT_Int num_curves; 1369 FT_Int nargs; 1370 1371 1372 FT_TRACE4(( " rcurveline\n" )); 1373 1374 if ( num_args < 8 ) 1375 goto Stack_Underflow; 1376 1377 nargs = num_args - 2; 1378 nargs = nargs - nargs % 6 + 2; 1379 num_curves = ( nargs - 2 ) / 6; 1380 1381 if ( cff_builder_start_point( builder, x, y ) || 1382 cff_check_points( builder, num_curves * 3 + 2 ) ) 1383 goto Fail; 1384 1385 args -= nargs; 1386 1387 /* first, add the curves */ 1388 while ( num_curves > 0 ) 1389 { 1390 x = ADD_LONG( x, args[0] ); 1391 y = ADD_LONG( y, args[1] ); 1392 cff_builder_add_point( builder, x, y, 0 ); 1393 1394 x = ADD_LONG( x, args[2] ); 1395 y = ADD_LONG( y, args[3] ); 1396 cff_builder_add_point( builder, x, y, 0 ); 1397 1398 x = ADD_LONG( x, args[4] ); 1399 y = ADD_LONG( y, args[5] ); 1400 cff_builder_add_point( builder, x, y, 1 ); 1401 1402 args += 6; 1403 num_curves--; 1404 } 1405 1406 /* then the final line */ 1407 x = ADD_LONG( x, args[0] ); 1408 y = ADD_LONG( y, args[1] ); 1409 cff_builder_add_point( builder, x, y, 1 ); 1410 1411 args = stack; 1412 } 1413 break; 1414 1415 case cff_op_hflex1: 1416 { 1417 FT_Pos start_y; 1418 1419 1420 FT_TRACE4(( " hflex1\n" )); 1421 1422 /* adding five more points: 4 control points, 1 on-curve point */ 1423 /* -- make sure we have enough space for the start point if it */ 1424 /* needs to be added */ 1425 if ( cff_builder_start_point( builder, x, y ) || 1426 cff_check_points( builder, 6 ) ) 1427 goto Fail; 1428 1429 /* record the starting point's y position for later use */ 1430 start_y = y; 1431 1432 /* first control point */ 1433 x = ADD_LONG( x, args[0] ); 1434 y = ADD_LONG( y, args[1] ); 1435 cff_builder_add_point( builder, x, y, 0 ); 1436 1437 /* second control point */ 1438 x = ADD_LONG( x, args[2] ); 1439 y = ADD_LONG( y, args[3] ); 1440 cff_builder_add_point( builder, x, y, 0 ); 1441 1442 /* join point; on curve, with y-value the same as the last */ 1443 /* control point's y-value */ 1444 x = ADD_LONG( x, args[4] ); 1445 cff_builder_add_point( builder, x, y, 1 ); 1446 1447 /* third control point, with y-value the same as the join */ 1448 /* point's y-value */ 1449 x = ADD_LONG( x, args[5] ); 1450 cff_builder_add_point( builder, x, y, 0 ); 1451 1452 /* fourth control point */ 1453 x = ADD_LONG( x, args[6] ); 1454 y = ADD_LONG( y, args[7] ); 1455 cff_builder_add_point( builder, x, y, 0 ); 1456 1457 /* ending point, with y-value the same as the start */ 1458 x = ADD_LONG( x, args[8] ); 1459 y = start_y; 1460 cff_builder_add_point( builder, x, y, 1 ); 1461 1462 args = stack; 1463 break; 1464 } 1465 1466 case cff_op_hflex: 1467 { 1468 FT_Pos start_y; 1469 1470 1471 FT_TRACE4(( " hflex\n" )); 1472 1473 /* adding six more points; 4 control points, 2 on-curve points */ 1474 if ( cff_builder_start_point( builder, x, y ) || 1475 cff_check_points( builder, 6 ) ) 1476 goto Fail; 1477 1478 /* record the starting point's y-position for later use */ 1479 start_y = y; 1480 1481 /* first control point */ 1482 x = ADD_LONG( x, args[0] ); 1483 cff_builder_add_point( builder, x, y, 0 ); 1484 1485 /* second control point */ 1486 x = ADD_LONG( x, args[1] ); 1487 y = ADD_LONG( y, args[2] ); 1488 cff_builder_add_point( builder, x, y, 0 ); 1489 1490 /* join point; on curve, with y-value the same as the last */ 1491 /* control point's y-value */ 1492 x = ADD_LONG( x, args[3] ); 1493 cff_builder_add_point( builder, x, y, 1 ); 1494 1495 /* third control point, with y-value the same as the join */ 1496 /* point's y-value */ 1497 x = ADD_LONG( x, args[4] ); 1498 cff_builder_add_point( builder, x, y, 0 ); 1499 1500 /* fourth control point */ 1501 x = ADD_LONG( x, args[5] ); 1502 y = start_y; 1503 cff_builder_add_point( builder, x, y, 0 ); 1504 1505 /* ending point, with y-value the same as the start point's */ 1506 /* y-value -- we don't add this point, though */ 1507 x = ADD_LONG( x, args[6] ); 1508 cff_builder_add_point( builder, x, y, 1 ); 1509 1510 args = stack; 1511 break; 1512 } 1513 1514 case cff_op_flex1: 1515 { 1516 FT_Pos start_x, start_y; /* record start x, y values for */ 1517 /* alter use */ 1518 FT_Fixed dx = 0, dy = 0; /* used in horizontal/vertical */ 1519 /* algorithm below */ 1520 FT_Int horizontal, count; 1521 FT_Fixed* temp; 1522 1523 1524 FT_TRACE4(( " flex1\n" )); 1525 1526 /* adding six more points; 4 control points, 2 on-curve points */ 1527 if ( cff_builder_start_point( builder, x, y ) || 1528 cff_check_points( builder, 6 ) ) 1529 goto Fail; 1530 1531 /* record the starting point's x, y position for later use */ 1532 start_x = x; 1533 start_y = y; 1534 1535 /* XXX: figure out whether this is supposed to be a horizontal */ 1536 /* or vertical flex; the Type 2 specification is vague... */ 1537 1538 temp = args; 1539 1540 /* grab up to the last argument */ 1541 for ( count = 5; count > 0; count-- ) 1542 { 1543 dx = ADD_LONG( dx, temp[0] ); 1544 dy = ADD_LONG( dy, temp[1] ); 1545 temp += 2; 1546 } 1547 1548 if ( dx < 0 ) 1549 dx = -dx; 1550 if ( dy < 0 ) 1551 dy = -dy; 1552 1553 /* strange test, but here it is... */ 1554 horizontal = ( dx > dy ); 1555 1556 for ( count = 5; count > 0; count-- ) 1557 { 1558 x = ADD_LONG( x, args[0] ); 1559 y = ADD_LONG( y, args[1] ); 1560 cff_builder_add_point( builder, x, y, 1561 (FT_Bool)( count == 3 ) ); 1562 args += 2; 1563 } 1564 1565 /* is last operand an x- or y-delta? */ 1566 if ( horizontal ) 1567 { 1568 x = ADD_LONG( x, args[0] ); 1569 y = start_y; 1570 } 1571 else 1572 { 1573 x = start_x; 1574 y = ADD_LONG( y, args[0] ); 1575 } 1576 1577 cff_builder_add_point( builder, x, y, 1 ); 1578 1579 args = stack; 1580 break; 1581 } 1582 1583 case cff_op_flex: 1584 { 1585 FT_UInt count; 1586 1587 1588 FT_TRACE4(( " flex\n" )); 1589 1590 if ( cff_builder_start_point( builder, x, y ) || 1591 cff_check_points( builder, 6 ) ) 1592 goto Fail; 1593 1594 for ( count = 6; count > 0; count-- ) 1595 { 1596 x = ADD_LONG( x, args[0] ); 1597 y = ADD_LONG( y, args[1] ); 1598 cff_builder_add_point( builder, x, y, 1599 (FT_Bool)( count == 4 || count == 1 ) ); 1600 args += 2; 1601 } 1602 1603 args = stack; 1604 } 1605 break; 1606 1607 case cff_op_seac: 1608 FT_TRACE4(( " seac\n" )); 1609 1610 error = cff_operator_seac( decoder, 1611 args[0], args[1], args[2], 1612 (FT_Int)( args[3] >> 16 ), 1613 (FT_Int)( args[4] >> 16 ) ); 1614 1615 /* add current outline to the glyph slot */ 1616 FT_GlyphLoader_Add( builder->loader ); 1617 1618 /* return now! */ 1619 FT_TRACE4(( "\n" )); 1620 return error; 1621 1622 case cff_op_endchar: 1623 /* in dictionaries, `endchar' simply indicates end of data */ 1624 if ( in_dict ) 1625 return error; 1626 1627 FT_TRACE4(( " endchar\n" )); 1628 1629 /* We are going to emulate the seac operator. */ 1630 if ( num_args >= 4 ) 1631 { 1632 /* Save glyph width so that the subglyphs don't overwrite it. */ 1633 FT_Pos glyph_width = decoder->glyph_width; 1634 1635 1636 error = cff_operator_seac( decoder, 1637 0L, args[-4], args[-3], 1638 (FT_Int)( args[-2] >> 16 ), 1639 (FT_Int)( args[-1] >> 16 ) ); 1640 1641 decoder->glyph_width = glyph_width; 1642 } 1643 else 1644 { 1645 cff_builder_close_contour( builder ); 1646 1647 /* close hints recording session */ 1648 if ( hinter ) 1649 { 1650 if ( hinter->close( hinter->hints, 1651 (FT_UInt)builder->current->n_points ) ) 1652 goto Syntax_Error; 1653 1654 /* apply hints to the loaded glyph outline now */ 1655 error = hinter->apply( hinter->hints, 1656 builder->current, 1657 (PSH_Globals)builder->hints_globals, 1658 decoder->hint_mode ); 1659 if ( error ) 1660 goto Fail; 1661 } 1662 1663 /* add current outline to the glyph slot */ 1664 FT_GlyphLoader_Add( builder->loader ); 1665 } 1666 1667 /* return now! */ 1668 FT_TRACE4(( "\n" )); 1669 return error; 1670 1671 case cff_op_abs: 1672 FT_TRACE4(( " abs\n" )); 1673 1674 if ( args[0] < 0 ) 1675 { 1676 if ( args[0] == FT_LONG_MIN ) 1677 args[0] = FT_LONG_MAX; 1678 else 1679 args[0] = -args[0]; 1680 } 1681 args++; 1682 break; 1683 1684 case cff_op_add: 1685 FT_TRACE4(( " add\n" )); 1686 1687 args[0] = ADD_LONG( args[0], args[1] ); 1688 args++; 1689 break; 1690 1691 case cff_op_sub: 1692 FT_TRACE4(( " sub\n" )); 1693 1694 args[0] = SUB_LONG( args[0], args[1] ); 1695 args++; 1696 break; 1697 1698 case cff_op_div: 1699 FT_TRACE4(( " div\n" )); 1700 1701 args[0] = FT_DivFix( args[0], args[1] ); 1702 args++; 1703 break; 1704 1705 case cff_op_neg: 1706 FT_TRACE4(( " neg\n" )); 1707 1708 if ( args[0] == FT_LONG_MIN ) 1709 args[0] = FT_LONG_MAX; 1710 args[0] = -args[0]; 1711 args++; 1712 break; 1713 1714 case cff_op_random: 1715 FT_TRACE4(( " random\n" )); 1716 1717 /* only use the lower 16 bits of `random' */ 1718 /* to generate a number in the range (0;1] */ 1719 args[0] = (FT_Fixed) 1720 ( ( decoder->current_subfont->random & 0xFFFF ) + 1 ); 1721 args++; 1722 1723 decoder->current_subfont->random = 1724 cff_random( decoder->current_subfont->random ); 1725 break; 1726 1727 case cff_op_mul: 1728 FT_TRACE4(( " mul\n" )); 1729 1730 args[0] = FT_MulFix( args[0], args[1] ); 1731 args++; 1732 break; 1733 1734 case cff_op_sqrt: 1735 FT_TRACE4(( " sqrt\n" )); 1736 1737 if ( args[0] > 0 ) 1738 { 1739 FT_Fixed root = args[0]; 1740 FT_Fixed new_root; 1741 1742 1743 for (;;) 1744 { 1745 new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1; 1746 if ( new_root == root ) 1747 break; 1748 root = new_root; 1749 } 1750 args[0] = new_root; 1751 } 1752 else 1753 args[0] = 0; 1754 args++; 1755 break; 1756 1757 case cff_op_drop: 1758 /* nothing */ 1759 FT_TRACE4(( " drop\n" )); 1760 1761 break; 1762 1763 case cff_op_exch: 1764 { 1765 FT_Fixed tmp; 1766 1767 1768 FT_TRACE4(( " exch\n" )); 1769 1770 tmp = args[0]; 1771 args[0] = args[1]; 1772 args[1] = tmp; 1773 args += 2; 1774 } 1775 break; 1776 1777 case cff_op_index: 1778 { 1779 FT_Int idx = (FT_Int)( args[0] >> 16 ); 1780 1781 1782 FT_TRACE4(( " index\n" )); 1783 1784 if ( idx < 0 ) 1785 idx = 0; 1786 else if ( idx > num_args - 2 ) 1787 idx = num_args - 2; 1788 args[0] = args[-( idx + 1 )]; 1789 args++; 1790 } 1791 break; 1792 1793 case cff_op_roll: 1794 { 1795 FT_Int count = (FT_Int)( args[0] >> 16 ); 1796 FT_Int idx = (FT_Int)( args[1] >> 16 ); 1797 1798 1799 FT_TRACE4(( " roll\n" )); 1800 1801 if ( count <= 0 ) 1802 count = 1; 1803 1804 args -= count; 1805 if ( args < stack ) 1806 goto Stack_Underflow; 1807 1808 if ( idx >= 0 ) 1809 { 1810 while ( idx > 0 ) 1811 { 1812 FT_Fixed tmp = args[count - 1]; 1813 FT_Int i; 1814 1815 1816 for ( i = count - 2; i >= 0; i-- ) 1817 args[i + 1] = args[i]; 1818 args[0] = tmp; 1819 idx--; 1820 } 1821 } 1822 else 1823 { 1824 while ( idx < 0 ) 1825 { 1826 FT_Fixed tmp = args[0]; 1827 FT_Int i; 1828 1829 1830 for ( i = 0; i < count - 1; i++ ) 1831 args[i] = args[i + 1]; 1832 args[count - 1] = tmp; 1833 idx++; 1834 } 1835 } 1836 args += count; 1837 } 1838 break; 1839 1840 case cff_op_dup: 1841 FT_TRACE4(( " dup\n" )); 1842 1843 args[1] = args[0]; 1844 args += 2; 1845 break; 1846 1847 case cff_op_put: 1848 { 1849 FT_Fixed val = args[0]; 1850 FT_Int idx = (FT_Int)( args[1] >> 16 ); 1851 1852 1853 FT_TRACE4(( " put\n" )); 1854 1855 /* the Type2 specification before version 16-March-2000 */ 1856 /* didn't give a hard-coded size limit of the temporary */ 1857 /* storage array; instead, an argument of the */ 1858 /* `MultipleMaster' operator set the size */ 1859 if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS ) 1860 decoder->buildchar[idx] = val; 1861 } 1862 break; 1863 1864 case cff_op_get: 1865 { 1866 FT_Int idx = (FT_Int)( args[0] >> 16 ); 1867 FT_Fixed val = 0; 1868 1869 1870 FT_TRACE4(( " get\n" )); 1871 1872 if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS ) 1873 val = decoder->buildchar[idx]; 1874 1875 args[0] = val; 1876 args++; 1877 } 1878 break; 1879 1880 case cff_op_store: 1881 /* this operator was removed from the Type2 specification */ 1882 /* in version 16-March-2000 */ 1883 1884 /* since we currently don't handle interpolation of multiple */ 1885 /* master fonts, this is a no-op */ 1886 FT_TRACE4(( " store\n" )); 1887 break; 1888 1889 case cff_op_load: 1890 /* this operator was removed from the Type2 specification */ 1891 /* in version 16-March-2000 */ 1892 { 1893 FT_Int reg_idx = (FT_Int)args[0]; 1894 FT_Int idx = (FT_Int)args[1]; 1895 FT_Int count = (FT_Int)args[2]; 1896 1897 1898 FT_TRACE4(( " load\n" )); 1899 1900 /* since we currently don't handle interpolation of multiple */ 1901 /* master fonts, we store a vector [1 0 0 ...] in the */ 1902 /* temporary storage array regardless of the Registry index */ 1903 if ( reg_idx >= 0 && reg_idx <= 2 && 1904 idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS && 1905 count >= 0 && count <= num_axes ) 1906 { 1907 FT_Int end, i; 1908 1909 1910 end = FT_MIN( idx + count, CFF_MAX_TRANS_ELEMENTS ); 1911 1912 if ( idx < end ) 1913 decoder->buildchar[idx] = 1 << 16; 1914 1915 for ( i = idx + 1; i < end; i++ ) 1916 decoder->buildchar[i] = 0; 1917 } 1918 } 1919 break; 1920 1921 case cff_op_blend: 1922 /* this operator was removed from the Type2 specification */ 1923 /* in version 16-March-2000 */ 1924 { 1925 FT_Int num_results = (FT_Int)( args[0] >> 16 ); 1926 1927 1928 FT_TRACE4(( " blend\n" )); 1929 1930 if ( num_results < 0 ) 1931 goto Syntax_Error; 1932 1933 if ( num_results * (FT_Int)num_designs > num_args ) 1934 goto Stack_Underflow; 1935 1936 /* since we currently don't handle interpolation of multiple */ 1937 /* master fonts, return the `num_results' values of the */ 1938 /* first master */ 1939 args -= num_results * ( num_designs - 1 ); 1940 num_args -= num_results * ( num_designs - 1 ); 1941 } 1942 break; 1943 1944 case cff_op_dotsection: 1945 /* this operator is deprecated and ignored by the parser */ 1946 FT_TRACE4(( " dotsection\n" )); 1947 break; 1948 1949 case cff_op_closepath: 1950 /* this is an invalid Type 2 operator; however, there */ 1951 /* exist fonts which are incorrectly converted from probably */ 1952 /* Type 1 to CFF, and some parsers seem to accept it */ 1953 1954 FT_TRACE4(( " closepath (invalid op)\n" )); 1955 1956 args = stack; 1957 break; 1958 1959 case cff_op_hsbw: 1960 /* this is an invalid Type 2 operator; however, there */ 1961 /* exist fonts which are incorrectly converted from probably */ 1962 /* Type 1 to CFF, and some parsers seem to accept it */ 1963 1964 FT_TRACE4(( " hsbw (invalid op)\n" )); 1965 1966 decoder->glyph_width = 1967 ADD_LONG( decoder->nominal_width, ( args[1] >> 16 ) ); 1968 1969 decoder->builder.left_bearing.x = args[0]; 1970 decoder->builder.left_bearing.y = 0; 1971 1972 x = ADD_LONG( decoder->builder.pos_x, args[0] ); 1973 y = decoder->builder.pos_y; 1974 args = stack; 1975 break; 1976 1977 case cff_op_sbw: 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(( " sbw (invalid op)\n" )); 1983 1984 decoder->glyph_width = 1985 ADD_LONG( decoder->nominal_width, ( args[2] >> 16 ) ); 1986 1987 decoder->builder.left_bearing.x = args[0]; 1988 decoder->builder.left_bearing.y = args[1]; 1989 1990 x = ADD_LONG( decoder->builder.pos_x, args[0] ); 1991 y = ADD_LONG( decoder->builder.pos_y, args[1] ); 1992 args = stack; 1993 break; 1994 1995 case cff_op_setcurrentpoint: 1996 /* this is an invalid Type 2 operator; however, there */ 1997 /* exist fonts which are incorrectly converted from probably */ 1998 /* Type 1 to CFF, and some parsers seem to accept it */ 1999 2000 FT_TRACE4(( " setcurrentpoint (invalid op)\n" )); 2001 2002 x = ADD_LONG( decoder->builder.pos_x, args[0] ); 2003 y = ADD_LONG( decoder->builder.pos_y, args[1] ); 2004 args = stack; 2005 break; 2006 2007 case cff_op_callothersubr: 2008 /* this is an invalid Type 2 operator; however, there */ 2009 /* exist fonts which are incorrectly converted from probably */ 2010 /* Type 1 to CFF, and some parsers seem to accept it */ 2011 2012 FT_TRACE4(( " callothersubr (invalid op)\n" )); 2013 2014 /* subsequent `pop' operands should add the arguments, */ 2015 /* this is the implementation described for `unknown' other */ 2016 /* subroutines in the Type1 spec. */ 2017 /* */ 2018 /* XXX Fix return arguments (see discussion below). */ 2019 args -= 2 + ( args[-2] >> 16 ); 2020 if ( args < stack ) 2021 goto Stack_Underflow; 2022 break; 2023 2024 case cff_op_pop: 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(( " pop (invalid op)\n" )); 2030 2031 /* XXX Increasing `args' is wrong: After a certain number of */ 2032 /* `pop's we get a stack overflow. Reason for doing it is */ 2033 /* code like this (actually found in a CFF font): */ 2034 /* */ 2035 /* 17 1 3 callothersubr */ 2036 /* pop */ 2037 /* callsubr */ 2038 /* */ 2039 /* Since we handle `callothersubr' as a no-op, and */ 2040 /* `callsubr' needs at least one argument, `pop' can't be a */ 2041 /* no-op too as it basically should be. */ 2042 /* */ 2043 /* The right solution would be to provide real support for */ 2044 /* `callothersubr' as done in `t1decode.c', however, given */ 2045 /* the fact that CFF fonts with `pop' are invalid, it is */ 2046 /* questionable whether it is worth the time. */ 2047 args++; 2048 break; 2049 2050 case cff_op_and: 2051 { 2052 FT_Fixed cond = ( args[0] && args[1] ); 2053 2054 2055 FT_TRACE4(( " and\n" )); 2056 2057 args[0] = cond ? 0x10000L : 0; 2058 args++; 2059 } 2060 break; 2061 2062 case cff_op_or: 2063 { 2064 FT_Fixed cond = ( args[0] || args[1] ); 2065 2066 2067 FT_TRACE4(( " or\n" )); 2068 2069 args[0] = cond ? 0x10000L : 0; 2070 args++; 2071 } 2072 break; 2073 2074 case cff_op_not: 2075 { 2076 FT_Fixed cond = !args[0]; 2077 2078 2079 FT_TRACE4(( " not\n" )); 2080 2081 args[0] = cond ? 0x10000L : 0; 2082 args++; 2083 } 2084 break; 2085 2086 case cff_op_eq: 2087 { 2088 FT_Fixed cond = ( args[0] == args[1] ); 2089 2090 2091 FT_TRACE4(( " eq\n" )); 2092 2093 args[0] = cond ? 0x10000L : 0; 2094 args++; 2095 } 2096 break; 2097 2098 case cff_op_ifelse: 2099 { 2100 FT_Fixed cond = ( args[2] <= args[3] ); 2101 2102 2103 FT_TRACE4(( " ifelse\n" )); 2104 2105 if ( !cond ) 2106 args[0] = args[1]; 2107 args++; 2108 } 2109 break; 2110 2111 case cff_op_callsubr: 2112 { 2113 FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) + 2114 decoder->locals_bias ); 2115 2116 2117 FT_TRACE4(( " callsubr (idx %d, entering level %d)\n", 2118 idx, 2119 zone - decoder->zones + 1 )); 2120 2121 if ( idx >= decoder->num_locals ) 2122 { 2123 FT_ERROR(( "cff_decoder_parse_charstrings:" 2124 " invalid local subr index\n" )); 2125 goto Syntax_Error; 2126 } 2127 2128 if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS ) 2129 { 2130 FT_ERROR(( "cff_decoder_parse_charstrings:" 2131 " too many nested subrs\n" )); 2132 goto Syntax_Error; 2133 } 2134 2135 zone->cursor = ip; /* save current instruction pointer */ 2136 2137 zone++; 2138 zone->base = decoder->locals[idx]; 2139 zone->limit = decoder->locals[idx + 1]; 2140 zone->cursor = zone->base; 2141 2142 if ( !zone->base || zone->limit == zone->base ) 2143 { 2144 FT_ERROR(( "cff_decoder_parse_charstrings:" 2145 " invoking empty subrs\n" )); 2146 goto Syntax_Error; 2147 } 2148 2149 decoder->zone = zone; 2150 ip = zone->base; 2151 limit = zone->limit; 2152 } 2153 break; 2154 2155 case cff_op_callgsubr: 2156 { 2157 FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) + 2158 decoder->globals_bias ); 2159 2160 2161 FT_TRACE4(( " callgsubr (idx %d, entering level %d)\n", 2162 idx, 2163 zone - decoder->zones + 1 )); 2164 2165 if ( idx >= decoder->num_globals ) 2166 { 2167 FT_ERROR(( "cff_decoder_parse_charstrings:" 2168 " invalid global subr index\n" )); 2169 goto Syntax_Error; 2170 } 2171 2172 if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS ) 2173 { 2174 FT_ERROR(( "cff_decoder_parse_charstrings:" 2175 " too many nested subrs\n" )); 2176 goto Syntax_Error; 2177 } 2178 2179 zone->cursor = ip; /* save current instruction pointer */ 2180 2181 zone++; 2182 zone->base = decoder->globals[idx]; 2183 zone->limit = decoder->globals[idx + 1]; 2184 zone->cursor = zone->base; 2185 2186 if ( !zone->base || zone->limit == zone->base ) 2187 { 2188 FT_ERROR(( "cff_decoder_parse_charstrings:" 2189 " invoking empty subrs\n" )); 2190 goto Syntax_Error; 2191 } 2192 2193 decoder->zone = zone; 2194 ip = zone->base; 2195 limit = zone->limit; 2196 } 2197 break; 2198 2199 case cff_op_return: 2200 FT_TRACE4(( " return (leaving level %d)\n", 2201 decoder->zone - decoder->zones )); 2202 2203 if ( decoder->zone <= decoder->zones ) 2204 { 2205 FT_ERROR(( "cff_decoder_parse_charstrings:" 2206 " unexpected return\n" )); 2207 goto Syntax_Error; 2208 } 2209 2210 decoder->zone--; 2211 zone = decoder->zone; 2212 ip = zone->cursor; 2213 limit = zone->limit; 2214 break; 2215 2216 default: 2217 FT_ERROR(( "Unimplemented opcode: %d", ip[-1] )); 2218 2219 if ( ip[-1] == 12 ) 2220 FT_ERROR(( " %d", ip[0] )); 2221 FT_ERROR(( "\n" )); 2222 2223 return FT_THROW( Unimplemented_Feature ); 2224 } 2225 2226 decoder->top = args; 2227 2228 if ( decoder->top - stack >= CFF_MAX_OPERANDS ) 2229 goto Stack_Overflow; 2230 2231 } /* general operator processing */ 2232 2233 } /* while ip < limit */ 2234 2235 FT_TRACE4(( "..end..\n\n" )); 2236 2237 Fail: 2238 return error; 2239 2240 MM_Error: 2241 FT_TRACE4(( "cff_decoder_parse_charstrings:" 2242 " invalid opcode found in top DICT charstring\n")); 2243 return FT_THROW( Invalid_File_Format ); 2244 2245 Syntax_Error: 2246 FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" )); 2247 return FT_THROW( Invalid_File_Format ); 2248 2249 Stack_Underflow: 2250 FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" )); 2251 return FT_THROW( Too_Few_Arguments ); 2252 2253 Stack_Overflow: 2254 FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" )); 2255 return FT_THROW( Stack_Overflow ); 2256 } 2257 2258 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ 2259 2260 2261 /************************************************************************** 2262 * 2263 * @Function: 2264 * cff_decoder_init 2265 * 2266 * @Description: 2267 * Initializes a given glyph decoder. 2268 * 2269 * @InOut: 2270 * decoder :: 2271 * A pointer to the glyph builder to initialize. 2272 * 2273 * @Input: 2274 * face :: 2275 * The current face object. 2276 * 2277 * size :: 2278 * The current size object. 2279 * 2280 * slot :: 2281 * The current glyph object. 2282 * 2283 * hinting :: 2284 * Whether hinting is active. 2285 * 2286 * hint_mode :: 2287 * The hinting mode. 2288 */ 2289 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)2290 cff_decoder_init( CFF_Decoder* decoder, 2291 TT_Face face, 2292 CFF_Size size, 2293 CFF_GlyphSlot slot, 2294 FT_Bool hinting, 2295 FT_Render_Mode hint_mode, 2296 CFF_Decoder_Get_Glyph_Callback get_callback, 2297 CFF_Decoder_Free_Glyph_Callback free_callback ) 2298 { 2299 CFF_Font cff = (CFF_Font)face->extra.data; 2300 2301 2302 /* clear everything */ 2303 FT_ZERO( decoder ); 2304 2305 /* initialize builder */ 2306 cff_builder_init( &decoder->builder, face, size, slot, hinting ); 2307 2308 /* initialize Type2 decoder */ 2309 decoder->cff = cff; 2310 decoder->num_globals = cff->global_subrs_index.count; 2311 decoder->globals = cff->global_subrs; 2312 decoder->globals_bias = cff_compute_bias( 2313 cff->top_font.font_dict.charstring_type, 2314 decoder->num_globals ); 2315 2316 decoder->hint_mode = hint_mode; 2317 2318 decoder->get_glyph_callback = get_callback; 2319 decoder->free_glyph_callback = free_callback; 2320 } 2321 2322 2323 /* this function is used to select the subfont */ 2324 /* and the locals subrs array */ 2325 FT_LOCAL_DEF( FT_Error ) cff_decoder_prepare(CFF_Decoder * decoder,CFF_Size size,FT_UInt glyph_index)2326 cff_decoder_prepare( CFF_Decoder* decoder, 2327 CFF_Size size, 2328 FT_UInt glyph_index ) 2329 { 2330 CFF_Builder *builder = &decoder->builder; 2331 CFF_Font cff = (CFF_Font)builder->face->extra.data; 2332 CFF_SubFont sub = &cff->top_font; 2333 FT_Error error = FT_Err_Ok; 2334 2335 FT_Service_CFFLoad cffload = (FT_Service_CFFLoad)cff->cffload; 2336 2337 2338 /* manage CID fonts */ 2339 if ( cff->num_subfonts ) 2340 { 2341 FT_Byte fd_index = cffload->fd_select_get( &cff->fd_select, 2342 glyph_index ); 2343 2344 2345 if ( fd_index >= cff->num_subfonts ) 2346 { 2347 FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" )); 2348 error = FT_THROW( Invalid_File_Format ); 2349 goto Exit; 2350 } 2351 2352 FT_TRACE3(( " in subfont %d:\n", fd_index )); 2353 2354 sub = cff->subfonts[fd_index]; 2355 2356 if ( builder->hints_funcs && size ) 2357 { 2358 FT_Size ftsize = FT_SIZE( size ); 2359 CFF_Internal internal = (CFF_Internal)ftsize->internal->module_data; 2360 2361 2362 /* for CFFs without subfonts, this value has already been set */ 2363 builder->hints_globals = (void *)internal->subfonts[fd_index]; 2364 } 2365 } 2366 2367 decoder->num_locals = sub->local_subrs_index.count; 2368 decoder->locals = sub->local_subrs; 2369 decoder->locals_bias = cff_compute_bias( 2370 decoder->cff->top_font.font_dict.charstring_type, 2371 decoder->num_locals ); 2372 2373 decoder->glyph_width = sub->private_dict.default_width; 2374 decoder->nominal_width = sub->private_dict.nominal_width; 2375 2376 decoder->current_subfont = sub; 2377 2378 Exit: 2379 return error; 2380 } 2381 2382 2383 /* END */ 2384