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