cffgload.c revision 41371e1e39c8528eb0c4bc40683c736e6683e60c
1/***************************************************************************/
2/*                                                                         */
3/*  cffgload.c                                                             */
4/*                                                                         */
5/*    OpenType Glyph Loader (body).                                        */
6/*                                                                         */
7/*  Copyright 1996-2012 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 enforce it by clearing the second bit  */
1517
1518            nargs = num_args & ~2;
1519
1520            if ( cff_builder_start_point( builder, x, y ) )
1521              goto Fail;
1522
1523            args -= nargs;
1524
1525            if ( nargs & 1 )
1526            {
1527              x += args[0];
1528              args++;
1529              nargs--;
1530            }
1531
1532            if ( check_points( builder, 3 * ( nargs / 4 ) ) )
1533              goto Fail;
1534
1535            while ( args < decoder->top )
1536            {
1537              y += args[0];
1538              cff_builder_add_point( builder, x, y, 0 );
1539              x += args[1];
1540              y += args[2];
1541              cff_builder_add_point( builder, x, y, 0 );
1542              y += args[3];
1543              cff_builder_add_point( builder, x, y, 1 );
1544              args += 4;
1545            }
1546            args = stack;
1547          }
1548          break;
1549
1550        case cff_op_hhcurveto:
1551          {
1552            FT_Int  nargs;
1553
1554
1555            FT_TRACE4(( " hhcurveto\n" ));
1556
1557            if ( num_args < 4 )
1558              goto Stack_Underflow;
1559
1560            /* if num_args isn't of the form 4n or 4n+1, */
1561            /* we enforce it by clearing the second bit  */
1562
1563            nargs = num_args & ~2;
1564
1565            if ( cff_builder_start_point( builder, x, y ) )
1566              goto Fail;
1567
1568            args -= nargs;
1569            if ( nargs & 1 )
1570            {
1571              y += args[0];
1572              args++;
1573              nargs--;
1574            }
1575
1576            if ( check_points( builder, 3 * ( nargs / 4 ) ) )
1577              goto Fail;
1578
1579            while ( args < decoder->top )
1580            {
1581              x += args[0];
1582              cff_builder_add_point( builder, x, y, 0 );
1583              x += args[1];
1584              y += args[2];
1585              cff_builder_add_point( builder, x, y, 0 );
1586              x += args[3];
1587              cff_builder_add_point( builder, x, y, 1 );
1588              args += 4;
1589            }
1590            args = stack;
1591          }
1592          break;
1593
1594        case cff_op_vhcurveto:
1595        case cff_op_hvcurveto:
1596          {
1597            FT_Int  phase;
1598            FT_Int  nargs;
1599
1600
1601            FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto\n"
1602                                               : " hvcurveto\n" ));
1603
1604            if ( cff_builder_start_point( builder, x, y ) )
1605              goto Fail;
1606
1607            if ( num_args < 4 )
1608              goto Stack_Underflow;
1609
1610            /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */
1611            /* we enforce it by clearing the second bit               */
1612
1613            nargs = num_args & ~2;
1614
1615            args -= nargs;
1616            if ( check_points( builder, ( nargs / 4 ) * 3 ) )
1617              goto Stack_Underflow;
1618
1619            phase = ( op == cff_op_hvcurveto );
1620
1621            while ( nargs >= 4 )
1622            {
1623              nargs -= 4;
1624              if ( phase )
1625              {
1626                x += args[0];
1627                cff_builder_add_point( builder, x, y, 0 );
1628                x += args[1];
1629                y += args[2];
1630                cff_builder_add_point( builder, x, y, 0 );
1631                y += args[3];
1632                if ( nargs == 1 )
1633                  x += args[4];
1634                cff_builder_add_point( builder, x, y, 1 );
1635              }
1636              else
1637              {
1638                y += args[0];
1639                cff_builder_add_point( builder, x, y, 0 );
1640                x += args[1];
1641                y += args[2];
1642                cff_builder_add_point( builder, x, y, 0 );
1643                x += args[3];
1644                if ( nargs == 1 )
1645                  y += args[4];
1646                cff_builder_add_point( builder, x, y, 1 );
1647              }
1648              args  += 4;
1649              phase ^= 1;
1650            }
1651            args = stack;
1652          }
1653          break;
1654
1655        case cff_op_rlinecurve:
1656          {
1657            FT_Int  num_lines;
1658            FT_Int  nargs;
1659
1660
1661            FT_TRACE4(( " rlinecurve\n" ));
1662
1663            if ( num_args < 8 )
1664              goto Stack_Underflow;
1665
1666            nargs     = num_args & ~1;
1667            num_lines = ( nargs - 6 ) / 2;
1668
1669            if ( cff_builder_start_point( builder, x, y ) ||
1670                 check_points( builder, num_lines + 3 )   )
1671              goto Fail;
1672
1673            args -= nargs;
1674
1675            /* first, add the line segments */
1676            while ( num_lines > 0 )
1677            {
1678              x += args[0];
1679              y += args[1];
1680              cff_builder_add_point( builder, x, y, 1 );
1681              args += 2;
1682              num_lines--;
1683            }
1684
1685            /* then the curve */
1686            x += args[0];
1687            y += args[1];
1688            cff_builder_add_point( builder, x, y, 0 );
1689            x += args[2];
1690            y += args[3];
1691            cff_builder_add_point( builder, x, y, 0 );
1692            x += args[4];
1693            y += args[5];
1694            cff_builder_add_point( builder, x, y, 1 );
1695            args = stack;
1696          }
1697          break;
1698
1699        case cff_op_rcurveline:
1700          {
1701            FT_Int  num_curves;
1702            FT_Int  nargs;
1703
1704
1705            FT_TRACE4(( " rcurveline\n" ));
1706
1707            if ( num_args < 8 )
1708              goto Stack_Underflow;
1709
1710            nargs      = num_args - 2;
1711            nargs      = nargs - nargs % 6 + 2;
1712            num_curves = ( nargs - 2 ) / 6;
1713
1714            if ( cff_builder_start_point ( builder, x, y ) ||
1715                 check_points( builder, num_curves * 3 + 2 ) )
1716              goto Fail;
1717
1718            args -= nargs;
1719
1720            /* first, add the curves */
1721            while ( num_curves > 0 )
1722            {
1723              x += args[0];
1724              y += args[1];
1725              cff_builder_add_point( builder, x, y, 0 );
1726              x += args[2];
1727              y += args[3];
1728              cff_builder_add_point( builder, x, y, 0 );
1729              x += args[4];
1730              y += args[5];
1731              cff_builder_add_point( builder, x, y, 1 );
1732              args += 6;
1733              num_curves--;
1734            }
1735
1736            /* then the final line */
1737            x += args[0];
1738            y += args[1];
1739            cff_builder_add_point( builder, x, y, 1 );
1740            args = stack;
1741          }
1742          break;
1743
1744        case cff_op_hflex1:
1745          {
1746            FT_Pos start_y;
1747
1748
1749            FT_TRACE4(( " hflex1\n" ));
1750
1751            /* adding five more points: 4 control points, 1 on-curve point */
1752            /* -- make sure we have enough space for the start point if it */
1753            /* needs to be added                                           */
1754            if ( cff_builder_start_point( builder, x, y ) ||
1755                 check_points( builder, 6 )               )
1756              goto Fail;
1757
1758            /* record the starting point's y position for later use */
1759            start_y = y;
1760
1761            /* first control point */
1762            x += args[0];
1763            y += args[1];
1764            cff_builder_add_point( builder, x, y, 0 );
1765
1766            /* second control point */
1767            x += args[2];
1768            y += args[3];
1769            cff_builder_add_point( builder, x, y, 0 );
1770
1771            /* join point; on curve, with y-value the same as the last */
1772            /* control point's y-value                                 */
1773            x += args[4];
1774            cff_builder_add_point( builder, x, y, 1 );
1775
1776            /* third control point, with y-value the same as the join */
1777            /* point's y-value                                        */
1778            x += args[5];
1779            cff_builder_add_point( builder, x, y, 0 );
1780
1781            /* fourth control point */
1782            x += args[6];
1783            y += args[7];
1784            cff_builder_add_point( builder, x, y, 0 );
1785
1786            /* ending point, with y-value the same as the start   */
1787            x += args[8];
1788            y  = start_y;
1789            cff_builder_add_point( builder, x, y, 1 );
1790
1791            args = stack;
1792            break;
1793          }
1794
1795        case cff_op_hflex:
1796          {
1797            FT_Pos start_y;
1798
1799
1800            FT_TRACE4(( " hflex\n" ));
1801
1802            /* adding six more points; 4 control points, 2 on-curve points */
1803            if ( cff_builder_start_point( builder, x, y ) ||
1804                 check_points( builder, 6 )               )
1805              goto Fail;
1806
1807            /* record the starting point's y-position for later use */
1808            start_y = y;
1809
1810            /* first control point */
1811            x += args[0];
1812            cff_builder_add_point( builder, x, y, 0 );
1813
1814            /* second control point */
1815            x += args[1];
1816            y += args[2];
1817            cff_builder_add_point( builder, x, y, 0 );
1818
1819            /* join point; on curve, with y-value the same as the last */
1820            /* control point's y-value                                 */
1821            x += args[3];
1822            cff_builder_add_point( builder, x, y, 1 );
1823
1824            /* third control point, with y-value the same as the join */
1825            /* point's y-value                                        */
1826            x += args[4];
1827            cff_builder_add_point( builder, x, y, 0 );
1828
1829            /* fourth control point */
1830            x += args[5];
1831            y  = start_y;
1832            cff_builder_add_point( builder, x, y, 0 );
1833
1834            /* ending point, with y-value the same as the start point's */
1835            /* y-value -- we don't add this point, though               */
1836            x += args[6];
1837            cff_builder_add_point( builder, x, y, 1 );
1838
1839            args = stack;
1840            break;
1841          }
1842
1843        case cff_op_flex1:
1844          {
1845            FT_Pos     start_x, start_y; /* record start x, y values for */
1846                                         /* alter use                    */
1847            FT_Fixed   dx = 0, dy = 0;   /* used in horizontal/vertical  */
1848                                         /* algorithm below              */
1849            FT_Int     horizontal, count;
1850            FT_Fixed*  temp;
1851
1852
1853            FT_TRACE4(( " flex1\n" ));
1854
1855            /* adding six more points; 4 control points, 2 on-curve points */
1856            if ( cff_builder_start_point( builder, x, y ) ||
1857                 check_points( builder, 6 )               )
1858              goto Fail;
1859
1860            /* record the starting point's x, y position for later use */
1861            start_x = x;
1862            start_y = y;
1863
1864            /* XXX: figure out whether this is supposed to be a horizontal */
1865            /*      or vertical flex; the Type 2 specification is vague... */
1866
1867            temp = args;
1868
1869            /* grab up to the last argument */
1870            for ( count = 5; count > 0; count-- )
1871            {
1872              dx += temp[0];
1873              dy += temp[1];
1874              temp += 2;
1875            }
1876
1877            if ( dx < 0 )
1878              dx = -dx;
1879            if ( dy < 0 )
1880              dy = -dy;
1881
1882            /* strange test, but here it is... */
1883            horizontal = ( dx > dy );
1884
1885            for ( count = 5; count > 0; count-- )
1886            {
1887              x += args[0];
1888              y += args[1];
1889              cff_builder_add_point( builder, x, y,
1890                                     (FT_Bool)( count == 3 ) );
1891              args += 2;
1892            }
1893
1894            /* is last operand an x- or y-delta? */
1895            if ( horizontal )
1896            {
1897              x += args[0];
1898              y  = start_y;
1899            }
1900            else
1901            {
1902              x  = start_x;
1903              y += args[0];
1904            }
1905
1906            cff_builder_add_point( builder, x, y, 1 );
1907
1908            args = stack;
1909            break;
1910           }
1911
1912        case cff_op_flex:
1913          {
1914            FT_UInt  count;
1915
1916
1917            FT_TRACE4(( " flex\n" ));
1918
1919            if ( cff_builder_start_point( builder, x, y ) ||
1920                 check_points( builder, 6 )               )
1921              goto Fail;
1922
1923            for ( count = 6; count > 0; count-- )
1924            {
1925              x += args[0];
1926              y += args[1];
1927              cff_builder_add_point( builder, x, y,
1928                                     (FT_Bool)( count == 4 || count == 1 ) );
1929              args += 2;
1930            }
1931
1932            args = stack;
1933          }
1934          break;
1935
1936        case cff_op_seac:
1937            FT_TRACE4(( " seac\n" ));
1938
1939            error = cff_operator_seac( decoder,
1940                                       args[0], args[1], args[2],
1941                                       (FT_Int)( args[3] >> 16 ),
1942                                       (FT_Int)( args[4] >> 16 ) );
1943
1944            /* add current outline to the glyph slot */
1945            FT_GlyphLoader_Add( builder->loader );
1946
1947            /* return now! */
1948            FT_TRACE4(( "\n" ));
1949            return error;
1950
1951        case cff_op_endchar:
1952          FT_TRACE4(( " endchar\n" ));
1953
1954          /* We are going to emulate the seac operator. */
1955          if ( num_args >= 4 )
1956          {
1957            /* Save glyph width so that the subglyphs don't overwrite it. */
1958            FT_Pos  glyph_width = decoder->glyph_width;
1959
1960
1961            error = cff_operator_seac( decoder,
1962                                       0L, args[-4], args[-3],
1963                                       (FT_Int)( args[-2] >> 16 ),
1964                                       (FT_Int)( args[-1] >> 16 ) );
1965
1966            decoder->glyph_width = glyph_width;
1967          }
1968          else
1969          {
1970            if ( !error )
1971              error = CFF_Err_Ok;
1972
1973            cff_builder_close_contour( builder );
1974
1975            /* close hints recording session */
1976            if ( hinter )
1977            {
1978              if ( hinter->close( hinter->hints,
1979                                  builder->current->n_points ) )
1980                goto Syntax_Error;
1981
1982              /* apply hints to the loaded glyph outline now */
1983              hinter->apply( hinter->hints,
1984                             builder->current,
1985                             (PSH_Globals)builder->hints_globals,
1986                             decoder->hint_mode );
1987            }
1988
1989            /* add current outline to the glyph slot */
1990            FT_GlyphLoader_Add( builder->loader );
1991          }
1992
1993          /* return now! */
1994          FT_TRACE4(( "\n" ));
1995          return error;
1996
1997        case cff_op_abs:
1998          FT_TRACE4(( " abs\n" ));
1999
2000          if ( args[0] < 0 )
2001            args[0] = -args[0];
2002          args++;
2003          break;
2004
2005        case cff_op_add:
2006          FT_TRACE4(( " add\n" ));
2007
2008          args[0] += args[1];
2009          args++;
2010          break;
2011
2012        case cff_op_sub:
2013          FT_TRACE4(( " sub\n" ));
2014
2015          args[0] -= args[1];
2016          args++;
2017          break;
2018
2019        case cff_op_div:
2020          FT_TRACE4(( " div\n" ));
2021
2022          args[0] = FT_DivFix( args[0], args[1] );
2023          args++;
2024          break;
2025
2026        case cff_op_neg:
2027          FT_TRACE4(( " neg\n" ));
2028
2029          args[0] = -args[0];
2030          args++;
2031          break;
2032
2033        case cff_op_random:
2034          {
2035            FT_Fixed  Rand;
2036
2037
2038            FT_TRACE4(( " rand\n" ));
2039
2040            Rand = seed;
2041            if ( Rand >= 0x8000L )
2042              Rand++;
2043
2044            args[0] = Rand;
2045            seed    = FT_MulFix( seed, 0x10000L - seed );
2046            if ( seed == 0 )
2047              seed += 0x2873;
2048            args++;
2049          }
2050          break;
2051
2052        case cff_op_mul:
2053          FT_TRACE4(( " mul\n" ));
2054
2055          args[0] = FT_MulFix( args[0], args[1] );
2056          args++;
2057          break;
2058
2059        case cff_op_sqrt:
2060          FT_TRACE4(( " sqrt\n" ));
2061
2062          if ( args[0] > 0 )
2063          {
2064            FT_Int    count = 9;
2065            FT_Fixed  root  = args[0];
2066            FT_Fixed  new_root;
2067
2068
2069            for (;;)
2070            {
2071              new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1;
2072              if ( new_root == root || count <= 0 )
2073                break;
2074              root = new_root;
2075            }
2076            args[0] = new_root;
2077          }
2078          else
2079            args[0] = 0;
2080          args++;
2081          break;
2082
2083        case cff_op_drop:
2084          /* nothing */
2085          FT_TRACE4(( " drop\n" ));
2086
2087          break;
2088
2089        case cff_op_exch:
2090          {
2091            FT_Fixed  tmp;
2092
2093
2094            FT_TRACE4(( " exch\n" ));
2095
2096            tmp     = args[0];
2097            args[0] = args[1];
2098            args[1] = tmp;
2099            args   += 2;
2100          }
2101          break;
2102
2103        case cff_op_index:
2104          {
2105            FT_Int  idx = (FT_Int)( args[0] >> 16 );
2106
2107
2108            FT_TRACE4(( " index\n" ));
2109
2110            if ( idx < 0 )
2111              idx = 0;
2112            else if ( idx > num_args - 2 )
2113              idx = num_args - 2;
2114            args[0] = args[-( idx + 1 )];
2115            args++;
2116          }
2117          break;
2118
2119        case cff_op_roll:
2120          {
2121            FT_Int  count = (FT_Int)( args[0] >> 16 );
2122            FT_Int  idx   = (FT_Int)( args[1] >> 16 );
2123
2124
2125            FT_TRACE4(( " roll\n" ));
2126
2127            if ( count <= 0 )
2128              count = 1;
2129
2130            args -= count;
2131            if ( args < stack )
2132              goto Stack_Underflow;
2133
2134            if ( idx >= 0 )
2135            {
2136              while ( idx > 0 )
2137              {
2138                FT_Fixed  tmp = args[count - 1];
2139                FT_Int    i;
2140
2141
2142                for ( i = count - 2; i >= 0; i-- )
2143                  args[i + 1] = args[i];
2144                args[0] = tmp;
2145                idx--;
2146              }
2147            }
2148            else
2149            {
2150              while ( idx < 0 )
2151              {
2152                FT_Fixed  tmp = args[0];
2153                FT_Int    i;
2154
2155
2156                for ( i = 0; i < count - 1; i++ )
2157                  args[i] = args[i + 1];
2158                args[count - 1] = tmp;
2159                idx++;
2160              }
2161            }
2162            args += count;
2163          }
2164          break;
2165
2166        case cff_op_dup:
2167          FT_TRACE4(( " dup\n" ));
2168
2169          args[1] = args[0];
2170          args += 2;
2171          break;
2172
2173        case cff_op_put:
2174          {
2175            FT_Fixed  val = args[0];
2176            FT_Int    idx = (FT_Int)( args[1] >> 16 );
2177
2178
2179            FT_TRACE4(( " put\n" ));
2180
2181            if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
2182              decoder->buildchar[idx] = val;
2183          }
2184          break;
2185
2186        case cff_op_get:
2187          {
2188            FT_Int    idx = (FT_Int)( args[0] >> 16 );
2189            FT_Fixed  val = 0;
2190
2191
2192            FT_TRACE4(( " get\n" ));
2193
2194            if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
2195              val = decoder->buildchar[idx];
2196
2197            args[0] = val;
2198            args++;
2199          }
2200          break;
2201
2202        case cff_op_store:
2203          FT_TRACE4(( " store\n"));
2204
2205          goto Unimplemented;
2206
2207        case cff_op_load:
2208          FT_TRACE4(( " load\n" ));
2209
2210          goto Unimplemented;
2211
2212        case cff_op_dotsection:
2213          /* this operator is deprecated and ignored by the parser */
2214          FT_TRACE4(( " dotsection\n" ));
2215          break;
2216
2217        case cff_op_closepath:
2218          /* this is an invalid Type 2 operator; however, there        */
2219          /* exist fonts which are incorrectly converted from probably */
2220          /* Type 1 to CFF, and some parsers seem to accept it         */
2221
2222          FT_TRACE4(( " closepath (invalid op)\n" ));
2223
2224          args = stack;
2225          break;
2226
2227        case cff_op_hsbw:
2228          /* this is an invalid Type 2 operator; however, there        */
2229          /* exist fonts which are incorrectly converted from probably */
2230          /* Type 1 to CFF, and some parsers seem to accept it         */
2231
2232          FT_TRACE4(( " hsbw (invalid op)\n" ));
2233
2234          decoder->glyph_width = decoder->nominal_width + ( args[1] >> 16 );
2235
2236          decoder->builder.left_bearing.x = args[0];
2237          decoder->builder.left_bearing.y = 0;
2238
2239          x    = decoder->builder.pos_x + args[0];
2240          y    = decoder->builder.pos_y;
2241          args = stack;
2242          break;
2243
2244        case cff_op_sbw:
2245          /* this is an invalid Type 2 operator; however, there        */
2246          /* exist fonts which are incorrectly converted from probably */
2247          /* Type 1 to CFF, and some parsers seem to accept it         */
2248
2249          FT_TRACE4(( " sbw (invalid op)\n" ));
2250
2251          decoder->glyph_width = decoder->nominal_width + ( args[2] >> 16 );
2252
2253          decoder->builder.left_bearing.x = args[0];
2254          decoder->builder.left_bearing.y = args[1];
2255
2256          x    = decoder->builder.pos_x + args[0];
2257          y    = decoder->builder.pos_y + args[1];
2258          args = stack;
2259          break;
2260
2261        case cff_op_setcurrentpoint:
2262          /* this is an invalid Type 2 operator; however, there        */
2263          /* exist fonts which are incorrectly converted from probably */
2264          /* Type 1 to CFF, and some parsers seem to accept it         */
2265
2266          FT_TRACE4(( " setcurrentpoint (invalid op)\n" ));
2267
2268          x    = decoder->builder.pos_x + args[0];
2269          y    = decoder->builder.pos_y + args[1];
2270          args = stack;
2271          break;
2272
2273        case cff_op_callothersubr:
2274          /* this is an invalid Type 2 operator; however, there        */
2275          /* exist fonts which are incorrectly converted from probably */
2276          /* Type 1 to CFF, and some parsers seem to accept it         */
2277
2278          FT_TRACE4(( " callothersubr (invalid op)\n" ));
2279
2280          /* subsequent `pop' operands should add the arguments,       */
2281          /* this is the implementation described for `unknown' other  */
2282          /* subroutines in the Type1 spec.                            */
2283          /*                                                           */
2284          /* XXX Fix return arguments (see discussion below).          */
2285          args -= 2 + ( args[-2] >> 16 );
2286          if ( args < stack )
2287            goto Stack_Underflow;
2288          break;
2289
2290        case cff_op_pop:
2291          /* this is an invalid Type 2 operator; however, there        */
2292          /* exist fonts which are incorrectly converted from probably */
2293          /* Type 1 to CFF, and some parsers seem to accept it         */
2294
2295          FT_TRACE4(( " pop (invalid op)\n" ));
2296
2297          /* XXX Increasing `args' is wrong: After a certain number of */
2298          /* `pop's we get a stack overflow.  Reason for doing it is   */
2299          /* code like this (actually found in a CFF font):            */
2300          /*                                                           */
2301          /*   17 1 3 callothersubr                                    */
2302          /*   pop                                                     */
2303          /*   callsubr                                                */
2304          /*                                                           */
2305          /* Since we handle `callothersubr' as a no-op, and           */
2306          /* `callsubr' needs at least one argument, `pop' can't be a  */
2307          /* no-op too as it basically should be.                      */
2308          /*                                                           */
2309          /* The right solution would be to provide real support for   */
2310          /* `callothersubr' as done in `t1decode.c', however, given   */
2311          /* the fact that CFF fonts with `pop' are invalid, it is     */
2312          /* questionable whether it is worth the time.                */
2313          args++;
2314          break;
2315
2316        case cff_op_and:
2317          {
2318            FT_Fixed  cond = args[0] && args[1];
2319
2320
2321            FT_TRACE4(( " and\n" ));
2322
2323            args[0] = cond ? 0x10000L : 0;
2324            args++;
2325          }
2326          break;
2327
2328        case cff_op_or:
2329          {
2330            FT_Fixed  cond = args[0] || args[1];
2331
2332
2333            FT_TRACE4(( " or\n" ));
2334
2335            args[0] = cond ? 0x10000L : 0;
2336            args++;
2337          }
2338          break;
2339
2340        case cff_op_eq:
2341          {
2342            FT_Fixed  cond = !args[0];
2343
2344
2345            FT_TRACE4(( " eq\n" ));
2346
2347            args[0] = cond ? 0x10000L : 0;
2348            args++;
2349          }
2350          break;
2351
2352        case cff_op_ifelse:
2353          {
2354            FT_Fixed  cond = ( args[2] <= args[3] );
2355
2356
2357            FT_TRACE4(( " ifelse\n" ));
2358
2359            if ( !cond )
2360              args[0] = args[1];
2361            args++;
2362          }
2363          break;
2364
2365        case cff_op_callsubr:
2366          {
2367            FT_UInt  idx = (FT_UInt)( ( args[0] >> 16 ) +
2368                                      decoder->locals_bias );
2369
2370
2371            FT_TRACE4(( " callsubr(%d)\n", idx ));
2372
2373            if ( idx >= decoder->num_locals )
2374            {
2375              FT_ERROR(( "cff_decoder_parse_charstrings:"
2376                         " invalid local subr index\n" ));
2377              goto Syntax_Error;
2378            }
2379
2380            if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
2381            {
2382              FT_ERROR(( "cff_decoder_parse_charstrings:"
2383                         " too many nested subrs\n" ));
2384              goto Syntax_Error;
2385            }
2386
2387            zone->cursor = ip;  /* save current instruction pointer */
2388
2389            zone++;
2390            zone->base   = decoder->locals[idx];
2391            zone->limit  = decoder->locals[idx + 1];
2392            zone->cursor = zone->base;
2393
2394            if ( !zone->base || zone->limit == zone->base )
2395            {
2396              FT_ERROR(( "cff_decoder_parse_charstrings:"
2397                         " invoking empty subrs\n" ));
2398              goto Syntax_Error;
2399            }
2400
2401            decoder->zone = zone;
2402            ip            = zone->base;
2403            limit         = zone->limit;
2404          }
2405          break;
2406
2407        case cff_op_callgsubr:
2408          {
2409            FT_UInt  idx = (FT_UInt)( ( args[0] >> 16 ) +
2410                                      decoder->globals_bias );
2411
2412
2413            FT_TRACE4(( " callgsubr(%d)\n", idx ));
2414
2415            if ( idx >= decoder->num_globals )
2416            {
2417              FT_ERROR(( "cff_decoder_parse_charstrings:"
2418                         " invalid global subr index\n" ));
2419              goto Syntax_Error;
2420            }
2421
2422            if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
2423            {
2424              FT_ERROR(( "cff_decoder_parse_charstrings:"
2425                         " too many nested subrs\n" ));
2426              goto Syntax_Error;
2427            }
2428
2429            zone->cursor = ip;  /* save current instruction pointer */
2430
2431            zone++;
2432            zone->base   = decoder->globals[idx];
2433            zone->limit  = decoder->globals[idx + 1];
2434            zone->cursor = zone->base;
2435
2436            if ( !zone->base || zone->limit == zone->base )
2437            {
2438              FT_ERROR(( "cff_decoder_parse_charstrings:"
2439                         " invoking empty subrs\n" ));
2440              goto Syntax_Error;
2441            }
2442
2443            decoder->zone = zone;
2444            ip            = zone->base;
2445            limit         = zone->limit;
2446          }
2447          break;
2448
2449        case cff_op_return:
2450          FT_TRACE4(( " return\n" ));
2451
2452          if ( decoder->zone <= decoder->zones )
2453          {
2454            FT_ERROR(( "cff_decoder_parse_charstrings:"
2455                       " unexpected return\n" ));
2456            goto Syntax_Error;
2457          }
2458
2459          decoder->zone--;
2460          zone  = decoder->zone;
2461          ip    = zone->cursor;
2462          limit = zone->limit;
2463          break;
2464
2465        default:
2466        Unimplemented:
2467          FT_ERROR(( "Unimplemented opcode: %d", ip[-1] ));
2468
2469          if ( ip[-1] == 12 )
2470            FT_ERROR(( " %d", ip[0] ));
2471          FT_ERROR(( "\n" ));
2472
2473          return CFF_Err_Unimplemented_Feature;
2474        }
2475
2476        decoder->top = args;
2477
2478        if ( decoder->top - stack >= CFF_MAX_OPERANDS )
2479          goto Stack_Overflow;
2480
2481      } /* general operator processing */
2482
2483    } /* while ip < limit */
2484
2485    FT_TRACE4(( "..end..\n\n" ));
2486
2487  Fail:
2488    return error;
2489
2490  Syntax_Error:
2491    FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" ));
2492    return CFF_Err_Invalid_File_Format;
2493
2494  Stack_Underflow:
2495    FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" ));
2496    return CFF_Err_Too_Few_Arguments;
2497
2498  Stack_Overflow:
2499    FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" ));
2500    return CFF_Err_Stack_Overflow;
2501  }
2502
2503
2504  /*************************************************************************/
2505  /*************************************************************************/
2506  /*************************************************************************/
2507  /**********                                                      *********/
2508  /**********                                                      *********/
2509  /**********            COMPUTE THE MAXIMUM ADVANCE WIDTH         *********/
2510  /**********                                                      *********/
2511  /**********    The following code is in charge of computing      *********/
2512  /**********    the maximum advance width of the font.  It        *********/
2513  /**********    quickly processes each glyph charstring to        *********/
2514  /**********    extract the value from either a `sbw' or `seac'   *********/
2515  /**********    operator.                                         *********/
2516  /**********                                                      *********/
2517  /*************************************************************************/
2518  /*************************************************************************/
2519  /*************************************************************************/
2520
2521
2522#if 0 /* unused until we support pure CFF fonts */
2523
2524
2525  FT_LOCAL_DEF( FT_Error )
2526  cff_compute_max_advance( TT_Face  face,
2527                           FT_Int*  max_advance )
2528  {
2529    FT_Error     error = CFF_Err_Ok;
2530    CFF_Decoder  decoder;
2531    FT_Int       glyph_index;
2532    CFF_Font     cff = (CFF_Font)face->other;
2533
2534
2535    *max_advance = 0;
2536
2537    /* Initialize load decoder */
2538    cff_decoder_init( &decoder, face, 0, 0, 0, 0 );
2539
2540    decoder.builder.metrics_only = 1;
2541    decoder.builder.load_points  = 0;
2542
2543    /* For each glyph, parse the glyph charstring and extract */
2544    /* the advance width.                                     */
2545    for ( glyph_index = 0; glyph_index < face->root.num_glyphs;
2546          glyph_index++ )
2547    {
2548      FT_Byte*  charstring;
2549      FT_ULong  charstring_len;
2550
2551
2552      /* now get load the unscaled outline */
2553      error = cff_get_glyph_data( face, glyph_index,
2554                                  &charstring, &charstring_len );
2555      if ( !error )
2556      {
2557        error = cff_decoder_prepare( &decoder, size, glyph_index );
2558        if ( !error )
2559          error = cff_decoder_parse_charstrings( &decoder,
2560                                                 charstring,
2561                                                 charstring_len );
2562
2563        cff_free_glyph_data( face, &charstring, &charstring_len );
2564      }
2565
2566      /* ignore the error if one has occurred -- skip to next glyph */
2567      error = CFF_Err_Ok;
2568    }
2569
2570    *max_advance = decoder.builder.advance.x;
2571
2572    return CFF_Err_Ok;
2573  }
2574
2575
2576#endif /* 0 */
2577
2578
2579  FT_LOCAL_DEF( FT_Error )
2580  cff_slot_load( CFF_GlyphSlot  glyph,
2581                 CFF_Size       size,
2582                 FT_UInt        glyph_index,
2583                 FT_Int32       load_flags )
2584  {
2585    FT_Error     error;
2586    CFF_Decoder  decoder;
2587    TT_Face      face = (TT_Face)glyph->root.face;
2588    FT_Bool      hinting, force_scaling;
2589    CFF_Font     cff  = (CFF_Font)face->extra.data;
2590
2591    FT_Matrix    font_matrix;
2592    FT_Vector    font_offset;
2593
2594
2595    force_scaling = FALSE;
2596
2597    /* in a CID-keyed font, consider `glyph_index' as a CID and map */
2598    /* it immediately to the real glyph_index -- if it isn't a      */
2599    /* subsetted font, glyph_indices and CIDs are identical, though */
2600    if ( cff->top_font.font_dict.cid_registry != 0xFFFFU &&
2601         cff->charset.cids                               )
2602    {
2603      /* don't handle CID 0 (.notdef) which is directly mapped to GID 0 */
2604      if ( glyph_index != 0 )
2605      {
2606        glyph_index = cff_charset_cid_to_gindex( &cff->charset,
2607                                                 glyph_index );
2608        if ( glyph_index == 0 )
2609          return CFF_Err_Invalid_Argument;
2610      }
2611    }
2612    else if ( glyph_index >= cff->num_glyphs )
2613      return CFF_Err_Invalid_Argument;
2614
2615    if ( load_flags & FT_LOAD_NO_RECURSE )
2616      load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
2617
2618    glyph->x_scale = 0x10000L;
2619    glyph->y_scale = 0x10000L;
2620    if ( size )
2621    {
2622      glyph->x_scale = size->root.metrics.x_scale;
2623      glyph->y_scale = size->root.metrics.y_scale;
2624    }
2625
2626#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
2627
2628    /* try to load embedded bitmap if any              */
2629    /*                                                 */
2630    /* XXX: The convention should be emphasized in     */
2631    /*      the documents because it can be confusing. */
2632    if ( size )
2633    {
2634      CFF_Face      cff_face = (CFF_Face)size->root.face;
2635      SFNT_Service  sfnt     = (SFNT_Service)cff_face->sfnt;
2636      FT_Stream     stream   = cff_face->root.stream;
2637
2638
2639      if ( size->strike_index != 0xFFFFFFFFUL      &&
2640           sfnt->load_eblc                         &&
2641           ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
2642      {
2643        TT_SBit_MetricsRec  metrics;
2644
2645
2646        error = sfnt->load_sbit_image( face,
2647                                       size->strike_index,
2648                                       glyph_index,
2649                                       (FT_Int)load_flags,
2650                                       stream,
2651                                       &glyph->root.bitmap,
2652                                       &metrics );
2653
2654        if ( !error )
2655        {
2656          glyph->root.outline.n_points   = 0;
2657          glyph->root.outline.n_contours = 0;
2658
2659          glyph->root.metrics.width  = (FT_Pos)metrics.width  << 6;
2660          glyph->root.metrics.height = (FT_Pos)metrics.height << 6;
2661
2662          glyph->root.metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6;
2663          glyph->root.metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6;
2664          glyph->root.metrics.horiAdvance  = (FT_Pos)metrics.horiAdvance  << 6;
2665
2666          glyph->root.metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6;
2667          glyph->root.metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6;
2668          glyph->root.metrics.vertAdvance  = (FT_Pos)metrics.vertAdvance  << 6;
2669
2670          glyph->root.format = FT_GLYPH_FORMAT_BITMAP;
2671
2672          if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
2673          {
2674            glyph->root.bitmap_left = metrics.vertBearingX;
2675            glyph->root.bitmap_top  = metrics.vertBearingY;
2676          }
2677          else
2678          {
2679            glyph->root.bitmap_left = metrics.horiBearingX;
2680            glyph->root.bitmap_top  = metrics.horiBearingY;
2681          }
2682          return error;
2683        }
2684      }
2685    }
2686
2687#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
2688
2689    /* return immediately if we only want the embedded bitmaps */
2690    if ( load_flags & FT_LOAD_SBITS_ONLY )
2691      return CFF_Err_Invalid_Argument;
2692
2693    /* if we have a CID subfont, use its matrix (which has already */
2694    /* been multiplied with the root matrix)                       */
2695
2696    /* this scaling is only relevant if the PS hinter isn't active */
2697    if ( cff->num_subfonts )
2698    {
2699      FT_ULong  top_upm, sub_upm;
2700      FT_Byte   fd_index = cff_fd_select_get( &cff->fd_select,
2701                                              glyph_index );
2702
2703      if ( fd_index >= cff->num_subfonts )
2704        fd_index = (FT_Byte)( cff->num_subfonts - 1 );
2705
2706      top_upm = cff->top_font.font_dict.units_per_em;
2707      sub_upm = cff->subfonts[fd_index]->font_dict.units_per_em;
2708
2709
2710      font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix;
2711      font_offset = cff->subfonts[fd_index]->font_dict.font_offset;
2712
2713      if ( top_upm != sub_upm )
2714      {
2715        glyph->x_scale = FT_MulDiv( glyph->x_scale, top_upm, sub_upm );
2716        glyph->y_scale = FT_MulDiv( glyph->y_scale, top_upm, sub_upm );
2717
2718        force_scaling = TRUE;
2719      }
2720    }
2721    else
2722    {
2723      font_matrix = cff->top_font.font_dict.font_matrix;
2724      font_offset = cff->top_font.font_dict.font_offset;
2725    }
2726
2727    glyph->root.outline.n_points   = 0;
2728    glyph->root.outline.n_contours = 0;
2729
2730    hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE   ) == 0 &&
2731                       ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
2732
2733    glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;  /* by default */
2734
2735    {
2736      FT_Byte*  charstring;
2737      FT_ULong  charstring_len;
2738
2739
2740      cff_decoder_init( &decoder, face, size, glyph, hinting,
2741                        FT_LOAD_TARGET_MODE( load_flags ) );
2742
2743      if ( load_flags & FT_LOAD_ADVANCE_ONLY )
2744        decoder.width_only = TRUE;
2745
2746      decoder.builder.no_recurse =
2747        (FT_Bool)( load_flags & FT_LOAD_NO_RECURSE );
2748
2749      /* now load the unscaled outline */
2750      error = cff_get_glyph_data( face, glyph_index,
2751                                  &charstring, &charstring_len );
2752      if ( error )
2753        goto Glyph_Build_Finished;
2754
2755      error = cff_decoder_prepare( &decoder, size, glyph_index );
2756      if ( error )
2757        goto Glyph_Build_Finished;
2758
2759      error = cff_decoder_parse_charstrings( &decoder,
2760                                             charstring,
2761                                             charstring_len );
2762
2763      cff_free_glyph_data( face, &charstring, charstring_len );
2764
2765      if ( error )
2766        goto Glyph_Build_Finished;
2767
2768#ifdef FT_CONFIG_OPTION_INCREMENTAL
2769      /* Control data and length may not be available for incremental */
2770      /* fonts.                                                       */
2771      if ( face->root.internal->incremental_interface )
2772      {
2773        glyph->root.control_data = 0;
2774        glyph->root.control_len = 0;
2775      }
2776      else
2777#endif /* FT_CONFIG_OPTION_INCREMENTAL */
2778
2779      /* We set control_data and control_len if charstrings is loaded. */
2780      /* See how charstring loads at cff_index_access_element() in     */
2781      /* cffload.c.                                                    */
2782      {
2783        CFF_Index  csindex = &cff->charstrings_index;
2784
2785
2786        if ( csindex->offsets )
2787        {
2788          glyph->root.control_data = csindex->bytes +
2789                                     csindex->offsets[glyph_index] - 1;
2790          glyph->root.control_len  = charstring_len;
2791        }
2792      }
2793
2794  Glyph_Build_Finished:
2795      /* save new glyph tables, if no error */
2796      if ( !error )
2797        cff_builder_done( &decoder.builder );
2798      /* XXX: anything to do for broken glyph entry? */
2799    }
2800
2801#ifdef FT_CONFIG_OPTION_INCREMENTAL
2802
2803    /* Incremental fonts can optionally override the metrics. */
2804    if ( !error                                                               &&
2805         face->root.internal->incremental_interface                           &&
2806         face->root.internal->incremental_interface->funcs->get_glyph_metrics )
2807    {
2808      FT_Incremental_MetricsRec  metrics;
2809
2810
2811      metrics.bearing_x = decoder.builder.left_bearing.x;
2812      metrics.bearing_y = 0;
2813      metrics.advance   = decoder.builder.advance.x;
2814      metrics.advance_v = decoder.builder.advance.y;
2815
2816      error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
2817                face->root.internal->incremental_interface->object,
2818                glyph_index, FALSE, &metrics );
2819
2820      decoder.builder.left_bearing.x = metrics.bearing_x;
2821      decoder.builder.advance.x      = metrics.advance;
2822      decoder.builder.advance.y      = metrics.advance_v;
2823    }
2824
2825#endif /* FT_CONFIG_OPTION_INCREMENTAL */
2826
2827    if ( !error )
2828    {
2829      /* Now, set the metrics -- this is rather simple, as   */
2830      /* the left side bearing is the xMin, and the top side */
2831      /* bearing the yMax.                                   */
2832
2833      /* For composite glyphs, return only left side bearing and */
2834      /* advance width.                                          */
2835      if ( load_flags & FT_LOAD_NO_RECURSE )
2836      {
2837        FT_Slot_Internal  internal = glyph->root.internal;
2838
2839
2840        glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x;
2841        glyph->root.metrics.horiAdvance  = decoder.glyph_width;
2842        internal->glyph_matrix           = font_matrix;
2843        internal->glyph_delta            = font_offset;
2844        internal->glyph_transformed      = 1;
2845      }
2846      else
2847      {
2848        FT_BBox            cbox;
2849        FT_Glyph_Metrics*  metrics = &glyph->root.metrics;
2850        FT_Vector          advance;
2851        FT_Bool            has_vertical_info;
2852
2853
2854        /* copy the _unscaled_ advance width */
2855        metrics->horiAdvance                    = decoder.glyph_width;
2856        glyph->root.linearHoriAdvance           = decoder.glyph_width;
2857        glyph->root.internal->glyph_transformed = 0;
2858
2859#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
2860        has_vertical_info = FT_BOOL( face->vertical_info                   &&
2861                                     face->vertical.number_Of_VMetrics > 0 &&
2862                                     face->vertical.long_metrics           );
2863#else
2864        has_vertical_info = FT_BOOL( face->vertical_info                   &&
2865                                     face->vertical.number_Of_VMetrics > 0 );
2866#endif
2867
2868        /* get the vertical metrics from the vtmx table if we have one */
2869        if ( has_vertical_info )
2870        {
2871          FT_Short   vertBearingY = 0;
2872          FT_UShort  vertAdvance  = 0;
2873
2874
2875          ( (SFNT_Service)face->sfnt )->get_metrics( face, 1,
2876                                                     glyph_index,
2877                                                     &vertBearingY,
2878                                                     &vertAdvance );
2879          metrics->vertBearingY = vertBearingY;
2880          metrics->vertAdvance  = vertAdvance;
2881        }
2882        else
2883        {
2884          /* make up vertical ones */
2885          if ( face->os2.version != 0xFFFFU )
2886            metrics->vertAdvance = (FT_Pos)( face->os2.sTypoAscender -
2887                                             face->os2.sTypoDescender );
2888          else
2889            metrics->vertAdvance = (FT_Pos)( face->horizontal.Ascender -
2890                                             face->horizontal.Descender );
2891        }
2892
2893        glyph->root.linearVertAdvance = metrics->vertAdvance;
2894
2895        glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;
2896
2897        glyph->root.outline.flags = 0;
2898        if ( size && size->root.metrics.y_ppem < 24 )
2899          glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION;
2900
2901        glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL;
2902
2903        if ( !( font_matrix.xx == 0x10000L &&
2904                font_matrix.yy == 0x10000L &&
2905                font_matrix.xy == 0        &&
2906                font_matrix.yx == 0        ) )
2907          FT_Outline_Transform( &glyph->root.outline, &font_matrix );
2908
2909        if ( !( font_offset.x == 0 &&
2910                font_offset.y == 0 ) )
2911          FT_Outline_Translate( &glyph->root.outline,
2912                                font_offset.x, font_offset.y );
2913
2914        advance.x = metrics->horiAdvance;
2915        advance.y = 0;
2916        FT_Vector_Transform( &advance, &font_matrix );
2917        metrics->horiAdvance = advance.x + font_offset.x;
2918
2919        advance.x = 0;
2920        advance.y = metrics->vertAdvance;
2921        FT_Vector_Transform( &advance, &font_matrix );
2922        metrics->vertAdvance = advance.y + font_offset.y;
2923
2924        if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || force_scaling )
2925        {
2926          /* scale the outline and the metrics */
2927          FT_Int       n;
2928          FT_Outline*  cur     = &glyph->root.outline;
2929          FT_Vector*   vec     = cur->points;
2930          FT_Fixed     x_scale = glyph->x_scale;
2931          FT_Fixed     y_scale = glyph->y_scale;
2932
2933
2934          /* First of all, scale the points */
2935          if ( !hinting || !decoder.builder.hints_funcs )
2936            for ( n = cur->n_points; n > 0; n--, vec++ )
2937            {
2938              vec->x = FT_MulFix( vec->x, x_scale );
2939              vec->y = FT_MulFix( vec->y, y_scale );
2940            }
2941
2942          /* Then scale the metrics */
2943          metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
2944          metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
2945        }
2946
2947        /* compute the other metrics */
2948        FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
2949
2950        metrics->width  = cbox.xMax - cbox.xMin;
2951        metrics->height = cbox.yMax - cbox.yMin;
2952
2953        metrics->horiBearingX = cbox.xMin;
2954        metrics->horiBearingY = cbox.yMax;
2955
2956        if ( has_vertical_info )
2957          metrics->vertBearingX = metrics->horiBearingX -
2958                                    metrics->horiAdvance / 2;
2959        else
2960        {
2961          if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
2962            ft_synthesize_vertical_metrics( metrics,
2963                                            metrics->vertAdvance );
2964        }
2965      }
2966    }
2967
2968    return error;
2969  }
2970
2971
2972/* END */
2973