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