1 /**************************************************************************** 2 * 3 * t1decode.c 4 * 5 * PostScript Type 1 decoding routines (body). 6 * 7 * Copyright 2000-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_INTERNAL_CALC_H 21 #include FT_INTERNAL_DEBUG_H 22 #include FT_INTERNAL_POSTSCRIPT_HINTS_H 23 #include FT_INTERNAL_HASH_H 24 #include FT_OUTLINE_H 25 26 #include "t1decode.h" 27 #include "psobjs.h" 28 29 #include "psauxerr.h" 30 31 /* ensure proper sign extension */ 32 #define Fix2Int( f ) ( (FT_Int)(FT_Short)( (f) >> 16 ) ) 33 34 /************************************************************************** 35 * 36 * The macro FT_COMPONENT is used in trace mode. It is an implicit 37 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log 38 * messages during execution. 39 */ 40 #undef FT_COMPONENT 41 #define FT_COMPONENT trace_t1decode 42 43 44 typedef enum T1_Operator_ 45 { 46 op_none = 0, 47 op_endchar, 48 op_hsbw, 49 op_seac, 50 op_sbw, 51 op_closepath, 52 op_hlineto, 53 op_hmoveto, 54 op_hvcurveto, 55 op_rlineto, 56 op_rmoveto, 57 op_rrcurveto, 58 op_vhcurveto, 59 op_vlineto, 60 op_vmoveto, 61 op_dotsection, 62 op_hstem, 63 op_hstem3, 64 op_vstem, 65 op_vstem3, 66 op_div, 67 op_callothersubr, 68 op_callsubr, 69 op_pop, 70 op_return, 71 op_setcurrentpoint, 72 op_unknown15, 73 74 op_max /* never remove this one */ 75 76 } T1_Operator; 77 78 79 static 80 const FT_Int t1_args_count[op_max] = 81 { 82 0, /* none */ 83 0, /* endchar */ 84 2, /* hsbw */ 85 5, /* seac */ 86 4, /* sbw */ 87 0, /* closepath */ 88 1, /* hlineto */ 89 1, /* hmoveto */ 90 4, /* hvcurveto */ 91 2, /* rlineto */ 92 2, /* rmoveto */ 93 6, /* rrcurveto */ 94 4, /* vhcurveto */ 95 1, /* vlineto */ 96 1, /* vmoveto */ 97 0, /* dotsection */ 98 2, /* hstem */ 99 6, /* hstem3 */ 100 2, /* vstem */ 101 6, /* vstem3 */ 102 2, /* div */ 103 -1, /* callothersubr */ 104 1, /* callsubr */ 105 0, /* pop */ 106 0, /* return */ 107 2, /* setcurrentpoint */ 108 2 /* opcode 15 (undocumented and obsolete) */ 109 }; 110 111 112 /************************************************************************** 113 * 114 * @Function: 115 * t1_lookup_glyph_by_stdcharcode_ps 116 * 117 * @Description: 118 * Looks up a given glyph by its StandardEncoding charcode. Used to 119 * implement the SEAC Type 1 operator in the Adobe engine 120 * 121 * @Input: 122 * face :: 123 * The current face object. 124 * 125 * charcode :: 126 * The character code to look for. 127 * 128 * @Return: 129 * A glyph index in the font face. Returns -1 if the corresponding 130 * glyph wasn't found. 131 */ 132 FT_LOCAL_DEF( FT_Int ) t1_lookup_glyph_by_stdcharcode_ps(PS_Decoder * decoder,FT_Int charcode)133 t1_lookup_glyph_by_stdcharcode_ps( PS_Decoder* decoder, 134 FT_Int charcode ) 135 { 136 FT_UInt n; 137 const FT_String* glyph_name; 138 FT_Service_PsCMaps psnames = decoder->psnames; 139 140 141 /* check range of standard char code */ 142 if ( charcode < 0 || charcode > 255 ) 143 return -1; 144 145 glyph_name = psnames->adobe_std_strings( 146 psnames->adobe_std_encoding[charcode]); 147 148 for ( n = 0; n < decoder->num_glyphs; n++ ) 149 { 150 FT_String* name = (FT_String*)decoder->glyph_names[n]; 151 152 153 if ( name && 154 name[0] == glyph_name[0] && 155 ft_strcmp( name, glyph_name ) == 0 ) 156 return (FT_Int)n; 157 } 158 159 return -1; 160 } 161 162 163 #ifdef T1_CONFIG_OPTION_OLD_ENGINE 164 165 /************************************************************************** 166 * 167 * @Function: 168 * t1_lookup_glyph_by_stdcharcode 169 * 170 * @Description: 171 * Looks up a given glyph by its StandardEncoding charcode. Used to 172 * implement the SEAC Type 1 operator. 173 * 174 * @Input: 175 * face :: 176 * The current face object. 177 * 178 * charcode :: 179 * The character code to look for. 180 * 181 * @Return: 182 * A glyph index in the font face. Returns -1 if the corresponding 183 * glyph wasn't found. 184 */ 185 static FT_Int t1_lookup_glyph_by_stdcharcode(T1_Decoder decoder,FT_Int charcode)186 t1_lookup_glyph_by_stdcharcode( T1_Decoder decoder, 187 FT_Int charcode ) 188 { 189 FT_UInt n; 190 const FT_String* glyph_name; 191 FT_Service_PsCMaps psnames = decoder->psnames; 192 193 194 /* check range of standard char code */ 195 if ( charcode < 0 || charcode > 255 ) 196 return -1; 197 198 glyph_name = psnames->adobe_std_strings( 199 psnames->adobe_std_encoding[charcode]); 200 201 for ( n = 0; n < decoder->num_glyphs; n++ ) 202 { 203 FT_String* name = (FT_String*)decoder->glyph_names[n]; 204 205 206 if ( name && 207 name[0] == glyph_name[0] && 208 ft_strcmp( name, glyph_name ) == 0 ) 209 return (FT_Int)n; 210 } 211 212 return -1; 213 } 214 215 216 /* parse a single Type 1 glyph */ 217 FT_LOCAL_DEF( FT_Error ) t1_decoder_parse_glyph(T1_Decoder decoder,FT_UInt glyph)218 t1_decoder_parse_glyph( T1_Decoder decoder, 219 FT_UInt glyph ) 220 { 221 return decoder->parse_callback( decoder, glyph ); 222 } 223 224 225 /************************************************************************** 226 * 227 * @Function: 228 * t1operator_seac 229 * 230 * @Description: 231 * Implements the `seac' Type 1 operator for a Type 1 decoder. 232 * 233 * @Input: 234 * decoder :: 235 * The current CID decoder. 236 * 237 * asb :: 238 * The accent's side bearing. 239 * 240 * adx :: 241 * The horizontal offset of the accent. 242 * 243 * ady :: 244 * The vertical offset of the accent. 245 * 246 * bchar :: 247 * The base character's StandardEncoding charcode. 248 * 249 * achar :: 250 * The accent character's StandardEncoding charcode. 251 * 252 * @Return: 253 * FreeType error code. 0 means success. 254 */ 255 static FT_Error t1operator_seac(T1_Decoder decoder,FT_Pos asb,FT_Pos adx,FT_Pos ady,FT_Int bchar,FT_Int achar)256 t1operator_seac( T1_Decoder decoder, 257 FT_Pos asb, 258 FT_Pos adx, 259 FT_Pos ady, 260 FT_Int bchar, 261 FT_Int achar ) 262 { 263 FT_Error error; 264 FT_Int bchar_index, achar_index; 265 #if 0 266 FT_Int n_base_points; 267 FT_Outline* base = decoder->builder.base; 268 #endif 269 FT_Vector left_bearing, advance; 270 271 #ifdef FT_CONFIG_OPTION_INCREMENTAL 272 T1_Face face = (T1_Face)decoder->builder.face; 273 #endif 274 275 276 if ( decoder->seac ) 277 { 278 FT_ERROR(( "t1operator_seac: invalid nested seac\n" )); 279 return FT_THROW( Syntax_Error ); 280 } 281 282 if ( decoder->builder.metrics_only ) 283 { 284 FT_ERROR(( "t1operator_seac: unexpected seac\n" )); 285 return FT_THROW( Syntax_Error ); 286 } 287 288 /* seac weirdness */ 289 adx += decoder->builder.left_bearing.x; 290 291 /* `glyph_names' is set to 0 for CID fonts which do not */ 292 /* include an encoding. How can we deal with these? */ 293 #ifdef FT_CONFIG_OPTION_INCREMENTAL 294 if ( decoder->glyph_names == 0 && 295 !face->root.internal->incremental_interface ) 296 #else 297 if ( decoder->glyph_names == 0 ) 298 #endif /* FT_CONFIG_OPTION_INCREMENTAL */ 299 { 300 FT_ERROR(( "t1operator_seac:" 301 " glyph names table not available in this font\n" )); 302 return FT_THROW( Syntax_Error ); 303 } 304 305 #ifdef FT_CONFIG_OPTION_INCREMENTAL 306 if ( face->root.internal->incremental_interface ) 307 { 308 /* the caller must handle the font encoding also */ 309 bchar_index = bchar; 310 achar_index = achar; 311 } 312 else 313 #endif 314 { 315 bchar_index = t1_lookup_glyph_by_stdcharcode( decoder, bchar ); 316 achar_index = t1_lookup_glyph_by_stdcharcode( decoder, achar ); 317 } 318 319 if ( bchar_index < 0 || achar_index < 0 ) 320 { 321 FT_ERROR(( "t1operator_seac:" 322 " invalid seac character code arguments\n" )); 323 return FT_THROW( Syntax_Error ); 324 } 325 326 /* if we are trying to load a composite glyph, do not load the */ 327 /* accent character and return the array of subglyphs. */ 328 if ( decoder->builder.no_recurse ) 329 { 330 FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph; 331 FT_GlyphLoader loader = glyph->internal->loader; 332 FT_SubGlyph subg; 333 334 335 /* reallocate subglyph array if necessary */ 336 error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 ); 337 if ( error ) 338 goto Exit; 339 340 subg = loader->current.subglyphs; 341 342 /* subglyph 0 = base character */ 343 subg->index = bchar_index; 344 subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES | 345 FT_SUBGLYPH_FLAG_USE_MY_METRICS; 346 subg->arg1 = 0; 347 subg->arg2 = 0; 348 subg++; 349 350 /* subglyph 1 = accent character */ 351 subg->index = achar_index; 352 subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; 353 subg->arg1 = (FT_Int)FIXED_TO_INT( adx - asb ); 354 subg->arg2 = (FT_Int)FIXED_TO_INT( ady ); 355 356 /* set up remaining glyph fields */ 357 glyph->num_subglyphs = 2; 358 glyph->subglyphs = loader->base.subglyphs; 359 glyph->format = FT_GLYPH_FORMAT_COMPOSITE; 360 361 loader->current.num_subglyphs = 2; 362 goto Exit; 363 } 364 365 /* First load `bchar' in builder */ 366 /* now load the unscaled outline */ 367 368 FT_GlyphLoader_Prepare( decoder->builder.loader ); /* prepare loader */ 369 370 /* the seac operator must not be nested */ 371 decoder->seac = TRUE; 372 error = t1_decoder_parse_glyph( decoder, (FT_UInt)bchar_index ); 373 decoder->seac = FALSE; 374 if ( error ) 375 goto Exit; 376 377 /* save the left bearing and width of the base character */ 378 /* as they will be erased by the next load. */ 379 380 left_bearing = decoder->builder.left_bearing; 381 advance = decoder->builder.advance; 382 383 decoder->builder.left_bearing.x = 0; 384 decoder->builder.left_bearing.y = 0; 385 386 decoder->builder.pos_x = adx - asb; 387 decoder->builder.pos_y = ady; 388 389 /* Now load `achar' on top of */ 390 /* the base outline */ 391 392 /* the seac operator must not be nested */ 393 decoder->seac = TRUE; 394 error = t1_decoder_parse_glyph( decoder, (FT_UInt)achar_index ); 395 decoder->seac = FALSE; 396 if ( error ) 397 goto Exit; 398 399 /* restore the left side bearing and */ 400 /* advance width of the base character */ 401 402 decoder->builder.left_bearing = left_bearing; 403 decoder->builder.advance = advance; 404 405 decoder->builder.pos_x = 0; 406 decoder->builder.pos_y = 0; 407 408 Exit: 409 return error; 410 } 411 412 413 /************************************************************************** 414 * 415 * @Function: 416 * t1_decoder_parse_charstrings 417 * 418 * @Description: 419 * Parses a given Type 1 charstrings program. 420 * 421 * @Input: 422 * decoder :: 423 * The current Type 1 decoder. 424 * 425 * charstring_base :: 426 * The base address of the charstring stream. 427 * 428 * charstring_len :: 429 * The length in bytes of the charstring stream. 430 * 431 * @Return: 432 * FreeType error code. 0 means success. 433 */ 434 FT_LOCAL_DEF( FT_Error ) t1_decoder_parse_charstrings(T1_Decoder decoder,FT_Byte * charstring_base,FT_UInt charstring_len)435 t1_decoder_parse_charstrings( T1_Decoder decoder, 436 FT_Byte* charstring_base, 437 FT_UInt charstring_len ) 438 { 439 FT_Error error; 440 T1_Decoder_Zone zone; 441 FT_Byte* ip; 442 FT_Byte* limit; 443 T1_Builder builder = &decoder->builder; 444 FT_Pos x, y, orig_x, orig_y; 445 FT_Int known_othersubr_result_cnt = 0; 446 FT_Int unknown_othersubr_result_cnt = 0; 447 FT_Bool large_int; 448 FT_Fixed seed; 449 450 T1_Hints_Funcs hinter; 451 452 #ifdef FT_DEBUG_LEVEL_TRACE 453 FT_Bool bol = TRUE; 454 #endif 455 456 457 /* compute random seed from stack address of parameter */ 458 seed = (FT_Fixed)( ( (FT_Offset)(char*)&seed ^ 459 (FT_Offset)(char*)&decoder ^ 460 (FT_Offset)(char*)&charstring_base ) & 461 FT_ULONG_MAX ); 462 seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL; 463 if ( seed == 0 ) 464 seed = 0x7384; 465 466 /* First of all, initialize the decoder */ 467 decoder->top = decoder->stack; 468 decoder->zone = decoder->zones; 469 zone = decoder->zones; 470 471 builder->parse_state = T1_Parse_Start; 472 473 hinter = (T1_Hints_Funcs)builder->hints_funcs; 474 475 /* a font that reads BuildCharArray without setting */ 476 /* its values first is buggy, but ... */ 477 FT_ASSERT( ( decoder->len_buildchar == 0 ) == 478 ( decoder->buildchar == NULL ) ); 479 480 if ( decoder->buildchar && decoder->len_buildchar > 0 ) 481 FT_ARRAY_ZERO( decoder->buildchar, decoder->len_buildchar ); 482 483 zone->base = charstring_base; 484 limit = zone->limit = charstring_base + charstring_len; 485 ip = zone->cursor = zone->base; 486 487 error = FT_Err_Ok; 488 489 x = orig_x = builder->pos_x; 490 y = orig_y = builder->pos_y; 491 492 /* begin hints recording session, if any */ 493 if ( hinter ) 494 hinter->open( hinter->hints ); 495 496 large_int = FALSE; 497 498 /* now, execute loop */ 499 while ( ip < limit ) 500 { 501 FT_Long* top = decoder->top; 502 T1_Operator op = op_none; 503 FT_Int32 value = 0; 504 505 506 FT_ASSERT( known_othersubr_result_cnt == 0 || 507 unknown_othersubr_result_cnt == 0 ); 508 509 #ifdef FT_DEBUG_LEVEL_TRACE 510 if ( bol ) 511 { 512 FT_TRACE5(( " (%d)", decoder->top - decoder->stack )); 513 bol = FALSE; 514 } 515 #endif 516 517 /********************************************************************** 518 * 519 * Decode operator or operand 520 * 521 */ 522 523 /* first of all, decompress operator or value */ 524 switch ( *ip++ ) 525 { 526 case 1: 527 op = op_hstem; 528 break; 529 530 case 3: 531 op = op_vstem; 532 break; 533 case 4: 534 op = op_vmoveto; 535 break; 536 case 5: 537 op = op_rlineto; 538 break; 539 case 6: 540 op = op_hlineto; 541 break; 542 case 7: 543 op = op_vlineto; 544 break; 545 case 8: 546 op = op_rrcurveto; 547 break; 548 case 9: 549 op = op_closepath; 550 break; 551 case 10: 552 op = op_callsubr; 553 break; 554 case 11: 555 op = op_return; 556 break; 557 558 case 13: 559 op = op_hsbw; 560 break; 561 case 14: 562 op = op_endchar; 563 break; 564 565 case 15: /* undocumented, obsolete operator */ 566 op = op_unknown15; 567 break; 568 569 case 21: 570 op = op_rmoveto; 571 break; 572 case 22: 573 op = op_hmoveto; 574 break; 575 576 case 30: 577 op = op_vhcurveto; 578 break; 579 case 31: 580 op = op_hvcurveto; 581 break; 582 583 case 12: 584 if ( ip >= limit ) 585 { 586 FT_ERROR(( "t1_decoder_parse_charstrings:" 587 " invalid escape (12+EOF)\n" )); 588 goto Syntax_Error; 589 } 590 591 switch ( *ip++ ) 592 { 593 case 0: 594 op = op_dotsection; 595 break; 596 case 1: 597 op = op_vstem3; 598 break; 599 case 2: 600 op = op_hstem3; 601 break; 602 case 6: 603 op = op_seac; 604 break; 605 case 7: 606 op = op_sbw; 607 break; 608 case 12: 609 op = op_div; 610 break; 611 case 16: 612 op = op_callothersubr; 613 break; 614 case 17: 615 op = op_pop; 616 break; 617 case 33: 618 op = op_setcurrentpoint; 619 break; 620 621 default: 622 FT_ERROR(( "t1_decoder_parse_charstrings:" 623 " invalid escape (12+%d)\n", 624 ip[-1] )); 625 goto Syntax_Error; 626 } 627 break; 628 629 case 255: /* four bytes integer */ 630 if ( ip + 4 > limit ) 631 { 632 FT_ERROR(( "t1_decoder_parse_charstrings:" 633 " unexpected EOF in integer\n" )); 634 goto Syntax_Error; 635 } 636 637 value = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) | 638 ( (FT_UInt32)ip[1] << 16 ) | 639 ( (FT_UInt32)ip[2] << 8 ) | 640 (FT_UInt32)ip[3] ); 641 ip += 4; 642 643 /* According to the specification, values > 32000 or < -32000 must */ 644 /* be followed by a `div' operator to make the result be in the */ 645 /* range [-32000;32000]. We expect that the second argument of */ 646 /* `div' is not a large number. Additionally, we don't handle */ 647 /* stuff like `<large1> <large2> <num> div <num> div' or */ 648 /* <large1> <large2> <num> div div'. This is probably not allowed */ 649 /* anyway. */ 650 if ( value > 32000 || value < -32000 ) 651 { 652 if ( large_int ) 653 { 654 FT_ERROR(( "t1_decoder_parse_charstrings:" 655 " no `div' after large integer\n" )); 656 } 657 else 658 large_int = TRUE; 659 } 660 else 661 { 662 if ( !large_int ) 663 value = (FT_Int32)( (FT_UInt32)value << 16 ); 664 } 665 666 break; 667 668 default: 669 if ( ip[-1] >= 32 ) 670 { 671 if ( ip[-1] < 247 ) 672 value = (FT_Int32)ip[-1] - 139; 673 else 674 { 675 if ( ++ip > limit ) 676 { 677 FT_ERROR(( "t1_decoder_parse_charstrings:" 678 " unexpected EOF in integer\n" )); 679 goto Syntax_Error; 680 } 681 682 if ( ip[-2] < 251 ) 683 value = ( ( ip[-2] - 247 ) * 256 ) + ip[-1] + 108; 684 else 685 value = -( ( ( ip[-2] - 251 ) * 256 ) + ip[-1] + 108 ); 686 } 687 688 if ( !large_int ) 689 value = (FT_Int32)( (FT_UInt32)value << 16 ); 690 } 691 else 692 { 693 FT_ERROR(( "t1_decoder_parse_charstrings:" 694 " invalid byte (%d)\n", ip[-1] )); 695 goto Syntax_Error; 696 } 697 } 698 699 if ( unknown_othersubr_result_cnt > 0 ) 700 { 701 switch ( op ) 702 { 703 case op_callsubr: 704 case op_return: 705 case op_none: 706 case op_pop: 707 break; 708 709 default: 710 /* all operands have been transferred by previous pops */ 711 unknown_othersubr_result_cnt = 0; 712 break; 713 } 714 } 715 716 if ( large_int && !( op == op_none || op == op_div ) ) 717 { 718 FT_ERROR(( "t1_decoder_parse_charstrings:" 719 " no `div' after large integer\n" )); 720 721 large_int = FALSE; 722 } 723 724 /********************************************************************** 725 * 726 * Push value on stack, or process operator 727 * 728 */ 729 if ( op == op_none ) 730 { 731 if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS ) 732 { 733 FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow\n" )); 734 goto Syntax_Error; 735 } 736 737 #ifdef FT_DEBUG_LEVEL_TRACE 738 if ( large_int ) 739 FT_TRACE4(( " %d", value )); 740 else 741 FT_TRACE4(( " %d", value / 65536 )); 742 #endif 743 744 *top++ = value; 745 decoder->top = top; 746 } 747 else if ( op == op_callothersubr ) /* callothersubr */ 748 { 749 FT_Int subr_no; 750 FT_Int arg_cnt; 751 752 753 #ifdef FT_DEBUG_LEVEL_TRACE 754 FT_TRACE4(( " callothersubr\n" )); 755 bol = TRUE; 756 #endif 757 758 if ( top - decoder->stack < 2 ) 759 goto Stack_Underflow; 760 761 top -= 2; 762 763 subr_no = Fix2Int( top[1] ); 764 arg_cnt = Fix2Int( top[0] ); 765 766 /************************************************************ 767 * 768 * remove all operands to callothersubr from the stack 769 * 770 * for handled othersubrs, where we know the number of 771 * arguments, we increase the stack by the value of 772 * known_othersubr_result_cnt 773 * 774 * for unhandled othersubrs the following pops adjust the 775 * stack pointer as necessary 776 */ 777 778 if ( arg_cnt > top - decoder->stack ) 779 goto Stack_Underflow; 780 781 top -= arg_cnt; 782 783 known_othersubr_result_cnt = 0; 784 unknown_othersubr_result_cnt = 0; 785 786 /* XXX TODO: The checks to `arg_count == <whatever>' */ 787 /* might not be correct; an othersubr expects a certain */ 788 /* number of operands on the PostScript stack (as opposed */ 789 /* to the T1 stack) but it doesn't have to put them there */ 790 /* by itself; previous othersubrs might have left the */ 791 /* operands there if they were not followed by an */ 792 /* appropriate number of pops */ 793 /* */ 794 /* On the other hand, Adobe Reader 7.0.8 for Linux doesn't */ 795 /* accept a font that contains charstrings like */ 796 /* */ 797 /* 100 200 2 20 callothersubr */ 798 /* 300 1 20 callothersubr pop */ 799 /* */ 800 /* Perhaps this is the reason why BuildCharArray exists. */ 801 802 switch ( subr_no ) 803 { 804 case 0: /* end flex feature */ 805 if ( arg_cnt != 3 ) 806 goto Unexpected_OtherSubr; 807 808 if ( !decoder->flex_state || 809 decoder->num_flex_vectors != 7 ) 810 { 811 FT_ERROR(( "t1_decoder_parse_charstrings:" 812 " unexpected flex end\n" )); 813 goto Syntax_Error; 814 } 815 816 /* the two `results' are popped by the following setcurrentpoint */ 817 top[0] = x; 818 top[1] = y; 819 known_othersubr_result_cnt = 2; 820 break; 821 822 case 1: /* start flex feature */ 823 if ( arg_cnt != 0 ) 824 goto Unexpected_OtherSubr; 825 826 if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) || 827 FT_SET_ERROR( t1_builder_check_points( builder, 6 ) ) ) 828 goto Fail; 829 830 decoder->flex_state = 1; 831 decoder->num_flex_vectors = 0; 832 break; 833 834 case 2: /* add flex vectors */ 835 { 836 FT_Int idx; 837 838 839 if ( arg_cnt != 0 ) 840 goto Unexpected_OtherSubr; 841 842 if ( !decoder->flex_state ) 843 { 844 FT_ERROR(( "t1_decoder_parse_charstrings:" 845 " missing flex start\n" )); 846 goto Syntax_Error; 847 } 848 849 /* note that we should not add a point for index 0; */ 850 /* this will move our current position to the flex */ 851 /* point without adding any point to the outline */ 852 idx = decoder->num_flex_vectors++; 853 if ( idx > 0 && idx < 7 ) 854 { 855 /* in malformed fonts it is possible to have other */ 856 /* opcodes in the middle of a flex (which don't */ 857 /* increase `num_flex_vectors'); we thus have to */ 858 /* check whether we can add a point */ 859 if ( FT_SET_ERROR( t1_builder_check_points( builder, 1 ) ) ) 860 goto Syntax_Error; 861 862 t1_builder_add_point( builder, 863 x, 864 y, 865 (FT_Byte)( idx == 3 || idx == 6 ) ); 866 } 867 } 868 break; 869 870 case 3: /* change hints */ 871 if ( arg_cnt != 1 ) 872 goto Unexpected_OtherSubr; 873 874 known_othersubr_result_cnt = 1; 875 876 if ( hinter ) 877 hinter->reset( hinter->hints, 878 (FT_UInt)builder->current->n_points ); 879 break; 880 881 case 12: 882 case 13: 883 /* counter control hints, clear stack */ 884 top = decoder->stack; 885 break; 886 887 case 14: 888 case 15: 889 case 16: 890 case 17: 891 case 18: /* multiple masters */ 892 { 893 PS_Blend blend = decoder->blend; 894 FT_UInt num_points, nn, mm; 895 FT_Long* delta; 896 FT_Long* values; 897 898 899 if ( !blend ) 900 { 901 FT_ERROR(( "t1_decoder_parse_charstrings:" 902 " unexpected multiple masters operator\n" )); 903 goto Syntax_Error; 904 } 905 906 num_points = (FT_UInt)subr_no - 13 + ( subr_no == 18 ); 907 if ( arg_cnt != (FT_Int)( num_points * blend->num_designs ) ) 908 { 909 FT_ERROR(( "t1_decoder_parse_charstrings:" 910 " incorrect number of multiple masters arguments\n" )); 911 goto Syntax_Error; 912 } 913 914 /* We want to compute */ 915 /* */ 916 /* a0*w0 + a1*w1 + ... + ak*wk */ 917 /* */ 918 /* but we only have a0, a1-a0, a2-a0, ..., ak-a0. */ 919 /* */ 920 /* However, given that w0 + w1 + ... + wk == 1, we can */ 921 /* rewrite it easily as */ 922 /* */ 923 /* a0 + (a1-a0)*w1 + (a2-a0)*w2 + ... + (ak-a0)*wk */ 924 /* */ 925 /* where k == num_designs-1. */ 926 /* */ 927 /* I guess that's why it's written in this `compact' */ 928 /* form. */ 929 /* */ 930 delta = top + num_points; 931 values = top; 932 for ( nn = 0; nn < num_points; nn++ ) 933 { 934 FT_Long tmp = values[0]; 935 936 937 for ( mm = 1; mm < blend->num_designs; mm++ ) 938 tmp = ADD_LONG( tmp, 939 FT_MulFix( *delta++, 940 blend->weight_vector[mm] ) ); 941 942 *values++ = tmp; 943 } 944 945 known_othersubr_result_cnt = (FT_Int)num_points; 946 break; 947 } 948 949 case 19: 950 /* <idx> 1 19 callothersubr */ 951 /* => replace elements starting from index cvi( <idx> ) */ 952 /* of BuildCharArray with WeightVector */ 953 { 954 FT_Int idx; 955 PS_Blend blend = decoder->blend; 956 957 958 if ( arg_cnt != 1 || !blend ) 959 goto Unexpected_OtherSubr; 960 961 idx = Fix2Int( top[0] ); 962 963 if ( idx < 0 || 964 (FT_UInt)idx + blend->num_designs > decoder->len_buildchar ) 965 goto Unexpected_OtherSubr; 966 967 ft_memcpy( &decoder->buildchar[idx], 968 blend->weight_vector, 969 blend->num_designs * 970 sizeof ( blend->weight_vector[0] ) ); 971 } 972 break; 973 974 case 20: 975 /* <arg1> <arg2> 2 20 callothersubr pop */ 976 /* ==> push <arg1> + <arg2> onto T1 stack */ 977 if ( arg_cnt != 2 ) 978 goto Unexpected_OtherSubr; 979 980 top[0] = ADD_LONG( top[0], top[1] ); 981 982 known_othersubr_result_cnt = 1; 983 break; 984 985 case 21: 986 /* <arg1> <arg2> 2 21 callothersubr pop */ 987 /* ==> push <arg1> - <arg2> onto T1 stack */ 988 if ( arg_cnt != 2 ) 989 goto Unexpected_OtherSubr; 990 991 top[0] = SUB_LONG( top[0], top[1] ); 992 993 known_othersubr_result_cnt = 1; 994 break; 995 996 case 22: 997 /* <arg1> <arg2> 2 22 callothersubr pop */ 998 /* ==> push <arg1> * <arg2> onto T1 stack */ 999 if ( arg_cnt != 2 ) 1000 goto Unexpected_OtherSubr; 1001 1002 top[0] = FT_MulFix( top[0], top[1] ); 1003 1004 known_othersubr_result_cnt = 1; 1005 break; 1006 1007 case 23: 1008 /* <arg1> <arg2> 2 23 callothersubr pop */ 1009 /* ==> push <arg1> / <arg2> onto T1 stack */ 1010 if ( arg_cnt != 2 || top[1] == 0 ) 1011 goto Unexpected_OtherSubr; 1012 1013 top[0] = FT_DivFix( top[0], top[1] ); 1014 1015 known_othersubr_result_cnt = 1; 1016 break; 1017 1018 case 24: 1019 /* <val> <idx> 2 24 callothersubr */ 1020 /* ==> set BuildCharArray[cvi( <idx> )] = <val> */ 1021 { 1022 FT_Int idx; 1023 PS_Blend blend = decoder->blend; 1024 1025 1026 if ( arg_cnt != 2 || !blend ) 1027 goto Unexpected_OtherSubr; 1028 1029 idx = Fix2Int( top[1] ); 1030 1031 if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar ) 1032 goto Unexpected_OtherSubr; 1033 1034 decoder->buildchar[idx] = top[0]; 1035 } 1036 break; 1037 1038 case 25: 1039 /* <idx> 1 25 callothersubr pop */ 1040 /* ==> push BuildCharArray[cvi( idx )] */ 1041 /* onto T1 stack */ 1042 { 1043 FT_Int idx; 1044 PS_Blend blend = decoder->blend; 1045 1046 1047 if ( arg_cnt != 1 || !blend ) 1048 goto Unexpected_OtherSubr; 1049 1050 idx = Fix2Int( top[0] ); 1051 1052 if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar ) 1053 goto Unexpected_OtherSubr; 1054 1055 top[0] = decoder->buildchar[idx]; 1056 } 1057 1058 known_othersubr_result_cnt = 1; 1059 break; 1060 1061 #if 0 1062 case 26: 1063 /* <val> mark <idx> ==> set BuildCharArray[cvi( <idx> )] = <val>, */ 1064 /* leave mark on T1 stack */ 1065 /* <val> <idx> ==> set BuildCharArray[cvi( <idx> )] = <val> */ 1066 XXX which routine has left its mark on the (PostScript) stack?; 1067 break; 1068 #endif 1069 1070 case 27: 1071 /* <res1> <res2> <val1> <val2> 4 27 callothersubr pop */ 1072 /* ==> push <res1> onto T1 stack if <val1> <= <val2>, */ 1073 /* otherwise push <res2> */ 1074 if ( arg_cnt != 4 ) 1075 goto Unexpected_OtherSubr; 1076 1077 if ( top[2] > top[3] ) 1078 top[0] = top[1]; 1079 1080 known_othersubr_result_cnt = 1; 1081 break; 1082 1083 case 28: 1084 /* 0 28 callothersubr pop */ 1085 /* => push random value from interval [0, 1) onto stack */ 1086 if ( arg_cnt != 0 ) 1087 goto Unexpected_OtherSubr; 1088 1089 { 1090 FT_Fixed Rand; 1091 1092 1093 Rand = seed; 1094 if ( Rand >= 0x8000L ) 1095 Rand++; 1096 1097 top[0] = Rand; 1098 1099 seed = FT_MulFix( seed, 0x10000L - seed ); 1100 if ( seed == 0 ) 1101 seed += 0x2873; 1102 } 1103 1104 known_othersubr_result_cnt = 1; 1105 break; 1106 1107 default: 1108 if ( arg_cnt >= 0 && subr_no >= 0 ) 1109 { 1110 FT_ERROR(( "t1_decoder_parse_charstrings:" 1111 " unknown othersubr [%d %d], wish me luck\n", 1112 arg_cnt, subr_no )); 1113 unknown_othersubr_result_cnt = arg_cnt; 1114 break; 1115 } 1116 /* fall through */ 1117 1118 Unexpected_OtherSubr: 1119 FT_ERROR(( "t1_decoder_parse_charstrings:" 1120 " invalid othersubr [%d %d]\n", arg_cnt, subr_no )); 1121 goto Syntax_Error; 1122 } 1123 1124 top += known_othersubr_result_cnt; 1125 1126 decoder->top = top; 1127 } 1128 else /* general operator */ 1129 { 1130 FT_Int num_args = t1_args_count[op]; 1131 1132 1133 FT_ASSERT( num_args >= 0 ); 1134 1135 if ( top - decoder->stack < num_args ) 1136 goto Stack_Underflow; 1137 1138 /* XXX Operators usually take their operands from the */ 1139 /* bottom of the stack, i.e., the operands are */ 1140 /* decoder->stack[0], ..., decoder->stack[num_args - 1]; */ 1141 /* only div, callsubr, and callothersubr are different. */ 1142 /* In practice it doesn't matter (?). */ 1143 1144 #ifdef FT_DEBUG_LEVEL_TRACE 1145 1146 switch ( op ) 1147 { 1148 case op_callsubr: 1149 case op_div: 1150 case op_callothersubr: 1151 case op_pop: 1152 case op_return: 1153 break; 1154 1155 default: 1156 if ( top - decoder->stack != num_args ) 1157 FT_TRACE0(( "t1_decoder_parse_charstrings:" 1158 " too much operands on the stack" 1159 " (seen %d, expected %d)\n", 1160 top - decoder->stack, num_args )); 1161 break; 1162 } 1163 1164 #endif /* FT_DEBUG_LEVEL_TRACE */ 1165 1166 top -= num_args; 1167 1168 switch ( op ) 1169 { 1170 case op_endchar: 1171 FT_TRACE4(( " endchar\n" )); 1172 1173 t1_builder_close_contour( builder ); 1174 1175 /* close hints recording session */ 1176 if ( hinter ) 1177 { 1178 if ( hinter->close( hinter->hints, 1179 (FT_UInt)builder->current->n_points ) ) 1180 goto Syntax_Error; 1181 1182 /* apply hints to the loaded glyph outline now */ 1183 error = hinter->apply( hinter->hints, 1184 builder->current, 1185 (PSH_Globals)builder->hints_globals, 1186 decoder->hint_mode ); 1187 if ( error ) 1188 goto Fail; 1189 } 1190 1191 /* add current outline to the glyph slot */ 1192 FT_GlyphLoader_Add( builder->loader ); 1193 1194 /* the compiler should optimize away this empty loop but ... */ 1195 1196 #ifdef FT_DEBUG_LEVEL_TRACE 1197 1198 if ( decoder->len_buildchar > 0 ) 1199 { 1200 FT_UInt i; 1201 1202 1203 FT_TRACE4(( "BuildCharArray = [ " )); 1204 1205 for ( i = 0; i < decoder->len_buildchar; i++ ) 1206 FT_TRACE4(( "%d ", decoder->buildchar[i] )); 1207 1208 FT_TRACE4(( "]\n" )); 1209 } 1210 1211 #endif /* FT_DEBUG_LEVEL_TRACE */ 1212 1213 FT_TRACE4(( "\n" )); 1214 1215 /* return now! */ 1216 return FT_Err_Ok; 1217 1218 case op_hsbw: 1219 FT_TRACE4(( " hsbw" )); 1220 1221 builder->parse_state = T1_Parse_Have_Width; 1222 1223 builder->left_bearing.x = ADD_LONG( builder->left_bearing.x, 1224 top[0] ); 1225 1226 builder->advance.x = top[1]; 1227 builder->advance.y = 0; 1228 1229 orig_x = x = ADD_LONG( builder->pos_x, top[0] ); 1230 orig_y = y = builder->pos_y; 1231 1232 FT_UNUSED( orig_y ); 1233 1234 /* the `metrics_only' indicates that we only want to compute */ 1235 /* the glyph's metrics (lsb + advance width), not load the */ 1236 /* rest of it; so exit immediately */ 1237 if ( builder->metrics_only ) 1238 { 1239 FT_TRACE4(( "\n" )); 1240 return FT_Err_Ok; 1241 } 1242 1243 break; 1244 1245 case op_seac: 1246 return t1operator_seac( decoder, 1247 top[0], 1248 top[1], 1249 top[2], 1250 Fix2Int( top[3] ), 1251 Fix2Int( top[4] ) ); 1252 1253 case op_sbw: 1254 FT_TRACE4(( " sbw" )); 1255 1256 builder->parse_state = T1_Parse_Have_Width; 1257 1258 builder->left_bearing.x = ADD_LONG( builder->left_bearing.x, 1259 top[0] ); 1260 builder->left_bearing.y = ADD_LONG( builder->left_bearing.y, 1261 top[1] ); 1262 1263 builder->advance.x = top[2]; 1264 builder->advance.y = top[3]; 1265 1266 x = ADD_LONG( builder->pos_x, top[0] ); 1267 y = ADD_LONG( builder->pos_y, top[1] ); 1268 1269 /* the `metrics_only' indicates that we only want to compute */ 1270 /* the glyph's metrics (lsb + advance width), not load the */ 1271 /* rest of it; so exit immediately */ 1272 if ( builder->metrics_only ) 1273 { 1274 FT_TRACE4(( "\n" )); 1275 return FT_Err_Ok; 1276 } 1277 1278 break; 1279 1280 case op_closepath: 1281 FT_TRACE4(( " closepath" )); 1282 1283 /* if there is no path, `closepath' is a no-op */ 1284 if ( builder->parse_state == T1_Parse_Have_Path || 1285 builder->parse_state == T1_Parse_Have_Moveto ) 1286 t1_builder_close_contour( builder ); 1287 1288 builder->parse_state = T1_Parse_Have_Width; 1289 break; 1290 1291 case op_hlineto: 1292 FT_TRACE4(( " hlineto" )); 1293 1294 if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ) 1295 goto Fail; 1296 1297 x = ADD_LONG( x, top[0] ); 1298 goto Add_Line; 1299 1300 case op_hmoveto: 1301 FT_TRACE4(( " hmoveto" )); 1302 1303 x = ADD_LONG( x, top[0] ); 1304 1305 if ( !decoder->flex_state ) 1306 { 1307 if ( builder->parse_state == T1_Parse_Start ) 1308 goto Syntax_Error; 1309 builder->parse_state = T1_Parse_Have_Moveto; 1310 } 1311 break; 1312 1313 case op_hvcurveto: 1314 FT_TRACE4(( " hvcurveto" )); 1315 1316 if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) || 1317 FT_SET_ERROR( t1_builder_check_points( builder, 3 ) ) ) 1318 goto Fail; 1319 1320 x = ADD_LONG( x, top[0] ); 1321 t1_builder_add_point( builder, x, y, 0 ); 1322 1323 x = ADD_LONG( x, top[1] ); 1324 y = ADD_LONG( y, top[2] ); 1325 t1_builder_add_point( builder, x, y, 0 ); 1326 1327 y = ADD_LONG( y, top[3] ); 1328 t1_builder_add_point( builder, x, y, 1 ); 1329 break; 1330 1331 case op_rlineto: 1332 FT_TRACE4(( " rlineto" )); 1333 1334 if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ) 1335 goto Fail; 1336 1337 x = ADD_LONG( x, top[0] ); 1338 y = ADD_LONG( y, top[1] ); 1339 1340 Add_Line: 1341 if ( FT_SET_ERROR( t1_builder_add_point1( builder, x, y ) ) ) 1342 goto Fail; 1343 break; 1344 1345 case op_rmoveto: 1346 FT_TRACE4(( " rmoveto" )); 1347 1348 x = ADD_LONG( x, top[0] ); 1349 y = ADD_LONG( y, top[1] ); 1350 1351 if ( !decoder->flex_state ) 1352 { 1353 if ( builder->parse_state == T1_Parse_Start ) 1354 goto Syntax_Error; 1355 builder->parse_state = T1_Parse_Have_Moveto; 1356 } 1357 break; 1358 1359 case op_rrcurveto: 1360 FT_TRACE4(( " rrcurveto" )); 1361 1362 if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) || 1363 FT_SET_ERROR( t1_builder_check_points( builder, 3 ) ) ) 1364 goto Fail; 1365 1366 x = ADD_LONG( x, top[0] ); 1367 y = ADD_LONG( y, top[1] ); 1368 t1_builder_add_point( builder, x, y, 0 ); 1369 1370 x = ADD_LONG( x, top[2] ); 1371 y = ADD_LONG( y, top[3] ); 1372 t1_builder_add_point( builder, x, y, 0 ); 1373 1374 x = ADD_LONG( x, top[4] ); 1375 y = ADD_LONG( y, top[5] ); 1376 t1_builder_add_point( builder, x, y, 1 ); 1377 break; 1378 1379 case op_vhcurveto: 1380 FT_TRACE4(( " vhcurveto" )); 1381 1382 if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) || 1383 FT_SET_ERROR( t1_builder_check_points( builder, 3 ) ) ) 1384 goto Fail; 1385 1386 y = ADD_LONG( y, top[0] ); 1387 t1_builder_add_point( builder, x, y, 0 ); 1388 1389 x = ADD_LONG( x, top[1] ); 1390 y = ADD_LONG( y, top[2] ); 1391 t1_builder_add_point( builder, x, y, 0 ); 1392 1393 x = ADD_LONG( x, top[3] ); 1394 t1_builder_add_point( builder, x, y, 1 ); 1395 break; 1396 1397 case op_vlineto: 1398 FT_TRACE4(( " vlineto" )); 1399 1400 if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ) 1401 goto Fail; 1402 1403 y = ADD_LONG( y, top[0] ); 1404 goto Add_Line; 1405 1406 case op_vmoveto: 1407 FT_TRACE4(( " vmoveto" )); 1408 1409 y = ADD_LONG( y, top[0] ); 1410 1411 if ( !decoder->flex_state ) 1412 { 1413 if ( builder->parse_state == T1_Parse_Start ) 1414 goto Syntax_Error; 1415 builder->parse_state = T1_Parse_Have_Moveto; 1416 } 1417 break; 1418 1419 case op_div: 1420 FT_TRACE4(( " div" )); 1421 1422 /* if `large_int' is set, we divide unscaled numbers; */ 1423 /* otherwise, we divide numbers in 16.16 format -- */ 1424 /* in both cases, it is the same operation */ 1425 *top = FT_DivFix( top[0], top[1] ); 1426 top++; 1427 1428 large_int = FALSE; 1429 break; 1430 1431 case op_callsubr: 1432 { 1433 FT_Int idx; 1434 1435 1436 FT_TRACE4(( " callsubr" )); 1437 1438 idx = Fix2Int( top[0] ); 1439 1440 if ( decoder->subrs_hash ) 1441 { 1442 size_t* val = ft_hash_num_lookup( idx, 1443 decoder->subrs_hash ); 1444 1445 1446 if ( val ) 1447 idx = *val; 1448 else 1449 idx = -1; 1450 } 1451 1452 if ( idx < 0 || idx >= decoder->num_subrs ) 1453 { 1454 FT_ERROR(( "t1_decoder_parse_charstrings:" 1455 " invalid subrs index\n" )); 1456 goto Syntax_Error; 1457 } 1458 1459 if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS ) 1460 { 1461 FT_ERROR(( "t1_decoder_parse_charstrings:" 1462 " too many nested subrs\n" )); 1463 goto Syntax_Error; 1464 } 1465 1466 zone->cursor = ip; /* save current instruction pointer */ 1467 1468 zone++; 1469 1470 /* The Type 1 driver stores subroutines without the seed bytes. */ 1471 /* The CID driver stores subroutines with seed bytes. This */ 1472 /* case is taken care of when decoder->subrs_len == 0. */ 1473 zone->base = decoder->subrs[idx]; 1474 1475 if ( decoder->subrs_len ) 1476 zone->limit = zone->base + decoder->subrs_len[idx]; 1477 else 1478 { 1479 /* We are using subroutines from a CID font. We must adjust */ 1480 /* for the seed bytes. */ 1481 zone->base += ( decoder->lenIV >= 0 ? decoder->lenIV : 0 ); 1482 zone->limit = decoder->subrs[idx + 1]; 1483 } 1484 1485 zone->cursor = zone->base; 1486 1487 if ( !zone->base ) 1488 { 1489 FT_ERROR(( "t1_decoder_parse_charstrings:" 1490 " invoking empty subrs\n" )); 1491 goto Syntax_Error; 1492 } 1493 1494 decoder->zone = zone; 1495 ip = zone->base; 1496 limit = zone->limit; 1497 break; 1498 } 1499 1500 case op_pop: 1501 FT_TRACE4(( " pop" )); 1502 1503 if ( known_othersubr_result_cnt > 0 ) 1504 { 1505 known_othersubr_result_cnt--; 1506 /* ignore, we pushed the operands ourselves */ 1507 break; 1508 } 1509 1510 if ( unknown_othersubr_result_cnt == 0 ) 1511 { 1512 FT_ERROR(( "t1_decoder_parse_charstrings:" 1513 " no more operands for othersubr\n" )); 1514 goto Syntax_Error; 1515 } 1516 1517 unknown_othersubr_result_cnt--; 1518 top++; /* `push' the operand to callothersubr onto the stack */ 1519 break; 1520 1521 case op_return: 1522 FT_TRACE4(( " return" )); 1523 1524 if ( zone <= decoder->zones ) 1525 { 1526 FT_ERROR(( "t1_decoder_parse_charstrings:" 1527 " unexpected return\n" )); 1528 goto Syntax_Error; 1529 } 1530 1531 zone--; 1532 ip = zone->cursor; 1533 limit = zone->limit; 1534 decoder->zone = zone; 1535 break; 1536 1537 case op_dotsection: 1538 FT_TRACE4(( " dotsection" )); 1539 1540 break; 1541 1542 case op_hstem: 1543 FT_TRACE4(( " hstem" )); 1544 1545 /* record horizontal hint */ 1546 if ( hinter ) 1547 { 1548 /* top[0] += builder->left_bearing.y; */ 1549 hinter->stem( hinter->hints, 1, top ); 1550 } 1551 break; 1552 1553 case op_hstem3: 1554 FT_TRACE4(( " hstem3" )); 1555 1556 /* record horizontal counter-controlled hints */ 1557 if ( hinter ) 1558 hinter->stem3( hinter->hints, 1, top ); 1559 break; 1560 1561 case op_vstem: 1562 FT_TRACE4(( " vstem" )); 1563 1564 /* record vertical hint */ 1565 if ( hinter ) 1566 { 1567 top[0] = ADD_LONG( top[0], orig_x ); 1568 hinter->stem( hinter->hints, 0, top ); 1569 } 1570 break; 1571 1572 case op_vstem3: 1573 FT_TRACE4(( " vstem3" )); 1574 1575 /* record vertical counter-controlled hints */ 1576 if ( hinter ) 1577 { 1578 FT_Pos dx = orig_x; 1579 1580 1581 top[0] = ADD_LONG( top[0], dx ); 1582 top[2] = ADD_LONG( top[2], dx ); 1583 top[4] = ADD_LONG( top[4], dx ); 1584 hinter->stem3( hinter->hints, 0, top ); 1585 } 1586 break; 1587 1588 case op_setcurrentpoint: 1589 FT_TRACE4(( " setcurrentpoint" )); 1590 1591 /* From the T1 specification, section 6.4: */ 1592 /* */ 1593 /* The setcurrentpoint command is used only in */ 1594 /* conjunction with results from OtherSubrs procedures. */ 1595 1596 /* known_othersubr_result_cnt != 0 is already handled */ 1597 /* above. */ 1598 1599 /* Note, however, that both Ghostscript and Adobe */ 1600 /* Distiller handle this situation by silently ignoring */ 1601 /* the inappropriate `setcurrentpoint' instruction. So */ 1602 /* we do the same. */ 1603 #if 0 1604 1605 if ( decoder->flex_state != 1 ) 1606 { 1607 FT_ERROR(( "t1_decoder_parse_charstrings:" 1608 " unexpected `setcurrentpoint'\n" )); 1609 goto Syntax_Error; 1610 } 1611 else 1612 ... 1613 #endif 1614 1615 x = top[0]; 1616 y = top[1]; 1617 decoder->flex_state = 0; 1618 break; 1619 1620 case op_unknown15: 1621 FT_TRACE4(( " opcode_15" )); 1622 /* nothing to do except to pop the two arguments */ 1623 break; 1624 1625 default: 1626 FT_ERROR(( "t1_decoder_parse_charstrings:" 1627 " unhandled opcode %d\n", op )); 1628 goto Syntax_Error; 1629 } 1630 1631 /* XXX Operators usually clear the operand stack; */ 1632 /* only div, callsubr, callothersubr, pop, and */ 1633 /* return are different. */ 1634 /* In practice it doesn't matter (?). */ 1635 1636 decoder->top = top; 1637 1638 #ifdef FT_DEBUG_LEVEL_TRACE 1639 FT_TRACE4(( "\n" )); 1640 bol = TRUE; 1641 #endif 1642 1643 } /* general operator processing */ 1644 1645 } /* while ip < limit */ 1646 1647 FT_TRACE4(( "..end..\n\n" )); 1648 1649 Fail: 1650 return error; 1651 1652 Syntax_Error: 1653 return FT_THROW( Syntax_Error ); 1654 1655 Stack_Underflow: 1656 return FT_THROW( Stack_Underflow ); 1657 } 1658 1659 1660 #else /* !T1_CONFIG_OPTION_OLD_ENGINE */ 1661 1662 1663 /************************************************************************** 1664 * 1665 * @Function: 1666 * t1_decoder_parse_metrics 1667 * 1668 * @Description: 1669 * Parses a given Type 1 charstrings program to extract width 1670 * 1671 * @Input: 1672 * decoder :: 1673 * The current Type 1 decoder. 1674 * 1675 * charstring_base :: 1676 * The base address of the charstring stream. 1677 * 1678 * charstring_len :: 1679 * The length in bytes of the charstring stream. 1680 * 1681 * @Return: 1682 * FreeType error code. 0 means success. 1683 */ 1684 FT_LOCAL_DEF( FT_Error ) t1_decoder_parse_metrics(T1_Decoder decoder,FT_Byte * charstring_base,FT_UInt charstring_len)1685 t1_decoder_parse_metrics( T1_Decoder decoder, 1686 FT_Byte* charstring_base, 1687 FT_UInt charstring_len ) 1688 { 1689 T1_Decoder_Zone zone; 1690 FT_Byte* ip; 1691 FT_Byte* limit; 1692 T1_Builder builder = &decoder->builder; 1693 1694 #ifdef FT_DEBUG_LEVEL_TRACE 1695 FT_Bool bol = TRUE; 1696 #endif 1697 1698 1699 /* First of all, initialize the decoder */ 1700 decoder->top = decoder->stack; 1701 decoder->zone = decoder->zones; 1702 zone = decoder->zones; 1703 1704 builder->parse_state = T1_Parse_Start; 1705 1706 zone->base = charstring_base; 1707 limit = zone->limit = charstring_base + charstring_len; 1708 ip = zone->cursor = zone->base; 1709 1710 /* now, execute loop */ 1711 while ( ip < limit ) 1712 { 1713 FT_Long* top = decoder->top; 1714 T1_Operator op = op_none; 1715 FT_Int32 value = 0; 1716 1717 1718 #ifdef FT_DEBUG_LEVEL_TRACE 1719 if ( bol ) 1720 { 1721 FT_TRACE5(( " (%d)", decoder->top - decoder->stack )); 1722 bol = FALSE; 1723 } 1724 #endif 1725 1726 /********************************************************************** 1727 * 1728 * Decode operator or operand 1729 * 1730 */ 1731 1732 /* first of all, decompress operator or value */ 1733 switch ( *ip++ ) 1734 { 1735 case 1: 1736 case 3: 1737 case 4: 1738 case 5: 1739 case 6: 1740 case 7: 1741 case 8: 1742 case 9: 1743 case 10: 1744 case 11: 1745 case 14: 1746 case 15: 1747 case 21: 1748 case 22: 1749 case 30: 1750 case 31: 1751 goto No_Width; 1752 1753 case 13: 1754 op = op_hsbw; 1755 break; 1756 1757 case 12: 1758 if ( ip >= limit ) 1759 { 1760 FT_ERROR(( "t1_decoder_parse_metrics:" 1761 " invalid escape (12+EOF)\n" )); 1762 goto Syntax_Error; 1763 } 1764 1765 switch ( *ip++ ) 1766 { 1767 case 7: 1768 op = op_sbw; 1769 break; 1770 1771 default: 1772 goto No_Width; 1773 } 1774 break; 1775 1776 case 255: /* four bytes integer */ 1777 if ( ip + 4 > limit ) 1778 { 1779 FT_ERROR(( "t1_decoder_parse_metrics:" 1780 " unexpected EOF in integer\n" )); 1781 goto Syntax_Error; 1782 } 1783 1784 value = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) | 1785 ( (FT_UInt32)ip[1] << 16 ) | 1786 ( (FT_UInt32)ip[2] << 8 ) | 1787 (FT_UInt32)ip[3] ); 1788 ip += 4; 1789 1790 /* According to the specification, values > 32000 or < -32000 must */ 1791 /* be followed by a `div' operator to make the result be in the */ 1792 /* range [-32000;32000]. We expect that the second argument of */ 1793 /* `div' is not a large number. Additionally, we don't handle */ 1794 /* stuff like `<large1> <large2> <num> div <num> div' or */ 1795 /* <large1> <large2> <num> div div'. This is probably not allowed */ 1796 /* anyway. */ 1797 if ( value > 32000 || value < -32000 ) 1798 { 1799 FT_ERROR(( "t1_decoder_parse_metrics:" 1800 " large integer found for width\n" )); 1801 goto Syntax_Error; 1802 } 1803 else 1804 { 1805 value = (FT_Int32)( (FT_UInt32)value << 16 ); 1806 } 1807 1808 break; 1809 1810 default: 1811 if ( ip[-1] >= 32 ) 1812 { 1813 if ( ip[-1] < 247 ) 1814 value = (FT_Int32)ip[-1] - 139; 1815 else 1816 { 1817 if ( ++ip > limit ) 1818 { 1819 FT_ERROR(( "t1_decoder_parse_metrics:" 1820 " unexpected EOF in integer\n" )); 1821 goto Syntax_Error; 1822 } 1823 1824 if ( ip[-2] < 251 ) 1825 value = ( ( ip[-2] - 247 ) * 256 ) + ip[-1] + 108; 1826 else 1827 value = -( ( ( ip[-2] - 251 ) * 256 ) + ip[-1] + 108 ); 1828 } 1829 1830 value = (FT_Int32)( (FT_UInt32)value << 16 ); 1831 } 1832 else 1833 { 1834 FT_ERROR(( "t1_decoder_parse_metrics:" 1835 " invalid byte (%d)\n", ip[-1] )); 1836 goto Syntax_Error; 1837 } 1838 } 1839 1840 /********************************************************************** 1841 * 1842 * Push value on stack, or process operator 1843 * 1844 */ 1845 if ( op == op_none ) 1846 { 1847 if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS ) 1848 { 1849 FT_ERROR(( "t1_decoder_parse_metrics: stack overflow\n" )); 1850 goto Syntax_Error; 1851 } 1852 1853 #ifdef FT_DEBUG_LEVEL_TRACE 1854 FT_TRACE4(( " %d", value / 65536 )); 1855 #endif 1856 1857 *top++ = value; 1858 decoder->top = top; 1859 } 1860 else /* general operator */ 1861 { 1862 FT_Int num_args = t1_args_count[op]; 1863 1864 1865 FT_ASSERT( num_args >= 0 ); 1866 1867 if ( top - decoder->stack < num_args ) 1868 goto Stack_Underflow; 1869 1870 #ifdef FT_DEBUG_LEVEL_TRACE 1871 1872 if ( top - decoder->stack != num_args ) 1873 FT_TRACE0(( "t1_decoder_parse_metrics:" 1874 " too much operands on the stack" 1875 " (seen %d, expected %d)\n", 1876 top - decoder->stack, num_args )); 1877 1878 #endif /* FT_DEBUG_LEVEL_TRACE */ 1879 1880 top -= num_args; 1881 1882 switch ( op ) 1883 { 1884 case op_hsbw: 1885 FT_TRACE4(( " hsbw" )); 1886 1887 builder->parse_state = T1_Parse_Have_Width; 1888 1889 builder->left_bearing.x = ADD_LONG( builder->left_bearing.x, 1890 top[0] ); 1891 1892 builder->advance.x = top[1]; 1893 builder->advance.y = 0; 1894 1895 /* we only want to compute the glyph's metrics */ 1896 /* (lsb + advance width), not load the rest of */ 1897 /* it; so exit immediately */ 1898 FT_TRACE4(( "\n" )); 1899 return FT_Err_Ok; 1900 1901 case op_sbw: 1902 FT_TRACE4(( " sbw" )); 1903 1904 builder->parse_state = T1_Parse_Have_Width; 1905 1906 builder->left_bearing.x = ADD_LONG( builder->left_bearing.x, 1907 top[0] ); 1908 builder->left_bearing.y = ADD_LONG( builder->left_bearing.y, 1909 top[1] ); 1910 1911 builder->advance.x = top[2]; 1912 builder->advance.y = top[3]; 1913 1914 /* we only want to compute the glyph's metrics */ 1915 /* (lsb + advance width), not load the rest of */ 1916 /* it; so exit immediately */ 1917 FT_TRACE4(( "\n" )); 1918 return FT_Err_Ok; 1919 1920 default: 1921 FT_ERROR(( "t1_decoder_parse_metrics:" 1922 " unhandled opcode %d\n", op )); 1923 goto Syntax_Error; 1924 } 1925 1926 } /* general operator processing */ 1927 1928 } /* while ip < limit */ 1929 1930 FT_TRACE4(( "..end..\n\n" )); 1931 1932 No_Width: 1933 FT_ERROR(( "t1_decoder_parse_metrics:" 1934 " no width, found op %d instead\n", 1935 ip[-1] )); 1936 Syntax_Error: 1937 return FT_THROW( Syntax_Error ); 1938 1939 Stack_Underflow: 1940 return FT_THROW( Stack_Underflow ); 1941 } 1942 1943 #endif /* !T1_CONFIG_OPTION_OLD_ENGINE */ 1944 1945 1946 /* initialize T1 decoder */ 1947 FT_LOCAL_DEF( FT_Error ) t1_decoder_init(T1_Decoder decoder,FT_Face face,FT_Size size,FT_GlyphSlot slot,FT_Byte ** glyph_names,PS_Blend blend,FT_Bool hinting,FT_Render_Mode hint_mode,T1_Decoder_Callback parse_callback)1948 t1_decoder_init( T1_Decoder decoder, 1949 FT_Face face, 1950 FT_Size size, 1951 FT_GlyphSlot slot, 1952 FT_Byte** glyph_names, 1953 PS_Blend blend, 1954 FT_Bool hinting, 1955 FT_Render_Mode hint_mode, 1956 T1_Decoder_Callback parse_callback ) 1957 { 1958 FT_ZERO( decoder ); 1959 1960 /* retrieve PSNames interface from list of current modules */ 1961 { 1962 FT_Service_PsCMaps psnames; 1963 1964 1965 FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); 1966 if ( !psnames ) 1967 { 1968 FT_ERROR(( "t1_decoder_init:" 1969 " the `psnames' module is not available\n" )); 1970 return FT_THROW( Unimplemented_Feature ); 1971 } 1972 1973 decoder->psnames = psnames; 1974 } 1975 1976 t1_builder_init( &decoder->builder, face, size, slot, hinting ); 1977 1978 /* decoder->buildchar and decoder->len_buildchar have to be */ 1979 /* initialized by the caller since we cannot know the length */ 1980 /* of the BuildCharArray */ 1981 1982 decoder->num_glyphs = (FT_UInt)face->num_glyphs; 1983 decoder->glyph_names = glyph_names; 1984 decoder->hint_mode = hint_mode; 1985 decoder->blend = blend; 1986 decoder->parse_callback = parse_callback; 1987 1988 decoder->funcs = t1_decoder_funcs; 1989 1990 return FT_Err_Ok; 1991 } 1992 1993 1994 /* finalize T1 decoder */ 1995 FT_LOCAL_DEF( void ) t1_decoder_done(T1_Decoder decoder)1996 t1_decoder_done( T1_Decoder decoder ) 1997 { 1998 FT_Memory memory = decoder->builder.memory; 1999 2000 2001 t1_builder_done( &decoder->builder ); 2002 2003 if ( decoder->cf2_instance.finalizer ) 2004 { 2005 decoder->cf2_instance.finalizer( decoder->cf2_instance.data ); 2006 FT_FREE( decoder->cf2_instance.data ); 2007 } 2008 } 2009 2010 2011 /* END */ 2012