Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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