< prev index next >

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

Print this page


   1 /***************************************************************************/
   2 /*                                                                         */
   3 /*  t1decode.c                                                             */
   4 /*                                                                         */
   5 /*    PostScript Type 1 decoding routines (body).                          */
   6 /*                                                                         */
   7 /*  Copyright 2000-2018 by                                                 */
   8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
   9 /*                                                                         */
  10 /*  This file is part of the FreeType project, and may only be used,       */
  11 /*  modified, and distributed under the terms of the FreeType project      */
  12 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  13 /*  this file you indicate that you have read the license and              */
  14 /*  understand and accept it fully.                                        */
  15 /*                                                                         */
  16 /***************************************************************************/
  17 
  18 
  19 #include <ft2build.h>
  20 #include FT_INTERNAL_CALC_H
  21 #include FT_INTERNAL_DEBUG_H
  22 #include FT_INTERNAL_POSTSCRIPT_HINTS_H
  23 #include FT_INTERNAL_HASH_H
  24 #include FT_OUTLINE_H
  25 
  26 #include "t1decode.h"
  27 #include "psobjs.h"
  28 
  29 #include "psauxerr.h"
  30 
  31 /* ensure proper sign extension */
  32 #define Fix2Int( f )  ( (FT_Int)(FT_Short)( (f) >> 16 ) )
  33 
  34   /*************************************************************************/
  35   /*                                                                       */
  36   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
  37   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
  38   /* messages during execution.                                            */
  39   /*                                                                       */
  40 #undef  FT_COMPONENT
  41 #define FT_COMPONENT  trace_t1decode
  42 
  43 
  44   typedef enum  T1_Operator_
  45   {
  46     op_none = 0,
  47     op_endchar,
  48     op_hsbw,
  49     op_seac,
  50     op_sbw,
  51     op_closepath,
  52     op_hlineto,
  53     op_hmoveto,
  54     op_hvcurveto,
  55     op_rlineto,
  56     op_rmoveto,
  57     op_rrcurveto,
  58     op_vhcurveto,
  59     op_vlineto,
  60     op_vmoveto,
  61     op_dotsection,


  92     2, /* rmoveto */
  93     6, /* rrcurveto */
  94     4, /* vhcurveto */
  95     1, /* vlineto */
  96     1, /* vmoveto */
  97     0, /* dotsection */
  98     2, /* hstem */
  99     6, /* hstem3 */
 100     2, /* vstem */
 101     6, /* vstem3 */
 102     2, /* div */
 103    -1, /* callothersubr */
 104     1, /* callsubr */
 105     0, /* pop */
 106     0, /* return */
 107     2, /* setcurrentpoint */
 108     2  /* opcode 15 (undocumented and obsolete) */
 109   };
 110 
 111 
 112   /*************************************************************************/
 113   /*                                                                       */
 114   /* <Function>                                                            */
 115   /*    t1_lookup_glyph_by_stdcharcode_ps                                  */
 116   /*                                                                       */
 117   /* <Description>                                                         */
 118   /*    Looks up a given glyph by its StandardEncoding charcode.  Used to  */
 119   /*    implement the SEAC Type 1 operator in the Adobe engine             */
 120   /*                                                                       */
 121   /* <Input>                                                               */
 122   /*    face     :: The current face object.                               */
 123   /*                                                                       */
 124   /*    charcode :: The character code to look for.                        */
 125   /*                                                                       */
 126   /* <Return>                                                              */
 127   /*    A glyph index in the font face.  Returns -1 if the corresponding   */
 128   /*    glyph wasn't found.                                                */
 129   /*                                                                       */


 130   FT_LOCAL_DEF( FT_Int )
 131   t1_lookup_glyph_by_stdcharcode_ps( PS_Decoder*  decoder,
 132                                      FT_Int       charcode )
 133   {
 134     FT_UInt             n;
 135     const FT_String*    glyph_name;
 136     FT_Service_PsCMaps  psnames = decoder->psnames;
 137 
 138 
 139     /* check range of standard char code */
 140     if ( charcode < 0 || charcode > 255 )
 141       return -1;
 142 
 143     glyph_name = psnames->adobe_std_strings(
 144                    psnames->adobe_std_encoding[charcode]);
 145 
 146     for ( n = 0; n < decoder->num_glyphs; n++ )
 147     {
 148       FT_String*  name = (FT_String*)decoder->glyph_names[n];
 149 
 150 
 151       if ( name                               &&
 152            name[0] == glyph_name[0]           &&
 153            ft_strcmp( name, glyph_name ) == 0 )
 154         return (FT_Int)n;
 155     }
 156 
 157     return -1;
 158   }
 159 
 160 
 161 #ifdef T1_CONFIG_OPTION_OLD_ENGINE
 162   /*************************************************************************/
 163   /*                                                                       */
 164   /* <Function>                                                            */
 165   /*    t1_lookup_glyph_by_stdcharcode                                     */
 166   /*                                                                       */
 167   /* <Description>                                                         */
 168   /*    Looks up a given glyph by its StandardEncoding charcode.  Used to  */
 169   /*    implement the SEAC Type 1 operator.                                */
 170   /*                                                                       */
 171   /* <Input>                                                               */
 172   /*    face     :: The current face object.                               */
 173   /*                                                                       */
 174   /*    charcode :: The character code to look for.                        */
 175   /*                                                                       */
 176   /* <Return>                                                              */
 177   /*    A glyph index in the font face.  Returns -1 if the corresponding   */
 178   /*    glyph wasn't found.                                                */
 179   /*                                                                       */



 180   static FT_Int
 181   t1_lookup_glyph_by_stdcharcode( T1_Decoder  decoder,
 182                                   FT_Int      charcode )
 183   {
 184     FT_UInt             n;
 185     const FT_String*    glyph_name;
 186     FT_Service_PsCMaps  psnames = decoder->psnames;
 187 
 188 
 189     /* check range of standard char code */
 190     if ( charcode < 0 || charcode > 255 )
 191       return -1;
 192 
 193     glyph_name = psnames->adobe_std_strings(
 194                    psnames->adobe_std_encoding[charcode]);
 195 
 196     for ( n = 0; n < decoder->num_glyphs; n++ )
 197     {
 198       FT_String*  name = (FT_String*)decoder->glyph_names[n];
 199 
 200 
 201       if ( name                               &&
 202            name[0] == glyph_name[0]           &&
 203            ft_strcmp( name, glyph_name ) == 0 )
 204         return (FT_Int)n;
 205     }
 206 
 207     return -1;
 208   }
 209 
 210 
 211   /* parse a single Type 1 glyph */
 212   FT_LOCAL_DEF( FT_Error )
 213   t1_decoder_parse_glyph( T1_Decoder  decoder,
 214                           FT_UInt     glyph )
 215   {
 216     return decoder->parse_callback( decoder, glyph );
 217   }
 218 
 219 
 220   /*************************************************************************/
 221   /*                                                                       */
 222   /* <Function>                                                            */
 223   /*    t1operator_seac                                                    */
 224   /*                                                                       */
 225   /* <Description>                                                         */
 226   /*    Implements the `seac' Type 1 operator for a Type 1 decoder.        */
 227   /*                                                                       */
 228   /* <Input>                                                               */
 229   /*    decoder :: The current CID decoder.                                */
 230   /*                                                                       */
 231   /*    asb     :: The accent's side bearing.                              */
 232   /*                                                                       */
 233   /*    adx     :: The horizontal offset of the accent.                    */
 234   /*                                                                       */
 235   /*    ady     :: The vertical offset of the accent.                      */
 236   /*                                                                       */
 237   /*    bchar   :: The base character's StandardEncoding charcode.         */
 238   /*                                                                       */
 239   /*    achar   :: The accent character's StandardEncoding charcode.       */
 240   /*                                                                       */
 241   /* <Return>                                                              */
 242   /*    FreeType error code.  0 means success.                             */
 243   /*                                                                       */






 244   static FT_Error
 245   t1operator_seac( T1_Decoder  decoder,
 246                    FT_Pos      asb,
 247                    FT_Pos      adx,
 248                    FT_Pos      ady,
 249                    FT_Int      bchar,
 250                    FT_Int      achar )
 251   {
 252     FT_Error     error;
 253     FT_Int       bchar_index, achar_index;
 254 #if 0
 255     FT_Int       n_base_points;
 256     FT_Outline*  base = decoder->builder.base;
 257 #endif
 258     FT_Vector    left_bearing, advance;
 259 
 260 #ifdef FT_CONFIG_OPTION_INCREMENTAL
 261     T1_Face      face  = (T1_Face)decoder->builder.face;
 262 #endif
 263 


 382     decoder->seac = TRUE;
 383     error = t1_decoder_parse_glyph( decoder, (FT_UInt)achar_index );
 384     decoder->seac = FALSE;
 385     if ( error )
 386       goto Exit;
 387 
 388     /* restore the left side bearing and   */
 389     /* advance width of the base character */
 390 
 391     decoder->builder.left_bearing = left_bearing;
 392     decoder->builder.advance      = advance;
 393 
 394     decoder->builder.pos_x = 0;
 395     decoder->builder.pos_y = 0;
 396 
 397   Exit:
 398     return error;
 399   }
 400 
 401 
 402   /*************************************************************************/
 403   /*                                                                       */
 404   /* <Function>                                                            */
 405   /*    t1_decoder_parse_charstrings                                       */
 406   /*                                                                       */
 407   /* <Description>                                                         */
 408   /*    Parses a given Type 1 charstrings program.                         */
 409   /*                                                                       */
 410   /* <Input>                                                               */
 411   /*    decoder         :: The current Type 1 decoder.                     */
 412   /*                                                                       */
 413   /*    charstring_base :: The base address of the charstring stream.      */
 414   /*                                                                       */
 415   /*    charstring_len  :: The length in bytes of the charstring stream.   */
 416   /*                                                                       */
 417   /* <Return>                                                              */
 418   /*    FreeType error code.  0 means success.                             */
 419   /*                                                                       */



 420   FT_LOCAL_DEF( FT_Error )
 421   t1_decoder_parse_charstrings( T1_Decoder  decoder,
 422                                 FT_Byte*    charstring_base,
 423                                 FT_UInt     charstring_len )
 424   {
 425     FT_Error         error;
 426     T1_Decoder_Zone  zone;
 427     FT_Byte*         ip;
 428     FT_Byte*         limit;
 429     T1_Builder       builder = &decoder->builder;
 430     FT_Pos           x, y, orig_x, orig_y;
 431     FT_Int           known_othersubr_result_cnt   = 0;
 432     FT_Int           unknown_othersubr_result_cnt = 0;
 433     FT_Bool          large_int;
 434     FT_Fixed         seed;
 435 
 436     T1_Hints_Funcs   hinter;
 437 
 438 #ifdef FT_DEBUG_LEVEL_TRACE
 439     FT_Bool          bol = TRUE;


 449     if ( seed == 0 )
 450       seed = 0x7384;
 451 
 452     /* First of all, initialize the decoder */
 453     decoder->top  = decoder->stack;
 454     decoder->zone = decoder->zones;
 455     zone          = decoder->zones;
 456 
 457     builder->parse_state = T1_Parse_Start;
 458 
 459     hinter = (T1_Hints_Funcs)builder->hints_funcs;
 460 
 461     /* a font that reads BuildCharArray without setting */
 462     /* its values first is buggy, but ...               */
 463     FT_ASSERT( ( decoder->len_buildchar == 0 ) ==
 464                ( decoder->buildchar == NULL )  );
 465 
 466     if ( decoder->buildchar && decoder->len_buildchar > 0 )
 467       FT_ARRAY_ZERO( decoder->buildchar, decoder->len_buildchar );
 468 
 469     FT_TRACE4(( "\n"
 470                 "Start charstring\n" ));
 471 
 472     zone->base           = charstring_base;
 473     limit = zone->limit  = charstring_base + charstring_len;
 474     ip    = zone->cursor = zone->base;
 475 
 476     error = FT_Err_Ok;
 477 
 478     x = orig_x = builder->pos_x;
 479     y = orig_y = builder->pos_y;
 480 
 481     /* begin hints recording session, if any */
 482     if ( hinter )
 483       hinter->open( hinter->hints );
 484 
 485     large_int = FALSE;
 486 
 487     /* now, execute loop */
 488     while ( ip < limit )
 489     {
 490       FT_Long*     top   = decoder->top;
 491       T1_Operator  op    = op_none;
 492       FT_Int32     value = 0;
 493 
 494 
 495       FT_ASSERT( known_othersubr_result_cnt == 0   ||
 496                  unknown_othersubr_result_cnt == 0 );
 497 
 498 #ifdef FT_DEBUG_LEVEL_TRACE
 499       if ( bol )
 500       {
 501         FT_TRACE5(( " (%d)", decoder->top - decoder->stack ));
 502         bol = FALSE;
 503       }
 504 #endif
 505 
 506       /*********************************************************************/
 507       /*                                                                   */
 508       /* Decode operator or operand                                        */
 509       /*                                                                   */
 510       /*                                                                   */
 511 
 512       /* first of all, decompress operator or value */
 513       switch ( *ip++ )
 514       {
 515       case 1:
 516         op = op_hstem;
 517         break;
 518 
 519       case 3:
 520         op = op_vstem;
 521         break;
 522       case 4:
 523         op = op_vmoveto;
 524         break;
 525       case 5:
 526         op = op_rlineto;
 527         break;
 528       case 6:
 529         op = op_hlineto;
 530         break;


 693         case op_return:
 694         case op_none:
 695         case op_pop:
 696           break;
 697 
 698         default:
 699           /* all operands have been transferred by previous pops */
 700           unknown_othersubr_result_cnt = 0;
 701           break;
 702         }
 703       }
 704 
 705       if ( large_int && !( op == op_none || op == op_div ) )
 706       {
 707         FT_ERROR(( "t1_decoder_parse_charstrings:"
 708                    " no `div' after large integer\n" ));
 709 
 710         large_int = FALSE;
 711       }
 712 
 713       /*********************************************************************/
 714       /*                                                                   */
 715       /*  Push value on stack, or process operator                         */
 716       /*                                                                   */
 717       /*                                                                   */
 718       if ( op == op_none )
 719       {
 720         if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS )
 721         {
 722           FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow\n" ));
 723           goto Syntax_Error;
 724         }
 725 
 726 #ifdef FT_DEBUG_LEVEL_TRACE
 727         if ( large_int )
 728           FT_TRACE4(( " %d", value ));
 729         else
 730           FT_TRACE4(( " %d", value / 65536 ));
 731 #endif
 732 
 733         *top++       = value;
 734         decoder->top = top;
 735       }
 736       else if ( op == op_callothersubr )  /* callothersubr */
 737       {
 738         FT_Int  subr_no;
 739         FT_Int  arg_cnt;
 740 
 741 
 742 #ifdef FT_DEBUG_LEVEL_TRACE
 743         FT_TRACE4(( " callothersubr\n" ));
 744         bol = TRUE;
 745 #endif
 746 
 747         if ( top - decoder->stack < 2 )
 748           goto Stack_Underflow;
 749 
 750         top -= 2;
 751 
 752         subr_no = Fix2Int( top[1] );
 753         arg_cnt = Fix2Int( top[0] );
 754 
 755         /***********************************************************/
 756         /*                                                         */
 757         /* remove all operands to callothersubr from the stack     */
 758         /*                                                         */
 759         /* for handled othersubrs, where we know the number of     */
 760         /* arguments, we increase the stack by the value of        */
 761         /* known_othersubr_result_cnt                              */
 762         /*                                                         */
 763         /* for unhandled othersubrs the following pops adjust the  */
 764         /* stack pointer as necessary                              */

 765 
 766         if ( arg_cnt > top - decoder->stack )
 767           goto Stack_Underflow;
 768 
 769         top -= arg_cnt;
 770 
 771         known_othersubr_result_cnt   = 0;
 772         unknown_othersubr_result_cnt = 0;
 773 
 774         /* XXX TODO: The checks to `arg_count == <whatever>'       */
 775         /* might not be correct; an othersubr expects a certain    */
 776         /* number of operands on the PostScript stack (as opposed  */
 777         /* to the T1 stack) but it doesn't have to put them there  */
 778         /* by itself; previous othersubrs might have left the      */
 779         /* operands there if they were not followed by an          */
 780         /* appropriate number of pops                              */
 781         /*                                                         */
 782         /* On the other hand, Adobe Reader 7.0.8 for Linux doesn't */
 783         /* accept a font that contains charstrings like            */
 784         /*                                                         */


1206         case op_hsbw:
1207           FT_TRACE4(( " hsbw" ));
1208 
1209           builder->parse_state = T1_Parse_Have_Width;
1210 
1211           builder->left_bearing.x = ADD_LONG( builder->left_bearing.x,
1212                                               top[0] );
1213 
1214           builder->advance.x = top[1];
1215           builder->advance.y = 0;
1216 
1217           orig_x = x = ADD_LONG( builder->pos_x, top[0] );
1218           orig_y = y = builder->pos_y;
1219 
1220           FT_UNUSED( orig_y );
1221 
1222           /* the `metrics_only' indicates that we only want to compute */
1223           /* the glyph's metrics (lsb + advance width), not load the   */
1224           /* rest of it; so exit immediately                           */
1225           if ( builder->metrics_only )


1226             return FT_Err_Ok;

1227 
1228           break;
1229 
1230         case op_seac:
1231           return t1operator_seac( decoder,
1232                                   top[0],
1233                                   top[1],
1234                                   top[2],
1235                                   Fix2Int( top[3] ),
1236                                   Fix2Int( top[4] ) );
1237 
1238         case op_sbw:
1239           FT_TRACE4(( " sbw" ));
1240 
1241           builder->parse_state = T1_Parse_Have_Width;
1242 
1243           builder->left_bearing.x = ADD_LONG( builder->left_bearing.x,
1244                                               top[0] );
1245           builder->left_bearing.y = ADD_LONG( builder->left_bearing.y,
1246                                               top[1] );
1247 
1248           builder->advance.x = top[2];
1249           builder->advance.y = top[3];
1250 
1251           x = ADD_LONG( builder->pos_x, top[0] );
1252           y = ADD_LONG( builder->pos_y, top[1] );
1253 
1254           /* the `metrics_only' indicates that we only want to compute */
1255           /* the glyph's metrics (lsb + advance width), not load the   */
1256           /* rest of it; so exit immediately                           */
1257           if ( builder->metrics_only )


1258             return FT_Err_Ok;

1259 
1260           break;
1261 
1262         case op_closepath:
1263           FT_TRACE4(( " closepath" ));
1264 
1265           /* if there is no path, `closepath' is a no-op */
1266           if ( builder->parse_state == T1_Parse_Have_Path   ||
1267                builder->parse_state == T1_Parse_Have_Moveto )
1268             t1_builder_close_contour( builder );
1269 
1270           builder->parse_state = T1_Parse_Have_Width;
1271           break;
1272 
1273         case op_hlineto:
1274           FT_TRACE4(( " hlineto" ));
1275 
1276           if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) )
1277             goto Fail;
1278 


1621         FT_TRACE4(( "\n" ));
1622         bol = TRUE;
1623 #endif
1624 
1625       } /* general operator processing */
1626 
1627     } /* while ip < limit */
1628 
1629     FT_TRACE4(( "..end..\n\n" ));
1630 
1631   Fail:
1632     return error;
1633 
1634   Syntax_Error:
1635     return FT_THROW( Syntax_Error );
1636 
1637   Stack_Underflow:
1638     return FT_THROW( Stack_Underflow );
1639   }
1640 
1641 #else /* T1_CONFIG_OPTION_OLD_ENGINE */
1642 
1643   /*************************************************************************/
1644   /*                                                                       */
1645   /* <Function>                                                            */
1646   /*    t1_decoder_parse_metrics                                           */
1647   /*                                                                       */
1648   /* <Description>                                                         */
1649   /*    Parses a given Type 1 charstrings program to extract width         */
1650   /*                                                                       */
1651   /* <Input>                                                               */
1652   /*    decoder         :: The current Type 1 decoder.                     */
1653   /*                                                                       */
1654   /*    charstring_base :: The base address of the charstring stream.      */
1655   /*                                                                       */
1656   /*    charstring_len  :: The length in bytes of the charstring stream.   */
1657   /*                                                                       */
1658   /* <Return>                                                              */
1659   /*    FreeType error code.  0 means success.                             */
1660   /*                                                                       */






1661   FT_LOCAL_DEF( FT_Error )
1662   t1_decoder_parse_metrics( T1_Decoder  decoder,
1663                             FT_Byte*    charstring_base,
1664                             FT_UInt     charstring_len )
1665   {
1666     T1_Decoder_Zone  zone;
1667     FT_Byte*         ip;
1668     FT_Byte*         limit;
1669     T1_Builder       builder = &decoder->builder;
1670 
1671 #ifdef FT_DEBUG_LEVEL_TRACE
1672     FT_Bool          bol = TRUE;
1673 #endif
1674 
1675 
1676     /* First of all, initialize the decoder */
1677     decoder->top  = decoder->stack;
1678     decoder->zone = decoder->zones;
1679     zone          = decoder->zones;
1680 
1681     builder->parse_state = T1_Parse_Start;
1682 
1683     FT_TRACE4(( "\n"
1684                 "Start charstring: get width\n" ));
1685 
1686     zone->base           = charstring_base;
1687     limit = zone->limit  = charstring_base + charstring_len;
1688     ip    = zone->cursor = zone->base;
1689 
1690     /* now, execute loop */
1691     while ( ip < limit )
1692     {
1693       FT_Long*     top   = decoder->top;
1694       T1_Operator  op    = op_none;
1695       FT_Int32     value = 0;
1696 
1697 
1698 #ifdef FT_DEBUG_LEVEL_TRACE
1699       if ( bol )
1700       {
1701         FT_TRACE5(( " (%d)", decoder->top - decoder->stack ));
1702         bol = FALSE;
1703       }
1704 #endif
1705 
1706       /*********************************************************************/
1707       /*                                                                   */
1708       /* Decode operator or operand                                        */
1709       /*                                                                   */
1710       /*                                                                   */
1711 
1712       /* first of all, decompress operator or value */
1713       switch ( *ip++ )
1714       {
1715       case 1:
1716       case 3:
1717       case 4:
1718       case 5:
1719       case 6:
1720       case 7:
1721       case 8:
1722       case 9:
1723       case 10:
1724       case 11:
1725       case 14:
1726       case 15:
1727       case 21:
1728       case 22:
1729       case 30:
1730       case 31:


1800                          " unexpected EOF in integer\n" ));
1801               goto Syntax_Error;
1802             }
1803 
1804             if ( ip[-2] < 251 )
1805               value =    ( ( ip[-2] - 247 ) * 256 ) + ip[-1] + 108;
1806             else
1807               value = -( ( ( ip[-2] - 251 ) * 256 ) + ip[-1] + 108 );
1808           }
1809 
1810           value = (FT_Int32)( (FT_UInt32)value << 16 );
1811         }
1812         else
1813         {
1814           FT_ERROR(( "t1_decoder_parse_metrics:"
1815                      " invalid byte (%d)\n", ip[-1] ));
1816           goto Syntax_Error;
1817         }
1818       }
1819 
1820       /*********************************************************************/
1821       /*                                                                   */
1822       /*  Push value on stack, or process operator                         */
1823       /*                                                                   */
1824       /*                                                                   */
1825       if ( op == op_none )
1826       {
1827         if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS )
1828         {
1829           FT_ERROR(( "t1_decoder_parse_metrics: stack overflow\n" ));
1830           goto Syntax_Error;
1831         }
1832 
1833 #ifdef FT_DEBUG_LEVEL_TRACE
1834           FT_TRACE4(( " %d", value / 65536 ));
1835 #endif
1836 
1837         *top++       = value;
1838         decoder->top = top;
1839       }
1840       else  /* general operator */
1841       {
1842         FT_Int  num_args = t1_args_count[op];
1843 
1844 


1858 #endif /* FT_DEBUG_LEVEL_TRACE */
1859 
1860         top -= num_args;
1861 
1862         switch ( op )
1863         {
1864         case op_hsbw:
1865           FT_TRACE4(( " hsbw" ));
1866 
1867           builder->parse_state = T1_Parse_Have_Width;
1868 
1869           builder->left_bearing.x = ADD_LONG( builder->left_bearing.x,
1870                                               top[0] );
1871 
1872           builder->advance.x = top[1];
1873           builder->advance.y = 0;
1874 
1875           /* we only want to compute the glyph's metrics */
1876           /* (lsb + advance width), not load the rest of */
1877           /* it; so exit immediately                     */

1878           return FT_Err_Ok;
1879 
1880         case op_sbw:
1881           FT_TRACE4(( " sbw" ));
1882 
1883           builder->parse_state = T1_Parse_Have_Width;
1884 
1885           builder->left_bearing.x = ADD_LONG( builder->left_bearing.x,
1886                                               top[0] );
1887           builder->left_bearing.y = ADD_LONG( builder->left_bearing.y,
1888                                               top[1] );
1889 
1890           builder->advance.x = top[2];
1891           builder->advance.y = top[3];
1892 
1893           /* we only want to compute the glyph's metrics */
1894           /* (lsb + advance width), not load the rest of */
1895           /* it; so exit immediately                     */

1896           return FT_Err_Ok;
1897 
1898         default:
1899           FT_ERROR(( "t1_decoder_parse_metrics:"
1900                      " unhandled opcode %d\n", op ));
1901           goto Syntax_Error;
1902         }
1903 
1904       } /* general operator processing */
1905 
1906     } /* while ip < limit */
1907 
1908     FT_TRACE4(( "..end..\n\n" ));
1909 
1910   No_Width:
1911     FT_ERROR(( "t1_decoder_parse_metrics:"
1912                " no width, found op %d instead\n",
1913                ip[-1] ));
1914   Syntax_Error:
1915     return FT_THROW( Syntax_Error );
1916 
1917   Stack_Underflow:
1918     return FT_THROW( Stack_Underflow );
1919   }
1920 #endif /* T1_CONFIG_OPTION_OLD_ENGINE */

1921 
1922 
1923   /* initialize T1 decoder */
1924   FT_LOCAL_DEF( FT_Error )
1925   t1_decoder_init( T1_Decoder           decoder,
1926                    FT_Face              face,
1927                    FT_Size              size,
1928                    FT_GlyphSlot         slot,
1929                    FT_Byte**            glyph_names,
1930                    PS_Blend             blend,
1931                    FT_Bool              hinting,
1932                    FT_Render_Mode       hint_mode,
1933                    T1_Decoder_Callback  parse_callback )
1934   {
1935     FT_ZERO( decoder );
1936 
1937     /* retrieve PSNames interface from list of current modules */
1938     {
1939       FT_Service_PsCMaps  psnames;
1940 
1941 
1942       FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
1943       if ( !psnames )
1944       {
1945         FT_ERROR(( "t1_decoder_init:"
1946                    " the `psnames' module is not available\n" ));
1947         return FT_THROW( Unimplemented_Feature );
1948       }
1949 
1950       decoder->psnames = psnames;
1951     }
1952 
1953     t1_builder_init( &decoder->builder, face, size, slot, hinting );
1954 
1955     /* decoder->buildchar and decoder->len_buildchar have to be  */
1956     /* initialized by the caller since we cannot know the length */
1957     /* of the BuildCharArray                                     */


   1 /****************************************************************************
   2  *
   3  * t1decode.c
   4  *
   5  *   PostScript Type 1 decoding routines (body).
   6  *
   7  * Copyright (C) 2000-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_INTERNAL_CALC_H
  21 #include FT_INTERNAL_DEBUG_H
  22 #include FT_INTERNAL_POSTSCRIPT_HINTS_H
  23 #include FT_INTERNAL_HASH_H
  24 #include FT_OUTLINE_H
  25 
  26 #include "t1decode.h"
  27 #include "psobjs.h"
  28 
  29 #include "psauxerr.h"
  30 
  31 /* ensure proper sign extension */
  32 #define Fix2Int( f )  ( (FT_Int)(FT_Short)( (f) >> 16 ) )
  33 
  34   /**************************************************************************
  35    *
  36    * The macro FT_COMPONENT is used in trace mode.  It is an implicit
  37    * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
  38    * messages during execution.
  39    */
  40 #undef  FT_COMPONENT
  41 #define FT_COMPONENT  t1decode
  42 
  43 
  44   typedef enum  T1_Operator_
  45   {
  46     op_none = 0,
  47     op_endchar,
  48     op_hsbw,
  49     op_seac,
  50     op_sbw,
  51     op_closepath,
  52     op_hlineto,
  53     op_hmoveto,
  54     op_hvcurveto,
  55     op_rlineto,
  56     op_rmoveto,
  57     op_rrcurveto,
  58     op_vhcurveto,
  59     op_vlineto,
  60     op_vmoveto,
  61     op_dotsection,


  92     2, /* rmoveto */
  93     6, /* rrcurveto */
  94     4, /* vhcurveto */
  95     1, /* vlineto */
  96     1, /* vmoveto */
  97     0, /* dotsection */
  98     2, /* hstem */
  99     6, /* hstem3 */
 100     2, /* vstem */
 101     6, /* vstem3 */
 102     2, /* div */
 103    -1, /* callothersubr */
 104     1, /* callsubr */
 105     0, /* pop */
 106     0, /* return */
 107     2, /* setcurrentpoint */
 108     2  /* opcode 15 (undocumented and obsolete) */
 109   };
 110 
 111 
 112   /**************************************************************************
 113    *
 114    * @Function:
 115    *   t1_lookup_glyph_by_stdcharcode_ps
 116    *
 117    * @Description:
 118    *   Looks up a given glyph by its StandardEncoding charcode.  Used to
 119    *   implement the SEAC Type 1 operator in the Adobe engine
 120    *
 121    * @Input:
 122    *   face ::
 123    *     The current face object.
 124    *
 125    *   charcode ::
 126    *     The character code to look for.
 127    *
 128    * @Return:
 129    *   A glyph index in the font face.  Returns -1 if the corresponding
 130    *   glyph wasn't found.
 131    */
 132   FT_LOCAL_DEF( FT_Int )
 133   t1_lookup_glyph_by_stdcharcode_ps( PS_Decoder*  decoder,
 134                                      FT_Int       charcode )
 135   {
 136     FT_UInt             n;
 137     const FT_String*    glyph_name;
 138     FT_Service_PsCMaps  psnames = decoder->psnames;
 139 
 140 
 141     /* check range of standard char code */
 142     if ( charcode < 0 || charcode > 255 )
 143       return -1;
 144 
 145     glyph_name = psnames->adobe_std_strings(
 146                    psnames->adobe_std_encoding[charcode]);
 147 
 148     for ( n = 0; n < decoder->num_glyphs; n++ )
 149     {
 150       FT_String*  name = (FT_String*)decoder->glyph_names[n];
 151 
 152 
 153       if ( name                               &&
 154            name[0] == glyph_name[0]           &&
 155            ft_strcmp( name, glyph_name ) == 0 )
 156         return (FT_Int)n;
 157     }
 158 
 159     return -1;
 160   }
 161 
 162 
 163 #ifdef T1_CONFIG_OPTION_OLD_ENGINE
 164 
 165   /**************************************************************************
 166    *
 167    * @Function:
 168    *   t1_lookup_glyph_by_stdcharcode
 169    *
 170    * @Description:
 171    *   Looks up a given glyph by its StandardEncoding charcode.  Used to
 172    *   implement the SEAC Type 1 operator.
 173    *
 174    * @Input:
 175    *   face ::
 176    *     The current face object.
 177    *
 178    *   charcode ::
 179    *     The character code to look for.
 180    *
 181    * @Return:
 182    *   A glyph index in the font face.  Returns -1 if the corresponding
 183    *   glyph wasn't found.
 184    */
 185   static FT_Int
 186   t1_lookup_glyph_by_stdcharcode( T1_Decoder  decoder,
 187                                   FT_Int      charcode )
 188   {
 189     FT_UInt             n;
 190     const FT_String*    glyph_name;
 191     FT_Service_PsCMaps  psnames = decoder->psnames;
 192 
 193 
 194     /* check range of standard char code */
 195     if ( charcode < 0 || charcode > 255 )
 196       return -1;
 197 
 198     glyph_name = psnames->adobe_std_strings(
 199                    psnames->adobe_std_encoding[charcode]);
 200 
 201     for ( n = 0; n < decoder->num_glyphs; n++ )
 202     {
 203       FT_String*  name = (FT_String*)decoder->glyph_names[n];
 204 
 205 
 206       if ( name                               &&
 207            name[0] == glyph_name[0]           &&
 208            ft_strcmp( name, glyph_name ) == 0 )
 209         return (FT_Int)n;
 210     }
 211 
 212     return -1;
 213   }
 214 
 215 
 216   /* parse a single Type 1 glyph */
 217   FT_LOCAL_DEF( FT_Error )
 218   t1_decoder_parse_glyph( T1_Decoder  decoder,
 219                           FT_UInt     glyph )
 220   {
 221     return decoder->parse_callback( decoder, glyph );
 222   }
 223 
 224 
 225   /**************************************************************************
 226    *
 227    * @Function:
 228    *   t1operator_seac
 229    *
 230    * @Description:
 231    *   Implements the `seac' Type 1 operator for a Type 1 decoder.
 232    *
 233    * @Input:
 234    *   decoder ::
 235    *     The current CID decoder.
 236    *
 237    *   asb ::
 238    *     The accent's side bearing.
 239    *
 240    *   adx ::
 241    *     The horizontal offset of the accent.
 242    *
 243    *   ady ::
 244    *     The vertical offset of the accent.
 245    *
 246    *   bchar ::
 247    *     The base character's StandardEncoding charcode.
 248    *
 249    *   achar ::
 250    *     The accent character's StandardEncoding charcode.
 251    *
 252    * @Return:
 253    *   FreeType error code.  0 means success.
 254    */
 255   static FT_Error
 256   t1operator_seac( T1_Decoder  decoder,
 257                    FT_Pos      asb,
 258                    FT_Pos      adx,
 259                    FT_Pos      ady,
 260                    FT_Int      bchar,
 261                    FT_Int      achar )
 262   {
 263     FT_Error     error;
 264     FT_Int       bchar_index, achar_index;
 265 #if 0
 266     FT_Int       n_base_points;
 267     FT_Outline*  base = decoder->builder.base;
 268 #endif
 269     FT_Vector    left_bearing, advance;
 270 
 271 #ifdef FT_CONFIG_OPTION_INCREMENTAL
 272     T1_Face      face  = (T1_Face)decoder->builder.face;
 273 #endif
 274 


 393     decoder->seac = TRUE;
 394     error = t1_decoder_parse_glyph( decoder, (FT_UInt)achar_index );
 395     decoder->seac = FALSE;
 396     if ( error )
 397       goto Exit;
 398 
 399     /* restore the left side bearing and   */
 400     /* advance width of the base character */
 401 
 402     decoder->builder.left_bearing = left_bearing;
 403     decoder->builder.advance      = advance;
 404 
 405     decoder->builder.pos_x = 0;
 406     decoder->builder.pos_y = 0;
 407 
 408   Exit:
 409     return error;
 410   }
 411 
 412 
 413   /**************************************************************************
 414    *
 415    * @Function:
 416    *   t1_decoder_parse_charstrings
 417    *
 418    * @Description:
 419    *   Parses a given Type 1 charstrings program.
 420    *
 421    * @Input:
 422    *   decoder ::
 423    *     The current Type 1 decoder.
 424    *
 425    *   charstring_base ::
 426    *     The base address of the charstring stream.
 427    *
 428    *   charstring_len ::
 429    *     The length in bytes of the charstring stream.
 430    *
 431    * @Return:
 432    *   FreeType error code.  0 means success.
 433    */
 434   FT_LOCAL_DEF( FT_Error )
 435   t1_decoder_parse_charstrings( T1_Decoder  decoder,
 436                                 FT_Byte*    charstring_base,
 437                                 FT_UInt     charstring_len )
 438   {
 439     FT_Error         error;
 440     T1_Decoder_Zone  zone;
 441     FT_Byte*         ip;
 442     FT_Byte*         limit;
 443     T1_Builder       builder = &decoder->builder;
 444     FT_Pos           x, y, orig_x, orig_y;
 445     FT_Int           known_othersubr_result_cnt   = 0;
 446     FT_Int           unknown_othersubr_result_cnt = 0;
 447     FT_Bool          large_int;
 448     FT_Fixed         seed;
 449 
 450     T1_Hints_Funcs   hinter;
 451 
 452 #ifdef FT_DEBUG_LEVEL_TRACE
 453     FT_Bool          bol = TRUE;


 463     if ( seed == 0 )
 464       seed = 0x7384;
 465 
 466     /* First of all, initialize the decoder */
 467     decoder->top  = decoder->stack;
 468     decoder->zone = decoder->zones;
 469     zone          = decoder->zones;
 470 
 471     builder->parse_state = T1_Parse_Start;
 472 
 473     hinter = (T1_Hints_Funcs)builder->hints_funcs;
 474 
 475     /* a font that reads BuildCharArray without setting */
 476     /* its values first is buggy, but ...               */
 477     FT_ASSERT( ( decoder->len_buildchar == 0 ) ==
 478                ( decoder->buildchar == NULL )  );
 479 
 480     if ( decoder->buildchar && decoder->len_buildchar > 0 )
 481       FT_ARRAY_ZERO( decoder->buildchar, decoder->len_buildchar );
 482 



 483     zone->base           = charstring_base;
 484     limit = zone->limit  = charstring_base + charstring_len;
 485     ip    = zone->cursor = zone->base;
 486 
 487     error = FT_Err_Ok;
 488 
 489     x = orig_x = builder->pos_x;
 490     y = orig_y = builder->pos_y;
 491 
 492     /* begin hints recording session, if any */
 493     if ( hinter )
 494       hinter->open( hinter->hints );
 495 
 496     large_int = FALSE;
 497 
 498     /* now, execute loop */
 499     while ( ip < limit )
 500     {
 501       FT_Long*     top   = decoder->top;
 502       T1_Operator  op    = op_none;
 503       FT_Int32     value = 0;
 504 
 505 
 506       FT_ASSERT( known_othersubr_result_cnt == 0   ||
 507                  unknown_othersubr_result_cnt == 0 );
 508 
 509 #ifdef FT_DEBUG_LEVEL_TRACE
 510       if ( bol )
 511       {
 512         FT_TRACE5(( " (%d)", decoder->top - decoder->stack ));
 513         bol = FALSE;
 514       }
 515 #endif
 516 
 517       /**********************************************************************
 518        *
 519        * Decode operator or operand
 520        *
 521        */
 522 
 523       /* first of all, decompress operator or value */
 524       switch ( *ip++ )
 525       {
 526       case 1:
 527         op = op_hstem;
 528         break;
 529 
 530       case 3:
 531         op = op_vstem;
 532         break;
 533       case 4:
 534         op = op_vmoveto;
 535         break;
 536       case 5:
 537         op = op_rlineto;
 538         break;
 539       case 6:
 540         op = op_hlineto;
 541         break;


 704         case op_return:
 705         case op_none:
 706         case op_pop:
 707           break;
 708 
 709         default:
 710           /* all operands have been transferred by previous pops */
 711           unknown_othersubr_result_cnt = 0;
 712           break;
 713         }
 714       }
 715 
 716       if ( large_int && !( op == op_none || op == op_div ) )
 717       {
 718         FT_ERROR(( "t1_decoder_parse_charstrings:"
 719                    " no `div' after large integer\n" ));
 720 
 721         large_int = FALSE;
 722       }
 723 
 724       /**********************************************************************
 725        *
 726        * Push value on stack, or process operator
 727        *
 728        */
 729       if ( op == op_none )
 730       {
 731         if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS )
 732         {
 733           FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow\n" ));
 734           goto Syntax_Error;
 735         }
 736 
 737 #ifdef FT_DEBUG_LEVEL_TRACE
 738         if ( large_int )
 739           FT_TRACE4(( " %d", value ));
 740         else
 741           FT_TRACE4(( " %d", value / 65536 ));
 742 #endif
 743 
 744         *top++       = value;
 745         decoder->top = top;
 746       }
 747       else if ( op == op_callothersubr )  /* callothersubr */
 748       {
 749         FT_Int  subr_no;
 750         FT_Int  arg_cnt;
 751 
 752 
 753 #ifdef FT_DEBUG_LEVEL_TRACE
 754         FT_TRACE4(( " callothersubr\n" ));
 755         bol = TRUE;
 756 #endif
 757 
 758         if ( top - decoder->stack < 2 )
 759           goto Stack_Underflow;
 760 
 761         top -= 2;
 762 
 763         subr_no = Fix2Int( top[1] );
 764         arg_cnt = Fix2Int( top[0] );
 765 
 766         /************************************************************
 767          *
 768          * remove all operands to callothersubr from the stack
 769          *
 770          * for handled othersubrs, where we know the number of
 771          * arguments, we increase the stack by the value of
 772          * known_othersubr_result_cnt
 773          *
 774          * for unhandled othersubrs the following pops adjust the
 775          * stack pointer as necessary
 776          */
 777 
 778         if ( arg_cnt > top - decoder->stack )
 779           goto Stack_Underflow;
 780 
 781         top -= arg_cnt;
 782 
 783         known_othersubr_result_cnt   = 0;
 784         unknown_othersubr_result_cnt = 0;
 785 
 786         /* XXX TODO: The checks to `arg_count == <whatever>'       */
 787         /* might not be correct; an othersubr expects a certain    */
 788         /* number of operands on the PostScript stack (as opposed  */
 789         /* to the T1 stack) but it doesn't have to put them there  */
 790         /* by itself; previous othersubrs might have left the      */
 791         /* operands there if they were not followed by an          */
 792         /* appropriate number of pops                              */
 793         /*                                                         */
 794         /* On the other hand, Adobe Reader 7.0.8 for Linux doesn't */
 795         /* accept a font that contains charstrings like            */
 796         /*                                                         */


1218         case op_hsbw:
1219           FT_TRACE4(( " hsbw" ));
1220 
1221           builder->parse_state = T1_Parse_Have_Width;
1222 
1223           builder->left_bearing.x = ADD_LONG( builder->left_bearing.x,
1224                                               top[0] );
1225 
1226           builder->advance.x = top[1];
1227           builder->advance.y = 0;
1228 
1229           orig_x = x = ADD_LONG( builder->pos_x, top[0] );
1230           orig_y = y = builder->pos_y;
1231 
1232           FT_UNUSED( orig_y );
1233 
1234           /* the `metrics_only' indicates that we only want to compute */
1235           /* the glyph's metrics (lsb + advance width), not load the   */
1236           /* rest of it; so exit immediately                           */
1237           if ( builder->metrics_only )
1238           {
1239             FT_TRACE4(( "\n" ));
1240             return FT_Err_Ok;
1241           }
1242 
1243           break;
1244 
1245         case op_seac:
1246           return t1operator_seac( decoder,
1247                                   top[0],
1248                                   top[1],
1249                                   top[2],
1250                                   Fix2Int( top[3] ),
1251                                   Fix2Int( top[4] ) );
1252 
1253         case op_sbw:
1254           FT_TRACE4(( " sbw" ));
1255 
1256           builder->parse_state = T1_Parse_Have_Width;
1257 
1258           builder->left_bearing.x = ADD_LONG( builder->left_bearing.x,
1259                                               top[0] );
1260           builder->left_bearing.y = ADD_LONG( builder->left_bearing.y,
1261                                               top[1] );
1262 
1263           builder->advance.x = top[2];
1264           builder->advance.y = top[3];
1265 
1266           x = ADD_LONG( builder->pos_x, top[0] );
1267           y = ADD_LONG( builder->pos_y, top[1] );
1268 
1269           /* the `metrics_only' indicates that we only want to compute */
1270           /* the glyph's metrics (lsb + advance width), not load the   */
1271           /* rest of it; so exit immediately                           */
1272           if ( builder->metrics_only )
1273           {
1274             FT_TRACE4(( "\n" ));
1275             return FT_Err_Ok;
1276           }
1277 
1278           break;
1279 
1280         case op_closepath:
1281           FT_TRACE4(( " closepath" ));
1282 
1283           /* if there is no path, `closepath' is a no-op */
1284           if ( builder->parse_state == T1_Parse_Have_Path   ||
1285                builder->parse_state == T1_Parse_Have_Moveto )
1286             t1_builder_close_contour( builder );
1287 
1288           builder->parse_state = T1_Parse_Have_Width;
1289           break;
1290 
1291         case op_hlineto:
1292           FT_TRACE4(( " hlineto" ));
1293 
1294           if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) )
1295             goto Fail;
1296 


1639         FT_TRACE4(( "\n" ));
1640         bol = TRUE;
1641 #endif
1642 
1643       } /* general operator processing */
1644 
1645     } /* while ip < limit */
1646 
1647     FT_TRACE4(( "..end..\n\n" ));
1648 
1649   Fail:
1650     return error;
1651 
1652   Syntax_Error:
1653     return FT_THROW( Syntax_Error );
1654 
1655   Stack_Underflow:
1656     return FT_THROW( Stack_Underflow );
1657   }
1658 

1659 
1660 #else /* !T1_CONFIG_OPTION_OLD_ENGINE */
1661 
1662 
1663   /**************************************************************************
1664    *
1665    * @Function:
1666    *   t1_decoder_parse_metrics
1667    *
1668    * @Description:
1669    *   Parses a given Type 1 charstrings program to extract width
1670    *
1671    * @Input:
1672    *   decoder ::
1673    *     The current Type 1 decoder.
1674    *
1675    *   charstring_base ::
1676    *     The base address of the charstring stream.
1677    *
1678    *   charstring_len ::
1679    *     The length in bytes of the charstring stream.
1680    *
1681    * @Return:
1682    *   FreeType error code.  0 means success.
1683    */
1684   FT_LOCAL_DEF( FT_Error )
1685   t1_decoder_parse_metrics( T1_Decoder  decoder,
1686                             FT_Byte*    charstring_base,
1687                             FT_UInt     charstring_len )
1688   {
1689     T1_Decoder_Zone  zone;
1690     FT_Byte*         ip;
1691     FT_Byte*         limit;
1692     T1_Builder       builder = &decoder->builder;
1693 
1694 #ifdef FT_DEBUG_LEVEL_TRACE
1695     FT_Bool          bol = TRUE;
1696 #endif
1697 
1698 
1699     /* First of all, initialize the decoder */
1700     decoder->top  = decoder->stack;
1701     decoder->zone = decoder->zones;
1702     zone          = decoder->zones;
1703 
1704     builder->parse_state = T1_Parse_Start;
1705 



1706     zone->base           = charstring_base;
1707     limit = zone->limit  = charstring_base + charstring_len;
1708     ip    = zone->cursor = zone->base;
1709 
1710     /* now, execute loop */
1711     while ( ip < limit )
1712     {
1713       FT_Long*     top   = decoder->top;
1714       T1_Operator  op    = op_none;
1715       FT_Int32     value = 0;
1716 
1717 
1718 #ifdef FT_DEBUG_LEVEL_TRACE
1719       if ( bol )
1720       {
1721         FT_TRACE5(( " (%d)", decoder->top - decoder->stack ));
1722         bol = FALSE;
1723       }
1724 #endif
1725 
1726       /**********************************************************************
1727        *
1728        * Decode operator or operand
1729        *
1730        */
1731 
1732       /* first of all, decompress operator or value */
1733       switch ( *ip++ )
1734       {
1735       case 1:
1736       case 3:
1737       case 4:
1738       case 5:
1739       case 6:
1740       case 7:
1741       case 8:
1742       case 9:
1743       case 10:
1744       case 11:
1745       case 14:
1746       case 15:
1747       case 21:
1748       case 22:
1749       case 30:
1750       case 31:


1820                          " unexpected EOF in integer\n" ));
1821               goto Syntax_Error;
1822             }
1823 
1824             if ( ip[-2] < 251 )
1825               value =    ( ( ip[-2] - 247 ) * 256 ) + ip[-1] + 108;
1826             else
1827               value = -( ( ( ip[-2] - 251 ) * 256 ) + ip[-1] + 108 );
1828           }
1829 
1830           value = (FT_Int32)( (FT_UInt32)value << 16 );
1831         }
1832         else
1833         {
1834           FT_ERROR(( "t1_decoder_parse_metrics:"
1835                      " invalid byte (%d)\n", ip[-1] ));
1836           goto Syntax_Error;
1837         }
1838       }
1839 
1840       /**********************************************************************
1841        *
1842        * Push value on stack, or process operator
1843        *
1844        */
1845       if ( op == op_none )
1846       {
1847         if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS )
1848         {
1849           FT_ERROR(( "t1_decoder_parse_metrics: stack overflow\n" ));
1850           goto Syntax_Error;
1851         }
1852 
1853 #ifdef FT_DEBUG_LEVEL_TRACE
1854           FT_TRACE4(( " %d", value / 65536 ));
1855 #endif
1856 
1857         *top++       = value;
1858         decoder->top = top;
1859       }
1860       else  /* general operator */
1861       {
1862         FT_Int  num_args = t1_args_count[op];
1863 
1864 


1878 #endif /* FT_DEBUG_LEVEL_TRACE */
1879 
1880         top -= num_args;
1881 
1882         switch ( op )
1883         {
1884         case op_hsbw:
1885           FT_TRACE4(( " hsbw" ));
1886 
1887           builder->parse_state = T1_Parse_Have_Width;
1888 
1889           builder->left_bearing.x = ADD_LONG( builder->left_bearing.x,
1890                                               top[0] );
1891 
1892           builder->advance.x = top[1];
1893           builder->advance.y = 0;
1894 
1895           /* we only want to compute the glyph's metrics */
1896           /* (lsb + advance width), not load the rest of */
1897           /* it; so exit immediately                     */
1898           FT_TRACE4(( "\n" ));
1899           return FT_Err_Ok;
1900 
1901         case op_sbw:
1902           FT_TRACE4(( " sbw" ));
1903 
1904           builder->parse_state = T1_Parse_Have_Width;
1905 
1906           builder->left_bearing.x = ADD_LONG( builder->left_bearing.x,
1907                                               top[0] );
1908           builder->left_bearing.y = ADD_LONG( builder->left_bearing.y,
1909                                               top[1] );
1910 
1911           builder->advance.x = top[2];
1912           builder->advance.y = top[3];
1913 
1914           /* we only want to compute the glyph's metrics */
1915           /* (lsb + advance width), not load the rest of */
1916           /* it; so exit immediately                     */
1917           FT_TRACE4(( "\n" ));
1918           return FT_Err_Ok;
1919 
1920         default:
1921           FT_ERROR(( "t1_decoder_parse_metrics:"
1922                      " unhandled opcode %d\n", op ));
1923           goto Syntax_Error;
1924         }
1925 
1926       } /* general operator processing */
1927 
1928     } /* while ip < limit */
1929 
1930     FT_TRACE4(( "..end..\n\n" ));
1931 
1932   No_Width:
1933     FT_ERROR(( "t1_decoder_parse_metrics:"
1934                " no width, found op %d instead\n",
1935                ip[-1] ));
1936   Syntax_Error:
1937     return FT_THROW( Syntax_Error );
1938 
1939   Stack_Underflow:
1940     return FT_THROW( Stack_Underflow );
1941   }
1942 
1943 #endif /* !T1_CONFIG_OPTION_OLD_ENGINE */
1944 
1945 
1946   /* initialize T1 decoder */
1947   FT_LOCAL_DEF( FT_Error )
1948   t1_decoder_init( T1_Decoder           decoder,
1949                    FT_Face              face,
1950                    FT_Size              size,
1951                    FT_GlyphSlot         slot,
1952                    FT_Byte**            glyph_names,
1953                    PS_Blend             blend,
1954                    FT_Bool              hinting,
1955                    FT_Render_Mode       hint_mode,
1956                    T1_Decoder_Callback  parse_callback )
1957   {
1958     FT_ZERO( decoder );
1959 
1960     /* retrieve `psnames' interface from list of current modules */
1961     {
1962       FT_Service_PsCMaps  psnames;
1963 
1964 
1965       FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
1966       if ( !psnames )
1967       {
1968         FT_ERROR(( "t1_decoder_init:"
1969                    " the `psnames' module is not available\n" ));
1970         return FT_THROW( Unimplemented_Feature );
1971       }
1972 
1973       decoder->psnames = psnames;
1974     }
1975 
1976     t1_builder_init( &decoder->builder, face, size, slot, hinting );
1977 
1978     /* decoder->buildchar and decoder->len_buildchar have to be  */
1979     /* initialized by the caller since we cannot know the length */
1980     /* of the BuildCharArray                                     */


< prev index next >