< prev index next >

src/java.desktop/share/native/libfreetype/src/psaux/cffdecode.c

Print this page


   1 /***************************************************************************/
   2 /*                                                                         */
   3 /*  cffdecode.c                                                            */
   4 /*                                                                         */
   5 /*    PostScript CFF (Type 2) decoding routines (body).                    */
   6 /*                                                                         */
   7 /*  Copyright 2017-2018 by                                                 */
   8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
   9 /*                                                                         */
  10 /*  This file is part of the FreeType project, and may only be used,       */
  11 /*  modified, and distributed under the terms of the FreeType project      */
  12 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  13 /*  this file you indicate that you have read the license and              */
  14 /*  understand and accept it fully.                                        */
  15 /*                                                                         */
  16 /***************************************************************************/
  17 
  18 
  19 #include <ft2build.h>
  20 #include FT_FREETYPE_H
  21 #include FT_INTERNAL_DEBUG_H
  22 #include FT_INTERNAL_SERVICE_H
  23 #include FT_SERVICE_CFF_TABLE_LOAD_H
  24 
  25 #include "cffdecode.h"
  26 #include "psobjs.h"
  27 
  28 #include "psauxerr.h"
  29 
  30 
  31   /*************************************************************************/
  32   /*                                                                       */
  33   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
  34   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
  35   /* messages during execution.                                            */
  36   /*                                                                       */
  37 #undef  FT_COMPONENT
  38 #define FT_COMPONENT  trace_cffdecode
  39 
  40 
  41 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
  42 
  43   typedef enum  CFF_Operator_
  44   {
  45     cff_op_unknown = 0,
  46 
  47     cff_op_rmoveto,
  48     cff_op_hmoveto,
  49     cff_op_vmoveto,
  50 
  51     cff_op_rlineto,
  52     cff_op_hlineto,
  53     cff_op_vlineto,
  54 
  55     cff_op_rrcurveto,
  56     cff_op_hhcurveto,
  57     cff_op_hvcurveto,
  58     cff_op_rcurveline,


 218                      FT_Pos        ady,
 219                      FT_Int        bchar,
 220                      FT_Int        achar )
 221   {
 222     FT_Error      error;
 223     CFF_Builder*  builder = &decoder->builder;
 224     FT_Int        bchar_index, achar_index;
 225     TT_Face       face    = decoder->builder.face;
 226     FT_Vector     left_bearing, advance;
 227     FT_Byte*      charstring;
 228     FT_ULong      charstring_len;
 229     FT_Pos        glyph_width;
 230 
 231 
 232     if ( decoder->seac )
 233     {
 234       FT_ERROR(( "cff_operator_seac: invalid nested seac\n" ));
 235       return FT_THROW( Syntax_Error );
 236     }
 237 
 238     adx += decoder->builder.left_bearing.x;
 239     ady += decoder->builder.left_bearing.y;
 240 
 241 #ifdef FT_CONFIG_OPTION_INCREMENTAL
 242     /* Incremental fonts don't necessarily have valid charsets.        */
 243     /* They use the character code, not the glyph index, in this case. */
 244     if ( face->root.internal->incremental_interface )
 245     {
 246       bchar_index = bchar;
 247       achar_index = achar;
 248     }
 249     else
 250 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
 251     {
 252       CFF_Font cff = (CFF_Font)(face->extra.data);
 253 
 254 
 255       bchar_index = cff_lookup_glyph_by_stdcharcode( cff, bchar );
 256       achar_index = cff_lookup_glyph_by_stdcharcode( cff, achar );
 257     }
 258 
 259     if ( bchar_index < 0 || achar_index < 0 )


 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 :: The `CharstringType' value of the top DICT   */
 392   /*                          dictionary.                                  */
 393   /*                                                                       */
 394   /*    num_subrs          :: The number of glyph subroutines.             */
 395   /*                                                                       */
 396   /* <Return>                                                              */
 397   /*    The bias value.                                                    */



 398   static FT_Int
 399   cff_compute_bias( FT_Int   in_charstring_type,
 400                     FT_UInt  num_subrs )
 401   {
 402     FT_Int  result;
 403 
 404 
 405     if ( in_charstring_type == 1 )
 406       result = 0;
 407     else if ( num_subrs < 1240 )
 408       result = 107;
 409     else if ( num_subrs < 33900U )
 410       result = 1131;
 411     else
 412       result = 32768U;
 413 
 414     return result;
 415   }
 416 
 417 


 447     }
 448 #endif
 449 
 450     cffload = (FT_Service_CFFLoad)cff->cffload;
 451 
 452     /* Get code to SID mapping from `cff_standard_encoding'. */
 453     glyph_sid = cffload->get_standard_encoding( (FT_UInt)charcode );
 454 
 455     for ( n = 0; n < cff->num_glyphs; n++ )
 456     {
 457       if ( cff->charset.sids[n] == glyph_sid )
 458         return (FT_Int)n;
 459     }
 460 
 461     return -1;
 462   }
 463 
 464 
 465 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
 466 
 467   /*************************************************************************/
 468   /*                                                                       */
 469   /* <Function>                                                            */
 470   /*    cff_decoder_parse_charstrings                                      */
 471   /*                                                                       */
 472   /* <Description>                                                         */
 473   /*    Parses a given Type 2 charstrings program.                         */
 474   /*                                                                       */
 475   /* <InOut>                                                               */
 476   /*    decoder         :: The current Type 1 decoder.                     */
 477   /*                                                                       */
 478   /* <Input>                                                               */
 479   /*    charstring_base :: The base of the charstring stream.              */
 480   /*                                                                       */
 481   /*    charstring_len  :: The length in bytes of the charstring stream.   */
 482   /*                                                                       */
 483   /*    in_dict         :: Set to 1 if function is called from top or      */
 484   /*                       private DICT (needed for Multiple Master CFFs). */
 485   /*                                                                       */
 486   /* <Return>                                                              */
 487   /*    FreeType error code.  0 means success.                             */
 488   /*                                                                       */




 489   FT_LOCAL_DEF( FT_Error )
 490   cff_decoder_parse_charstrings( CFF_Decoder*  decoder,
 491                                  FT_Byte*      charstring_base,
 492                                  FT_ULong      charstring_len,
 493                                  FT_Bool       in_dict )
 494   {
 495     FT_Error           error;
 496     CFF_Decoder_Zone*  zone;
 497     FT_Byte*           ip;
 498     FT_Byte*           limit;
 499     CFF_Builder*       builder = &decoder->builder;
 500     FT_Pos             x, y;
 501     FT_Fixed*          stack;
 502     FT_Int             charstring_type =
 503                          decoder->cff->top_font.font_dict.charstring_type;
 504     FT_UShort          num_designs =
 505                          decoder->cff->top_font.font_dict.num_designs;
 506     FT_UShort          num_axes =
 507                          decoder->cff->top_font.font_dict.num_axes;
 508 


 526     zone->base           = charstring_base;
 527     limit = zone->limit  = charstring_base + charstring_len;
 528     ip    = zone->cursor = zone->base;
 529 
 530     error = FT_Err_Ok;
 531 
 532     x = builder->pos_x;
 533     y = builder->pos_y;
 534 
 535     /* begin hints recording session, if any */
 536     if ( hinter )
 537       hinter->open( hinter->hints );
 538 
 539     /* now execute loop */
 540     while ( ip < limit )
 541     {
 542       CFF_Operator  op;
 543       FT_Byte       v;
 544 
 545 
 546       /********************************************************************/
 547       /*                                                                  */
 548       /* Decode operator or operand                                       */
 549       /*                                                                  */
 550       v = *ip++;
 551       if ( v >= 32 || v == 28 )
 552       {
 553         FT_Int    shift = 16;
 554         FT_Int32  val;
 555 
 556 
 557         /* this is an operand, push it on the stack */
 558 
 559         /* if we use shifts, all computations are done with unsigned */
 560         /* values; the conversion to a signed value is the last step */
 561         if ( v == 28 )
 562         {
 563           if ( ip + 1 >= limit )
 564             goto Syntax_Error;
 565           val = (FT_Short)( ( (FT_UShort)ip[0] << 8 ) | ip[1] );
 566           ip += 2;
 567         }
 568         else if ( v < 247 )
 569           val = (FT_Int32)v - 139;


 836           case cff_op_vlineto:
 837           case cff_op_rrcurveto:
 838           case cff_op_hstemhm:
 839           case cff_op_hintmask:
 840           case cff_op_cntrmask:
 841           case cff_op_rmoveto:
 842           case cff_op_hmoveto:
 843           case cff_op_vstemhm:
 844           case cff_op_rcurveline:
 845           case cff_op_rlinecurve:
 846           case cff_op_vvcurveto:
 847           case cff_op_hhcurveto:
 848           case cff_op_vhcurveto:
 849           case cff_op_hvcurveto:
 850           case cff_op_hflex:
 851           case cff_op_flex:
 852           case cff_op_hflex1:
 853           case cff_op_flex1:
 854           case cff_op_callsubr:
 855           case cff_op_callgsubr:









 856             goto MM_Error;
 857 
 858           default:
 859             break;
 860           }
 861         }
 862 
 863         /* check arguments */
 864         req_args = cff_argument_counts[op];
 865         if ( req_args & CFF_COUNT_CHECK_WIDTH )
 866         {
 867           if ( num_args > 0 && decoder->read_width )
 868           {
 869             /* If `nominal_width' is non-zero, the number is really a      */
 870             /* difference against `nominal_width'.  Else, the number here  */
 871             /* is truly a width, not a difference against `nominal_width'. */
 872             /* If the font does not set `nominal_width', then              */
 873             /* `nominal_width' defaults to zero, and so we can set         */
 874             /* `glyph_width' to `nominal_width' plus number on the stack   */
 875             /* -- for either case.                                         */


 931         if ( num_args < req_args )
 932           goto Stack_Underflow;
 933         args     -= req_args;
 934         num_args -= req_args;
 935 
 936         /* At this point, `args' points to the first argument of the  */
 937         /* operand in case `req_args' isn't zero.  Otherwise, we have */
 938         /* to adjust `args' manually.                                 */
 939 
 940         /* Note that we only pop arguments from the stack which we    */
 941         /* really need and can digest so that we can continue in case */
 942         /* of superfluous stack elements.                             */
 943 
 944         switch ( op )
 945         {
 946         case cff_op_hstem:
 947         case cff_op_vstem:
 948         case cff_op_hstemhm:
 949         case cff_op_vstemhm:
 950           /* the number of arguments is always even here */
 951           FT_TRACE4((
 952               op == cff_op_hstem   ? " hstem\n"   :
 953             ( op == cff_op_vstem   ? " vstem\n"   :
 954             ( op == cff_op_hstemhm ? " hstemhm\n" : " vstemhm\n" ) ) ));
 955 
 956           if ( hinter )
 957             hinter->stems( hinter->hints,
 958                            ( op == cff_op_hstem || op == cff_op_hstemhm ),
 959                            num_args / 2,
 960                            args - ( num_args & ~1 ) );
 961 
 962           decoder->num_hints += num_args / 2;
 963           args = stack;
 964           break;
 965 
 966         case cff_op_hintmask:
 967         case cff_op_cntrmask:
 968           FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" ));

 969 
 970           /* implement vstem when needed --                        */
 971           /* the specification doesn't say it, but this also works */
 972           /* with the 'cntrmask' operator                          */
 973           /*                                                       */
 974           if ( num_args > 0 )
 975           {
 976             if ( hinter )
 977               hinter->stems( hinter->hints,
 978                              0,
 979                              num_args / 2,
 980                              args - ( num_args & ~1 ) );
 981 
 982             decoder->num_hints += num_args / 2;
 983           }
 984 
 985           /* In a valid charstring there must be at least one byte */
 986           /* after `hintmask' or `cntrmask' (e.g., for a `return'  */
 987           /* instruction).  Additionally, there must be space for  */
 988           /* `num_hints' bits.                                     */


1061           if ( num_args < 2 )
1062             goto Stack_Underflow;
1063 
1064           args -= num_args & ~1;
1065           while ( args < decoder->top )
1066           {
1067             x = ADD_LONG( x, args[0] );
1068             y = ADD_LONG( y, args[1] );
1069             cff_builder_add_point( builder, x, y, 1 );
1070             args += 2;
1071           }
1072           args = stack;
1073           break;
1074 
1075         case cff_op_hlineto:
1076         case cff_op_vlineto:
1077           {
1078             FT_Int  phase = ( op == cff_op_hlineto );
1079 
1080 
1081             FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n"
1082                                              : " vlineto\n" ));
1083 
1084             if ( num_args < 0 )
1085               goto Stack_Underflow;
1086 
1087             /* there exist subsetted fonts (found in PDFs) */
1088             /* which call `hlineto' without arguments      */
1089             if ( num_args == 0 )
1090               break;
1091 
1092             if ( cff_builder_start_point( builder, x, y ) ||
1093                  cff_check_points( builder, num_args )    )
1094               goto Fail;
1095 
1096             args = stack;
1097             while ( args < decoder->top )
1098             {
1099               if ( phase )
1100                 x = ADD_LONG( x, args[0] );
1101               else
1102                 y = ADD_LONG( y, args[0] );


1233               x = ADD_LONG( x, args[1] );
1234               y = ADD_LONG( y, args[2] );
1235               cff_builder_add_point( builder, x, y, 0 );
1236 
1237               x = ADD_LONG( x, args[3] );
1238               cff_builder_add_point( builder, x, y, 1 );
1239 
1240               args += 4;
1241             }
1242             args = stack;
1243           }
1244           break;
1245 
1246         case cff_op_vhcurveto:
1247         case cff_op_hvcurveto:
1248           {
1249             FT_Int  phase;
1250             FT_Int  nargs;
1251 
1252 
1253             FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto\n"
1254                                                : " hvcurveto\n" ));
1255 
1256             if ( cff_builder_start_point( builder, x, y ) )
1257               goto Fail;
1258 
1259             if ( num_args < 4 )
1260               goto Stack_Underflow;
1261 
1262             /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */
1263             /* we enforce it by clearing the second bit               */
1264 
1265             nargs = num_args & ~2;
1266 
1267             args -= nargs;
1268             if ( cff_check_points( builder, ( nargs / 4 ) * 3 ) )
1269               goto Stack_Underflow;
1270 
1271             phase = ( op == cff_op_hvcurveto );
1272 
1273             while ( nargs >= 4 )
1274             {


1522               goto Fail;
1523 
1524             /* record the starting point's x, y position for later use */
1525             start_x = x;
1526             start_y = y;
1527 
1528             /* XXX: figure out whether this is supposed to be a horizontal */
1529             /*      or vertical flex; the Type 2 specification is vague... */
1530 
1531             temp = args;
1532 
1533             /* grab up to the last argument */
1534             for ( count = 5; count > 0; count-- )
1535             {
1536               dx    = ADD_LONG( dx, temp[0] );
1537               dy    = ADD_LONG( dy, temp[1] );
1538               temp += 2;
1539             }
1540 
1541             if ( dx < 0 )
1542               dx = -dx;
1543             if ( dy < 0 )
1544               dy = -dy;
1545 
1546             /* strange test, but here it is... */
1547             horizontal = ( dx > dy );
1548 
1549             for ( count = 5; count > 0; count-- )
1550             {
1551               x = ADD_LONG( x, args[0] );
1552               y = ADD_LONG( y, args[1] );
1553               cff_builder_add_point( builder, x, y,
1554                                      (FT_Bool)( count == 3 ) );
1555               args += 2;
1556             }
1557 
1558             /* is last operand an x- or y-delta? */
1559             if ( horizontal )
1560             {
1561               x = ADD_LONG( x, args[0] );
1562               y = start_y;
1563             }
1564             else
1565             {
1566               x = start_x;
1567               y = ADD_LONG( y, args[0] );
1568             }
1569 
1570             cff_builder_add_point( builder, x, y, 1 );
1571 
1572             args = stack;
1573             break;
1574            }
1575 
1576         case cff_op_flex:
1577           {
1578             FT_UInt  count;
1579 
1580 
1581             FT_TRACE4(( " flex\n" ));
1582 
1583             if ( cff_builder_start_point( builder, x, y ) ||
1584                  cff_check_points( builder, 6 )           )
1585               goto Fail;
1586 
1587             for ( count = 6; count > 0; count-- )
1588             {
1589               x = ADD_LONG( x, args[0] );
1590               y = ADD_LONG( y, args[1] );
1591               cff_builder_add_point( builder, x, y,
1592                                      (FT_Bool)( count == 4 || count == 1 ) );
1593               args += 2;
1594             }
1595 
1596             args = stack;
1597           }
1598           break;
1599 
1600         case cff_op_seac:
1601           FT_TRACE4(( " seac\n" ));
1602 
1603           error = cff_operator_seac( decoder,
1604                                      args[0], args[1], args[2],
1605                                      (FT_Int)( args[3] >> 16 ),
1606                                      (FT_Int)( args[4] >> 16 ) );
1607 
1608           /* add current outline to the glyph slot */
1609           FT_GlyphLoader_Add( builder->loader );
1610 
1611           /* return now! */
1612           FT_TRACE4(( "\n" ));


1688           args++;
1689           break;
1690 
1691         case cff_op_div:
1692           FT_TRACE4(( " div\n" ));
1693 
1694           args[0] = FT_DivFix( args[0], args[1] );
1695           args++;
1696           break;
1697 
1698         case cff_op_neg:
1699           FT_TRACE4(( " neg\n" ));
1700 
1701           if ( args[0] == FT_LONG_MIN )
1702             args[0] = FT_LONG_MAX;
1703           args[0] = -args[0];
1704           args++;
1705           break;
1706 
1707         case cff_op_random:





1708           FT_TRACE4(( " random\n" ));
1709 
1710           /* only use the lower 16 bits of `random'  */
1711           /* to generate a number in the range (0;1] */
1712           args[0] = (FT_Fixed)
1713                       ( ( decoder->current_subfont->random & 0xFFFF ) + 1 );
1714           args++;
1715 
1716           decoder->current_subfont->random =
1717             cff_random( decoder->current_subfont->random );
1718           break;
1719 
1720         case cff_op_mul:
1721           FT_TRACE4(( " mul\n" ));
1722 
1723           args[0] = FT_MulFix( args[0], args[1] );
1724           args++;
1725           break;
1726 
1727         case cff_op_sqrt:
1728           FT_TRACE4(( " sqrt\n" ));
1729 
1730           if ( args[0] > 0 )



1731           {
1732             FT_Fixed  root = args[0];
1733             FT_Fixed  new_root;
1734 
1735 
1736             for (;;)
1737             {
1738               new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1;
1739               if ( new_root == root )
1740                 break;
1741               root = new_root;
1742             }
1743             args[0] = new_root;
1744           }
1745           else
1746             args[0] = 0;
1747           args++;
1748           break;
1749 
1750         case cff_op_drop:


1783           }
1784           break;
1785 
1786         case cff_op_roll:
1787           {
1788             FT_Int  count = (FT_Int)( args[0] >> 16 );
1789             FT_Int  idx   = (FT_Int)( args[1] >> 16 );
1790 
1791 
1792             FT_TRACE4(( " roll\n" ));
1793 
1794             if ( count <= 0 )
1795               count = 1;
1796 
1797             args -= count;
1798             if ( args < stack )
1799               goto Stack_Underflow;
1800 
1801             if ( idx >= 0 )
1802             {

1803               while ( idx > 0 )
1804               {
1805                 FT_Fixed  tmp = args[count - 1];
1806                 FT_Int    i;
1807 
1808 
1809                 for ( i = count - 2; i >= 0; i-- )
1810                   args[i + 1] = args[i];
1811                 args[0] = tmp;
1812                 idx--;
1813               }
1814             }
1815             else
1816             {




1817               while ( idx < 0 )
1818               {
1819                 FT_Fixed  tmp = args[0];
1820                 FT_Int    i;
1821 
1822 
1823                 for ( i = 0; i < count - 1; i++ )
1824                   args[i] = args[i + 1];
1825                 args[count - 1] = tmp;
1826                 idx++;
1827               }
1828             }
1829             args += count;
1830           }
1831           break;
1832 
1833         case cff_op_dup:
1834           FT_TRACE4(( " dup\n" ));
1835 
1836           args[1] = args[0];


1897                  idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS &&
1898                  count >= 0 && count <= num_axes          )
1899             {
1900               FT_Int  end, i;
1901 
1902 
1903               end = FT_MIN( idx + count, CFF_MAX_TRANS_ELEMENTS );
1904 
1905               if ( idx < end )
1906                 decoder->buildchar[idx] = 1 << 16;
1907 
1908               for ( i = idx + 1; i < end; i++ )
1909                 decoder->buildchar[i] = 0;
1910             }
1911           }
1912           break;
1913 
1914         case cff_op_blend:
1915           /* this operator was removed from the Type2 specification */
1916           /* in version 16-March-2000                               */

1917           {
1918             FT_Int  num_results = (FT_Int)( args[0] >> 16 );
1919 
1920 
1921             FT_TRACE4(( " blend\n" ));
1922 
1923             if ( num_results < 0 )
1924               goto Syntax_Error;
1925 
1926             if ( num_results * (FT_Int)num_designs > num_args )

1927               goto Stack_Underflow;
1928 
1929             /* since we currently don't handle interpolation of multiple */
1930             /* master fonts, return the `num_results' values of the      */
1931             /* first master                                              */
1932             args     -= num_results * ( num_designs - 1 );
1933             num_args -= num_results * ( num_designs - 1 );
1934           }


1935           break;
1936 
1937         case cff_op_dotsection:
1938           /* this operator is deprecated and ignored by the parser */
1939           FT_TRACE4(( " dotsection\n" ));
1940           break;
1941 
1942         case cff_op_closepath:
1943           /* this is an invalid Type 2 operator; however, there        */
1944           /* exist fonts which are incorrectly converted from probably */
1945           /* Type 1 to CFF, and some parsers seem to accept it         */
1946 
1947           FT_TRACE4(( " closepath (invalid op)\n" ));
1948 
1949           args = stack;
1950           break;
1951 
1952         case cff_op_hsbw:
1953           /* this is an invalid Type 2 operator; however, there        */
1954           /* exist fonts which are incorrectly converted from probably */


1981           decoder->builder.left_bearing.y = args[1];
1982 
1983           x    = ADD_LONG( decoder->builder.pos_x, args[0] );
1984           y    = ADD_LONG( decoder->builder.pos_y, args[1] );
1985           args = stack;
1986           break;
1987 
1988         case cff_op_setcurrentpoint:
1989           /* this is an invalid Type 2 operator; however, there        */
1990           /* exist fonts which are incorrectly converted from probably */
1991           /* Type 1 to CFF, and some parsers seem to accept it         */
1992 
1993           FT_TRACE4(( " setcurrentpoint (invalid op)\n" ));
1994 
1995           x    = ADD_LONG( decoder->builder.pos_x, args[0] );
1996           y    = ADD_LONG( decoder->builder.pos_y, args[1] );
1997           args = stack;
1998           break;
1999 
2000         case cff_op_callothersubr:




2001           /* this is an invalid Type 2 operator; however, there        */
2002           /* exist fonts which are incorrectly converted from probably */
2003           /* Type 1 to CFF, and some parsers seem to accept it         */

2004 
2005           FT_TRACE4(( " callothersubr (invalid op)\n" ));
2006 
2007           /* subsequent `pop' operands should add the arguments,       */
2008           /* this is the implementation described for `unknown' other  */
2009           /* subroutines in the Type1 spec.                            */
2010           /*                                                           */
2011           /* XXX Fix return arguments (see discussion below).          */
2012           args -= 2 + ( args[-2] >> 16 );





2013           if ( args < stack )
2014             goto Stack_Underflow;

2015           break;
2016 
2017         case cff_op_pop:
2018           /* this is an invalid Type 2 operator; however, there        */
2019           /* exist fonts which are incorrectly converted from probably */
2020           /* Type 1 to CFF, and some parsers seem to accept it         */
2021 
2022           FT_TRACE4(( " pop (invalid op)\n" ));
2023 
2024           /* XXX Increasing `args' is wrong: After a certain number of */
2025           /* `pop's we get a stack overflow.  Reason for doing it is   */
2026           /* code like this (actually found in a CFF font):            */
2027           /*                                                           */
2028           /*   17 1 3 callothersubr                                    */
2029           /*   pop                                                     */
2030           /*   callsubr                                                */
2031           /*                                                           */
2032           /* Since we handle `callothersubr' as a no-op, and           */
2033           /* `callsubr' needs at least one argument, `pop' can't be a  */
2034           /* no-op too as it basically should be.                      */


2234     FT_TRACE4(( "cff_decoder_parse_charstrings:"
2235                 " invalid opcode found in top DICT charstring\n"));
2236     return FT_THROW( Invalid_File_Format );
2237 
2238   Syntax_Error:
2239     FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" ));
2240     return FT_THROW( Invalid_File_Format );
2241 
2242   Stack_Underflow:
2243     FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" ));
2244     return FT_THROW( Too_Few_Arguments );
2245 
2246   Stack_Overflow:
2247     FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" ));
2248     return FT_THROW( Stack_Overflow );
2249   }
2250 
2251 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
2252 
2253 
2254   /*************************************************************************/
2255   /*                                                                       */
2256   /* <Function>                                                            */
2257   /*    cff_decoder_init                                                   */
2258   /*                                                                       */
2259   /* <Description>                                                         */
2260   /*    Initializes a given glyph decoder.                                 */
2261   /*                                                                       */
2262   /* <InOut>                                                               */
2263   /*    decoder :: A pointer to the glyph builder to initialize.           */
2264   /*                                                                       */
2265   /* <Input>                                                               */
2266   /*    face      :: The current face object.                              */
2267   /*                                                                       */
2268   /*    size      :: The current size object.                              */
2269   /*                                                                       */
2270   /*    slot      :: The current glyph object.                             */
2271   /*                                                                       */
2272   /*    hinting   :: Whether hinting is active.                            */
2273   /*                                                                       */
2274   /*    hint_mode :: The hinting mode.                                     */
2275   /*                                                                       */






2276   FT_LOCAL_DEF( void )
2277   cff_decoder_init( CFF_Decoder*                     decoder,
2278                     TT_Face                          face,
2279                     CFF_Size                         size,
2280                     CFF_GlyphSlot                    slot,
2281                     FT_Bool                          hinting,
2282                     FT_Render_Mode                   hint_mode,
2283                     CFF_Decoder_Get_Glyph_Callback   get_callback,
2284                     CFF_Decoder_Free_Glyph_Callback  free_callback )
2285   {
2286     CFF_Font  cff = (CFF_Font)face->extra.data;
2287 
2288 
2289     /* clear everything */
2290     FT_ZERO( decoder );
2291 
2292     /* initialize builder */
2293     cff_builder_init( &decoder->builder, face, size, slot, hinting );
2294 
2295     /* initialize Type2 decoder */


   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,


 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 )


 361 
 362   Exit:
 363     return error;
 364   }
 365 
 366 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
 367 
 368 
 369   /*************************************************************************/
 370   /*************************************************************************/
 371   /*************************************************************************/
 372   /**********                                                      *********/
 373   /**********                                                      *********/
 374   /**********             GENERIC CHARSTRING PARSING               *********/
 375   /**********                                                      *********/
 376   /**********                                                      *********/
 377   /*************************************************************************/
 378   /*************************************************************************/
 379   /*************************************************************************/
 380 
 381   /**************************************************************************
 382    *
 383    * @Function:
 384    *   cff_compute_bias
 385    *
 386    * @Description:
 387    *   Computes the bias value in dependence of the number of glyph
 388    *   subroutines.
 389    *
 390    * @Input:
 391    *   in_charstring_type ::
 392    *     The `CharstringType' value of the top DICT
 393    *     dictionary.
 394    *
 395    *   num_subrs ::
 396    *     The number of glyph subroutines.
 397    *
 398    * @Return:
 399    *   The bias value.
 400    */
 401   static FT_Int
 402   cff_compute_bias( FT_Int   in_charstring_type,
 403                     FT_UInt  num_subrs )
 404   {
 405     FT_Int  result;
 406 
 407 
 408     if ( in_charstring_type == 1 )
 409       result = 0;
 410     else if ( num_subrs < 1240 )
 411       result = 107;
 412     else if ( num_subrs < 33900U )
 413       result = 1131;
 414     else
 415       result = 32768U;
 416 
 417     return result;
 418   }
 419 
 420 


 450     }
 451 #endif
 452 
 453     cffload = (FT_Service_CFFLoad)cff->cffload;
 454 
 455     /* Get code to SID mapping from `cff_standard_encoding'. */
 456     glyph_sid = cffload->get_standard_encoding( (FT_UInt)charcode );
 457 
 458     for ( n = 0; n < cff->num_glyphs; n++ )
 459     {
 460       if ( cff->charset.sids[n] == glyph_sid )
 461         return (FT_Int)n;
 462     }
 463 
 464     return -1;
 465   }
 466 
 467 
 468 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
 469 
 470   /**************************************************************************
 471    *
 472    * @Function:
 473    *   cff_decoder_parse_charstrings
 474    *
 475    * @Description:
 476    *   Parses a given Type 2 charstrings program.
 477    *
 478    * @InOut:
 479    *   decoder ::
 480    *     The current Type 1 decoder.
 481    *
 482    * @Input:
 483    *   charstring_base ::
 484    *     The base of the charstring stream.
 485    *
 486    *   charstring_len ::
 487    *     The length in bytes of the charstring stream.
 488    *
 489    *   in_dict ::
 490    *     Set to 1 if function is called from top or
 491    *     private DICT (needed for Multiple Master CFFs).
 492    *
 493    * @Return:
 494    *   FreeType error code.  0 means success.
 495    */
 496   FT_LOCAL_DEF( FT_Error )
 497   cff_decoder_parse_charstrings( CFF_Decoder*  decoder,
 498                                  FT_Byte*      charstring_base,
 499                                  FT_ULong      charstring_len,
 500                                  FT_Bool       in_dict )
 501   {
 502     FT_Error           error;
 503     CFF_Decoder_Zone*  zone;
 504     FT_Byte*           ip;
 505     FT_Byte*           limit;
 506     CFF_Builder*       builder = &decoder->builder;
 507     FT_Pos             x, y;
 508     FT_Fixed*          stack;
 509     FT_Int             charstring_type =
 510                          decoder->cff->top_font.font_dict.charstring_type;
 511     FT_UShort          num_designs =
 512                          decoder->cff->top_font.font_dict.num_designs;
 513     FT_UShort          num_axes =
 514                          decoder->cff->top_font.font_dict.num_axes;
 515 


 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;


 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.                                         */


 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.                                     */


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] );


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             {


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" ));


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:


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];


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 */


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.                      */


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 )
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 */


< prev index next >