1 /**************************************************************************** 2 * 3 * cffdecode.c 4 * 5 * PostScript CFF (Type 2) decoding routines (body). 6 * 7 * Copyright (C) 2017-2019 by 8 * David Turner, Robert Wilhelm, and Werner Lemberg. 9 * 10 * This file is part of the FreeType project, and may only be used, 11 * modified, and distributed under the terms of the FreeType project 12 * license, LICENSE.TXT. By continuing to use, modify, or distribute 13 * this file you indicate that you have read the license and 14 * understand and accept it fully. 15 * 16 */ 17 18 19 #include <ft2build.h> 20 #include FT_FREETYPE_H 21 #include FT_INTERNAL_DEBUG_H 22 #include FT_INTERNAL_SERVICE_H 23 #include FT_SERVICE_CFF_TABLE_LOAD_H 24 25 #include "cffdecode.h" 26 #include "psobjs.h" 27 28 #include "psauxerr.h" 29 30 31 /************************************************************************** 32 * 33 * The macro FT_COMPONENT is used in trace mode. It is an implicit 34 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log 35 * messages during execution. 36 */ 37 #undef FT_COMPONENT 38 #define FT_COMPONENT cffdecode 39 40 41 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE 42 43 typedef enum CFF_Operator_ 44 { 45 cff_op_unknown = 0, 46 47 cff_op_rmoveto, 48 cff_op_hmoveto, 49 cff_op_vmoveto, 50 51 cff_op_rlineto, 52 cff_op_hlineto, 53 cff_op_vlineto, 54 55 cff_op_rrcurveto, 56 cff_op_hhcurveto, 57 cff_op_hvcurveto, 58 cff_op_rcurveline, 59 cff_op_rlinecurve, 60 cff_op_vhcurveto, 61 cff_op_vvcurveto, 62 63 cff_op_flex, 64 cff_op_hflex, 65 cff_op_hflex1, 66 cff_op_flex1, 67 68 cff_op_endchar, 69 70 cff_op_hstem, 71 cff_op_vstem, 72 cff_op_hstemhm, 73 cff_op_vstemhm, 74 75 cff_op_hintmask, 76 cff_op_cntrmask, 77 cff_op_dotsection, /* deprecated, acts as no-op */ 78 79 cff_op_abs, 80 cff_op_add, 81 cff_op_sub, 82 cff_op_div, 83 cff_op_neg, 84 cff_op_random, 85 cff_op_mul, 86 cff_op_sqrt, 87 88 cff_op_blend, 89 90 cff_op_drop, 91 cff_op_exch, 92 cff_op_index, 93 cff_op_roll, 94 cff_op_dup, 95 96 cff_op_put, 97 cff_op_get, 98 cff_op_store, 99 cff_op_load, 100 101 cff_op_and, 102 cff_op_or, 103 cff_op_not, 104 cff_op_eq, 105 cff_op_ifelse, 106 107 cff_op_callsubr, 108 cff_op_callgsubr, 109 cff_op_return, 110 111 /* Type 1 opcodes: invalid but seen in real life */ 112 cff_op_hsbw, 113 cff_op_closepath, 114 cff_op_callothersubr, 115 cff_op_pop, 116 cff_op_seac, 117 cff_op_sbw, 118 cff_op_setcurrentpoint, 119 120 /* do not remove */ 121 cff_op_max 122 123 } CFF_Operator; 124 125 126 #define CFF_COUNT_CHECK_WIDTH 0x80 127 #define CFF_COUNT_EXACT 0x40 128 #define CFF_COUNT_CLEAR_STACK 0x20 129 130 /* count values which have the `CFF_COUNT_CHECK_WIDTH' flag set are */ 131 /* used for checking the width and requested numbers of arguments */ 132 /* only; they are set to zero afterwards */ 133 134 /* the other two flags are informative only and unused currently */ 135 136 static const FT_Byte cff_argument_counts[] = 137 { 138 0, /* unknown */ 139 140 2 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, /* rmoveto */ 141 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, 142 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, 143 144 0 | CFF_COUNT_CLEAR_STACK, /* rlineto */ 145 0 | CFF_COUNT_CLEAR_STACK, 146 0 | CFF_COUNT_CLEAR_STACK, 147 148 0 | CFF_COUNT_CLEAR_STACK, /* rrcurveto */ 149 0 | CFF_COUNT_CLEAR_STACK, 150 0 | CFF_COUNT_CLEAR_STACK, 151 0 | CFF_COUNT_CLEAR_STACK, 152 0 | CFF_COUNT_CLEAR_STACK, 153 0 | CFF_COUNT_CLEAR_STACK, 154 0 | CFF_COUNT_CLEAR_STACK, 155 156 13, /* flex */ 157 7, 158 9, 159 11, 160 161 0 | CFF_COUNT_CHECK_WIDTH, /* endchar */ 162 163 2 | CFF_COUNT_CHECK_WIDTH, /* hstem */ 164 2 | CFF_COUNT_CHECK_WIDTH, 165 2 | CFF_COUNT_CHECK_WIDTH, 166 2 | CFF_COUNT_CHECK_WIDTH, 167 168 0 | CFF_COUNT_CHECK_WIDTH, /* hintmask */ 169 0 | CFF_COUNT_CHECK_WIDTH, /* cntrmask */ 170 0, /* dotsection */ 171 172 1, /* abs */ 173 2, 174 2, 175 2, 176 1, 177 0, 178 2, 179 1, 180 181 1, /* blend */ 182 183 1, /* drop */ 184 2, 185 1, 186 2, 187 1, 188 189 2, /* put */ 190 1, 191 4, 192 3, 193 194 2, /* and */ 195 2, 196 1, 197 2, 198 4, 199 200 1, /* callsubr */ 201 1, 202 0, 203 204 2, /* hsbw */ 205 0, 206 0, 207 0, 208 5, /* seac */ 209 4, /* sbw */ 210 2 /* setcurrentpoint */ 211 }; 212 213 214 static FT_Error 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 = ADD_LONG( adx, decoder->builder.left_bearing.x ); 239 ady = ADD_LONG( ady, decoder->builder.left_bearing.y ); 240 241 #ifdef FT_CONFIG_OPTION_INCREMENTAL 242 /* Incremental fonts don't necessarily have valid charsets. */ 243 /* They use the character code, not the glyph index, in this case. */ 244 if ( face->root.internal->incremental_interface ) 245 { 246 bchar_index = bchar; 247 achar_index = achar; 248 } 249 else 250 #endif /* FT_CONFIG_OPTION_INCREMENTAL */ 251 { 252 CFF_Font cff = (CFF_Font)(face->extra.data); 253 254 255 bchar_index = cff_lookup_glyph_by_stdcharcode( cff, bchar ); 256 achar_index = cff_lookup_glyph_by_stdcharcode( cff, achar ); 257 } 258 259 if ( bchar_index < 0 || achar_index < 0 ) 260 { 261 FT_ERROR(( "cff_operator_seac:" 262 " invalid seac character code arguments\n" )); 263 return FT_THROW( Syntax_Error ); 264 } 265 266 /* If we are trying to load a composite glyph, do not load the */ 267 /* accent character and return the array of subglyphs. */ 268 if ( builder->no_recurse ) 269 { 270 FT_GlyphSlot glyph = (FT_GlyphSlot)builder->glyph; 271 FT_GlyphLoader loader = glyph->internal->loader; 272 FT_SubGlyph subg; 273 274 275 /* reallocate subglyph array if necessary */ 276 error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 ); 277 if ( error ) 278 goto Exit; 279 280 subg = loader->current.subglyphs; 281 282 /* subglyph 0 = base character */ 283 subg->index = bchar_index; 284 subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES | 285 FT_SUBGLYPH_FLAG_USE_MY_METRICS; 286 subg->arg1 = 0; 287 subg->arg2 = 0; 288 subg++; 289 290 /* subglyph 1 = accent character */ 291 subg->index = achar_index; 292 subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; 293 subg->arg1 = (FT_Int)( adx >> 16 ); 294 subg->arg2 = (FT_Int)( ady >> 16 ); 295 296 /* set up remaining glyph fields */ 297 glyph->num_subglyphs = 2; 298 glyph->subglyphs = loader->base.subglyphs; 299 glyph->format = FT_GLYPH_FORMAT_COMPOSITE; 300 301 loader->current.num_subglyphs = 2; 302 } 303 304 FT_GlyphLoader_Prepare( builder->loader ); 305 306 /* First load `bchar' in builder */ 307 error = decoder->get_glyph_callback( face, (FT_UInt)bchar_index, 308 &charstring, &charstring_len ); 309 if ( !error ) 310 { 311 /* the seac operator must not be nested */ 312 decoder->seac = TRUE; 313 error = cff_decoder_parse_charstrings( decoder, charstring, 314 charstring_len, 0 ); 315 decoder->seac = FALSE; 316 317 decoder->free_glyph_callback( face, &charstring, charstring_len ); 318 319 if ( error ) 320 goto Exit; 321 } 322 323 /* Save the left bearing, advance and glyph width of the base */ 324 /* character as they will be erased by the next load. */ 325 326 left_bearing = builder->left_bearing; 327 advance = builder->advance; 328 glyph_width = decoder->glyph_width; 329 330 builder->left_bearing.x = 0; 331 builder->left_bearing.y = 0; 332 333 builder->pos_x = 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 /* deprecated opcodes */ 864 case cff_op_dotsection: 865 /* invalid Type 1 opcodes */ 866 case cff_op_hsbw: 867 case cff_op_closepath: 868 case cff_op_callothersubr: 869 case cff_op_seac: 870 case cff_op_sbw: 871 case cff_op_setcurrentpoint: 872 goto MM_Error; 873 874 default: 875 break; 876 } 877 } 878 879 /* check arguments */ 880 req_args = cff_argument_counts[op]; 881 if ( req_args & CFF_COUNT_CHECK_WIDTH ) 882 { 883 if ( num_args > 0 && decoder->read_width ) 884 { 885 /* If `nominal_width' is non-zero, the number is really a */ 886 /* difference against `nominal_width'. Else, the number here */ 887 /* is truly a width, not a difference against `nominal_width'. */ 888 /* If the font does not set `nominal_width', then */ 889 /* `nominal_width' defaults to zero, and so we can set */ 890 /* `glyph_width' to `nominal_width' plus number on the stack */ 891 /* -- for either case. */ 892 893 FT_Int set_width_ok; 894 895 896 switch ( op ) 897 { 898 case cff_op_hmoveto: 899 case cff_op_vmoveto: 900 set_width_ok = num_args & 2; 901 break; 902 903 case cff_op_hstem: 904 case cff_op_vstem: 905 case cff_op_hstemhm: 906 case cff_op_vstemhm: 907 case cff_op_rmoveto: 908 case cff_op_hintmask: 909 case cff_op_cntrmask: 910 set_width_ok = num_args & 1; 911 break; 912 913 case cff_op_endchar: 914 /* If there is a width specified for endchar, we either have */ 915 /* 1 argument or 5 arguments. We like to argue. */ 916 set_width_ok = in_dict 917 ? 0 918 : ( ( num_args == 5 ) || ( num_args == 1 ) ); 919 break; 920 921 default: 922 set_width_ok = 0; 923 break; 924 } 925 926 if ( set_width_ok ) 927 { 928 decoder->glyph_width = decoder->nominal_width + 929 ( stack[0] >> 16 ); 930 931 if ( decoder->width_only ) 932 { 933 /* we only want the advance width; stop here */ 934 break; 935 } 936 937 /* Consumed an argument. */ 938 num_args--; 939 } 940 } 941 942 decoder->read_width = 0; 943 req_args = 0; 944 } 945 946 req_args &= 0x000F; 947 if ( num_args < req_args ) 948 goto Stack_Underflow; 949 args -= req_args; 950 num_args -= req_args; 951 952 /* At this point, `args' points to the first argument of the */ 953 /* operand in case `req_args' isn't zero. Otherwise, we have */ 954 /* to adjust `args' manually. */ 955 956 /* Note that we only pop arguments from the stack which we */ 957 /* really need and can digest so that we can continue in case */ 958 /* of superfluous stack elements. */ 959 960 switch ( op ) 961 { 962 case cff_op_hstem: 963 case cff_op_vstem: 964 case cff_op_hstemhm: 965 case cff_op_vstemhm: 966 /* the number of arguments is always even here */ 967 FT_TRACE4(( "%s\n", 968 op == cff_op_hstem ? " hstem" : 969 ( op == cff_op_vstem ? " vstem" : 970 ( op == cff_op_hstemhm ? " hstemhm" : " vstemhm" ) ) )); 971 972 if ( hinter ) 973 hinter->stems( hinter->hints, 974 ( op == cff_op_hstem || op == cff_op_hstemhm ), 975 num_args / 2, 976 args - ( num_args & ~1 ) ); 977 978 decoder->num_hints += num_args / 2; 979 args = stack; 980 break; 981 982 case cff_op_hintmask: 983 case cff_op_cntrmask: 984 FT_TRACE4(( "%s", op == cff_op_hintmask ? " hintmask" 985 : " cntrmask" )); 986 987 /* implement vstem when needed -- */ 988 /* the specification doesn't say it, but this also works */ 989 /* with the 'cntrmask' operator */ 990 /* */ 991 if ( num_args > 0 ) 992 { 993 if ( hinter ) 994 hinter->stems( hinter->hints, 995 0, 996 num_args / 2, 997 args - ( num_args & ~1 ) ); 998 999 decoder->num_hints += num_args / 2; 1000 } 1001 1002 /* In a valid charstring there must be at least one byte */ 1003 /* after `hintmask' or `cntrmask' (e.g., for a `return' */ 1004 /* instruction). Additionally, there must be space for */ 1005 /* `num_hints' bits. */ 1006 1007 if ( ( ip + ( ( decoder->num_hints + 7 ) >> 3 ) ) >= limit ) 1008 goto Syntax_Error; 1009 1010 if ( hinter ) 1011 { 1012 if ( op == cff_op_hintmask ) 1013 hinter->hintmask( hinter->hints, 1014 (FT_UInt)builder->current->n_points, 1015 (FT_UInt)decoder->num_hints, 1016 ip ); 1017 else 1018 hinter->counter( hinter->hints, 1019 (FT_UInt)decoder->num_hints, 1020 ip ); 1021 } 1022 1023 #ifdef FT_DEBUG_LEVEL_TRACE 1024 { 1025 FT_UInt maskbyte; 1026 1027 1028 FT_TRACE4(( " (maskbytes:" )); 1029 1030 for ( maskbyte = 0; 1031 maskbyte < (FT_UInt)( ( decoder->num_hints + 7 ) >> 3 ); 1032 maskbyte++, ip++ ) 1033 FT_TRACE4(( " 0x%02X", *ip )); 1034 1035 FT_TRACE4(( ")\n" )); 1036 } 1037 #else 1038 ip += ( decoder->num_hints + 7 ) >> 3; 1039 #endif 1040 args = stack; 1041 break; 1042 1043 case cff_op_rmoveto: 1044 FT_TRACE4(( " rmoveto\n" )); 1045 1046 cff_builder_close_contour( builder ); 1047 builder->path_begun = 0; 1048 x = ADD_LONG( x, args[-2] ); 1049 y = ADD_LONG( y, args[-1] ); 1050 args = stack; 1051 break; 1052 1053 case cff_op_vmoveto: 1054 FT_TRACE4(( " vmoveto\n" )); 1055 1056 cff_builder_close_contour( builder ); 1057 builder->path_begun = 0; 1058 y = ADD_LONG( y, args[-1] ); 1059 args = stack; 1060 break; 1061 1062 case cff_op_hmoveto: 1063 FT_TRACE4(( " hmoveto\n" )); 1064 1065 cff_builder_close_contour( builder ); 1066 builder->path_begun = 0; 1067 x = ADD_LONG( x, args[-1] ); 1068 args = stack; 1069 break; 1070 1071 case cff_op_rlineto: 1072 FT_TRACE4(( " rlineto\n" )); 1073 1074 if ( cff_builder_start_point( builder, x, y ) || 1075 cff_check_points( builder, num_args / 2 ) ) 1076 goto Fail; 1077 1078 if ( num_args < 2 ) 1079 goto Stack_Underflow; 1080 1081 args -= num_args & ~1; 1082 while ( args < decoder->top ) 1083 { 1084 x = ADD_LONG( x, args[0] ); 1085 y = ADD_LONG( y, args[1] ); 1086 cff_builder_add_point( builder, x, y, 1 ); 1087 args += 2; 1088 } 1089 args = stack; 1090 break; 1091 1092 case cff_op_hlineto: 1093 case cff_op_vlineto: 1094 { 1095 FT_Int phase = ( op == cff_op_hlineto ); 1096 1097 1098 FT_TRACE4(( "%s\n", op == cff_op_hlineto ? " hlineto" 1099 : " vlineto" )); 1100 1101 if ( num_args < 0 ) 1102 goto Stack_Underflow; 1103 1104 /* there exist subsetted fonts (found in PDFs) */ 1105 /* which call `hlineto' without arguments */ 1106 if ( num_args == 0 ) 1107 break; 1108 1109 if ( cff_builder_start_point( builder, x, y ) || 1110 cff_check_points( builder, num_args ) ) 1111 goto Fail; 1112 1113 args = stack; 1114 while ( args < decoder->top ) 1115 { 1116 if ( phase ) 1117 x = ADD_LONG( x, args[0] ); 1118 else 1119 y = ADD_LONG( y, args[0] ); 1120 1121 if ( cff_builder_add_point1( builder, x, y ) ) 1122 goto Fail; 1123 1124 args++; 1125 phase ^= 1; 1126 } 1127 args = stack; 1128 } 1129 break; 1130 1131 case cff_op_rrcurveto: 1132 { 1133 FT_Int nargs; 1134 1135 1136 FT_TRACE4(( " rrcurveto\n" )); 1137 1138 if ( num_args < 6 ) 1139 goto Stack_Underflow; 1140 1141 nargs = num_args - num_args % 6; 1142 1143 if ( cff_builder_start_point( builder, x, y ) || 1144 cff_check_points( builder, nargs / 2 ) ) 1145 goto Fail; 1146 1147 args -= nargs; 1148 while ( args < decoder->top ) 1149 { 1150 x = ADD_LONG( x, args[0] ); 1151 y = ADD_LONG( y, args[1] ); 1152 cff_builder_add_point( builder, x, y, 0 ); 1153 1154 x = ADD_LONG( x, args[2] ); 1155 y = ADD_LONG( y, args[3] ); 1156 cff_builder_add_point( builder, x, y, 0 ); 1157 1158 x = ADD_LONG( x, args[4] ); 1159 y = ADD_LONG( y, args[5] ); 1160 cff_builder_add_point( builder, x, y, 1 ); 1161 1162 args += 6; 1163 } 1164 args = stack; 1165 } 1166 break; 1167 1168 case cff_op_vvcurveto: 1169 { 1170 FT_Int nargs; 1171 1172 1173 FT_TRACE4(( " vvcurveto\n" )); 1174 1175 if ( num_args < 4 ) 1176 goto Stack_Underflow; 1177 1178 /* if num_args isn't of the form 4n or 4n+1, */ 1179 /* we enforce it by clearing the second bit */ 1180 1181 nargs = num_args & ~2; 1182 1183 if ( cff_builder_start_point( builder, x, y ) ) 1184 goto Fail; 1185 1186 args -= nargs; 1187 1188 if ( nargs & 1 ) 1189 { 1190 x = ADD_LONG( x, args[0] ); 1191 args++; 1192 nargs--; 1193 } 1194 1195 if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) ) 1196 goto Fail; 1197 1198 while ( args < decoder->top ) 1199 { 1200 y = ADD_LONG( y, args[0] ); 1201 cff_builder_add_point( builder, x, y, 0 ); 1202 1203 x = ADD_LONG( x, args[1] ); 1204 y = ADD_LONG( y, args[2] ); 1205 cff_builder_add_point( builder, x, y, 0 ); 1206 1207 y = ADD_LONG( y, args[3] ); 1208 cff_builder_add_point( builder, x, y, 1 ); 1209 1210 args += 4; 1211 } 1212 args = stack; 1213 } 1214 break; 1215 1216 case cff_op_hhcurveto: 1217 { 1218 FT_Int nargs; 1219 1220 1221 FT_TRACE4(( " hhcurveto\n" )); 1222 1223 if ( num_args < 4 ) 1224 goto Stack_Underflow; 1225 1226 /* if num_args isn't of the form 4n or 4n+1, */ 1227 /* we enforce it by clearing the second bit */ 1228 1229 nargs = num_args & ~2; 1230 1231 if ( cff_builder_start_point( builder, x, y ) ) 1232 goto Fail; 1233 1234 args -= nargs; 1235 if ( nargs & 1 ) 1236 { 1237 y = ADD_LONG( y, args[0] ); 1238 args++; 1239 nargs--; 1240 } 1241 1242 if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) ) 1243 goto Fail; 1244 1245 while ( args < decoder->top ) 1246 { 1247 x = ADD_LONG( x, args[0] ); 1248 cff_builder_add_point( builder, x, y, 0 ); 1249 1250 x = ADD_LONG( x, args[1] ); 1251 y = ADD_LONG( y, args[2] ); 1252 cff_builder_add_point( builder, x, y, 0 ); 1253 1254 x = ADD_LONG( x, args[3] ); 1255 cff_builder_add_point( builder, x, y, 1 ); 1256 1257 args += 4; 1258 } 1259 args = stack; 1260 } 1261 break; 1262 1263 case cff_op_vhcurveto: 1264 case cff_op_hvcurveto: 1265 { 1266 FT_Int phase; 1267 FT_Int nargs; 1268 1269 1270 FT_TRACE4(( "%s\n", op == cff_op_vhcurveto ? " vhcurveto" 1271 : " hvcurveto" )); 1272 1273 if ( cff_builder_start_point( builder, x, y ) ) 1274 goto Fail; 1275 1276 if ( num_args < 4 ) 1277 goto Stack_Underflow; 1278 1279 /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */ 1280 /* we enforce it by clearing the second bit */ 1281 1282 nargs = num_args & ~2; 1283 1284 args -= nargs; 1285 if ( cff_check_points( builder, ( nargs / 4 ) * 3 ) ) 1286 goto Stack_Underflow; 1287 1288 phase = ( op == cff_op_hvcurveto ); 1289 1290 while ( nargs >= 4 ) 1291 { 1292 nargs -= 4; 1293 if ( phase ) 1294 { 1295 x = ADD_LONG( x, args[0] ); 1296 cff_builder_add_point( builder, x, y, 0 ); 1297 1298 x = ADD_LONG( x, args[1] ); 1299 y = ADD_LONG( y, args[2] ); 1300 cff_builder_add_point( builder, x, y, 0 ); 1301 1302 y = ADD_LONG( y, args[3] ); 1303 if ( nargs == 1 ) 1304 x = ADD_LONG( x, args[4] ); 1305 cff_builder_add_point( builder, x, y, 1 ); 1306 } 1307 else 1308 { 1309 y = ADD_LONG( y, args[0] ); 1310 cff_builder_add_point( builder, x, y, 0 ); 1311 1312 x = ADD_LONG( x, args[1] ); 1313 y = ADD_LONG( y, args[2] ); 1314 cff_builder_add_point( builder, x, y, 0 ); 1315 1316 x = ADD_LONG( x, args[3] ); 1317 if ( nargs == 1 ) 1318 y = ADD_LONG( y, args[4] ); 1319 cff_builder_add_point( builder, x, y, 1 ); 1320 } 1321 args += 4; 1322 phase ^= 1; 1323 } 1324 args = stack; 1325 } 1326 break; 1327 1328 case cff_op_rlinecurve: 1329 { 1330 FT_Int num_lines; 1331 FT_Int nargs; 1332 1333 1334 FT_TRACE4(( " rlinecurve\n" )); 1335 1336 if ( num_args < 8 ) 1337 goto Stack_Underflow; 1338 1339 nargs = num_args & ~1; 1340 num_lines = ( nargs - 6 ) / 2; 1341 1342 if ( cff_builder_start_point( builder, x, y ) || 1343 cff_check_points( builder, num_lines + 3 ) ) 1344 goto Fail; 1345 1346 args -= nargs; 1347 1348 /* first, add the line segments */ 1349 while ( num_lines > 0 ) 1350 { 1351 x = ADD_LONG( x, args[0] ); 1352 y = ADD_LONG( y, args[1] ); 1353 cff_builder_add_point( builder, x, y, 1 ); 1354 1355 args += 2; 1356 num_lines--; 1357 } 1358 1359 /* then the curve */ 1360 x = ADD_LONG( x, args[0] ); 1361 y = ADD_LONG( y, args[1] ); 1362 cff_builder_add_point( builder, x, y, 0 ); 1363 1364 x = ADD_LONG( x, args[2] ); 1365 y = ADD_LONG( y, args[3] ); 1366 cff_builder_add_point( builder, x, y, 0 ); 1367 1368 x = ADD_LONG( x, args[4] ); 1369 y = ADD_LONG( y, args[5] ); 1370 cff_builder_add_point( builder, x, y, 1 ); 1371 1372 args = stack; 1373 } 1374 break; 1375 1376 case cff_op_rcurveline: 1377 { 1378 FT_Int num_curves; 1379 FT_Int nargs; 1380 1381 1382 FT_TRACE4(( " rcurveline\n" )); 1383 1384 if ( num_args < 8 ) 1385 goto Stack_Underflow; 1386 1387 nargs = num_args - 2; 1388 nargs = nargs - nargs % 6 + 2; 1389 num_curves = ( nargs - 2 ) / 6; 1390 1391 if ( cff_builder_start_point( builder, x, y ) || 1392 cff_check_points( builder, num_curves * 3 + 2 ) ) 1393 goto Fail; 1394 1395 args -= nargs; 1396 1397 /* first, add the curves */ 1398 while ( num_curves > 0 ) 1399 { 1400 x = ADD_LONG( x, args[0] ); 1401 y = ADD_LONG( y, args[1] ); 1402 cff_builder_add_point( builder, x, y, 0 ); 1403 1404 x = ADD_LONG( x, args[2] ); 1405 y = ADD_LONG( y, args[3] ); 1406 cff_builder_add_point( builder, x, y, 0 ); 1407 1408 x = ADD_LONG( x, args[4] ); 1409 y = ADD_LONG( y, args[5] ); 1410 cff_builder_add_point( builder, x, y, 1 ); 1411 1412 args += 6; 1413 num_curves--; 1414 } 1415 1416 /* then the final line */ 1417 x = ADD_LONG( x, args[0] ); 1418 y = ADD_LONG( y, args[1] ); 1419 cff_builder_add_point( builder, x, y, 1 ); 1420 1421 args = stack; 1422 } 1423 break; 1424 1425 case cff_op_hflex1: 1426 { 1427 FT_Pos start_y; 1428 1429 1430 FT_TRACE4(( " hflex1\n" )); 1431 1432 /* adding five more points: 4 control points, 1 on-curve point */ 1433 /* -- make sure we have enough space for the start point if it */ 1434 /* needs to be added */ 1435 if ( cff_builder_start_point( builder, x, y ) || 1436 cff_check_points( builder, 6 ) ) 1437 goto Fail; 1438 1439 /* record the starting point's y position for later use */ 1440 start_y = y; 1441 1442 /* first control point */ 1443 x = ADD_LONG( x, args[0] ); 1444 y = ADD_LONG( y, args[1] ); 1445 cff_builder_add_point( builder, x, y, 0 ); 1446 1447 /* second control point */ 1448 x = ADD_LONG( x, args[2] ); 1449 y = ADD_LONG( y, args[3] ); 1450 cff_builder_add_point( builder, x, y, 0 ); 1451 1452 /* join point; on curve, with y-value the same as the last */ 1453 /* control point's y-value */ 1454 x = ADD_LONG( x, args[4] ); 1455 cff_builder_add_point( builder, x, y, 1 ); 1456 1457 /* third control point, with y-value the same as the join */ 1458 /* point's y-value */ 1459 x = ADD_LONG( x, args[5] ); 1460 cff_builder_add_point( builder, x, y, 0 ); 1461 1462 /* fourth control point */ 1463 x = ADD_LONG( x, args[6] ); 1464 y = ADD_LONG( y, args[7] ); 1465 cff_builder_add_point( builder, x, y, 0 ); 1466 1467 /* ending point, with y-value the same as the start */ 1468 x = ADD_LONG( x, args[8] ); 1469 y = start_y; 1470 cff_builder_add_point( builder, x, y, 1 ); 1471 1472 args = stack; 1473 break; 1474 } 1475 1476 case cff_op_hflex: 1477 { 1478 FT_Pos start_y; 1479 1480 1481 FT_TRACE4(( " hflex\n" )); 1482 1483 /* adding six more points; 4 control points, 2 on-curve points */ 1484 if ( cff_builder_start_point( builder, x, y ) || 1485 cff_check_points( builder, 6 ) ) 1486 goto Fail; 1487 1488 /* record the starting point's y-position for later use */ 1489 start_y = y; 1490 1491 /* first control point */ 1492 x = ADD_LONG( x, args[0] ); 1493 cff_builder_add_point( builder, x, y, 0 ); 1494 1495 /* second control point */ 1496 x = ADD_LONG( x, args[1] ); 1497 y = ADD_LONG( y, args[2] ); 1498 cff_builder_add_point( builder, x, y, 0 ); 1499 1500 /* join point; on curve, with y-value the same as the last */ 1501 /* control point's y-value */ 1502 x = ADD_LONG( x, args[3] ); 1503 cff_builder_add_point( builder, x, y, 1 ); 1504 1505 /* third control point, with y-value the same as the join */ 1506 /* point's y-value */ 1507 x = ADD_LONG( x, args[4] ); 1508 cff_builder_add_point( builder, x, y, 0 ); 1509 1510 /* fourth control point */ 1511 x = ADD_LONG( x, args[5] ); 1512 y = start_y; 1513 cff_builder_add_point( builder, x, y, 0 ); 1514 1515 /* ending point, with y-value the same as the start point's */ 1516 /* y-value -- we don't add this point, though */ 1517 x = ADD_LONG( x, args[6] ); 1518 cff_builder_add_point( builder, x, y, 1 ); 1519 1520 args = stack; 1521 break; 1522 } 1523 1524 case cff_op_flex1: 1525 { 1526 FT_Pos start_x, start_y; /* record start x, y values for */ 1527 /* alter use */ 1528 FT_Fixed dx = 0, dy = 0; /* used in horizontal/vertical */ 1529 /* algorithm below */ 1530 FT_Int horizontal, count; 1531 FT_Fixed* temp; 1532 1533 1534 FT_TRACE4(( " flex1\n" )); 1535 1536 /* adding six more points; 4 control points, 2 on-curve points */ 1537 if ( cff_builder_start_point( builder, x, y ) || 1538 cff_check_points( builder, 6 ) ) 1539 goto Fail; 1540 1541 /* record the starting point's x, y position for later use */ 1542 start_x = x; 1543 start_y = y; 1544 1545 /* XXX: figure out whether this is supposed to be a horizontal */ 1546 /* or vertical flex; the Type 2 specification is vague... */ 1547 1548 temp = args; 1549 1550 /* grab up to the last argument */ 1551 for ( count = 5; count > 0; count-- ) 1552 { 1553 dx = ADD_LONG( dx, temp[0] ); 1554 dy = ADD_LONG( dy, temp[1] ); 1555 temp += 2; 1556 } 1557 1558 if ( dx < 0 ) 1559 dx = NEG_LONG( dx ); 1560 if ( dy < 0 ) 1561 dy = NEG_LONG( dy ); 1562 1563 /* strange test, but here it is... */ 1564 horizontal = ( dx > dy ); 1565 1566 for ( count = 5; count > 0; count-- ) 1567 { 1568 x = ADD_LONG( x, args[0] ); 1569 y = ADD_LONG( y, args[1] ); 1570 cff_builder_add_point( builder, x, y, 1571 FT_BOOL( count == 3 ) ); 1572 args += 2; 1573 } 1574 1575 /* is last operand an x- or y-delta? */ 1576 if ( horizontal ) 1577 { 1578 x = ADD_LONG( x, args[0] ); 1579 y = start_y; 1580 } 1581 else 1582 { 1583 x = start_x; 1584 y = ADD_LONG( y, args[0] ); 1585 } 1586 1587 cff_builder_add_point( builder, x, y, 1 ); 1588 1589 args = stack; 1590 break; 1591 } 1592 1593 case cff_op_flex: 1594 { 1595 FT_UInt count; 1596 1597 1598 FT_TRACE4(( " flex\n" )); 1599 1600 if ( cff_builder_start_point( builder, x, y ) || 1601 cff_check_points( builder, 6 ) ) 1602 goto Fail; 1603 1604 for ( count = 6; count > 0; count-- ) 1605 { 1606 x = ADD_LONG( x, args[0] ); 1607 y = ADD_LONG( y, args[1] ); 1608 cff_builder_add_point( builder, x, y, 1609 FT_BOOL( count == 4 || count == 1 ) ); 1610 args += 2; 1611 } 1612 1613 args = stack; 1614 } 1615 break; 1616 1617 case cff_op_seac: 1618 FT_TRACE4(( " seac\n" )); 1619 1620 error = cff_operator_seac( decoder, 1621 args[0], args[1], args[2], 1622 (FT_Int)( args[3] >> 16 ), 1623 (FT_Int)( args[4] >> 16 ) ); 1624 1625 /* add current outline to the glyph slot */ 1626 FT_GlyphLoader_Add( builder->loader ); 1627 1628 /* return now! */ 1629 FT_TRACE4(( "\n" )); 1630 return error; 1631 1632 case cff_op_endchar: 1633 /* in dictionaries, `endchar' simply indicates end of data */ 1634 if ( in_dict ) 1635 return error; 1636 1637 FT_TRACE4(( " endchar\n" )); 1638 1639 /* We are going to emulate the seac operator. */ 1640 if ( num_args >= 4 ) 1641 { 1642 /* Save glyph width so that the subglyphs don't overwrite it. */ 1643 FT_Pos glyph_width = decoder->glyph_width; 1644 1645 1646 error = cff_operator_seac( decoder, 1647 0L, args[-4], args[-3], 1648 (FT_Int)( args[-2] >> 16 ), 1649 (FT_Int)( args[-1] >> 16 ) ); 1650 1651 decoder->glyph_width = glyph_width; 1652 } 1653 else 1654 { 1655 cff_builder_close_contour( builder ); 1656 1657 /* close hints recording session */ 1658 if ( hinter ) 1659 { 1660 if ( hinter->close( hinter->hints, 1661 (FT_UInt)builder->current->n_points ) ) 1662 goto Syntax_Error; 1663 1664 /* apply hints to the loaded glyph outline now */ 1665 error = hinter->apply( hinter->hints, 1666 builder->current, 1667 (PSH_Globals)builder->hints_globals, 1668 decoder->hint_mode ); 1669 if ( error ) 1670 goto Fail; 1671 } 1672 1673 /* add current outline to the glyph slot */ 1674 FT_GlyphLoader_Add( builder->loader ); 1675 } 1676 1677 /* return now! */ 1678 FT_TRACE4(( "\n" )); 1679 return error; 1680 1681 case cff_op_abs: 1682 FT_TRACE4(( " abs\n" )); 1683 1684 if ( args[0] < 0 ) 1685 { 1686 if ( args[0] == FT_LONG_MIN ) 1687 args[0] = FT_LONG_MAX; 1688 else 1689 args[0] = -args[0]; 1690 } 1691 args++; 1692 break; 1693 1694 case cff_op_add: 1695 FT_TRACE4(( " add\n" )); 1696 1697 args[0] = ADD_LONG( args[0], args[1] ); 1698 args++; 1699 break; 1700 1701 case cff_op_sub: 1702 FT_TRACE4(( " sub\n" )); 1703 1704 args[0] = SUB_LONG( args[0], args[1] ); 1705 args++; 1706 break; 1707 1708 case cff_op_div: 1709 FT_TRACE4(( " div\n" )); 1710 1711 args[0] = FT_DivFix( args[0], args[1] ); 1712 args++; 1713 break; 1714 1715 case cff_op_neg: 1716 FT_TRACE4(( " neg\n" )); 1717 1718 if ( args[0] == FT_LONG_MIN ) 1719 args[0] = FT_LONG_MAX; 1720 args[0] = -args[0]; 1721 args++; 1722 break; 1723 1724 case cff_op_random: 1725 { 1726 FT_UInt32* randval = in_dict ? &decoder->cff->top_font.random 1727 : &decoder->current_subfont->random; 1728 1729 1730 FT_TRACE4(( " random\n" )); 1731 1732 /* only use the lower 16 bits of `random' */ 1733 /* to generate a number in the range (0;1] */ 1734 args[0] = (FT_Fixed)( ( *randval & 0xFFFF ) + 1 ); 1735 args++; 1736 1737 *randval = cff_random( *randval ); 1738 } 1739 break; 1740 1741 case cff_op_mul: 1742 FT_TRACE4(( " mul\n" )); 1743 1744 args[0] = FT_MulFix( args[0], args[1] ); 1745 args++; 1746 break; 1747 1748 case cff_op_sqrt: 1749 FT_TRACE4(( " sqrt\n" )); 1750 1751 /* without upper limit the loop below might not finish */ 1752 if ( args[0] > 0x7FFFFFFFL ) 1753 args[0] = 46341; 1754 else if ( args[0] > 0 ) 1755 { 1756 FT_Fixed root = args[0]; 1757 FT_Fixed new_root; 1758 1759 1760 for (;;) 1761 { 1762 new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1; 1763 if ( new_root == root ) 1764 break; 1765 root = new_root; 1766 } 1767 args[0] = new_root; 1768 } 1769 else 1770 args[0] = 0; 1771 args++; 1772 break; 1773 1774 case cff_op_drop: 1775 /* nothing */ 1776 FT_TRACE4(( " drop\n" )); 1777 1778 break; 1779 1780 case cff_op_exch: 1781 { 1782 FT_Fixed tmp; 1783 1784 1785 FT_TRACE4(( " exch\n" )); 1786 1787 tmp = args[0]; 1788 args[0] = args[1]; 1789 args[1] = tmp; 1790 args += 2; 1791 } 1792 break; 1793 1794 case cff_op_index: 1795 { 1796 FT_Int idx = (FT_Int)( args[0] >> 16 ); 1797 1798 1799 FT_TRACE4(( " index\n" )); 1800 1801 if ( idx < 0 ) 1802 idx = 0; 1803 else if ( idx > num_args - 2 ) 1804 idx = num_args - 2; 1805 args[0] = args[-( idx + 1 )]; 1806 args++; 1807 } 1808 break; 1809 1810 case cff_op_roll: 1811 { 1812 FT_Int count = (FT_Int)( args[0] >> 16 ); 1813 FT_Int idx = (FT_Int)( args[1] >> 16 ); 1814 1815 1816 FT_TRACE4(( " roll\n" )); 1817 1818 if ( count <= 0 ) 1819 count = 1; 1820 1821 args -= count; 1822 if ( args < stack ) 1823 goto Stack_Underflow; 1824 1825 if ( idx >= 0 ) 1826 { 1827 idx = idx % count; 1828 while ( idx > 0 ) 1829 { 1830 FT_Fixed tmp = args[count - 1]; 1831 FT_Int i; 1832 1833 1834 for ( i = count - 2; i >= 0; i-- ) 1835 args[i + 1] = args[i]; 1836 args[0] = tmp; 1837 idx--; 1838 } 1839 } 1840 else 1841 { 1842 /* before C99 it is implementation-defined whether */ 1843 /* the result of `%' is negative if the first operand */ 1844 /* is negative */ 1845 idx = -( NEG_INT( idx ) % count ); 1846 while ( idx < 0 ) 1847 { 1848 FT_Fixed tmp = args[0]; 1849 FT_Int i; 1850 1851 1852 for ( i = 0; i < count - 1; i++ ) 1853 args[i] = args[i + 1]; 1854 args[count - 1] = tmp; 1855 idx++; 1856 } 1857 } 1858 args += count; 1859 } 1860 break; 1861 1862 case cff_op_dup: 1863 FT_TRACE4(( " dup\n" )); 1864 1865 args[1] = args[0]; 1866 args += 2; 1867 break; 1868 1869 case cff_op_put: 1870 { 1871 FT_Fixed val = args[0]; 1872 FT_Int idx = (FT_Int)( args[1] >> 16 ); 1873 1874 1875 FT_TRACE4(( " put\n" )); 1876 1877 /* the Type2 specification before version 16-March-2000 */ 1878 /* didn't give a hard-coded size limit of the temporary */ 1879 /* storage array; instead, an argument of the */ 1880 /* `MultipleMaster' operator set the size */ 1881 if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS ) 1882 decoder->buildchar[idx] = val; 1883 } 1884 break; 1885 1886 case cff_op_get: 1887 { 1888 FT_Int idx = (FT_Int)( args[0] >> 16 ); 1889 FT_Fixed val = 0; 1890 1891 1892 FT_TRACE4(( " get\n" )); 1893 1894 if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS ) 1895 val = decoder->buildchar[idx]; 1896 1897 args[0] = val; 1898 args++; 1899 } 1900 break; 1901 1902 case cff_op_store: 1903 /* this operator was removed from the Type2 specification */ 1904 /* in version 16-March-2000 */ 1905 1906 /* since we currently don't handle interpolation of multiple */ 1907 /* master fonts, this is a no-op */ 1908 FT_TRACE4(( " store\n" )); 1909 break; 1910 1911 case cff_op_load: 1912 /* this operator was removed from the Type2 specification */ 1913 /* in version 16-March-2000 */ 1914 { 1915 FT_Int reg_idx = (FT_Int)args[0]; 1916 FT_Int idx = (FT_Int)args[1]; 1917 FT_Int count = (FT_Int)args[2]; 1918 1919 1920 FT_TRACE4(( " load\n" )); 1921 1922 /* since we currently don't handle interpolation of multiple */ 1923 /* master fonts, we store a vector [1 0 0 ...] in the */ 1924 /* temporary storage array regardless of the Registry index */ 1925 if ( reg_idx >= 0 && reg_idx <= 2 && 1926 idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS && 1927 count >= 0 && count <= num_axes ) 1928 { 1929 FT_Int end, i; 1930 1931 1932 end = FT_MIN( idx + count, CFF_MAX_TRANS_ELEMENTS ); 1933 1934 if ( idx < end ) 1935 decoder->buildchar[idx] = 1 << 16; 1936 1937 for ( i = idx + 1; i < end; i++ ) 1938 decoder->buildchar[i] = 0; 1939 } 1940 } 1941 break; 1942 1943 case cff_op_blend: 1944 /* this operator was removed from the Type2 specification */ 1945 /* in version 16-March-2000 */ 1946 if ( num_designs ) 1947 { 1948 FT_Int num_results = (FT_Int)( args[0] >> 16 ); 1949 1950 1951 FT_TRACE4(( " blend\n" )); 1952 1953 if ( num_results < 0 ) 1954 goto Syntax_Error; 1955 1956 if ( num_results > num_args || 1957 num_results * (FT_Int)num_designs > num_args ) 1958 goto Stack_Underflow; 1959 1960 /* since we currently don't handle interpolation of multiple */ 1961 /* master fonts, return the `num_results' values of the */ 1962 /* first master */ 1963 args -= num_results * ( num_designs - 1 ); 1964 num_args -= num_results * ( num_designs - 1 ); 1965 } 1966 else 1967 goto Syntax_Error; 1968 break; 1969 1970 case cff_op_dotsection: 1971 /* this operator is deprecated and ignored by the parser */ 1972 FT_TRACE4(( " dotsection\n" )); 1973 break; 1974 1975 case cff_op_closepath: 1976 /* this is an invalid Type 2 operator; however, there */ 1977 /* exist fonts which are incorrectly converted from probably */ 1978 /* Type 1 to CFF, and some parsers seem to accept it */ 1979 1980 FT_TRACE4(( " closepath (invalid op)\n" )); 1981 1982 args = stack; 1983 break; 1984 1985 case cff_op_hsbw: 1986 /* this is an invalid Type 2 operator; however, there */ 1987 /* exist fonts which are incorrectly converted from probably */ 1988 /* Type 1 to CFF, and some parsers seem to accept it */ 1989 1990 FT_TRACE4(( " hsbw (invalid op)\n" )); 1991 1992 decoder->glyph_width = 1993 ADD_LONG( decoder->nominal_width, ( args[1] >> 16 ) ); 1994 1995 decoder->builder.left_bearing.x = args[0]; 1996 decoder->builder.left_bearing.y = 0; 1997 1998 x = ADD_LONG( decoder->builder.pos_x, args[0] ); 1999 y = decoder->builder.pos_y; 2000 args = stack; 2001 break; 2002 2003 case cff_op_sbw: 2004 /* this is an invalid Type 2 operator; however, there */ 2005 /* exist fonts which are incorrectly converted from probably */ 2006 /* Type 1 to CFF, and some parsers seem to accept it */ 2007 2008 FT_TRACE4(( " sbw (invalid op)\n" )); 2009 2010 decoder->glyph_width = 2011 ADD_LONG( decoder->nominal_width, ( args[2] >> 16 ) ); 2012 2013 decoder->builder.left_bearing.x = args[0]; 2014 decoder->builder.left_bearing.y = args[1]; 2015 2016 x = ADD_LONG( decoder->builder.pos_x, args[0] ); 2017 y = ADD_LONG( decoder->builder.pos_y, args[1] ); 2018 args = stack; 2019 break; 2020 2021 case cff_op_setcurrentpoint: 2022 /* this is an invalid Type 2 operator; however, there */ 2023 /* exist fonts which are incorrectly converted from probably */ 2024 /* Type 1 to CFF, and some parsers seem to accept it */ 2025 2026 FT_TRACE4(( " setcurrentpoint (invalid op)\n" )); 2027 2028 x = ADD_LONG( decoder->builder.pos_x, args[0] ); 2029 y = ADD_LONG( decoder->builder.pos_y, args[1] ); 2030 args = stack; 2031 break; 2032 2033 case cff_op_callothersubr: 2034 { 2035 FT_Fixed arg; 2036 2037 2038 /* this is an invalid Type 2 operator; however, there */ 2039 /* exist fonts which are incorrectly converted from */ 2040 /* probably Type 1 to CFF, and some parsers seem to accept */ 2041 /* it */ 2042 2043 FT_TRACE4(( " callothersubr (invalid op)\n" )); 2044 2045 /* subsequent `pop' operands should add the arguments, */ 2046 /* this is the implementation described for `unknown' */ 2047 /* other subroutines in the Type1 spec. */ 2048 /* */ 2049 /* XXX Fix return arguments (see discussion below). */ 2050 2051 arg = 2 + ( args[-2] >> 16 ); 2052 if ( arg >= CFF_MAX_OPERANDS ) 2053 goto Stack_Underflow; 2054 2055 args -= arg; 2056 if ( args < stack ) 2057 goto Stack_Underflow; 2058 } 2059 break; 2060 2061 case cff_op_pop: 2062 /* this is an invalid Type 2 operator; however, there */ 2063 /* exist fonts which are incorrectly converted from probably */ 2064 /* Type 1 to CFF, and some parsers seem to accept it */ 2065 2066 FT_TRACE4(( " pop (invalid op)\n" )); 2067 2068 /* XXX Increasing `args' is wrong: After a certain number of */ 2069 /* `pop's we get a stack overflow. Reason for doing it is */ 2070 /* code like this (actually found in a CFF font): */ 2071 /* */ 2072 /* 17 1 3 callothersubr */ 2073 /* pop */ 2074 /* callsubr */ 2075 /* */ 2076 /* Since we handle `callothersubr' as a no-op, and */ 2077 /* `callsubr' needs at least one argument, `pop' can't be a */ 2078 /* no-op too as it basically should be. */ 2079 /* */ 2080 /* The right solution would be to provide real support for */ 2081 /* `callothersubr' as done in `t1decode.c', however, given */ 2082 /* the fact that CFF fonts with `pop' are invalid, it is */ 2083 /* questionable whether it is worth the time. */ 2084 args++; 2085 break; 2086 2087 case cff_op_and: 2088 { 2089 FT_Fixed cond = ( args[0] && args[1] ); 2090 2091 2092 FT_TRACE4(( " and\n" )); 2093 2094 args[0] = cond ? 0x10000L : 0; 2095 args++; 2096 } 2097 break; 2098 2099 case cff_op_or: 2100 { 2101 FT_Fixed cond = ( args[0] || args[1] ); 2102 2103 2104 FT_TRACE4(( " or\n" )); 2105 2106 args[0] = cond ? 0x10000L : 0; 2107 args++; 2108 } 2109 break; 2110 2111 case cff_op_not: 2112 { 2113 FT_Fixed cond = !args[0]; 2114 2115 2116 FT_TRACE4(( " not\n" )); 2117 2118 args[0] = cond ? 0x10000L : 0; 2119 args++; 2120 } 2121 break; 2122 2123 case cff_op_eq: 2124 { 2125 FT_Fixed cond = ( args[0] == args[1] ); 2126 2127 2128 FT_TRACE4(( " eq\n" )); 2129 2130 args[0] = cond ? 0x10000L : 0; 2131 args++; 2132 } 2133 break; 2134 2135 case cff_op_ifelse: 2136 { 2137 FT_Fixed cond = ( args[2] <= args[3] ); 2138 2139 2140 FT_TRACE4(( " ifelse\n" )); 2141 2142 if ( !cond ) 2143 args[0] = args[1]; 2144 args++; 2145 } 2146 break; 2147 2148 case cff_op_callsubr: 2149 { 2150 FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) + 2151 decoder->locals_bias ); 2152 2153 2154 FT_TRACE4(( " callsubr (idx %d, entering level %d)\n", 2155 idx, 2156 zone - decoder->zones + 1 )); 2157 2158 if ( idx >= decoder->num_locals ) 2159 { 2160 FT_ERROR(( "cff_decoder_parse_charstrings:" 2161 " invalid local subr index\n" )); 2162 goto Syntax_Error; 2163 } 2164 2165 if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS ) 2166 { 2167 FT_ERROR(( "cff_decoder_parse_charstrings:" 2168 " too many nested subrs\n" )); 2169 goto Syntax_Error; 2170 } 2171 2172 zone->cursor = ip; /* save current instruction pointer */ 2173 2174 zone++; 2175 zone->base = decoder->locals[idx]; 2176 zone->limit = decoder->locals[idx + 1]; 2177 zone->cursor = zone->base; 2178 2179 if ( !zone->base || zone->limit == zone->base ) 2180 { 2181 FT_ERROR(( "cff_decoder_parse_charstrings:" 2182 " invoking empty subrs\n" )); 2183 goto Syntax_Error; 2184 } 2185 2186 decoder->zone = zone; 2187 ip = zone->base; 2188 limit = zone->limit; 2189 } 2190 break; 2191 2192 case cff_op_callgsubr: 2193 { 2194 FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) + 2195 decoder->globals_bias ); 2196 2197 2198 FT_TRACE4(( " callgsubr (idx %d, entering level %d)\n", 2199 idx, 2200 zone - decoder->zones + 1 )); 2201 2202 if ( idx >= decoder->num_globals ) 2203 { 2204 FT_ERROR(( "cff_decoder_parse_charstrings:" 2205 " invalid global subr index\n" )); 2206 goto Syntax_Error; 2207 } 2208 2209 if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS ) 2210 { 2211 FT_ERROR(( "cff_decoder_parse_charstrings:" 2212 " too many nested subrs\n" )); 2213 goto Syntax_Error; 2214 } 2215 2216 zone->cursor = ip; /* save current instruction pointer */ 2217 2218 zone++; 2219 zone->base = decoder->globals[idx]; 2220 zone->limit = decoder->globals[idx + 1]; 2221 zone->cursor = zone->base; 2222 2223 if ( !zone->base || zone->limit == zone->base ) 2224 { 2225 FT_ERROR(( "cff_decoder_parse_charstrings:" 2226 " invoking empty subrs\n" )); 2227 goto Syntax_Error; 2228 } 2229 2230 decoder->zone = zone; 2231 ip = zone->base; 2232 limit = zone->limit; 2233 } 2234 break; 2235 2236 case cff_op_return: 2237 FT_TRACE4(( " return (leaving level %d)\n", 2238 decoder->zone - decoder->zones )); 2239 2240 if ( decoder->zone <= decoder->zones ) 2241 { 2242 FT_ERROR(( "cff_decoder_parse_charstrings:" 2243 " unexpected return\n" )); 2244 goto Syntax_Error; 2245 } 2246 2247 decoder->zone--; 2248 zone = decoder->zone; 2249 ip = zone->cursor; 2250 limit = zone->limit; 2251 break; 2252 2253 default: 2254 FT_ERROR(( "Unimplemented opcode: %d", ip[-1] )); 2255 2256 if ( ip[-1] == 12 ) 2257 FT_ERROR(( " %d", ip[0] )); 2258 FT_ERROR(( "\n" )); 2259 2260 return FT_THROW( Unimplemented_Feature ); 2261 } 2262 2263 decoder->top = args; 2264 2265 if ( decoder->top - stack >= CFF_MAX_OPERANDS ) 2266 goto Stack_Overflow; 2267 2268 } /* general operator processing */ 2269 2270 } /* while ip < limit */ 2271 2272 FT_TRACE4(( "..end..\n\n" )); 2273 2274 Fail: 2275 return error; 2276 2277 MM_Error: 2278 FT_TRACE4(( "cff_decoder_parse_charstrings:" 2279 " invalid opcode found in top DICT charstring\n")); 2280 return FT_THROW( Invalid_File_Format ); 2281 2282 Syntax_Error: 2283 FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" )); 2284 return FT_THROW( Invalid_File_Format ); 2285 2286 Stack_Underflow: 2287 FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" )); 2288 return FT_THROW( Too_Few_Arguments ); 2289 2290 Stack_Overflow: 2291 FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" )); 2292 return FT_THROW( Stack_Overflow ); 2293 } 2294 2295 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ 2296 2297 2298 /************************************************************************** 2299 * 2300 * @Function: 2301 * cff_decoder_init 2302 * 2303 * @Description: 2304 * Initializes a given glyph decoder. 2305 * 2306 * @InOut: 2307 * decoder :: 2308 * A pointer to the glyph builder to initialize. 2309 * 2310 * @Input: 2311 * face :: 2312 * The current face object. 2313 * 2314 * size :: 2315 * The current size object. 2316 * 2317 * slot :: 2318 * The current glyph object. 2319 * 2320 * hinting :: 2321 * Whether hinting is active. 2322 * 2323 * hint_mode :: 2324 * The hinting mode. 2325 */ 2326 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)2327 cff_decoder_init( CFF_Decoder* decoder, 2328 TT_Face face, 2329 CFF_Size size, 2330 CFF_GlyphSlot slot, 2331 FT_Bool hinting, 2332 FT_Render_Mode hint_mode, 2333 CFF_Decoder_Get_Glyph_Callback get_callback, 2334 CFF_Decoder_Free_Glyph_Callback free_callback ) 2335 { 2336 CFF_Font cff = (CFF_Font)face->extra.data; 2337 2338 2339 /* clear everything */ 2340 FT_ZERO( decoder ); 2341 2342 /* initialize builder */ 2343 cff_builder_init( &decoder->builder, face, size, slot, hinting ); 2344 2345 /* initialize Type2 decoder */ 2346 decoder->cff = cff; 2347 decoder->num_globals = cff->global_subrs_index.count; 2348 decoder->globals = cff->global_subrs; 2349 decoder->globals_bias = cff_compute_bias( 2350 cff->top_font.font_dict.charstring_type, 2351 decoder->num_globals ); 2352 2353 decoder->hint_mode = hint_mode; 2354 2355 decoder->get_glyph_callback = get_callback; 2356 decoder->free_glyph_callback = free_callback; 2357 } 2358 2359 2360 /* this function is used to select the subfont */ 2361 /* and the locals subrs array */ 2362 FT_LOCAL_DEF( FT_Error ) cff_decoder_prepare(CFF_Decoder * decoder,CFF_Size size,FT_UInt glyph_index)2363 cff_decoder_prepare( CFF_Decoder* decoder, 2364 CFF_Size size, 2365 FT_UInt glyph_index ) 2366 { 2367 CFF_Builder *builder = &decoder->builder; 2368 CFF_Font cff = (CFF_Font)builder->face->extra.data; 2369 CFF_SubFont sub = &cff->top_font; 2370 FT_Error error = FT_Err_Ok; 2371 2372 FT_Service_CFFLoad cffload = (FT_Service_CFFLoad)cff->cffload; 2373 2374 2375 /* manage CID fonts */ 2376 if ( cff->num_subfonts ) 2377 { 2378 FT_Byte fd_index = cffload->fd_select_get( &cff->fd_select, 2379 glyph_index ); 2380 2381 2382 if ( fd_index >= cff->num_subfonts ) 2383 { 2384 FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" )); 2385 error = FT_THROW( Invalid_File_Format ); 2386 goto Exit; 2387 } 2388 2389 FT_TRACE3(( " in subfont %d:\n", fd_index )); 2390 2391 sub = cff->subfonts[fd_index]; 2392 2393 if ( builder->hints_funcs && size ) 2394 { 2395 FT_Size ftsize = FT_SIZE( size ); 2396 CFF_Internal internal = (CFF_Internal)ftsize->internal->module_data; 2397 2398 2399 /* for CFFs without subfonts, this value has already been set */ 2400 builder->hints_globals = (void *)internal->subfonts[fd_index]; 2401 } 2402 } 2403 2404 decoder->num_locals = sub->local_subrs_index.count; 2405 decoder->locals = sub->local_subrs; 2406 decoder->locals_bias = cff_compute_bias( 2407 decoder->cff->top_font.font_dict.charstring_type, 2408 decoder->num_locals ); 2409 2410 decoder->glyph_width = sub->private_dict.default_width; 2411 decoder->nominal_width = sub->private_dict.nominal_width; 2412 2413 decoder->current_subfont = sub; 2414 2415 Exit: 2416 return error; 2417 } 2418 2419 2420 /* END */ 2421