Subversion Repositories Kolibri OS

Rev

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

  1. /***************************************************************************/
  2. /*                                                                         */
  3. /*  cffgload.c                                                             */
  4. /*                                                                         */
  5. /*    OpenType Glyph Loader (body).                                        */
  6. /*                                                                         */
  7. /*  Copyright 1996-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_DEBUG_H
  21. #include FT_INTERNAL_STREAM_H
  22. #include FT_INTERNAL_SFNT_H
  23. #include FT_OUTLINE_H
  24. #include FT_CFF_DRIVER_H
  25.  
  26. #include "cffobjs.h"
  27. #include "cffload.h"
  28. #include "cffgload.h"
  29. #include "cf2ft.h"      /* for cf2_decoder_parse_charstrings */
  30.  
  31. #include "cfferrs.h"
  32.  
  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_cffgload
  42.  
  43.  
  44. #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
  45.  
  46.   typedef enum  CFF_Operator_
  47.   {
  48.     cff_op_unknown = 0,
  49.  
  50.     cff_op_rmoveto,
  51.     cff_op_hmoveto,
  52.     cff_op_vmoveto,
  53.  
  54.     cff_op_rlineto,
  55.     cff_op_hlineto,
  56.     cff_op_vlineto,
  57.  
  58.     cff_op_rrcurveto,
  59.     cff_op_hhcurveto,
  60.     cff_op_hvcurveto,
  61.     cff_op_rcurveline,
  62.     cff_op_rlinecurve,
  63.     cff_op_vhcurveto,
  64.     cff_op_vvcurveto,
  65.  
  66.     cff_op_flex,
  67.     cff_op_hflex,
  68.     cff_op_hflex1,
  69.     cff_op_flex1,
  70.  
  71.     cff_op_endchar,
  72.  
  73.     cff_op_hstem,
  74.     cff_op_vstem,
  75.     cff_op_hstemhm,
  76.     cff_op_vstemhm,
  77.  
  78.     cff_op_hintmask,
  79.     cff_op_cntrmask,
  80.     cff_op_dotsection,  /* deprecated, acts as no-op */
  81.  
  82.     cff_op_abs,
  83.     cff_op_add,
  84.     cff_op_sub,
  85.     cff_op_div,
  86.     cff_op_neg,
  87.     cff_op_random,
  88.     cff_op_mul,
  89.     cff_op_sqrt,
  90.  
  91.     cff_op_blend,
  92.  
  93.     cff_op_drop,
  94.     cff_op_exch,
  95.     cff_op_index,
  96.     cff_op_roll,
  97.     cff_op_dup,
  98.  
  99.     cff_op_put,
  100.     cff_op_get,
  101.     cff_op_store,
  102.     cff_op_load,
  103.  
  104.     cff_op_and,
  105.     cff_op_or,
  106.     cff_op_not,
  107.     cff_op_eq,
  108.     cff_op_ifelse,
  109.  
  110.     cff_op_callsubr,
  111.     cff_op_callgsubr,
  112.     cff_op_return,
  113.  
  114.     /* Type 1 opcodes: invalid but seen in real life */
  115.     cff_op_hsbw,
  116.     cff_op_closepath,
  117.     cff_op_callothersubr,
  118.     cff_op_pop,
  119.     cff_op_seac,
  120.     cff_op_sbw,
  121.     cff_op_setcurrentpoint,
  122.  
  123.     /* do not remove */
  124.     cff_op_max
  125.  
  126.   } CFF_Operator;
  127.  
  128.  
  129. #define CFF_COUNT_CHECK_WIDTH  0x80
  130. #define CFF_COUNT_EXACT        0x40
  131. #define CFF_COUNT_CLEAR_STACK  0x20
  132.  
  133.   /* count values which have the `CFF_COUNT_CHECK_WIDTH' flag set are  */
  134.   /* used for checking the width and requested numbers of arguments    */
  135.   /* only; they are set to zero afterwards                             */
  136.  
  137.   /* the other two flags are informative only and unused currently     */
  138.  
  139.   static const FT_Byte  cff_argument_counts[] =
  140.   {
  141.     0,  /* unknown */
  142.  
  143.     2 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, /* rmoveto */
  144.     1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT,
  145.     1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT,
  146.  
  147.     0 | CFF_COUNT_CLEAR_STACK, /* rlineto */
  148.     0 | CFF_COUNT_CLEAR_STACK,
  149.     0 | CFF_COUNT_CLEAR_STACK,
  150.  
  151.     0 | CFF_COUNT_CLEAR_STACK, /* rrcurveto */
  152.     0 | CFF_COUNT_CLEAR_STACK,
  153.     0 | CFF_COUNT_CLEAR_STACK,
  154.     0 | CFF_COUNT_CLEAR_STACK,
  155.     0 | CFF_COUNT_CLEAR_STACK,
  156.     0 | CFF_COUNT_CLEAR_STACK,
  157.     0 | CFF_COUNT_CLEAR_STACK,
  158.  
  159.     13, /* flex */
  160.     7,
  161.     9,
  162.     11,
  163.  
  164.     0 | CFF_COUNT_CHECK_WIDTH, /* endchar */
  165.  
  166.     2 | CFF_COUNT_CHECK_WIDTH, /* hstem */
  167.     2 | CFF_COUNT_CHECK_WIDTH,
  168.     2 | CFF_COUNT_CHECK_WIDTH,
  169.     2 | CFF_COUNT_CHECK_WIDTH,
  170.  
  171.     0 | CFF_COUNT_CHECK_WIDTH, /* hintmask */
  172.     0 | CFF_COUNT_CHECK_WIDTH, /* cntrmask */
  173.     0, /* dotsection */
  174.  
  175.     1, /* abs */
  176.     2,
  177.     2,
  178.     2,
  179.     1,
  180.     0,
  181.     2,
  182.     1,
  183.  
  184.     1, /* blend */
  185.  
  186.     1, /* drop */
  187.     2,
  188.     1,
  189.     2,
  190.     1,
  191.  
  192.     2, /* put */
  193.     1,
  194.     4,
  195.     3,
  196.  
  197.     2, /* and */
  198.     2,
  199.     1,
  200.     2,
  201.     4,
  202.  
  203.     1, /* callsubr */
  204.     1,
  205.     0,
  206.  
  207.     2, /* hsbw */
  208.     0,
  209.     0,
  210.     0,
  211.     5, /* seac */
  212.     4, /* sbw */
  213.     2  /* setcurrentpoint */
  214.   };
  215.  
  216. #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
  217.  
  218.  
  219.   /*************************************************************************/
  220.   /*************************************************************************/
  221.   /*************************************************************************/
  222.   /**********                                                      *********/
  223.   /**********                                                      *********/
  224.   /**********             GENERIC CHARSTRING PARSING               *********/
  225.   /**********                                                      *********/
  226.   /**********                                                      *********/
  227.   /*************************************************************************/
  228.   /*************************************************************************/
  229.   /*************************************************************************/
  230.  
  231.  
  232.   /*************************************************************************/
  233.   /*                                                                       */
  234.   /* <Function>                                                            */
  235.   /*    cff_builder_init                                                   */
  236.   /*                                                                       */
  237.   /* <Description>                                                         */
  238.   /*    Initializes a given glyph builder.                                 */
  239.   /*                                                                       */
  240.   /* <InOut>                                                               */
  241.   /*    builder :: A pointer to the glyph builder to initialize.           */
  242.   /*                                                                       */
  243.   /* <Input>                                                               */
  244.   /*    face    :: The current face object.                                */
  245.   /*                                                                       */
  246.   /*    size    :: The current size object.                                */
  247.   /*                                                                       */
  248.   /*    glyph   :: The current glyph object.                               */
  249.   /*                                                                       */
  250.   /*    hinting :: Whether hinting is active.                              */
  251.   /*                                                                       */
  252.   static void
  253.   cff_builder_init( CFF_Builder*   builder,
  254.                     TT_Face        face,
  255.                     CFF_Size       size,
  256.                     CFF_GlyphSlot  glyph,
  257.                     FT_Bool        hinting )
  258.   {
  259.     builder->path_begun  = 0;
  260.     builder->load_points = 1;
  261.  
  262.     builder->face   = face;
  263.     builder->glyph  = glyph;
  264.     builder->memory = face->root.memory;
  265.  
  266.     if ( glyph )
  267.     {
  268.       FT_GlyphLoader  loader = glyph->root.internal->loader;
  269.  
  270.  
  271.       builder->loader  = loader;
  272.       builder->base    = &loader->base.outline;
  273.       builder->current = &loader->current.outline;
  274.       FT_GlyphLoader_Rewind( loader );
  275.  
  276.       builder->hints_globals = 0;
  277.       builder->hints_funcs   = 0;
  278.  
  279.       if ( hinting && size )
  280.       {
  281.         CFF_Internal  internal = (CFF_Internal)size->root.internal;
  282.  
  283.  
  284.         builder->hints_globals = (void *)internal->topfont;
  285.         builder->hints_funcs   = glyph->root.internal->glyph_hints;
  286.       }
  287.     }
  288.  
  289.     builder->pos_x = 0;
  290.     builder->pos_y = 0;
  291.  
  292.     builder->left_bearing.x = 0;
  293.     builder->left_bearing.y = 0;
  294.     builder->advance.x      = 0;
  295.     builder->advance.y      = 0;
  296.   }
  297.  
  298.  
  299.   /*************************************************************************/
  300.   /*                                                                       */
  301.   /* <Function>                                                            */
  302.   /*    cff_builder_done                                                   */
  303.   /*                                                                       */
  304.   /* <Description>                                                         */
  305.   /*    Finalizes a given glyph builder.  Its contents can still be used   */
  306.   /*    after the call, but the function saves important information       */
  307.   /*    within the corresponding glyph slot.                               */
  308.   /*                                                                       */
  309.   /* <Input>                                                               */
  310.   /*    builder :: A pointer to the glyph builder to finalize.             */
  311.   /*                                                                       */
  312.   static void
  313.   cff_builder_done( CFF_Builder*  builder )
  314.   {
  315.     CFF_GlyphSlot  glyph = builder->glyph;
  316.  
  317.  
  318.     if ( glyph )
  319.       glyph->root.outline = *builder->base;
  320.   }
  321.  
  322.  
  323.   /*************************************************************************/
  324.   /*                                                                       */
  325.   /* <Function>                                                            */
  326.   /*    cff_compute_bias                                                   */
  327.   /*                                                                       */
  328.   /* <Description>                                                         */
  329.   /*    Computes the bias value in dependence of the number of glyph       */
  330.   /*    subroutines.                                                       */
  331.   /*                                                                       */
  332.   /* <Input>                                                               */
  333.   /*    in_charstring_type :: The `CharstringType' value of the top DICT   */
  334.   /*                          dictionary.                                  */
  335.   /*                                                                       */
  336.   /*    num_subrs          :: The number of glyph subroutines.             */
  337.   /*                                                                       */
  338.   /* <Return>                                                              */
  339.   /*    The bias value.                                                    */
  340.   static FT_Int
  341.   cff_compute_bias( FT_Int   in_charstring_type,
  342.                     FT_UInt  num_subrs )
  343.   {
  344.     FT_Int  result;
  345.  
  346.  
  347.     if ( in_charstring_type == 1 )
  348.       result = 0;
  349.     else if ( num_subrs < 1240 )
  350.       result = 107;
  351.     else if ( num_subrs < 33900U )
  352.       result = 1131;
  353.     else
  354.       result = 32768U;
  355.  
  356.     return result;
  357.   }
  358.  
  359.  
  360.   /*************************************************************************/
  361.   /*                                                                       */
  362.   /* <Function>                                                            */
  363.   /*    cff_decoder_init                                                   */
  364.   /*                                                                       */
  365.   /* <Description>                                                         */
  366.   /*    Initializes a given glyph decoder.                                 */
  367.   /*                                                                       */
  368.   /* <InOut>                                                               */
  369.   /*    decoder :: A pointer to the glyph builder to initialize.           */
  370.   /*                                                                       */
  371.   /* <Input>                                                               */
  372.   /*    face      :: The current face object.                              */
  373.   /*                                                                       */
  374.   /*    size      :: The current size object.                              */
  375.   /*                                                                       */
  376.   /*    slot      :: The current glyph object.                             */
  377.   /*                                                                       */
  378.   /*    hinting   :: Whether hinting is active.                            */
  379.   /*                                                                       */
  380.   /*    hint_mode :: The hinting mode.                                     */
  381.   /*                                                                       */
  382.   FT_LOCAL_DEF( void )
  383.   cff_decoder_init( CFF_Decoder*    decoder,
  384.                     TT_Face         face,
  385.                     CFF_Size        size,
  386.                     CFF_GlyphSlot   slot,
  387.                     FT_Bool         hinting,
  388.                     FT_Render_Mode  hint_mode )
  389.   {
  390.     CFF_Font  cff = (CFF_Font)face->extra.data;
  391.  
  392.  
  393.     /* clear everything */
  394.     FT_MEM_ZERO( decoder, sizeof ( *decoder ) );
  395.  
  396.     /* initialize builder */
  397.     cff_builder_init( &decoder->builder, face, size, slot, hinting );
  398.  
  399.     /* initialize Type2 decoder */
  400.     decoder->cff          = cff;
  401.     decoder->num_globals  = cff->global_subrs_index.count;
  402.     decoder->globals      = cff->global_subrs;
  403.     decoder->globals_bias = cff_compute_bias(
  404.                               cff->top_font.font_dict.charstring_type,
  405.                               decoder->num_globals );
  406.  
  407.     decoder->hint_mode    = hint_mode;
  408.   }
  409.  
  410.  
  411.   /* this function is used to select the subfont */
  412.   /* and the locals subrs array                  */
  413.   FT_LOCAL_DEF( FT_Error )
  414.   cff_decoder_prepare( CFF_Decoder*  decoder,
  415.                        CFF_Size      size,
  416.                        FT_UInt       glyph_index )
  417.   {
  418.     CFF_Builder  *builder = &decoder->builder;
  419.     CFF_Font      cff     = (CFF_Font)builder->face->extra.data;
  420.     CFF_SubFont   sub     = &cff->top_font;
  421.     FT_Error      error   = FT_Err_Ok;
  422.  
  423.  
  424.     /* manage CID fonts */
  425.     if ( cff->num_subfonts )
  426.     {
  427.       FT_Byte  fd_index = cff_fd_select_get( &cff->fd_select, glyph_index );
  428.  
  429.  
  430.       if ( fd_index >= cff->num_subfonts )
  431.       {
  432.         FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" ));
  433.         error = FT_THROW( Invalid_File_Format );
  434.         goto Exit;
  435.       }
  436.  
  437.       FT_TRACE3(( "glyph index %d (subfont %d):\n", glyph_index, fd_index ));
  438.  
  439.       sub = cff->subfonts[fd_index];
  440.  
  441.       if ( builder->hints_funcs && size )
  442.       {
  443.         CFF_Internal  internal = (CFF_Internal)size->root.internal;
  444.  
  445.  
  446.         /* for CFFs without subfonts, this value has already been set */
  447.         builder->hints_globals = (void *)internal->subfonts[fd_index];
  448.       }
  449.     }
  450. #ifdef FT_DEBUG_LEVEL_TRACE
  451.     else
  452.       FT_TRACE3(( "glyph index %d:\n", glyph_index ));
  453. #endif
  454.  
  455.     decoder->num_locals    = sub->local_subrs_index.count;
  456.     decoder->locals        = sub->local_subrs;
  457.     decoder->locals_bias   = cff_compute_bias(
  458.                                decoder->cff->top_font.font_dict.charstring_type,
  459.                                decoder->num_locals );
  460.  
  461.     decoder->glyph_width   = sub->private_dict.default_width;
  462.     decoder->nominal_width = sub->private_dict.nominal_width;
  463.  
  464.     decoder->current_subfont = sub;     /* for Adobe's CFF handler */
  465.  
  466.   Exit:
  467.     return error;
  468.   }
  469.  
  470.  
  471.   /* check that there is enough space for `count' more points */
  472.   FT_LOCAL_DEF( FT_Error )
  473.   cff_check_points( CFF_Builder*  builder,
  474.                     FT_Int        count )
  475.   {
  476.     return FT_GLYPHLOADER_CHECK_POINTS( builder->loader, count, 0 );
  477.   }
  478.  
  479.  
  480.   /* add a new point, do not check space */
  481.   FT_LOCAL_DEF( void )
  482.   cff_builder_add_point( CFF_Builder*  builder,
  483.                          FT_Pos        x,
  484.                          FT_Pos        y,
  485.                          FT_Byte       flag )
  486.   {
  487.     FT_Outline*  outline = builder->current;
  488.  
  489.  
  490.     if ( builder->load_points )
  491.     {
  492.       FT_Vector*  point   = outline->points + outline->n_points;
  493.       FT_Byte*    control = (FT_Byte*)outline->tags + outline->n_points;
  494.  
  495. #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
  496.       CFF_Driver  driver  = (CFF_Driver)FT_FACE_DRIVER( builder->face );
  497.  
  498.  
  499.       if ( driver->hinting_engine == FT_CFF_HINTING_FREETYPE )
  500.       {
  501.         point->x = x >> 16;
  502.         point->y = y >> 16;
  503.       }
  504.       else
  505. #endif
  506.       {
  507.         /* cf2_decoder_parse_charstrings uses 16.16 coordinates */
  508.         point->x = x >> 10;
  509.         point->y = y >> 10;
  510.       }
  511.       *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC );
  512.     }
  513.  
  514.     outline->n_points++;
  515.   }
  516.  
  517.  
  518.   /* check space for a new on-curve point, then add it */
  519.   FT_LOCAL_DEF( FT_Error )
  520.   cff_builder_add_point1( CFF_Builder*  builder,
  521.                           FT_Pos        x,
  522.                           FT_Pos        y )
  523.   {
  524.     FT_Error  error;
  525.  
  526.  
  527.     error = cff_check_points( builder, 1 );
  528.     if ( !error )
  529.       cff_builder_add_point( builder, x, y, 1 );
  530.  
  531.     return error;
  532.   }
  533.  
  534.  
  535.   /* check space for a new contour, then add it */
  536.   static FT_Error
  537.   cff_builder_add_contour( CFF_Builder*  builder )
  538.   {
  539.     FT_Outline*  outline = builder->current;
  540.     FT_Error     error;
  541.  
  542.  
  543.     if ( !builder->load_points )
  544.     {
  545.       outline->n_contours++;
  546.       return FT_Err_Ok;
  547.     }
  548.  
  549.     error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 );
  550.     if ( !error )
  551.     {
  552.       if ( outline->n_contours > 0 )
  553.         outline->contours[outline->n_contours - 1] =
  554.           (short)( outline->n_points - 1 );
  555.  
  556.       outline->n_contours++;
  557.     }
  558.  
  559.     return error;
  560.   }
  561.  
  562.  
  563.   /* if a path was begun, add its first on-curve point */
  564.   FT_LOCAL_DEF( FT_Error )
  565.   cff_builder_start_point( CFF_Builder*  builder,
  566.                            FT_Pos        x,
  567.                            FT_Pos        y )
  568.   {
  569.     FT_Error  error = FT_Err_Ok;
  570.  
  571.  
  572.     /* test whether we are building a new contour */
  573.     if ( !builder->path_begun )
  574.     {
  575.       builder->path_begun = 1;
  576.       error = cff_builder_add_contour( builder );
  577.       if ( !error )
  578.         error = cff_builder_add_point1( builder, x, y );
  579.     }
  580.  
  581.     return error;
  582.   }
  583.  
  584.  
  585.   /* close the current contour */
  586.   FT_LOCAL_DEF( void )
  587.   cff_builder_close_contour( CFF_Builder*  builder )
  588.   {
  589.     FT_Outline*  outline = builder->current;
  590.     FT_Int       first;
  591.  
  592.  
  593.     if ( !outline )
  594.       return;
  595.  
  596.     first = outline->n_contours <= 1
  597.             ? 0 : outline->contours[outline->n_contours - 2] + 1;
  598.  
  599.     /* We must not include the last point in the path if it */
  600.     /* is located on the first point.                       */
  601.     if ( outline->n_points > 1 )
  602.     {
  603.       FT_Vector*  p1      = outline->points + first;
  604.       FT_Vector*  p2      = outline->points + outline->n_points - 1;
  605.       FT_Byte*    control = (FT_Byte*)outline->tags + outline->n_points - 1;
  606.  
  607.  
  608.       /* `delete' last point only if it coincides with the first    */
  609.       /* point and if it is not a control point (which can happen). */
  610.       if ( p1->x == p2->x && p1->y == p2->y )
  611.         if ( *control == FT_CURVE_TAG_ON )
  612.           outline->n_points--;
  613.     }
  614.  
  615.     if ( outline->n_contours > 0 )
  616.     {
  617.       /* Don't add contours only consisting of one point, i.e., */
  618.       /* check whether begin point and last point are the same. */
  619.       if ( first == outline->n_points - 1 )
  620.       {
  621.         outline->n_contours--;
  622.         outline->n_points--;
  623.       }
  624.       else
  625.         outline->contours[outline->n_contours - 1] =
  626.           (short)( outline->n_points - 1 );
  627.     }
  628.   }
  629.  
  630.  
  631.   FT_LOCAL_DEF( FT_Int )
  632.   cff_lookup_glyph_by_stdcharcode( CFF_Font  cff,
  633.                                    FT_Int    charcode )
  634.   {
  635.     FT_UInt    n;
  636.     FT_UShort  glyph_sid;
  637.  
  638.  
  639.     /* CID-keyed fonts don't have glyph names */
  640.     if ( !cff->charset.sids )
  641.       return -1;
  642.  
  643.     /* check range of standard char code */
  644.     if ( charcode < 0 || charcode > 255 )
  645.       return -1;
  646.  
  647.     /* Get code to SID mapping from `cff_standard_encoding'. */
  648.     glyph_sid = cff_get_standard_encoding( (FT_UInt)charcode );
  649.  
  650.     for ( n = 0; n < cff->num_glyphs; n++ )
  651.     {
  652.       if ( cff->charset.sids[n] == glyph_sid )
  653.         return n;
  654.     }
  655.  
  656.     return -1;
  657.   }
  658.  
  659.  
  660.   FT_LOCAL_DEF( FT_Error )
  661.   cff_get_glyph_data( TT_Face    face,
  662.                       FT_UInt    glyph_index,
  663.                       FT_Byte**  pointer,
  664.                       FT_ULong*  length )
  665.   {
  666. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  667.     /* For incremental fonts get the character data using the */
  668.     /* callback function.                                     */
  669.     if ( face->root.internal->incremental_interface )
  670.     {
  671.       FT_Data   data;
  672.       FT_Error  error =
  673.                   face->root.internal->incremental_interface->funcs->get_glyph_data(
  674.                     face->root.internal->incremental_interface->object,
  675.                     glyph_index, &data );
  676.  
  677.  
  678.       *pointer = (FT_Byte*)data.pointer;
  679.       *length = data.length;
  680.  
  681.       return error;
  682.     }
  683.     else
  684. #endif /* FT_CONFIG_OPTION_INCREMENTAL */
  685.  
  686.     {
  687.       CFF_Font  cff  = (CFF_Font)(face->extra.data);
  688.  
  689.  
  690.       return cff_index_access_element( &cff->charstrings_index, glyph_index,
  691.                                        pointer, length );
  692.     }
  693.   }
  694.  
  695.  
  696.   FT_LOCAL_DEF( void )
  697.   cff_free_glyph_data( TT_Face    face,
  698.                        FT_Byte**  pointer,
  699.                        FT_ULong   length )
  700.   {
  701. #ifndef FT_CONFIG_OPTION_INCREMENTAL
  702.     FT_UNUSED( length );
  703. #endif
  704.  
  705. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  706.     /* For incremental fonts get the character data using the */
  707.     /* callback function.                                     */
  708.     if ( face->root.internal->incremental_interface )
  709.     {
  710.       FT_Data data;
  711.  
  712.  
  713.       data.pointer = *pointer;
  714.       data.length  = length;
  715.  
  716.       face->root.internal->incremental_interface->funcs->free_glyph_data(
  717.         face->root.internal->incremental_interface->object, &data );
  718.     }
  719.     else
  720. #endif /* FT_CONFIG_OPTION_INCREMENTAL */
  721.  
  722.     {
  723.       CFF_Font  cff = (CFF_Font)(face->extra.data);
  724.  
  725.  
  726.       cff_index_forget_element( &cff->charstrings_index, pointer );
  727.     }
  728.   }
  729.  
  730.  
  731. #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
  732.  
  733.   static FT_Error
  734.   cff_operator_seac( CFF_Decoder*  decoder,
  735.                      FT_Pos        asb,
  736.                      FT_Pos        adx,
  737.                      FT_Pos        ady,
  738.                      FT_Int        bchar,
  739.                      FT_Int        achar )
  740.   {
  741.     FT_Error      error;
  742.     CFF_Builder*  builder = &decoder->builder;
  743.     FT_Int        bchar_index, achar_index;
  744.     TT_Face       face = decoder->builder.face;
  745.     FT_Vector     left_bearing, advance;
  746.     FT_Byte*      charstring;
  747.     FT_ULong      charstring_len;
  748.     FT_Pos        glyph_width;
  749.  
  750.  
  751.     if ( decoder->seac )
  752.     {
  753.       FT_ERROR(( "cff_operator_seac: invalid nested seac\n" ));
  754.       return FT_THROW( Syntax_Error );
  755.     }
  756.  
  757.     adx += decoder->builder.left_bearing.x;
  758.     ady += decoder->builder.left_bearing.y;
  759.  
  760. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  761.     /* Incremental fonts don't necessarily have valid charsets.        */
  762.     /* They use the character code, not the glyph index, in this case. */
  763.     if ( face->root.internal->incremental_interface )
  764.     {
  765.       bchar_index = bchar;
  766.       achar_index = achar;
  767.     }
  768.     else
  769. #endif /* FT_CONFIG_OPTION_INCREMENTAL */
  770.     {
  771.       CFF_Font cff = (CFF_Font)(face->extra.data);
  772.  
  773.  
  774.       bchar_index = cff_lookup_glyph_by_stdcharcode( cff, bchar );
  775.       achar_index = cff_lookup_glyph_by_stdcharcode( cff, achar );
  776.     }
  777.  
  778.     if ( bchar_index < 0 || achar_index < 0 )
  779.     {
  780.       FT_ERROR(( "cff_operator_seac:"
  781.                  " invalid seac character code arguments\n" ));
  782.       return FT_THROW( Syntax_Error );
  783.     }
  784.  
  785.     /* If we are trying to load a composite glyph, do not load the */
  786.     /* accent character and return the array of subglyphs.         */
  787.     if ( builder->no_recurse )
  788.     {
  789.       FT_GlyphSlot    glyph  = (FT_GlyphSlot)builder->glyph;
  790.       FT_GlyphLoader  loader = glyph->internal->loader;
  791.       FT_SubGlyph     subg;
  792.  
  793.  
  794.       /* reallocate subglyph array if necessary */
  795.       error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 );
  796.       if ( error )
  797.         goto Exit;
  798.  
  799.       subg = loader->current.subglyphs;
  800.  
  801.       /* subglyph 0 = base character */
  802.       subg->index = bchar_index;
  803.       subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |
  804.                     FT_SUBGLYPH_FLAG_USE_MY_METRICS;
  805.       subg->arg1  = 0;
  806.       subg->arg2  = 0;
  807.       subg++;
  808.  
  809.       /* subglyph 1 = accent character */
  810.       subg->index = achar_index;
  811.       subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;
  812.       subg->arg1  = (FT_Int)( adx >> 16 );
  813.       subg->arg2  = (FT_Int)( ady >> 16 );
  814.  
  815.       /* set up remaining glyph fields */
  816.       glyph->num_subglyphs = 2;
  817.       glyph->subglyphs     = loader->base.subglyphs;
  818.       glyph->format        = FT_GLYPH_FORMAT_COMPOSITE;
  819.  
  820.       loader->current.num_subglyphs = 2;
  821.     }
  822.  
  823.     FT_GlyphLoader_Prepare( builder->loader );
  824.  
  825.     /* First load `bchar' in builder */
  826.     error = cff_get_glyph_data( face, bchar_index,
  827.                                 &charstring, &charstring_len );
  828.     if ( !error )
  829.     {
  830.       /* the seac operator must not be nested */
  831.       decoder->seac = TRUE;
  832.       error = cff_decoder_parse_charstrings( decoder, charstring,
  833.                                              charstring_len );
  834.       decoder->seac = FALSE;
  835.  
  836.       cff_free_glyph_data( face, &charstring, charstring_len );
  837.  
  838.       if ( error )
  839.         goto Exit;
  840.     }
  841.  
  842.     /* Save the left bearing, advance and glyph width of the base */
  843.     /* character as they will be erased by the next load.         */
  844.  
  845.     left_bearing = builder->left_bearing;
  846.     advance      = builder->advance;
  847.     glyph_width  = decoder->glyph_width;
  848.  
  849.     builder->left_bearing.x = 0;
  850.     builder->left_bearing.y = 0;
  851.  
  852.     builder->pos_x = adx - asb;
  853.     builder->pos_y = ady;
  854.  
  855.     /* Now load `achar' on top of the base outline. */
  856.     error = cff_get_glyph_data( face, achar_index,
  857.                                 &charstring, &charstring_len );
  858.     if ( !error )
  859.     {
  860.       /* the seac operator must not be nested */
  861.       decoder->seac = TRUE;
  862.       error = cff_decoder_parse_charstrings( decoder, charstring,
  863.                                              charstring_len );
  864.       decoder->seac = FALSE;
  865.  
  866.       cff_free_glyph_data( face, &charstring, charstring_len );
  867.  
  868.       if ( error )
  869.         goto Exit;
  870.     }
  871.  
  872.     /* Restore the left side bearing, advance and glyph width */
  873.     /* of the base character.                                 */
  874.     builder->left_bearing = left_bearing;
  875.     builder->advance      = advance;
  876.     decoder->glyph_width  = glyph_width;
  877.  
  878.     builder->pos_x = 0;
  879.     builder->pos_y = 0;
  880.  
  881.   Exit:
  882.     return error;
  883.   }
  884.  
  885.  
  886.   /*************************************************************************/
  887.   /*                                                                       */
  888.   /* <Function>                                                            */
  889.   /*    cff_decoder_parse_charstrings                                      */
  890.   /*                                                                       */
  891.   /* <Description>                                                         */
  892.   /*    Parses a given Type 2 charstrings program.                         */
  893.   /*                                                                       */
  894.   /* <InOut>                                                               */
  895.   /*    decoder         :: The current Type 1 decoder.                     */
  896.   /*                                                                       */
  897.   /* <Input>                                                               */
  898.   /*    charstring_base :: The base of the charstring stream.              */
  899.   /*                                                                       */
  900.   /*    charstring_len  :: The length in bytes of the charstring stream.   */
  901.   /*                                                                       */
  902.   /* <Return>                                                              */
  903.   /*    FreeType error code.  0 means success.                             */
  904.   /*                                                                       */
  905.   FT_LOCAL_DEF( FT_Error )
  906.   cff_decoder_parse_charstrings( CFF_Decoder*  decoder,
  907.                                  FT_Byte*      charstring_base,
  908.                                  FT_ULong      charstring_len )
  909.   {
  910.     FT_Error           error;
  911.     CFF_Decoder_Zone*  zone;
  912.     FT_Byte*           ip;
  913.     FT_Byte*           limit;
  914.     CFF_Builder*       builder = &decoder->builder;
  915.     FT_Pos             x, y;
  916.     FT_Fixed           seed;
  917.     FT_Fixed*          stack;
  918.     FT_Int             charstring_type =
  919.                          decoder->cff->top_font.font_dict.charstring_type;
  920.  
  921.     T2_Hints_Funcs     hinter;
  922.  
  923.  
  924.     /* set default width */
  925.     decoder->num_hints  = 0;
  926.     decoder->read_width = 1;
  927.  
  928.     /* compute random seed from stack address of parameter */
  929.     seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed              ^
  930.                          (FT_PtrDist)(char*)&decoder           ^
  931.                          (FT_PtrDist)(char*)&charstring_base ) &
  932.                          FT_ULONG_MAX ) ;
  933.     seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL;
  934.     if ( seed == 0 )
  935.       seed = 0x7384;
  936.  
  937.     /* initialize the decoder */
  938.     decoder->top  = decoder->stack;
  939.     decoder->zone = decoder->zones;
  940.     zone          = decoder->zones;
  941.     stack         = decoder->top;
  942.  
  943.     hinter = (T2_Hints_Funcs)builder->hints_funcs;
  944.  
  945.     builder->path_begun = 0;
  946.  
  947.     zone->base           = charstring_base;
  948.     limit = zone->limit  = charstring_base + charstring_len;
  949.     ip    = zone->cursor = zone->base;
  950.  
  951.     error = FT_Err_Ok;
  952.  
  953.     x = builder->pos_x;
  954.     y = builder->pos_y;
  955.  
  956.     /* begin hints recording session, if any */
  957.     if ( hinter )
  958.       hinter->open( hinter->hints );
  959.  
  960.     /* now execute loop */
  961.     while ( ip < limit )
  962.     {
  963.       CFF_Operator  op;
  964.       FT_Byte       v;
  965.  
  966.  
  967.       /********************************************************************/
  968.       /*                                                                  */
  969.       /* Decode operator or operand                                       */
  970.       /*                                                                  */
  971.       v = *ip++;
  972.       if ( v >= 32 || v == 28 )
  973.       {
  974.         FT_Int    shift = 16;
  975.         FT_Int32  val;
  976.  
  977.  
  978.         /* this is an operand, push it on the stack */
  979.  
  980.         /* if we use shifts, all computations are done with unsigned */
  981.         /* values; the conversion to a signed value is the last step */
  982.         if ( v == 28 )
  983.         {
  984.           if ( ip + 1 >= limit )
  985.             goto Syntax_Error;
  986.           val = (FT_Short)( ( (FT_UShort)ip[0] << 8 ) | ip[1] );
  987.           ip += 2;
  988.         }
  989.         else if ( v < 247 )
  990.           val = (FT_Int32)v - 139;
  991.         else if ( v < 251 )
  992.         {
  993.           if ( ip >= limit )
  994.             goto Syntax_Error;
  995.           val = ( (FT_Int32)v - 247 ) * 256 + *ip++ + 108;
  996.         }
  997.         else if ( v < 255 )
  998.         {
  999.           if ( ip >= limit )
  1000.             goto Syntax_Error;
  1001.           val = -( (FT_Int32)v - 251 ) * 256 - *ip++ - 108;
  1002.         }
  1003.         else
  1004.         {
  1005.           if ( ip + 3 >= limit )
  1006.             goto Syntax_Error;
  1007.           val = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) |
  1008.                             ( (FT_UInt32)ip[1] << 16 ) |
  1009.                             ( (FT_UInt32)ip[2] <<  8 ) |
  1010.                               (FT_UInt32)ip[3]         );
  1011.           ip    += 4;
  1012.           if ( charstring_type == 2 )
  1013.             shift = 0;
  1014.         }
  1015.         if ( decoder->top - stack >= CFF_MAX_OPERANDS )
  1016.           goto Stack_Overflow;
  1017.  
  1018.         val             = (FT_Int32)( (FT_UInt32)val << shift );
  1019.         *decoder->top++ = val;
  1020.  
  1021. #ifdef FT_DEBUG_LEVEL_TRACE
  1022.         if ( !( val & 0xFFFFL ) )
  1023.           FT_TRACE4(( " %hd", (FT_Short)( (FT_UInt32)val >> 16 ) ));
  1024.         else
  1025.           FT_TRACE4(( " %.2f", val / 65536.0 ));
  1026. #endif
  1027.  
  1028.       }
  1029.       else
  1030.       {
  1031.         /* The specification says that normally arguments are to be taken */
  1032.         /* from the bottom of the stack.  However, this seems not to be   */
  1033.         /* correct, at least for Acroread 7.0.8 on GNU/Linux: It pops the */
  1034.         /* arguments similar to a PS interpreter.                         */
  1035.  
  1036.         FT_Fixed*  args     = decoder->top;
  1037.         FT_Int     num_args = (FT_Int)( args - decoder->stack );
  1038.         FT_Int     req_args;
  1039.  
  1040.  
  1041.         /* find operator */
  1042.         op = cff_op_unknown;
  1043.  
  1044.         switch ( v )
  1045.         {
  1046.         case 1:
  1047.           op = cff_op_hstem;
  1048.           break;
  1049.         case 3:
  1050.           op = cff_op_vstem;
  1051.           break;
  1052.         case 4:
  1053.           op = cff_op_vmoveto;
  1054.           break;
  1055.         case 5:
  1056.           op = cff_op_rlineto;
  1057.           break;
  1058.         case 6:
  1059.           op = cff_op_hlineto;
  1060.           break;
  1061.         case 7:
  1062.           op = cff_op_vlineto;
  1063.           break;
  1064.         case 8:
  1065.           op = cff_op_rrcurveto;
  1066.           break;
  1067.         case 9:
  1068.           op = cff_op_closepath;
  1069.           break;
  1070.         case 10:
  1071.           op = cff_op_callsubr;
  1072.           break;
  1073.         case 11:
  1074.           op = cff_op_return;
  1075.           break;
  1076.         case 12:
  1077.           {
  1078.             if ( ip >= limit )
  1079.               goto Syntax_Error;
  1080.             v = *ip++;
  1081.  
  1082.             switch ( v )
  1083.             {
  1084.             case 0:
  1085.               op = cff_op_dotsection;
  1086.               break;
  1087.             case 1: /* this is actually the Type1 vstem3 operator */
  1088.               op = cff_op_vstem;
  1089.               break;
  1090.             case 2: /* this is actually the Type1 hstem3 operator */
  1091.               op = cff_op_hstem;
  1092.               break;
  1093.             case 3:
  1094.               op = cff_op_and;
  1095.               break;
  1096.             case 4:
  1097.               op = cff_op_or;
  1098.               break;
  1099.             case 5:
  1100.               op = cff_op_not;
  1101.               break;
  1102.             case 6:
  1103.               op = cff_op_seac;
  1104.               break;
  1105.             case 7:
  1106.               op = cff_op_sbw;
  1107.               break;
  1108.             case 8:
  1109.               op = cff_op_store;
  1110.               break;
  1111.             case 9:
  1112.               op = cff_op_abs;
  1113.               break;
  1114.             case 10:
  1115.               op = cff_op_add;
  1116.               break;
  1117.             case 11:
  1118.               op = cff_op_sub;
  1119.               break;
  1120.             case 12:
  1121.               op = cff_op_div;
  1122.               break;
  1123.             case 13:
  1124.               op = cff_op_load;
  1125.               break;
  1126.             case 14:
  1127.               op = cff_op_neg;
  1128.               break;
  1129.             case 15:
  1130.               op = cff_op_eq;
  1131.               break;
  1132.             case 16:
  1133.               op = cff_op_callothersubr;
  1134.               break;
  1135.             case 17:
  1136.               op = cff_op_pop;
  1137.               break;
  1138.             case 18:
  1139.               op = cff_op_drop;
  1140.               break;
  1141.             case 20:
  1142.               op = cff_op_put;
  1143.               break;
  1144.             case 21:
  1145.               op = cff_op_get;
  1146.               break;
  1147.             case 22:
  1148.               op = cff_op_ifelse;
  1149.               break;
  1150.             case 23:
  1151.               op = cff_op_random;
  1152.               break;
  1153.             case 24:
  1154.               op = cff_op_mul;
  1155.               break;
  1156.             case 26:
  1157.               op = cff_op_sqrt;
  1158.               break;
  1159.             case 27:
  1160.               op = cff_op_dup;
  1161.               break;
  1162.             case 28:
  1163.               op = cff_op_exch;
  1164.               break;
  1165.             case 29:
  1166.               op = cff_op_index;
  1167.               break;
  1168.             case 30:
  1169.               op = cff_op_roll;
  1170.               break;
  1171.             case 33:
  1172.               op = cff_op_setcurrentpoint;
  1173.               break;
  1174.             case 34:
  1175.               op = cff_op_hflex;
  1176.               break;
  1177.             case 35:
  1178.               op = cff_op_flex;
  1179.               break;
  1180.             case 36:
  1181.               op = cff_op_hflex1;
  1182.               break;
  1183.             case 37:
  1184.               op = cff_op_flex1;
  1185.               break;
  1186.             default:
  1187.               FT_TRACE4(( " unknown op (12, %d)\n", v ));
  1188.               break;
  1189.             }
  1190.           }
  1191.           break;
  1192.         case 13:
  1193.           op = cff_op_hsbw;
  1194.           break;
  1195.         case 14:
  1196.           op = cff_op_endchar;
  1197.           break;
  1198.         case 16:
  1199.           op = cff_op_blend;
  1200.           break;
  1201.         case 18:
  1202.           op = cff_op_hstemhm;
  1203.           break;
  1204.         case 19:
  1205.           op = cff_op_hintmask;
  1206.           break;
  1207.         case 20:
  1208.           op = cff_op_cntrmask;
  1209.           break;
  1210.         case 21:
  1211.           op = cff_op_rmoveto;
  1212.           break;
  1213.         case 22:
  1214.           op = cff_op_hmoveto;
  1215.           break;
  1216.         case 23:
  1217.           op = cff_op_vstemhm;
  1218.           break;
  1219.         case 24:
  1220.           op = cff_op_rcurveline;
  1221.           break;
  1222.         case 25:
  1223.           op = cff_op_rlinecurve;
  1224.           break;
  1225.         case 26:
  1226.           op = cff_op_vvcurveto;
  1227.           break;
  1228.         case 27:
  1229.           op = cff_op_hhcurveto;
  1230.           break;
  1231.         case 29:
  1232.           op = cff_op_callgsubr;
  1233.           break;
  1234.         case 30:
  1235.           op = cff_op_vhcurveto;
  1236.           break;
  1237.         case 31:
  1238.           op = cff_op_hvcurveto;
  1239.           break;
  1240.         default:
  1241.           FT_TRACE4(( " unknown op (%d)\n", v ));
  1242.           break;
  1243.         }
  1244.  
  1245.         if ( op == cff_op_unknown )
  1246.           continue;
  1247.  
  1248.         /* check arguments */
  1249.         req_args = cff_argument_counts[op];
  1250.         if ( req_args & CFF_COUNT_CHECK_WIDTH )
  1251.         {
  1252.           if ( num_args > 0 && decoder->read_width )
  1253.           {
  1254.             /* If `nominal_width' is non-zero, the number is really a      */
  1255.             /* difference against `nominal_width'.  Else, the number here  */
  1256.             /* is truly a width, not a difference against `nominal_width'. */
  1257.             /* If the font does not set `nominal_width', then              */
  1258.             /* `nominal_width' defaults to zero, and so we can set         */
  1259.             /* `glyph_width' to `nominal_width' plus number on the stack   */
  1260.             /* -- for either case.                                         */
  1261.  
  1262.             FT_Int  set_width_ok;
  1263.  
  1264.  
  1265.             switch ( op )
  1266.             {
  1267.             case cff_op_hmoveto:
  1268.             case cff_op_vmoveto:
  1269.               set_width_ok = num_args & 2;
  1270.               break;
  1271.  
  1272.             case cff_op_hstem:
  1273.             case cff_op_vstem:
  1274.             case cff_op_hstemhm:
  1275.             case cff_op_vstemhm:
  1276.             case cff_op_rmoveto:
  1277.             case cff_op_hintmask:
  1278.             case cff_op_cntrmask:
  1279.               set_width_ok = num_args & 1;
  1280.               break;
  1281.  
  1282.             case cff_op_endchar:
  1283.               /* If there is a width specified for endchar, we either have */
  1284.               /* 1 argument or 5 arguments.  We like to argue.             */
  1285.               set_width_ok = ( num_args == 5 ) || ( num_args == 1 );
  1286.               break;
  1287.  
  1288.             default:
  1289.               set_width_ok = 0;
  1290.               break;
  1291.             }
  1292.  
  1293.             if ( set_width_ok )
  1294.             {
  1295.               decoder->glyph_width = decoder->nominal_width +
  1296.                                        ( stack[0] >> 16 );
  1297.  
  1298.               if ( decoder->width_only )
  1299.               {
  1300.                 /* we only want the advance width; stop here */
  1301.                 break;
  1302.               }
  1303.  
  1304.               /* Consumed an argument. */
  1305.               num_args--;
  1306.             }
  1307.           }
  1308.  
  1309.           decoder->read_width = 0;
  1310.           req_args            = 0;
  1311.         }
  1312.  
  1313.         req_args &= 0x000F;
  1314.         if ( num_args < req_args )
  1315.           goto Stack_Underflow;
  1316.         args     -= req_args;
  1317.         num_args -= req_args;
  1318.  
  1319.         /* At this point, `args' points to the first argument of the  */
  1320.         /* operand in case `req_args' isn't zero.  Otherwise, we have */
  1321.         /* to adjust `args' manually.                                 */
  1322.  
  1323.         /* Note that we only pop arguments from the stack which we    */
  1324.         /* really need and can digest so that we can continue in case */
  1325.         /* of superfluous stack elements.                             */
  1326.  
  1327.         switch ( op )
  1328.         {
  1329.         case cff_op_hstem:
  1330.         case cff_op_vstem:
  1331.         case cff_op_hstemhm:
  1332.         case cff_op_vstemhm:
  1333.           /* the number of arguments is always even here */
  1334.           FT_TRACE4((
  1335.               op == cff_op_hstem   ? " hstem\n"   :
  1336.             ( op == cff_op_vstem   ? " vstem\n"   :
  1337.             ( op == cff_op_hstemhm ? " hstemhm\n" : " vstemhm\n" ) ) ));
  1338.  
  1339.           if ( hinter )
  1340.             hinter->stems( hinter->hints,
  1341.                            ( op == cff_op_hstem || op == cff_op_hstemhm ),
  1342.                            num_args / 2,
  1343.                            args - ( num_args & ~1 ) );
  1344.  
  1345.           decoder->num_hints += num_args / 2;
  1346.           args = stack;
  1347.           break;
  1348.  
  1349.         case cff_op_hintmask:
  1350.         case cff_op_cntrmask:
  1351.           FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" ));
  1352.  
  1353.           /* implement vstem when needed --                        */
  1354.           /* the specification doesn't say it, but this also works */
  1355.           /* with the 'cntrmask' operator                          */
  1356.           /*                                                       */
  1357.           if ( num_args > 0 )
  1358.           {
  1359.             if ( hinter )
  1360.               hinter->stems( hinter->hints,
  1361.                              0,
  1362.                              num_args / 2,
  1363.                              args - ( num_args & ~1 ) );
  1364.  
  1365.             decoder->num_hints += num_args / 2;
  1366.           }
  1367.  
  1368.           /* In a valid charstring there must be at least one byte */
  1369.           /* after `hintmask' or `cntrmask' (e.g., for a `return'  */
  1370.           /* instruction).  Additionally, there must be space for  */
  1371.           /* `num_hints' bits.                                     */
  1372.  
  1373.           if ( ( ip + ( ( decoder->num_hints + 7 ) >> 3 ) ) >= limit )
  1374.             goto Syntax_Error;
  1375.  
  1376.           if ( hinter )
  1377.           {
  1378.             if ( op == cff_op_hintmask )
  1379.               hinter->hintmask( hinter->hints,
  1380.                                 builder->current->n_points,
  1381.                                 decoder->num_hints,
  1382.                                 ip );
  1383.             else
  1384.               hinter->counter( hinter->hints,
  1385.                                decoder->num_hints,
  1386.                                ip );
  1387.           }
  1388.  
  1389. #ifdef FT_DEBUG_LEVEL_TRACE
  1390.           {
  1391.             FT_UInt maskbyte;
  1392.  
  1393.  
  1394.             FT_TRACE4(( " (maskbytes:" ));
  1395.  
  1396.             for ( maskbyte = 0;
  1397.                   maskbyte < (FT_UInt)( ( decoder->num_hints + 7 ) >> 3 );
  1398.                   maskbyte++, ip++ )
  1399.               FT_TRACE4(( " 0x%02X", *ip ));
  1400.  
  1401.             FT_TRACE4(( ")\n" ));
  1402.           }
  1403. #else
  1404.           ip += ( decoder->num_hints + 7 ) >> 3;
  1405. #endif
  1406.           args = stack;
  1407.           break;
  1408.  
  1409.         case cff_op_rmoveto:
  1410.           FT_TRACE4(( " rmoveto\n" ));
  1411.  
  1412.           cff_builder_close_contour( builder );
  1413.           builder->path_begun = 0;
  1414.           x   += args[-2];
  1415.           y   += args[-1];
  1416.           args = stack;
  1417.           break;
  1418.  
  1419.         case cff_op_vmoveto:
  1420.           FT_TRACE4(( " vmoveto\n" ));
  1421.  
  1422.           cff_builder_close_contour( builder );
  1423.           builder->path_begun = 0;
  1424.           y   += args[-1];
  1425.           args = stack;
  1426.           break;
  1427.  
  1428.         case cff_op_hmoveto:
  1429.           FT_TRACE4(( " hmoveto\n" ));
  1430.  
  1431.           cff_builder_close_contour( builder );
  1432.           builder->path_begun = 0;
  1433.           x   += args[-1];
  1434.           args = stack;
  1435.           break;
  1436.  
  1437.         case cff_op_rlineto:
  1438.           FT_TRACE4(( " rlineto\n" ));
  1439.  
  1440.           if ( cff_builder_start_point( builder, x, y )  ||
  1441.                cff_check_points( builder, num_args / 2 ) )
  1442.             goto Fail;
  1443.  
  1444.           if ( num_args < 2 )
  1445.             goto Stack_Underflow;
  1446.  
  1447.           args -= num_args & ~1;
  1448.           while ( args < decoder->top )
  1449.           {
  1450.             x += args[0];
  1451.             y += args[1];
  1452.             cff_builder_add_point( builder, x, y, 1 );
  1453.             args += 2;
  1454.           }
  1455.           args = stack;
  1456.           break;
  1457.  
  1458.         case cff_op_hlineto:
  1459.         case cff_op_vlineto:
  1460.           {
  1461.             FT_Int  phase = ( op == cff_op_hlineto );
  1462.  
  1463.  
  1464.             FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n"
  1465.                                              : " vlineto\n" ));
  1466.  
  1467.             if ( num_args < 0 )
  1468.               goto Stack_Underflow;
  1469.  
  1470.             /* there exist subsetted fonts (found in PDFs) */
  1471.             /* which call `hlineto' without arguments      */
  1472.             if ( num_args == 0 )
  1473.               break;
  1474.  
  1475.             if ( cff_builder_start_point( builder, x, y ) ||
  1476.                  cff_check_points( builder, num_args )    )
  1477.               goto Fail;
  1478.  
  1479.             args = stack;
  1480.             while ( args < decoder->top )
  1481.             {
  1482.               if ( phase )
  1483.                 x += args[0];
  1484.               else
  1485.                 y += args[0];
  1486.  
  1487.               if ( cff_builder_add_point1( builder, x, y ) )
  1488.                 goto Fail;
  1489.  
  1490.               args++;
  1491.               phase ^= 1;
  1492.             }
  1493.             args = stack;
  1494.           }
  1495.           break;
  1496.  
  1497.         case cff_op_rrcurveto:
  1498.           {
  1499.             FT_Int  nargs;
  1500.  
  1501.  
  1502.             FT_TRACE4(( " rrcurveto\n" ));
  1503.  
  1504.             if ( num_args < 6 )
  1505.               goto Stack_Underflow;
  1506.  
  1507.             nargs = num_args - num_args % 6;
  1508.  
  1509.             if ( cff_builder_start_point( builder, x, y ) ||
  1510.                  cff_check_points( builder, nargs / 2 )   )
  1511.               goto Fail;
  1512.  
  1513.             args -= nargs;
  1514.             while ( args < decoder->top )
  1515.             {
  1516.               x += args[0];
  1517.               y += args[1];
  1518.               cff_builder_add_point( builder, x, y, 0 );
  1519.               x += args[2];
  1520.               y += args[3];
  1521.               cff_builder_add_point( builder, x, y, 0 );
  1522.               x += args[4];
  1523.               y += args[5];
  1524.               cff_builder_add_point( builder, x, y, 1 );
  1525.               args += 6;
  1526.             }
  1527.             args = stack;
  1528.           }
  1529.           break;
  1530.  
  1531.         case cff_op_vvcurveto:
  1532.           {
  1533.             FT_Int  nargs;
  1534.  
  1535.  
  1536.             FT_TRACE4(( " vvcurveto\n" ));
  1537.  
  1538.             if ( num_args < 4 )
  1539.               goto Stack_Underflow;
  1540.  
  1541.             /* if num_args isn't of the form 4n or 4n+1, */
  1542.             /* we enforce it by clearing the second bit  */
  1543.  
  1544.             nargs = num_args & ~2;
  1545.  
  1546.             if ( cff_builder_start_point( builder, x, y ) )
  1547.               goto Fail;
  1548.  
  1549.             args -= nargs;
  1550.  
  1551.             if ( nargs & 1 )
  1552.             {
  1553.               x += args[0];
  1554.               args++;
  1555.               nargs--;
  1556.             }
  1557.  
  1558.             if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) )
  1559.               goto Fail;
  1560.  
  1561.             while ( args < decoder->top )
  1562.             {
  1563.               y += args[0];
  1564.               cff_builder_add_point( builder, x, y, 0 );
  1565.               x += args[1];
  1566.               y += args[2];
  1567.               cff_builder_add_point( builder, x, y, 0 );
  1568.               y += args[3];
  1569.               cff_builder_add_point( builder, x, y, 1 );
  1570.               args += 4;
  1571.             }
  1572.             args = stack;
  1573.           }
  1574.           break;
  1575.  
  1576.         case cff_op_hhcurveto:
  1577.           {
  1578.             FT_Int  nargs;
  1579.  
  1580.  
  1581.             FT_TRACE4(( " hhcurveto\n" ));
  1582.  
  1583.             if ( num_args < 4 )
  1584.               goto Stack_Underflow;
  1585.  
  1586.             /* if num_args isn't of the form 4n or 4n+1, */
  1587.             /* we enforce it by clearing the second bit  */
  1588.  
  1589.             nargs = num_args & ~2;
  1590.  
  1591.             if ( cff_builder_start_point( builder, x, y ) )
  1592.               goto Fail;
  1593.  
  1594.             args -= nargs;
  1595.             if ( nargs & 1 )
  1596.             {
  1597.               y += args[0];
  1598.               args++;
  1599.               nargs--;
  1600.             }
  1601.  
  1602.             if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) )
  1603.               goto Fail;
  1604.  
  1605.             while ( args < decoder->top )
  1606.             {
  1607.               x += args[0];
  1608.               cff_builder_add_point( builder, x, y, 0 );
  1609.               x += args[1];
  1610.               y += args[2];
  1611.               cff_builder_add_point( builder, x, y, 0 );
  1612.               x += args[3];
  1613.               cff_builder_add_point( builder, x, y, 1 );
  1614.               args += 4;
  1615.             }
  1616.             args = stack;
  1617.           }
  1618.           break;
  1619.  
  1620.         case cff_op_vhcurveto:
  1621.         case cff_op_hvcurveto:
  1622.           {
  1623.             FT_Int  phase;
  1624.             FT_Int  nargs;
  1625.  
  1626.  
  1627.             FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto\n"
  1628.                                                : " hvcurveto\n" ));
  1629.  
  1630.             if ( cff_builder_start_point( builder, x, y ) )
  1631.               goto Fail;
  1632.  
  1633.             if ( num_args < 4 )
  1634.               goto Stack_Underflow;
  1635.  
  1636.             /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */
  1637.             /* we enforce it by clearing the second bit               */
  1638.  
  1639.             nargs = num_args & ~2;
  1640.  
  1641.             args -= nargs;
  1642.             if ( cff_check_points( builder, ( nargs / 4 ) * 3 ) )
  1643.               goto Stack_Underflow;
  1644.  
  1645.             phase = ( op == cff_op_hvcurveto );
  1646.  
  1647.             while ( nargs >= 4 )
  1648.             {
  1649.               nargs -= 4;
  1650.               if ( phase )
  1651.               {
  1652.                 x += args[0];
  1653.                 cff_builder_add_point( builder, x, y, 0 );
  1654.                 x += args[1];
  1655.                 y += args[2];
  1656.                 cff_builder_add_point( builder, x, y, 0 );
  1657.                 y += args[3];
  1658.                 if ( nargs == 1 )
  1659.                   x += args[4];
  1660.                 cff_builder_add_point( builder, x, y, 1 );
  1661.               }
  1662.               else
  1663.               {
  1664.                 y += args[0];
  1665.                 cff_builder_add_point( builder, x, y, 0 );
  1666.                 x += args[1];
  1667.                 y += args[2];
  1668.                 cff_builder_add_point( builder, x, y, 0 );
  1669.                 x += args[3];
  1670.                 if ( nargs == 1 )
  1671.                   y += args[4];
  1672.                 cff_builder_add_point( builder, x, y, 1 );
  1673.               }
  1674.               args  += 4;
  1675.               phase ^= 1;
  1676.             }
  1677.             args = stack;
  1678.           }
  1679.           break;
  1680.  
  1681.         case cff_op_rlinecurve:
  1682.           {
  1683.             FT_Int  num_lines;
  1684.             FT_Int  nargs;
  1685.  
  1686.  
  1687.             FT_TRACE4(( " rlinecurve\n" ));
  1688.  
  1689.             if ( num_args < 8 )
  1690.               goto Stack_Underflow;
  1691.  
  1692.             nargs     = num_args & ~1;
  1693.             num_lines = ( nargs - 6 ) / 2;
  1694.  
  1695.             if ( cff_builder_start_point( builder, x, y )   ||
  1696.                  cff_check_points( builder, num_lines + 3 ) )
  1697.               goto Fail;
  1698.  
  1699.             args -= nargs;
  1700.  
  1701.             /* first, add the line segments */
  1702.             while ( num_lines > 0 )
  1703.             {
  1704.               x += args[0];
  1705.               y += args[1];
  1706.               cff_builder_add_point( builder, x, y, 1 );
  1707.               args += 2;
  1708.               num_lines--;
  1709.             }
  1710.  
  1711.             /* then the curve */
  1712.             x += args[0];
  1713.             y += args[1];
  1714.             cff_builder_add_point( builder, x, y, 0 );
  1715.             x += args[2];
  1716.             y += args[3];
  1717.             cff_builder_add_point( builder, x, y, 0 );
  1718.             x += args[4];
  1719.             y += args[5];
  1720.             cff_builder_add_point( builder, x, y, 1 );
  1721.             args = stack;
  1722.           }
  1723.           break;
  1724.  
  1725.         case cff_op_rcurveline:
  1726.           {
  1727.             FT_Int  num_curves;
  1728.             FT_Int  nargs;
  1729.  
  1730.  
  1731.             FT_TRACE4(( " rcurveline\n" ));
  1732.  
  1733.             if ( num_args < 8 )
  1734.               goto Stack_Underflow;
  1735.  
  1736.             nargs      = num_args - 2;
  1737.             nargs      = nargs - nargs % 6 + 2;
  1738.             num_curves = ( nargs - 2 ) / 6;
  1739.  
  1740.             if ( cff_builder_start_point( builder, x, y )        ||
  1741.                  cff_check_points( builder, num_curves * 3 + 2 ) )
  1742.               goto Fail;
  1743.  
  1744.             args -= nargs;
  1745.  
  1746.             /* first, add the curves */
  1747.             while ( num_curves > 0 )
  1748.             {
  1749.               x += args[0];
  1750.               y += args[1];
  1751.               cff_builder_add_point( builder, x, y, 0 );
  1752.               x += args[2];
  1753.               y += args[3];
  1754.               cff_builder_add_point( builder, x, y, 0 );
  1755.               x += args[4];
  1756.               y += args[5];
  1757.               cff_builder_add_point( builder, x, y, 1 );
  1758.               args += 6;
  1759.               num_curves--;
  1760.             }
  1761.  
  1762.             /* then the final line */
  1763.             x += args[0];
  1764.             y += args[1];
  1765.             cff_builder_add_point( builder, x, y, 1 );
  1766.             args = stack;
  1767.           }
  1768.           break;
  1769.  
  1770.         case cff_op_hflex1:
  1771.           {
  1772.             FT_Pos start_y;
  1773.  
  1774.  
  1775.             FT_TRACE4(( " hflex1\n" ));
  1776.  
  1777.             /* adding five more points: 4 control points, 1 on-curve point */
  1778.             /* -- make sure we have enough space for the start point if it */
  1779.             /* needs to be added                                           */
  1780.             if ( cff_builder_start_point( builder, x, y ) ||
  1781.                  cff_check_points( builder, 6 )           )
  1782.               goto Fail;
  1783.  
  1784.             /* record the starting point's y position for later use */
  1785.             start_y = y;
  1786.  
  1787.             /* first control point */
  1788.             x += args[0];
  1789.             y += args[1];
  1790.             cff_builder_add_point( builder, x, y, 0 );
  1791.  
  1792.             /* second control point */
  1793.             x += args[2];
  1794.             y += args[3];
  1795.             cff_builder_add_point( builder, x, y, 0 );
  1796.  
  1797.             /* join point; on curve, with y-value the same as the last */
  1798.             /* control point's y-value                                 */
  1799.             x += args[4];
  1800.             cff_builder_add_point( builder, x, y, 1 );
  1801.  
  1802.             /* third control point, with y-value the same as the join */
  1803.             /* point's y-value                                        */
  1804.             x += args[5];
  1805.             cff_builder_add_point( builder, x, y, 0 );
  1806.  
  1807.             /* fourth control point */
  1808.             x += args[6];
  1809.             y += args[7];
  1810.             cff_builder_add_point( builder, x, y, 0 );
  1811.  
  1812.             /* ending point, with y-value the same as the start   */
  1813.             x += args[8];
  1814.             y  = start_y;
  1815.             cff_builder_add_point( builder, x, y, 1 );
  1816.  
  1817.             args = stack;
  1818.             break;
  1819.           }
  1820.  
  1821.         case cff_op_hflex:
  1822.           {
  1823.             FT_Pos start_y;
  1824.  
  1825.  
  1826.             FT_TRACE4(( " hflex\n" ));
  1827.  
  1828.             /* adding six more points; 4 control points, 2 on-curve points */
  1829.             if ( cff_builder_start_point( builder, x, y ) ||
  1830.                  cff_check_points( builder, 6 )           )
  1831.               goto Fail;
  1832.  
  1833.             /* record the starting point's y-position for later use */
  1834.             start_y = y;
  1835.  
  1836.             /* first control point */
  1837.             x += args[0];
  1838.             cff_builder_add_point( builder, x, y, 0 );
  1839.  
  1840.             /* second control point */
  1841.             x += args[1];
  1842.             y += args[2];
  1843.             cff_builder_add_point( builder, x, y, 0 );
  1844.  
  1845.             /* join point; on curve, with y-value the same as the last */
  1846.             /* control point's y-value                                 */
  1847.             x += args[3];
  1848.             cff_builder_add_point( builder, x, y, 1 );
  1849.  
  1850.             /* third control point, with y-value the same as the join */
  1851.             /* point's y-value                                        */
  1852.             x += args[4];
  1853.             cff_builder_add_point( builder, x, y, 0 );
  1854.  
  1855.             /* fourth control point */
  1856.             x += args[5];
  1857.             y  = start_y;
  1858.             cff_builder_add_point( builder, x, y, 0 );
  1859.  
  1860.             /* ending point, with y-value the same as the start point's */
  1861.             /* y-value -- we don't add this point, though               */
  1862.             x += args[6];
  1863.             cff_builder_add_point( builder, x, y, 1 );
  1864.  
  1865.             args = stack;
  1866.             break;
  1867.           }
  1868.  
  1869.         case cff_op_flex1:
  1870.           {
  1871.             FT_Pos     start_x, start_y; /* record start x, y values for */
  1872.                                          /* alter use                    */
  1873.             FT_Fixed   dx = 0, dy = 0;   /* used in horizontal/vertical  */
  1874.                                          /* algorithm below              */
  1875.             FT_Int     horizontal, count;
  1876.             FT_Fixed*  temp;
  1877.  
  1878.  
  1879.             FT_TRACE4(( " flex1\n" ));
  1880.  
  1881.             /* adding six more points; 4 control points, 2 on-curve points */
  1882.             if ( cff_builder_start_point( builder, x, y ) ||
  1883.                  cff_check_points( builder, 6 )           )
  1884.               goto Fail;
  1885.  
  1886.             /* record the starting point's x, y position for later use */
  1887.             start_x = x;
  1888.             start_y = y;
  1889.  
  1890.             /* XXX: figure out whether this is supposed to be a horizontal */
  1891.             /*      or vertical flex; the Type 2 specification is vague... */
  1892.  
  1893.             temp = args;
  1894.  
  1895.             /* grab up to the last argument */
  1896.             for ( count = 5; count > 0; count-- )
  1897.             {
  1898.               dx += temp[0];
  1899.               dy += temp[1];
  1900.               temp += 2;
  1901.             }
  1902.  
  1903.             if ( dx < 0 )
  1904.               dx = -dx;
  1905.             if ( dy < 0 )
  1906.               dy = -dy;
  1907.  
  1908.             /* strange test, but here it is... */
  1909.             horizontal = ( dx > dy );
  1910.  
  1911.             for ( count = 5; count > 0; count-- )
  1912.             {
  1913.               x += args[0];
  1914.               y += args[1];
  1915.               cff_builder_add_point( builder, x, y,
  1916.                                      (FT_Bool)( count == 3 ) );
  1917.               args += 2;
  1918.             }
  1919.  
  1920.             /* is last operand an x- or y-delta? */
  1921.             if ( horizontal )
  1922.             {
  1923.               x += args[0];
  1924.               y  = start_y;
  1925.             }
  1926.             else
  1927.             {
  1928.               x  = start_x;
  1929.               y += args[0];
  1930.             }
  1931.  
  1932.             cff_builder_add_point( builder, x, y, 1 );
  1933.  
  1934.             args = stack;
  1935.             break;
  1936.            }
  1937.  
  1938.         case cff_op_flex:
  1939.           {
  1940.             FT_UInt  count;
  1941.  
  1942.  
  1943.             FT_TRACE4(( " flex\n" ));
  1944.  
  1945.             if ( cff_builder_start_point( builder, x, y ) ||
  1946.                  cff_check_points( builder, 6 )           )
  1947.               goto Fail;
  1948.  
  1949.             for ( count = 6; count > 0; count-- )
  1950.             {
  1951.               x += args[0];
  1952.               y += args[1];
  1953.               cff_builder_add_point( builder, x, y,
  1954.                                      (FT_Bool)( count == 4 || count == 1 ) );
  1955.               args += 2;
  1956.             }
  1957.  
  1958.             args = stack;
  1959.           }
  1960.           break;
  1961.  
  1962.         case cff_op_seac:
  1963.             FT_TRACE4(( " seac\n" ));
  1964.  
  1965.             error = cff_operator_seac( decoder,
  1966.                                        args[0], args[1], args[2],
  1967.                                        (FT_Int)( args[3] >> 16 ),
  1968.                                        (FT_Int)( args[4] >> 16 ) );
  1969.  
  1970.             /* add current outline to the glyph slot */
  1971.             FT_GlyphLoader_Add( builder->loader );
  1972.  
  1973.             /* return now! */
  1974.             FT_TRACE4(( "\n" ));
  1975.             return error;
  1976.  
  1977.         case cff_op_endchar:
  1978.           FT_TRACE4(( " endchar\n" ));
  1979.  
  1980.           /* We are going to emulate the seac operator. */
  1981.           if ( num_args >= 4 )
  1982.           {
  1983.             /* Save glyph width so that the subglyphs don't overwrite it. */
  1984.             FT_Pos  glyph_width = decoder->glyph_width;
  1985.  
  1986.  
  1987.             error = cff_operator_seac( decoder,
  1988.                                        0L, args[-4], args[-3],
  1989.                                        (FT_Int)( args[-2] >> 16 ),
  1990.                                        (FT_Int)( args[-1] >> 16 ) );
  1991.  
  1992.             decoder->glyph_width = glyph_width;
  1993.           }
  1994.           else
  1995.           {
  1996.             if ( !error )
  1997.               error = FT_Err_Ok;
  1998.  
  1999.             cff_builder_close_contour( builder );
  2000.  
  2001.             /* close hints recording session */
  2002.             if ( hinter )
  2003.             {
  2004.               if ( hinter->close( hinter->hints,
  2005.                                   builder->current->n_points ) )
  2006.                 goto Syntax_Error;
  2007.  
  2008.               /* apply hints to the loaded glyph outline now */
  2009.               hinter->apply( hinter->hints,
  2010.                              builder->current,
  2011.                              (PSH_Globals)builder->hints_globals,
  2012.                              decoder->hint_mode );
  2013.             }
  2014.  
  2015.             /* add current outline to the glyph slot */
  2016.             FT_GlyphLoader_Add( builder->loader );
  2017.           }
  2018.  
  2019.           /* return now! */
  2020.           FT_TRACE4(( "\n" ));
  2021.           return error;
  2022.  
  2023.         case cff_op_abs:
  2024.           FT_TRACE4(( " abs\n" ));
  2025.  
  2026.           if ( args[0] < 0 )
  2027.             args[0] = -args[0];
  2028.           args++;
  2029.           break;
  2030.  
  2031.         case cff_op_add:
  2032.           FT_TRACE4(( " add\n" ));
  2033.  
  2034.           args[0] += args[1];
  2035.           args++;
  2036.           break;
  2037.  
  2038.         case cff_op_sub:
  2039.           FT_TRACE4(( " sub\n" ));
  2040.  
  2041.           args[0] -= args[1];
  2042.           args++;
  2043.           break;
  2044.  
  2045.         case cff_op_div:
  2046.           FT_TRACE4(( " div\n" ));
  2047.  
  2048.           args[0] = FT_DivFix( args[0], args[1] );
  2049.           args++;
  2050.           break;
  2051.  
  2052.         case cff_op_neg:
  2053.           FT_TRACE4(( " neg\n" ));
  2054.  
  2055.           args[0] = -args[0];
  2056.           args++;
  2057.           break;
  2058.  
  2059.         case cff_op_random:
  2060.           {
  2061.             FT_Fixed  Rand;
  2062.  
  2063.  
  2064.             FT_TRACE4(( " rand\n" ));
  2065.  
  2066.             Rand = seed;
  2067.             if ( Rand >= 0x8000L )
  2068.               Rand++;
  2069.  
  2070.             args[0] = Rand;
  2071.             seed    = FT_MulFix( seed, 0x10000L - seed );
  2072.             if ( seed == 0 )
  2073.               seed += 0x2873;
  2074.             args++;
  2075.           }
  2076.           break;
  2077.  
  2078.         case cff_op_mul:
  2079.           FT_TRACE4(( " mul\n" ));
  2080.  
  2081.           args[0] = FT_MulFix( args[0], args[1] );
  2082.           args++;
  2083.           break;
  2084.  
  2085.         case cff_op_sqrt:
  2086.           FT_TRACE4(( " sqrt\n" ));
  2087.  
  2088.           if ( args[0] > 0 )
  2089.           {
  2090.             FT_Int    count = 9;
  2091.             FT_Fixed  root  = args[0];
  2092.             FT_Fixed  new_root;
  2093.  
  2094.  
  2095.             for (;;)
  2096.             {
  2097.               new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1;
  2098.               if ( new_root == root || count <= 0 )
  2099.                 break;
  2100.               root = new_root;
  2101.             }
  2102.             args[0] = new_root;
  2103.           }
  2104.           else
  2105.             args[0] = 0;
  2106.           args++;
  2107.           break;
  2108.  
  2109.         case cff_op_drop:
  2110.           /* nothing */
  2111.           FT_TRACE4(( " drop\n" ));
  2112.  
  2113.           break;
  2114.  
  2115.         case cff_op_exch:
  2116.           {
  2117.             FT_Fixed  tmp;
  2118.  
  2119.  
  2120.             FT_TRACE4(( " exch\n" ));
  2121.  
  2122.             tmp     = args[0];
  2123.             args[0] = args[1];
  2124.             args[1] = tmp;
  2125.             args   += 2;
  2126.           }
  2127.           break;
  2128.  
  2129.         case cff_op_index:
  2130.           {
  2131.             FT_Int  idx = (FT_Int)( args[0] >> 16 );
  2132.  
  2133.  
  2134.             FT_TRACE4(( " index\n" ));
  2135.  
  2136.             if ( idx < 0 )
  2137.               idx = 0;
  2138.             else if ( idx > num_args - 2 )
  2139.               idx = num_args - 2;
  2140.             args[0] = args[-( idx + 1 )];
  2141.             args++;
  2142.           }
  2143.           break;
  2144.  
  2145.         case cff_op_roll:
  2146.           {
  2147.             FT_Int  count = (FT_Int)( args[0] >> 16 );
  2148.             FT_Int  idx   = (FT_Int)( args[1] >> 16 );
  2149.  
  2150.  
  2151.             FT_TRACE4(( " roll\n" ));
  2152.  
  2153.             if ( count <= 0 )
  2154.               count = 1;
  2155.  
  2156.             args -= count;
  2157.             if ( args < stack )
  2158.               goto Stack_Underflow;
  2159.  
  2160.             if ( idx >= 0 )
  2161.             {
  2162.               while ( idx > 0 )
  2163.               {
  2164.                 FT_Fixed  tmp = args[count - 1];
  2165.                 FT_Int    i;
  2166.  
  2167.  
  2168.                 for ( i = count - 2; i >= 0; i-- )
  2169.                   args[i + 1] = args[i];
  2170.                 args[0] = tmp;
  2171.                 idx--;
  2172.               }
  2173.             }
  2174.             else
  2175.             {
  2176.               while ( idx < 0 )
  2177.               {
  2178.                 FT_Fixed  tmp = args[0];
  2179.                 FT_Int    i;
  2180.  
  2181.  
  2182.                 for ( i = 0; i < count - 1; i++ )
  2183.                   args[i] = args[i + 1];
  2184.                 args[count - 1] = tmp;
  2185.                 idx++;
  2186.               }
  2187.             }
  2188.             args += count;
  2189.           }
  2190.           break;
  2191.  
  2192.         case cff_op_dup:
  2193.           FT_TRACE4(( " dup\n" ));
  2194.  
  2195.           args[1] = args[0];
  2196.           args += 2;
  2197.           break;
  2198.  
  2199.         case cff_op_put:
  2200.           {
  2201.             FT_Fixed  val = args[0];
  2202.             FT_Int    idx = (FT_Int)( args[1] >> 16 );
  2203.  
  2204.  
  2205.             FT_TRACE4(( " put\n" ));
  2206.  
  2207.             if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
  2208.               decoder->buildchar[idx] = val;
  2209.           }
  2210.           break;
  2211.  
  2212.         case cff_op_get:
  2213.           {
  2214.             FT_Int    idx = (FT_Int)( args[0] >> 16 );
  2215.             FT_Fixed  val = 0;
  2216.  
  2217.  
  2218.             FT_TRACE4(( " get\n" ));
  2219.  
  2220.             if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
  2221.               val = decoder->buildchar[idx];
  2222.  
  2223.             args[0] = val;
  2224.             args++;
  2225.           }
  2226.           break;
  2227.  
  2228.         case cff_op_store:
  2229.           FT_TRACE4(( " store\n"));
  2230.  
  2231.           goto Unimplemented;
  2232.  
  2233.         case cff_op_load:
  2234.           FT_TRACE4(( " load\n" ));
  2235.  
  2236.           goto Unimplemented;
  2237.  
  2238.         case cff_op_dotsection:
  2239.           /* this operator is deprecated and ignored by the parser */
  2240.           FT_TRACE4(( " dotsection\n" ));
  2241.           break;
  2242.  
  2243.         case cff_op_closepath:
  2244.           /* this is an invalid Type 2 operator; however, there        */
  2245.           /* exist fonts which are incorrectly converted from probably */
  2246.           /* Type 1 to CFF, and some parsers seem to accept it         */
  2247.  
  2248.           FT_TRACE4(( " closepath (invalid op)\n" ));
  2249.  
  2250.           args = stack;
  2251.           break;
  2252.  
  2253.         case cff_op_hsbw:
  2254.           /* this is an invalid Type 2 operator; however, there        */
  2255.           /* exist fonts which are incorrectly converted from probably */
  2256.           /* Type 1 to CFF, and some parsers seem to accept it         */
  2257.  
  2258.           FT_TRACE4(( " hsbw (invalid op)\n" ));
  2259.  
  2260.           decoder->glyph_width = decoder->nominal_width + ( args[1] >> 16 );
  2261.  
  2262.           decoder->builder.left_bearing.x = args[0];
  2263.           decoder->builder.left_bearing.y = 0;
  2264.  
  2265.           x    = decoder->builder.pos_x + args[0];
  2266.           y    = decoder->builder.pos_y;
  2267.           args = stack;
  2268.           break;
  2269.  
  2270.         case cff_op_sbw:
  2271.           /* this is an invalid Type 2 operator; however, there        */
  2272.           /* exist fonts which are incorrectly converted from probably */
  2273.           /* Type 1 to CFF, and some parsers seem to accept it         */
  2274.  
  2275.           FT_TRACE4(( " sbw (invalid op)\n" ));
  2276.  
  2277.           decoder->glyph_width = decoder->nominal_width + ( args[2] >> 16 );
  2278.  
  2279.           decoder->builder.left_bearing.x = args[0];
  2280.           decoder->builder.left_bearing.y = args[1];
  2281.  
  2282.           x    = decoder->builder.pos_x + args[0];
  2283.           y    = decoder->builder.pos_y + args[1];
  2284.           args = stack;
  2285.           break;
  2286.  
  2287.         case cff_op_setcurrentpoint:
  2288.           /* this is an invalid Type 2 operator; however, there        */
  2289.           /* exist fonts which are incorrectly converted from probably */
  2290.           /* Type 1 to CFF, and some parsers seem to accept it         */
  2291.  
  2292.           FT_TRACE4(( " setcurrentpoint (invalid op)\n" ));
  2293.  
  2294.           x    = decoder->builder.pos_x + args[0];
  2295.           y    = decoder->builder.pos_y + args[1];
  2296.           args = stack;
  2297.           break;
  2298.  
  2299.         case cff_op_callothersubr:
  2300.           /* this is an invalid Type 2 operator; however, there        */
  2301.           /* exist fonts which are incorrectly converted from probably */
  2302.           /* Type 1 to CFF, and some parsers seem to accept it         */
  2303.  
  2304.           FT_TRACE4(( " callothersubr (invalid op)\n" ));
  2305.  
  2306.           /* subsequent `pop' operands should add the arguments,       */
  2307.           /* this is the implementation described for `unknown' other  */
  2308.           /* subroutines in the Type1 spec.                            */
  2309.           /*                                                           */
  2310.           /* XXX Fix return arguments (see discussion below).          */
  2311.           args -= 2 + ( args[-2] >> 16 );
  2312.           if ( args < stack )
  2313.             goto Stack_Underflow;
  2314.           break;
  2315.  
  2316.         case cff_op_pop:
  2317.           /* this is an invalid Type 2 operator; however, there        */
  2318.           /* exist fonts which are incorrectly converted from probably */
  2319.           /* Type 1 to CFF, and some parsers seem to accept it         */
  2320.  
  2321.           FT_TRACE4(( " pop (invalid op)\n" ));
  2322.  
  2323.           /* XXX Increasing `args' is wrong: After a certain number of */
  2324.           /* `pop's we get a stack overflow.  Reason for doing it is   */
  2325.           /* code like this (actually found in a CFF font):            */
  2326.           /*                                                           */
  2327.           /*   17 1 3 callothersubr                                    */
  2328.           /*   pop                                                     */
  2329.           /*   callsubr                                                */
  2330.           /*                                                           */
  2331.           /* Since we handle `callothersubr' as a no-op, and           */
  2332.           /* `callsubr' needs at least one argument, `pop' can't be a  */
  2333.           /* no-op too as it basically should be.                      */
  2334.           /*                                                           */
  2335.           /* The right solution would be to provide real support for   */
  2336.           /* `callothersubr' as done in `t1decode.c', however, given   */
  2337.           /* the fact that CFF fonts with `pop' are invalid, it is     */
  2338.           /* questionable whether it is worth the time.                */
  2339.           args++;
  2340.           break;
  2341.  
  2342.         case cff_op_and:
  2343.           {
  2344.             FT_Fixed  cond = args[0] && args[1];
  2345.  
  2346.  
  2347.             FT_TRACE4(( " and\n" ));
  2348.  
  2349.             args[0] = cond ? 0x10000L : 0;
  2350.             args++;
  2351.           }
  2352.           break;
  2353.  
  2354.         case cff_op_or:
  2355.           {
  2356.             FT_Fixed  cond = args[0] || args[1];
  2357.  
  2358.  
  2359.             FT_TRACE4(( " or\n" ));
  2360.  
  2361.             args[0] = cond ? 0x10000L : 0;
  2362.             args++;
  2363.           }
  2364.           break;
  2365.  
  2366.         case cff_op_eq:
  2367.           {
  2368.             FT_Fixed  cond = !args[0];
  2369.  
  2370.  
  2371.             FT_TRACE4(( " eq\n" ));
  2372.  
  2373.             args[0] = cond ? 0x10000L : 0;
  2374.             args++;
  2375.           }
  2376.           break;
  2377.  
  2378.         case cff_op_ifelse:
  2379.           {
  2380.             FT_Fixed  cond = ( args[2] <= args[3] );
  2381.  
  2382.  
  2383.             FT_TRACE4(( " ifelse\n" ));
  2384.  
  2385.             if ( !cond )
  2386.               args[0] = args[1];
  2387.             args++;
  2388.           }
  2389.           break;
  2390.  
  2391.         case cff_op_callsubr:
  2392.           {
  2393.             FT_UInt  idx = (FT_UInt)( ( args[0] >> 16 ) +
  2394.                                       decoder->locals_bias );
  2395.  
  2396.  
  2397.             FT_TRACE4(( " callsubr(%d)\n", idx ));
  2398.  
  2399.             if ( idx >= decoder->num_locals )
  2400.             {
  2401.               FT_ERROR(( "cff_decoder_parse_charstrings:"
  2402.                          " invalid local subr index\n" ));
  2403.               goto Syntax_Error;
  2404.             }
  2405.  
  2406.             if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
  2407.             {
  2408.               FT_ERROR(( "cff_decoder_parse_charstrings:"
  2409.                          " too many nested subrs\n" ));
  2410.               goto Syntax_Error;
  2411.             }
  2412.  
  2413.             zone->cursor = ip;  /* save current instruction pointer */
  2414.  
  2415.             zone++;
  2416.             zone->base   = decoder->locals[idx];
  2417.             zone->limit  = decoder->locals[idx + 1];
  2418.             zone->cursor = zone->base;
  2419.  
  2420.             if ( !zone->base || zone->limit == zone->base )
  2421.             {
  2422.               FT_ERROR(( "cff_decoder_parse_charstrings:"
  2423.                          " invoking empty subrs\n" ));
  2424.               goto Syntax_Error;
  2425.             }
  2426.  
  2427.             decoder->zone = zone;
  2428.             ip            = zone->base;
  2429.             limit         = zone->limit;
  2430.           }
  2431.           break;
  2432.  
  2433.         case cff_op_callgsubr:
  2434.           {
  2435.             FT_UInt  idx = (FT_UInt)( ( args[0] >> 16 ) +
  2436.                                       decoder->globals_bias );
  2437.  
  2438.  
  2439.             FT_TRACE4(( " callgsubr(%d)\n", idx ));
  2440.  
  2441.             if ( idx >= decoder->num_globals )
  2442.             {
  2443.               FT_ERROR(( "cff_decoder_parse_charstrings:"
  2444.                          " invalid global subr index\n" ));
  2445.               goto Syntax_Error;
  2446.             }
  2447.  
  2448.             if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
  2449.             {
  2450.               FT_ERROR(( "cff_decoder_parse_charstrings:"
  2451.                          " too many nested subrs\n" ));
  2452.               goto Syntax_Error;
  2453.             }
  2454.  
  2455.             zone->cursor = ip;  /* save current instruction pointer */
  2456.  
  2457.             zone++;
  2458.             zone->base   = decoder->globals[idx];
  2459.             zone->limit  = decoder->globals[idx + 1];
  2460.             zone->cursor = zone->base;
  2461.  
  2462.             if ( !zone->base || zone->limit == zone->base )
  2463.             {
  2464.               FT_ERROR(( "cff_decoder_parse_charstrings:"
  2465.                          " invoking empty subrs\n" ));
  2466.               goto Syntax_Error;
  2467.             }
  2468.  
  2469.             decoder->zone = zone;
  2470.             ip            = zone->base;
  2471.             limit         = zone->limit;
  2472.           }
  2473.           break;
  2474.  
  2475.         case cff_op_return:
  2476.           FT_TRACE4(( " return\n" ));
  2477.  
  2478.           if ( decoder->zone <= decoder->zones )
  2479.           {
  2480.             FT_ERROR(( "cff_decoder_parse_charstrings:"
  2481.                        " unexpected return\n" ));
  2482.             goto Syntax_Error;
  2483.           }
  2484.  
  2485.           decoder->zone--;
  2486.           zone  = decoder->zone;
  2487.           ip    = zone->cursor;
  2488.           limit = zone->limit;
  2489.           break;
  2490.  
  2491.         default:
  2492.         Unimplemented:
  2493.           FT_ERROR(( "Unimplemented opcode: %d", ip[-1] ));
  2494.  
  2495.           if ( ip[-1] == 12 )
  2496.             FT_ERROR(( " %d", ip[0] ));
  2497.           FT_ERROR(( "\n" ));
  2498.  
  2499.           return FT_THROW( Unimplemented_Feature );
  2500.         }
  2501.  
  2502.         decoder->top = args;
  2503.  
  2504.         if ( decoder->top - stack >= CFF_MAX_OPERANDS )
  2505.           goto Stack_Overflow;
  2506.  
  2507.       } /* general operator processing */
  2508.  
  2509.     } /* while ip < limit */
  2510.  
  2511.     FT_TRACE4(( "..end..\n\n" ));
  2512.  
  2513.   Fail:
  2514.     return error;
  2515.  
  2516.   Syntax_Error:
  2517.     FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" ));
  2518.     return FT_THROW( Invalid_File_Format );
  2519.  
  2520.   Stack_Underflow:
  2521.     FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" ));
  2522.     return FT_THROW( Too_Few_Arguments );
  2523.  
  2524.   Stack_Overflow:
  2525.     FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" ));
  2526.     return FT_THROW( Stack_Overflow );
  2527.   }
  2528.  
  2529. #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
  2530.  
  2531.  
  2532.   /*************************************************************************/
  2533.   /*************************************************************************/
  2534.   /*************************************************************************/
  2535.   /**********                                                      *********/
  2536.   /**********                                                      *********/
  2537.   /**********            COMPUTE THE MAXIMUM ADVANCE WIDTH         *********/
  2538.   /**********                                                      *********/
  2539.   /**********    The following code is in charge of computing      *********/
  2540.   /**********    the maximum advance width of the font.  It        *********/
  2541.   /**********    quickly processes each glyph charstring to        *********/
  2542.   /**********    extract the value from either a `sbw' or `seac'   *********/
  2543.   /**********    operator.                                         *********/
  2544.   /**********                                                      *********/
  2545.   /*************************************************************************/
  2546.   /*************************************************************************/
  2547.   /*************************************************************************/
  2548.  
  2549.  
  2550. #if 0 /* unused until we support pure CFF fonts */
  2551.  
  2552.  
  2553.   FT_LOCAL_DEF( FT_Error )
  2554.   cff_compute_max_advance( TT_Face  face,
  2555.                            FT_Int*  max_advance )
  2556.   {
  2557.     FT_Error     error = FT_Err_Ok;
  2558.     CFF_Decoder  decoder;
  2559.     FT_Int       glyph_index;
  2560.     CFF_Font     cff = (CFF_Font)face->other;
  2561.  
  2562.  
  2563.     *max_advance = 0;
  2564.  
  2565.     /* Initialize load decoder */
  2566.     cff_decoder_init( &decoder, face, 0, 0, 0, 0 );
  2567.  
  2568.     decoder.builder.metrics_only = 1;
  2569.     decoder.builder.load_points  = 0;
  2570.  
  2571.     /* For each glyph, parse the glyph charstring and extract */
  2572.     /* the advance width.                                     */
  2573.     for ( glyph_index = 0; glyph_index < face->root.num_glyphs;
  2574.           glyph_index++ )
  2575.     {
  2576.       FT_Byte*  charstring;
  2577.       FT_ULong  charstring_len;
  2578.  
  2579.  
  2580.       /* now get load the unscaled outline */
  2581.       error = cff_get_glyph_data( face, glyph_index,
  2582.                                   &charstring, &charstring_len );
  2583.       if ( !error )
  2584.       {
  2585.         error = cff_decoder_prepare( &decoder, size, glyph_index );
  2586.         if ( !error )
  2587.           error = cff_decoder_parse_charstrings( &decoder,
  2588.                                                  charstring,
  2589.                                                  charstring_len );
  2590.  
  2591.         cff_free_glyph_data( face, &charstring, &charstring_len );
  2592.       }
  2593.  
  2594.       /* ignore the error if one has occurred -- skip to next glyph */
  2595.       error = FT_Err_Ok;
  2596.     }
  2597.  
  2598.     *max_advance = decoder.builder.advance.x;
  2599.  
  2600.     return FT_Err_Ok;
  2601.   }
  2602.  
  2603.  
  2604. #endif /* 0 */
  2605.  
  2606.  
  2607.   FT_LOCAL_DEF( FT_Error )
  2608.   cff_slot_load( CFF_GlyphSlot  glyph,
  2609.                  CFF_Size       size,
  2610.                  FT_UInt        glyph_index,
  2611.                  FT_Int32       load_flags )
  2612.   {
  2613.     FT_Error     error;
  2614.     CFF_Decoder  decoder;
  2615.     TT_Face      face = (TT_Face)glyph->root.face;
  2616.     FT_Bool      hinting, scaled, force_scaling;
  2617.     CFF_Font     cff  = (CFF_Font)face->extra.data;
  2618.  
  2619.     FT_Matrix    font_matrix;
  2620.     FT_Vector    font_offset;
  2621.  
  2622.  
  2623.     force_scaling = FALSE;
  2624.  
  2625.     /* in a CID-keyed font, consider `glyph_index' as a CID and map */
  2626.     /* it immediately to the real glyph_index -- if it isn't a      */
  2627.     /* subsetted font, glyph_indices and CIDs are identical, though */
  2628.     if ( cff->top_font.font_dict.cid_registry != 0xFFFFU &&
  2629.          cff->charset.cids                               )
  2630.     {
  2631.       /* don't handle CID 0 (.notdef) which is directly mapped to GID 0 */
  2632.       if ( glyph_index != 0 )
  2633.       {
  2634.         glyph_index = cff_charset_cid_to_gindex( &cff->charset,
  2635.                                                  glyph_index );
  2636.         if ( glyph_index == 0 )
  2637.           return FT_THROW( Invalid_Argument );
  2638.       }
  2639.     }
  2640.     else if ( glyph_index >= cff->num_glyphs )
  2641.       return FT_THROW( Invalid_Argument );
  2642.  
  2643.     if ( load_flags & FT_LOAD_NO_RECURSE )
  2644.       load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
  2645.  
  2646.     glyph->x_scale = 0x10000L;
  2647.     glyph->y_scale = 0x10000L;
  2648.     if ( size )
  2649.     {
  2650.       glyph->x_scale = size->root.metrics.x_scale;
  2651.       glyph->y_scale = size->root.metrics.y_scale;
  2652.     }
  2653.  
  2654. #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
  2655.  
  2656.     /* try to load embedded bitmap if any              */
  2657.     /*                                                 */
  2658.     /* XXX: The convention should be emphasized in     */
  2659.     /*      the documents because it can be confusing. */
  2660.     if ( size )
  2661.     {
  2662.       CFF_Face      cff_face = (CFF_Face)size->root.face;
  2663.       SFNT_Service  sfnt     = (SFNT_Service)cff_face->sfnt;
  2664.       FT_Stream     stream   = cff_face->root.stream;
  2665.  
  2666.  
  2667.       if ( size->strike_index != 0xFFFFFFFFUL      &&
  2668.            sfnt->load_eblc                         &&
  2669.            ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
  2670.       {
  2671.         TT_SBit_MetricsRec  metrics;
  2672.  
  2673.  
  2674.         error = sfnt->load_sbit_image( face,
  2675.                                        size->strike_index,
  2676.                                        glyph_index,
  2677.                                        (FT_Int)load_flags,
  2678.                                        stream,
  2679.                                        &glyph->root.bitmap,
  2680.                                        &metrics );
  2681.  
  2682.         if ( !error )
  2683.         {
  2684.           FT_Bool    has_vertical_info;
  2685.           FT_UShort  advance;
  2686.           FT_Short   dummy;
  2687.  
  2688.  
  2689.           glyph->root.outline.n_points   = 0;
  2690.           glyph->root.outline.n_contours = 0;
  2691.  
  2692.           glyph->root.metrics.width  = (FT_Pos)metrics.width  << 6;
  2693.           glyph->root.metrics.height = (FT_Pos)metrics.height << 6;
  2694.  
  2695.           glyph->root.metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6;
  2696.           glyph->root.metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6;
  2697.           glyph->root.metrics.horiAdvance  = (FT_Pos)metrics.horiAdvance  << 6;
  2698.  
  2699.           glyph->root.metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6;
  2700.           glyph->root.metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6;
  2701.           glyph->root.metrics.vertAdvance  = (FT_Pos)metrics.vertAdvance  << 6;
  2702.  
  2703.           glyph->root.format = FT_GLYPH_FORMAT_BITMAP;
  2704.  
  2705.           if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
  2706.           {
  2707.             glyph->root.bitmap_left = metrics.vertBearingX;
  2708.             glyph->root.bitmap_top  = metrics.vertBearingY;
  2709.           }
  2710.           else
  2711.           {
  2712.             glyph->root.bitmap_left = metrics.horiBearingX;
  2713.             glyph->root.bitmap_top  = metrics.horiBearingY;
  2714.           }
  2715.  
  2716.           /* compute linear advance widths */
  2717.  
  2718.           ( (SFNT_Service)face->sfnt )->get_metrics( face, 0,
  2719.                                                      glyph_index,
  2720.                                                      &dummy,
  2721.                                                      &advance );
  2722.           glyph->root.linearHoriAdvance = advance;
  2723.  
  2724.           has_vertical_info = FT_BOOL(
  2725.                                 face->vertical_info                   &&
  2726.                                 face->vertical.number_Of_VMetrics > 0 );
  2727.  
  2728.           /* get the vertical metrics from the vtmx table if we have one */
  2729.           if ( has_vertical_info )
  2730.           {
  2731.             ( (SFNT_Service)face->sfnt )->get_metrics( face, 1,
  2732.                                                        glyph_index,
  2733.                                                        &dummy,
  2734.                                                        &advance );
  2735.             glyph->root.linearVertAdvance = advance;
  2736.           }
  2737.           else
  2738.           {
  2739.             /* make up vertical ones */
  2740.             if ( face->os2.version != 0xFFFFU )
  2741.               glyph->root.linearVertAdvance = (FT_Pos)
  2742.                 ( face->os2.sTypoAscender - face->os2.sTypoDescender );
  2743.             else
  2744.               glyph->root.linearVertAdvance = (FT_Pos)
  2745.                 ( face->horizontal.Ascender - face->horizontal.Descender );
  2746.           }
  2747.  
  2748.           return error;
  2749.         }
  2750.       }
  2751.     }
  2752.  
  2753. #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
  2754.  
  2755.     /* return immediately if we only want the embedded bitmaps */
  2756.     if ( load_flags & FT_LOAD_SBITS_ONLY )
  2757.       return FT_THROW( Invalid_Argument );
  2758.  
  2759.     /* if we have a CID subfont, use its matrix (which has already */
  2760.     /* been multiplied with the root matrix)                       */
  2761.  
  2762.     /* this scaling is only relevant if the PS hinter isn't active */
  2763.     if ( cff->num_subfonts )
  2764.     {
  2765.       FT_ULong  top_upm, sub_upm;
  2766.       FT_Byte   fd_index = cff_fd_select_get( &cff->fd_select,
  2767.                                               glyph_index );
  2768.  
  2769.  
  2770.       if ( fd_index >= cff->num_subfonts )
  2771.         fd_index = (FT_Byte)( cff->num_subfonts - 1 );
  2772.  
  2773.       top_upm = cff->top_font.font_dict.units_per_em;
  2774.       sub_upm = cff->subfonts[fd_index]->font_dict.units_per_em;
  2775.  
  2776.  
  2777.       font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix;
  2778.       font_offset = cff->subfonts[fd_index]->font_dict.font_offset;
  2779.  
  2780.       if ( top_upm != sub_upm )
  2781.       {
  2782.         glyph->x_scale = FT_MulDiv( glyph->x_scale, top_upm, sub_upm );
  2783.         glyph->y_scale = FT_MulDiv( glyph->y_scale, top_upm, sub_upm );
  2784.  
  2785.         force_scaling = TRUE;
  2786.       }
  2787.     }
  2788.     else
  2789.     {
  2790.       font_matrix = cff->top_font.font_dict.font_matrix;
  2791.       font_offset = cff->top_font.font_dict.font_offset;
  2792.     }
  2793.  
  2794.     glyph->root.outline.n_points   = 0;
  2795.     glyph->root.outline.n_contours = 0;
  2796.  
  2797.     /* top-level code ensures that FT_LOAD_NO_HINTING is set */
  2798.     /* if FT_LOAD_NO_SCALE is active                         */
  2799.     hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
  2800.     scaled  = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE   ) == 0 );
  2801.  
  2802.     glyph->hint        = hinting;
  2803.     glyph->scaled      = scaled;
  2804.     glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;  /* by default */
  2805.  
  2806.     {
  2807. #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
  2808.       CFF_Driver  driver = (CFF_Driver)FT_FACE_DRIVER( face );
  2809. #endif
  2810.  
  2811.  
  2812.       FT_Byte*  charstring;
  2813.       FT_ULong  charstring_len;
  2814.  
  2815.  
  2816.       cff_decoder_init( &decoder, face, size, glyph, hinting,
  2817.                         FT_LOAD_TARGET_MODE( load_flags ) );
  2818.  
  2819.       if ( load_flags & FT_LOAD_ADVANCE_ONLY )
  2820.         decoder.width_only = TRUE;
  2821.  
  2822.       decoder.builder.no_recurse =
  2823.         (FT_Bool)( load_flags & FT_LOAD_NO_RECURSE );
  2824.  
  2825.       /* now load the unscaled outline */
  2826.       error = cff_get_glyph_data( face, glyph_index,
  2827.                                   &charstring, &charstring_len );
  2828.       if ( error )
  2829.         goto Glyph_Build_Finished;
  2830.  
  2831.       error = cff_decoder_prepare( &decoder, size, glyph_index );
  2832.       if ( error )
  2833.         goto Glyph_Build_Finished;
  2834.  
  2835. #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
  2836.       /* choose which CFF renderer to use */
  2837.       if ( driver->hinting_engine == FT_CFF_HINTING_FREETYPE )
  2838.         error = cff_decoder_parse_charstrings( &decoder,
  2839.                                                charstring,
  2840.                                                charstring_len );
  2841.       else
  2842. #endif
  2843.       {
  2844.         error = cf2_decoder_parse_charstrings( &decoder,
  2845.                                                charstring,
  2846.                                                charstring_len );
  2847.  
  2848.         /* Adobe's engine uses 16.16 numbers everywhere;              */
  2849.         /* as a consequence, glyphs larger than 2000ppem get rejected */
  2850.         if ( FT_ERR_EQ( error, Glyph_Too_Big ) )
  2851.         {
  2852.           /* this time, we retry unhinted and scale up the glyph later on */
  2853.           /* (the engine uses and sets the hardcoded value 0x10000 / 64 = */
  2854.           /* 0x400 for both `x_scale' and `y_scale' in this case)         */
  2855.           hinting       = FALSE;
  2856.           force_scaling = TRUE;
  2857.           glyph->hint   = hinting;
  2858.  
  2859.           error = cf2_decoder_parse_charstrings( &decoder,
  2860.                                                  charstring,
  2861.                                                  charstring_len );
  2862.         }
  2863.       }
  2864.  
  2865.       cff_free_glyph_data( face, &charstring, charstring_len );
  2866.  
  2867.       if ( error )
  2868.         goto Glyph_Build_Finished;
  2869.  
  2870. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  2871.       /* Control data and length may not be available for incremental */
  2872.       /* fonts.                                                       */
  2873.       if ( face->root.internal->incremental_interface )
  2874.       {
  2875.         glyph->root.control_data = 0;
  2876.         glyph->root.control_len = 0;
  2877.       }
  2878.       else
  2879. #endif /* FT_CONFIG_OPTION_INCREMENTAL */
  2880.  
  2881.       /* We set control_data and control_len if charstrings is loaded. */
  2882.       /* See how charstring loads at cff_index_access_element() in     */
  2883.       /* cffload.c.                                                    */
  2884.       {
  2885.         CFF_Index  csindex = &cff->charstrings_index;
  2886.  
  2887.  
  2888.         if ( csindex->offsets )
  2889.         {
  2890.           glyph->root.control_data = csindex->bytes +
  2891.                                      csindex->offsets[glyph_index] - 1;
  2892.           glyph->root.control_len  = charstring_len;
  2893.         }
  2894.       }
  2895.  
  2896.   Glyph_Build_Finished:
  2897.       /* save new glyph tables, if no error */
  2898.       if ( !error )
  2899.         cff_builder_done( &decoder.builder );
  2900.       /* XXX: anything to do for broken glyph entry? */
  2901.     }
  2902.  
  2903. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  2904.  
  2905.     /* Incremental fonts can optionally override the metrics. */
  2906.     if ( !error                                                               &&
  2907.          face->root.internal->incremental_interface                           &&
  2908.          face->root.internal->incremental_interface->funcs->get_glyph_metrics )
  2909.     {
  2910.       FT_Incremental_MetricsRec  metrics;
  2911.  
  2912.  
  2913.       metrics.bearing_x = decoder.builder.left_bearing.x;
  2914.       metrics.bearing_y = 0;
  2915.       metrics.advance   = decoder.builder.advance.x;
  2916.       metrics.advance_v = decoder.builder.advance.y;
  2917.  
  2918.       error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
  2919.                 face->root.internal->incremental_interface->object,
  2920.                 glyph_index, FALSE, &metrics );
  2921.  
  2922.       decoder.builder.left_bearing.x = metrics.bearing_x;
  2923.       decoder.builder.advance.x      = metrics.advance;
  2924.       decoder.builder.advance.y      = metrics.advance_v;
  2925.     }
  2926.  
  2927. #endif /* FT_CONFIG_OPTION_INCREMENTAL */
  2928.  
  2929.     if ( !error )
  2930.     {
  2931.       /* Now, set the metrics -- this is rather simple, as   */
  2932.       /* the left side bearing is the xMin, and the top side */
  2933.       /* bearing the yMax.                                   */
  2934.  
  2935.       /* For composite glyphs, return only left side bearing and */
  2936.       /* advance width.                                          */
  2937.       if ( load_flags & FT_LOAD_NO_RECURSE )
  2938.       {
  2939.         FT_Slot_Internal  internal = glyph->root.internal;
  2940.  
  2941.  
  2942.         glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x;
  2943.         glyph->root.metrics.horiAdvance  = decoder.glyph_width;
  2944.         internal->glyph_matrix           = font_matrix;
  2945.         internal->glyph_delta            = font_offset;
  2946.         internal->glyph_transformed      = 1;
  2947.       }
  2948.       else
  2949.       {
  2950.         FT_BBox            cbox;
  2951.         FT_Glyph_Metrics*  metrics = &glyph->root.metrics;
  2952.         FT_Vector          advance;
  2953.         FT_Bool            has_vertical_info;
  2954.  
  2955.  
  2956.         /* copy the _unscaled_ advance width */
  2957.         metrics->horiAdvance                    = decoder.glyph_width;
  2958.         glyph->root.linearHoriAdvance           = decoder.glyph_width;
  2959.         glyph->root.internal->glyph_transformed = 0;
  2960.  
  2961.         has_vertical_info = FT_BOOL( face->vertical_info                   &&
  2962.                                      face->vertical.number_Of_VMetrics > 0 );
  2963.  
  2964.         /* get the vertical metrics from the vtmx table if we have one */
  2965.         if ( has_vertical_info )
  2966.         {
  2967.           FT_Short   vertBearingY = 0;
  2968.           FT_UShort  vertAdvance  = 0;
  2969.  
  2970.  
  2971.           ( (SFNT_Service)face->sfnt )->get_metrics( face, 1,
  2972.                                                      glyph_index,
  2973.                                                      &vertBearingY,
  2974.                                                      &vertAdvance );
  2975.           metrics->vertBearingY = vertBearingY;
  2976.           metrics->vertAdvance  = vertAdvance;
  2977.         }
  2978.         else
  2979.         {
  2980.           /* make up vertical ones */
  2981.           if ( face->os2.version != 0xFFFFU )
  2982.             metrics->vertAdvance = (FT_Pos)( face->os2.sTypoAscender -
  2983.                                              face->os2.sTypoDescender );
  2984.           else
  2985.             metrics->vertAdvance = (FT_Pos)( face->horizontal.Ascender -
  2986.                                              face->horizontal.Descender );
  2987.         }
  2988.  
  2989.         glyph->root.linearVertAdvance = metrics->vertAdvance;
  2990.  
  2991.         glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;
  2992.  
  2993.         glyph->root.outline.flags = 0;
  2994.         if ( size && size->root.metrics.y_ppem < 24 )
  2995.           glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION;
  2996.  
  2997.         glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL;
  2998.  
  2999.         if ( !( font_matrix.xx == 0x10000L &&
  3000.                 font_matrix.yy == 0x10000L &&
  3001.                 font_matrix.xy == 0        &&
  3002.                 font_matrix.yx == 0        ) )
  3003.           FT_Outline_Transform( &glyph->root.outline, &font_matrix );
  3004.  
  3005.         if ( !( font_offset.x == 0 &&
  3006.                 font_offset.y == 0 ) )
  3007.           FT_Outline_Translate( &glyph->root.outline,
  3008.                                 font_offset.x, font_offset.y );
  3009.  
  3010.         advance.x = metrics->horiAdvance;
  3011.         advance.y = 0;
  3012.         FT_Vector_Transform( &advance, &font_matrix );
  3013.         metrics->horiAdvance = advance.x + font_offset.x;
  3014.  
  3015.         advance.x = 0;
  3016.         advance.y = metrics->vertAdvance;
  3017.         FT_Vector_Transform( &advance, &font_matrix );
  3018.         metrics->vertAdvance = advance.y + font_offset.y;
  3019.  
  3020.         if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || force_scaling )
  3021.         {
  3022.           /* scale the outline and the metrics */
  3023.           FT_Int       n;
  3024.           FT_Outline*  cur     = &glyph->root.outline;
  3025.           FT_Vector*   vec     = cur->points;
  3026.           FT_Fixed     x_scale = glyph->x_scale;
  3027.           FT_Fixed     y_scale = glyph->y_scale;
  3028.  
  3029.  
  3030.           /* First of all, scale the points */
  3031.           if ( !hinting || !decoder.builder.hints_funcs )
  3032.             for ( n = cur->n_points; n > 0; n--, vec++ )
  3033.             {
  3034.               vec->x = FT_MulFix( vec->x, x_scale );
  3035.               vec->y = FT_MulFix( vec->y, y_scale );
  3036.             }
  3037.  
  3038.           /* Then scale the metrics */
  3039.           metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
  3040.           metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
  3041.         }
  3042.  
  3043.         /* compute the other metrics */
  3044.         FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
  3045.  
  3046.         metrics->width  = cbox.xMax - cbox.xMin;
  3047.         metrics->height = cbox.yMax - cbox.yMin;
  3048.  
  3049.         metrics->horiBearingX = cbox.xMin;
  3050.         metrics->horiBearingY = cbox.yMax;
  3051.  
  3052.         if ( has_vertical_info )
  3053.           metrics->vertBearingX = metrics->horiBearingX -
  3054.                                     metrics->horiAdvance / 2;
  3055.         else
  3056.         {
  3057.           if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
  3058.             ft_synthesize_vertical_metrics( metrics,
  3059.                                             metrics->vertAdvance );
  3060.         }
  3061.       }
  3062.     }
  3063.  
  3064.     return error;
  3065.   }
  3066.  
  3067.  
  3068. /* END */
  3069.