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