1727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/***************************************************************************/
2727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*                                                                         */
3727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  cf2intrp.c                                                             */
4727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*                                                                         */
5727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*    Adobe's CFF Interpreter (body).                                      */
6727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*                                                                         */
7727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  Copyright 2007-2013 Adobe Systems Incorporated.                        */
8727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*                                                                         */
9727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  This software, and all works of authorship, whether in source or       */
10727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  object code form as indicated by the copyright notice(s) included      */
11727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  herein (collectively, the "Work") is made available, and may only be   */
12727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  used, modified, and distributed under the FreeType Project License,    */
13727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  LICENSE.TXT.  Additionally, subject to the terms and conditions of the */
14727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  FreeType Project License, each contributor to the Work hereby grants   */
15727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  to any individual or legal entity exercising permissions granted by    */
16727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  the FreeType Project License and this section (hereafter, "You" or     */
17727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  "Your") a perpetual, worldwide, non-exclusive, no-charge,              */
18727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  royalty-free, irrevocable (except as stated in this section) patent    */
19727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  license to make, have made, use, offer to sell, sell, import, and      */
20727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  otherwise transfer the Work, where such license applies only to those  */
21727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  patent claims licensable by such contributor that are necessarily      */
22727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  infringed by their contribution(s) alone or by combination of their    */
23727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  contribution(s) with the Work to which such contribution(s) was        */
24727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  submitted.  If You institute patent litigation against any entity      */
25727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  (including a cross-claim or counterclaim in a lawsuit) alleging that   */
26727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  the Work or a contribution incorporated within the Work constitutes    */
27727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  direct or contributory patent infringement, then any patent licenses   */
28727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  granted to You under this License for that Work shall terminate as of  */
29727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  the date such litigation is filed.                                     */
30727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*                                                                         */
31727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  By using, modifying, or distributing the Work you indicate that you    */
32727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  have read and understood the terms and conditions of the               */
33727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  FreeType Project License as well as those provided in this section,    */
34727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  and you accept them fully.                                             */
35727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*                                                                         */
36727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/***************************************************************************/
37727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
38727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
39727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include "cf2ft.h"
40727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include FT_INTERNAL_DEBUG_H
41727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
42727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include "cf2glue.h"
43727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include "cf2font.h"
44727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include "cf2stack.h"
45727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include "cf2hints.h"
46727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
47727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include "cf2error.h"
48727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
49727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
50727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /*************************************************************************/
51727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /*                                                                       */
52727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
53727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
54727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /* messages during execution.                                            */
55727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /*                                                                       */
56727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#undef  FT_COMPONENT
57727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#define FT_COMPONENT  trace_cf2interp
58727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
59727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
60727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /* some operators are not implemented yet */
61727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#define CF2_FIXME  FT_TRACE4(( "cf2_interpT2CharString:"            \
62727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                               " operator not implemented yet\n" ))
63727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
64727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
65727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
66727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_LOCAL_DEF( void )
67727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  cf2_hintmask_init( CF2_HintMask  hintmask,
68727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                     FT_Error*     error )
69727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  {
70727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_ZERO( hintmask );
71727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
72727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    hintmask->error = error;
73727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  }
74727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
75727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
76727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_LOCAL_DEF( FT_Bool )
77727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  cf2_hintmask_isValid( const CF2_HintMask  hintmask )
78727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  {
79727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return hintmask->isValid;
80727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  }
81727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
82727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
83727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_LOCAL_DEF( FT_Bool )
84727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  cf2_hintmask_isNew( const CF2_HintMask  hintmask )
85727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  {
86727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return hintmask->isNew;
87727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  }
88727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
89727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
90727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_LOCAL_DEF( void )
91727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  cf2_hintmask_setNew( CF2_HintMask  hintmask,
92727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                       FT_Bool       val )
93727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  {
94727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    hintmask->isNew = val;
95727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  }
96727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
97727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
98727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /* clients call `getMaskPtr' in order to iterate */
99727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /* through hint mask                             */
100727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
101727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_LOCAL_DEF( FT_Byte* )
102727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  cf2_hintmask_getMaskPtr( CF2_HintMask  hintmask )
103727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  {
104727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return hintmask->mask;
105727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  }
106727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
107727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
108727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  static size_t
109727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  cf2_hintmask_setCounts( CF2_HintMask  hintmask,
110727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          size_t        bitCount )
111727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  {
112727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( bitCount > CF2_MAX_HINTS )
113727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
114727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      /* total of h and v stems must be <= 96 */
115727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      CF2_SET_ERROR( hintmask->error, Invalid_Glyph_Format );
116727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return 0;
117727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
118727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
119727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    hintmask->bitCount  = bitCount;
120727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    hintmask->byteCount = ( hintmask->bitCount + 7 ) / 8;
121727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
122727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    hintmask->isValid = TRUE;
123727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    hintmask->isNew   = TRUE;
124727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
125727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return bitCount;
126727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  }
127727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
128727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
129727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /* consume the hintmask bytes from the charstring, advancing the src */
130727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /* pointer                                                           */
131727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  static void
132727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  cf2_hintmask_read( CF2_HintMask  hintmask,
133727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                     CF2_Buffer    charstring,
134727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                     size_t        bitCount )
135727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  {
136727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    size_t  i;
137727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
138727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#ifndef CF2_NDEBUG
139727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* these are the bits in the final mask byte that should be zero  */
140727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* Note: this variable is only used in an assert expression below */
141727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* and then only if CF2_NDEBUG is not defined                     */
142727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    CF2_UInt  mask = ( 1 << ( -(CF2_Int)bitCount & 7 ) ) - 1;
143727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif
144727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
145727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
146727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* initialize counts and isValid */
147727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( cf2_hintmask_setCounts( hintmask, bitCount ) == 0 )
148727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return;
149727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
150727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_ASSERT( hintmask->byteCount > 0 );
151727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
152727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_TRACE4(( " (maskbytes:" ));
153727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
154727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* set mask and advance interpreter's charstring pointer */
155727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    for ( i = 0; i < hintmask->byteCount; i++ )
156727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
157727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      hintmask->mask[i] = (FT_Byte)cf2_buf_readByte( charstring );
158727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_TRACE4(( " 0x%02X", hintmask->mask[i] ));
159727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
160727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
161727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_TRACE4(( ")\n" ));
162727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
163727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* assert any unused bits in last byte are zero unless there's a prior */
164727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* error                                                               */
165727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* bitCount -> mask, 0 -> 0, 1 -> 7f, 2 -> 3f, ... 6 -> 3, 7 -> 1      */
166727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#ifndef CF2_NDEBUG
167727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_ASSERT( ( hintmask->mask[hintmask->byteCount - 1] & mask ) == 0 ||
168727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease               *hintmask->error                                        );
169727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif
170727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  }
171727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
172727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
173727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_LOCAL_DEF( void )
174727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  cf2_hintmask_setAll( CF2_HintMask  hintmask,
175727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                       size_t        bitCount )
176727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  {
177727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    size_t    i;
178727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    CF2_UInt  mask = ( 1 << ( -(CF2_Int)bitCount & 7 ) ) - 1;
179727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
180727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
181727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* initialize counts and isValid */
182727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( cf2_hintmask_setCounts( hintmask, bitCount ) == 0 )
183727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return;
184727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
185727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_ASSERT( hintmask->byteCount > 0 );
186727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_ASSERT( hintmask->byteCount <
187727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                 sizeof ( hintmask->mask ) / sizeof ( hintmask->mask[0] ) );
188727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
189727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* set mask to all ones */
190727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    for ( i = 0; i < hintmask->byteCount; i++ )
191727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      hintmask->mask[i] = 0xFF;
192727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
193727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* clear unused bits                                              */
194727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* bitCount -> mask, 0 -> 0, 1 -> 7f, 2 -> 3f, ... 6 -> 3, 7 -> 1 */
195727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    hintmask->mask[hintmask->byteCount - 1] &= ~mask;
196727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  }
197727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
198727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
199727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /* Type2 charstring opcodes */
200727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  enum
201727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  {
202727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdRESERVED_0,   /* 0 */
203727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdHSTEM,        /* 1 */
204727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdRESERVED_2,   /* 2 */
205727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdVSTEM,        /* 3 */
206727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdVMOVETO,      /* 4 */
207727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdRLINETO,      /* 5 */
208727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdHLINETO,      /* 6 */
209727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdVLINETO,      /* 7 */
210727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdRRCURVETO,    /* 8 */
211727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdRESERVED_9,   /* 9 */
212727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdCALLSUBR,     /* 10 */
213727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdRETURN,       /* 11 */
214727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdESC,          /* 12 */
215727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdRESERVED_13,  /* 13 */
216727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdENDCHAR,      /* 14 */
217727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdRESERVED_15,  /* 15 */
218727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdRESERVED_16,  /* 16 */
219727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdRESERVED_17,  /* 17 */
220727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdHSTEMHM,      /* 18 */
221727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdHINTMASK,     /* 19 */
222727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdCNTRMASK,     /* 20 */
223727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdRMOVETO,      /* 21 */
224727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdHMOVETO,      /* 22 */
225727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdVSTEMHM,      /* 23 */
226727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdRCURVELINE,   /* 24 */
227727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdRLINECURVE,   /* 25 */
228727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdVVCURVETO,    /* 26 */
229727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdHHCURVETO,    /* 27 */
230727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdEXTENDEDNMBR, /* 28 */
231727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdCALLGSUBR,    /* 29 */
232727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdVHCURVETO,    /* 30 */
233727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_cmdHVCURVETO     /* 31 */
234727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  };
235727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
236727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  enum
237727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  {
238727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escDOTSECTION,   /* 0 */
239727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escRESERVED_1,   /* 1 */
240727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escRESERVED_2,   /* 2 */
241727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escAND,          /* 3 */
242727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escOR,           /* 4 */
243727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escNOT,          /* 5 */
244727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escRESERVED_6,   /* 6 */
245727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escRESERVED_7,   /* 7 */
246727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escRESERVED_8,   /* 8 */
247727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escABS,          /* 9 */
248727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escADD,          /* 10     like otherADD */
249727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escSUB,          /* 11     like otherSUB */
250727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escDIV,          /* 12 */
251727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escRESERVED_13,  /* 13 */
252727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escNEG,          /* 14 */
253727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escEQ,           /* 15 */
254727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escRESERVED_16,  /* 16 */
255727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escRESERVED_17,  /* 17 */
256727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escDROP,         /* 18 */
257727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escRESERVED_19,  /* 19 */
258727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escPUT,          /* 20     like otherPUT    */
259727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escGET,          /* 21     like otherGET    */
260727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escIFELSE,       /* 22     like otherIFELSE */
261727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escRANDOM,       /* 23     like otherRANDOM */
262727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escMUL,          /* 24     like otherMUL    */
263727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escRESERVED_25,  /* 25 */
264727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escSQRT,         /* 26 */
265727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escDUP,          /* 27     like otherDUP    */
266727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escEXCH,         /* 28     like otherEXCH   */
267727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escINDEX,        /* 29 */
268727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escROLL,         /* 30 */
269727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escRESERVED_31,  /* 31 */
270727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escRESERVED_32,  /* 32 */
271727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escRESERVED_33,  /* 33 */
272727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escHFLEX,        /* 34 */
273727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escFLEX,         /* 35 */
274727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escHFLEX1,       /* 36 */
275727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_escFLEX1         /* 37 */
276727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  };
277727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
278727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
279727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /* `stemHintArray' does not change once we start drawing the outline. */
280727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  static void
281727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  cf2_doStems( const CF2_Font  font,
282727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease               CF2_Stack       opStack,
283727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease               CF2_ArrStack    stemHintArray,
284727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease               CF2_Fixed*      width,
285727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease               FT_Bool*        haveWidth,
286727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease               CF2_Fixed       hintOffset )
287727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  {
288727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    CF2_UInt  i;
289727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    CF2_UInt  count       = cf2_stack_count( opStack );
290ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    FT_Bool   hasWidthArg = (FT_Bool)( count & 1 );
291727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
292727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* variable accumulates delta values from operand stack */
293727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    CF2_Fixed  position = hintOffset;
294727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
295727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( hasWidthArg && ! *haveWidth )
296727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      *width = cf2_stack_getReal( opStack, 0 ) +
297727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                 cf2_getNominalWidthX( font->decoder );
298727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
299727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( font->decoder->width_only )
300727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      goto exit;
301727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
302727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    for ( i = hasWidthArg ? 1 : 0; i < count; i += 2 )
303727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
304727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      /* construct a CF2_StemHint and push it onto the list */
305727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      CF2_StemHintRec  stemhint;
306727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
307727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
308727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      stemhint.min  =
309727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        position   += cf2_stack_getReal( opStack, i );
310727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      stemhint.max  =
311727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        position   += cf2_stack_getReal( opStack, i + 1 );
312727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
313727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      stemhint.used  = FALSE;
314727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      stemhint.maxDS =
315727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      stemhint.minDS = 0;
316727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
317727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      cf2_arrstack_push( stemHintArray, &stemhint ); /* defer error check */
318727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
319727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
320727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_stack_clear( opStack );
321727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
322727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  exit:
323727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* cf2_doStems must define a width (may be default) */
324727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    *haveWidth = TRUE;
325727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  }
326727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
327727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
328727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  static void
329727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  cf2_doFlex( CF2_Stack       opStack,
330727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              CF2_Fixed*      curX,
331727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              CF2_Fixed*      curY,
332727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              CF2_GlyphPath   glyphPath,
333727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              const FT_Bool*  readFromStack,
334727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              FT_Bool         doConditionalLastRead )
335727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  {
336727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    CF2_Fixed  vals[14];
337727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    CF2_UInt   index;
338727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Bool    isHFlex;
339727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    CF2_Int    top, i, j;
340727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
341727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
342727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    vals[0] = *curX;
343727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    vals[1] = *curY;
344727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    index   = 0;
345727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    isHFlex = readFromStack[9] == FALSE;
346727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    top     = isHFlex ? 9 : 10;
347727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
348727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    for ( i = 0; i < top; i++ )
349727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
350727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      vals[i + 2] = vals[i];
351727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( readFromStack[i] )
352727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        vals[i + 2] += cf2_stack_getReal( opStack, index++ );
353727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
354727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
355727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( isHFlex )
356727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      vals[9 + 2] = *curY;
357727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
358727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( doConditionalLastRead )
359727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
360ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      FT_Bool    lastIsX = (FT_Bool)( cf2_fixedAbs( vals[10] - *curX ) >
361ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease                                        cf2_fixedAbs( vals[11] - *curY ) );
362727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      CF2_Fixed  lastVal = cf2_stack_getReal( opStack, index );
363727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
364727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
365727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( lastIsX )
366727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      {
367727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        vals[12] = vals[10] + lastVal;
368727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        vals[13] = *curY;
369727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      }
370727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      else
371727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      {
372727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        vals[12] = *curX;
373727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        vals[13] = vals[11] + lastVal;
374727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      }
375727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
376727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    else
377727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
378727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( readFromStack[10] )
379727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        vals[12] = vals[10] + cf2_stack_getReal( opStack, index++ );
380727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      else
381727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        vals[12] = *curX;
382727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
383727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( readFromStack[11] )
384727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        vals[13] = vals[11] + cf2_stack_getReal( opStack, index );
385727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      else
386727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        vals[13] = *curY;
387727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
388727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
389727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    for ( j = 0; j < 2; j++ )
390727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      cf2_glyphpath_curveTo( glyphPath, vals[j * 6 + 2],
391727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                        vals[j * 6 + 3],
392727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                        vals[j * 6 + 4],
393727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                        vals[j * 6 + 5],
394727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                        vals[j * 6 + 6],
395727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                        vals[j * 6 + 7] );
396727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
397727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_stack_clear( opStack );
398727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
399727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    *curX = vals[12];
400727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    *curY = vals[13];
401727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  }
402727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
403727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
404727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /*
405727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease   * `error' is a shared error code used by many objects in this
406727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease   * routine.  Before the code continues from an error, it must check and
407727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease   * record the error in `*error'.  The idea is that this shared
408727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease   * error code will record the first error encountered.  If testing
409727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease   * for an error anyway, the cost of `goto exit' is small, so we do it,
410727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease   * even if continuing would be safe.  In this case, `lastError' is
411727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease   * set, so the testing and storing can be done in one place, at `exit'.
412727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease   *
413727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease   * Continuing after an error is intended for objects which do their own
414727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease   * testing of `*error', e.g., array stack functions.  This allows us to
415727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease   * avoid an extra test after the call.
416727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease   *
417727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease   * Unimplemented opcodes are ignored.
418727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease   *
419727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease   */
420727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_LOCAL_DEF( void )
421727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  cf2_interpT2CharString( CF2_Font              font,
422727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          CF2_Buffer            buf,
423727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          CF2_OutlineCallbacks  callbacks,
424727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          const FT_Vector*      translation,
425727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          FT_Bool               doingSeac,
426727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          CF2_Fixed             curX,
427727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          CF2_Fixed             curY,
428727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          CF2_Fixed*            width )
429727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  {
430727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* lastError is used for errors that are immediately tested */
431727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Error  lastError = FT_Err_Ok;
432727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
433727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* pointer to parsed font object */
434727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    CFF_Decoder*  decoder = font->decoder;
435727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
436727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Error*  error  = &font->error;
437727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Memory  memory = font->memory;
438727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
439727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    CF2_Fixed  scaleY        = font->innerTransform.d;
440727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    CF2_Fixed  nominalWidthX = cf2_getNominalWidthX( decoder );
441727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
442727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* save this for hinting seac accents */
443727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    CF2_Fixed  hintOriginY = curY;
444727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
445727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    CF2_Stack  opStack = NULL;
446727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Byte    op1;                       /* first opcode byte */
447727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
448727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* instruction limit; 20,000,000 matches Avalon */
449727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_UInt32  instructionLimit = 20000000UL;
450727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
451727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    CF2_ArrStackRec  subrStack;
452727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
453727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Bool     haveWidth;
454727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    CF2_Buffer  charstring = NULL;
455727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
456727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    CF2_Int  charstringIndex = -1;       /* initialize to empty */
457727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
458727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* TODO: placeholders for hint structures */
459727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
460727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* objects used for hinting */
461727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    CF2_ArrStackRec  hStemHintArray;
462727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    CF2_ArrStackRec  vStemHintArray;
463727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
464727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    CF2_HintMaskRec   hintMask;
465727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    CF2_GlyphPathRec  glyphPath;
466727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
467727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
468727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* initialize the remaining objects */
469727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_arrstack_init( &subrStack,
470727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                       memory,
471727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                       error,
472727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                       sizeof ( CF2_BufferRec ) );
473727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_arrstack_init( &hStemHintArray,
474727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                       memory,
475727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                       error,
476727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                       sizeof ( CF2_StemHintRec ) );
477727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_arrstack_init( &vStemHintArray,
478727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                       memory,
479727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                       error,
480727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                       sizeof ( CF2_StemHintRec ) );
481727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
482727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* initialize CF2_StemHint arrays */
483727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_hintmask_init( &hintMask, error );
484727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
485727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* initialize path map to manage drawing operations */
486727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
487727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* Note: last 4 params are used to handle `MoveToPermissive', which */
488727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /*       may need to call `hintMap.Build'                           */
489727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* TODO: MoveToPermissive is gone; are these still needed?          */
490727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_glyphpath_init( &glyphPath,
491727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                        font,
492727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                        callbacks,
493727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                        scaleY,
494727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                        /* hShift, */
495727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                        &hStemHintArray,
496727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                        &vStemHintArray,
497727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                        &hintMask,
498727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                        hintOriginY,
499727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                        &font->blues,
500727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                        translation );
501727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
502727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /*
503727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease     * Initialize state for width parsing.  From the CFF Spec:
504727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease     *
505727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease     *   The first stack-clearing operator, which must be one of hstem,
506727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease     *   hstemhm, vstem, vstemhm, cntrmask, hintmask, hmoveto, vmoveto,
507727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease     *   rmoveto, or endchar, takes an additional argument - the width (as
508727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease     *   described earlier), which may be expressed as zero or one numeric
509727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease     *   argument.
510727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease     *
511727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease     * What we implement here uses the first validly specified width, but
512727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease     * does not detect errors for specifying more than one width.
513727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease     *
514727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease     * If one of the above operators occurs without explicitly specifying
515727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease     * a width, we assume the default width.
516727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease     *
517727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease     */
518727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    haveWidth = FALSE;
519727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    *width    = cf2_getDefaultWidthX( decoder );
520727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
521727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /*
522727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease     * Note: at this point, all pointers to resources must be NULL
523727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease     * and all local objects must be initialized.
524727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease     * There must be no branches to exit: above this point.
525727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease     *
526727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease     */
527727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
528727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* allocate an operand stack */
529727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    opStack = cf2_stack_init( memory, error );
530727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( !opStack )
531727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
532727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      lastError = FT_THROW( Out_Of_Memory );
533727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      goto exit;
534727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
535727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
536727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* initialize subroutine stack by placing top level charstring as */
537727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* first element (max depth plus one for the charstring)          */
538727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* Note: Caller owns and must finalize the first charstring.      */
539727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /*       Our copy of it does not change that requirement.         */
540727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_arrstack_setCount( &subrStack, CF2_MAX_SUBR + 1 );
541727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
542727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    charstring  = (CF2_Buffer)cf2_arrstack_getBuffer( &subrStack );
543727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    *charstring = *buf;    /* structure copy */
544727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
545727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    charstringIndex = 0;       /* entry is valid now */
546727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
547727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* catch errors so far */
548727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( *error )
549727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      goto exit;
550727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
551727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* main interpreter loop */
552727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    while ( 1 )
553727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
554727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( cf2_buf_isEnd( charstring ) )
555727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      {
556727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* If we've reached the end of the charstring, simulate a */
557727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* cf2_cmdRETURN or cf2_cmdENDCHAR.                       */
558727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( charstringIndex )
559727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          op1 = cf2_cmdRETURN;  /* end of buffer for subroutine */
560727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        else
561727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          op1 = cf2_cmdENDCHAR; /* end of buffer for top level charstring */
562727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      }
563727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      else
564727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        op1 = (FT_Byte)cf2_buf_readByte( charstring );
565727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
566727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      /* check for errors once per loop */
567727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( *error )
568727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        goto exit;
569727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
570727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      instructionLimit--;
571727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( instructionLimit == 0 )
572727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      {
573727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        lastError = FT_THROW( Invalid_Glyph_Format );
574727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        goto exit;
575727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      }
576727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
577727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      switch( op1 )
578727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      {
579727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdRESERVED_0:
580727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdRESERVED_2:
581727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdRESERVED_9:
582727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdRESERVED_13:
583727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdRESERVED_15:
584727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdRESERVED_16:
585727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdRESERVED_17:
586727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* we may get here if we have a prior error */
587727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        FT_TRACE4(( " unknown op (%d)\n", op1 ));
588727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        break;
589727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
590727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdHSTEMHM:
591727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdHSTEM:
592727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        FT_TRACE4(( op1 == cf2_cmdHSTEMHM ? " hstemhm\n" : " hstem\n" ));
593727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
594727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* never add hints after the mask is computed */
595727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( cf2_hintmask_isValid( &hintMask ) )
596727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          FT_TRACE4(( "cf2_interpT2CharString:"
597727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                      " invalid horizontal hint mask\n" ));
598727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
599727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        cf2_doStems( font,
600727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                     opStack,
601727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                     &hStemHintArray,
602727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                     width,
603727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                     &haveWidth,
604727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                     0 );
605727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
606727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( font->decoder->width_only )
607727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            goto exit;
608727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
609727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        break;
610727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
611727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdVSTEMHM:
612727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdVSTEM:
613727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        FT_TRACE4(( op1 == cf2_cmdVSTEMHM ? " vstemhm\n" : " vstem\n" ));
614727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
615727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* never add hints after the mask is computed */
616727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( cf2_hintmask_isValid( &hintMask ) )
617727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          FT_TRACE4(( "cf2_interpT2CharString:"
618727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                      " invalid vertical hint mask\n" ));
619727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
620727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        cf2_doStems( font,
621727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                     opStack,
622727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                     &vStemHintArray,
623727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                     width,
624727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                     &haveWidth,
625727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                     0 );
626727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
627727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( font->decoder->width_only )
628727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            goto exit;
629727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
630727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        break;
631727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
632727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdVMOVETO:
633727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        FT_TRACE4(( " vmoveto\n" ));
634727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
635727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( cf2_stack_count( opStack ) > 1 && !haveWidth )
636727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          *width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX;
637727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
638727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* width is defined or default after this */
639727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        haveWidth = TRUE;
640727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
641727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( font->decoder->width_only )
642727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            goto exit;
643727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
644727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        curY += cf2_stack_popFixed( opStack );
645727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
646727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        cf2_glyphpath_moveTo( &glyphPath, curX, curY );
647727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
648727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        break;
649727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
650727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdRLINETO:
651727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        {
652727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          CF2_UInt  index;
653727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          CF2_UInt  count = cf2_stack_count( opStack );
654727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
655727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
656727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          FT_TRACE4(( " rlineto\n" ));
657727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
658727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          for ( index = 0; index < count; index += 2 )
659727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          {
660727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            curX += cf2_stack_getReal( opStack, index + 0 );
661727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            curY += cf2_stack_getReal( opStack, index + 1 );
662727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
663727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            cf2_glyphpath_lineTo( &glyphPath, curX, curY );
664727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          }
665727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
666727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          cf2_stack_clear( opStack );
667727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        }
668727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        continue; /* no need to clear stack again */
669727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
670727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdHLINETO:
671727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdVLINETO:
672727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        {
673727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          CF2_UInt  index;
674727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          CF2_UInt  count = cf2_stack_count( opStack );
675727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
676727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          FT_Bool  isX = op1 == cf2_cmdHLINETO;
677727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
678727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
679727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          FT_TRACE4(( isX ? " hlineto\n" : " vlineto\n" ));
680727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
681727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          for ( index = 0; index < count; index++ )
682727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          {
683727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_Fixed  v = cf2_stack_getReal( opStack, index );
684727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
685727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
686727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            if ( isX )
687727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              curX += v;
688727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            else
689727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              curY += v;
690727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
691727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            isX = !isX;
692727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
693727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            cf2_glyphpath_lineTo( &glyphPath, curX, curY );
694727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          }
695727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
696727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          cf2_stack_clear( opStack );
697727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        }
698727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        continue;
699727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
700727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdRCURVELINE:
701727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdRRCURVETO:
702727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        {
703727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          CF2_UInt  count = cf2_stack_count( opStack );
704727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          CF2_UInt  index = 0;
705727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
706727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
707727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          FT_TRACE4(( op1 == cf2_cmdRCURVELINE ? " rcurveline\n"
708727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                               : " rrcurveto\n" ));
709727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
710727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          while ( index + 6 <= count )
711727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          {
712727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_Fixed  x1 = cf2_stack_getReal( opStack, index + 0 ) + curX;
713727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_Fixed  y1 = cf2_stack_getReal( opStack, index + 1 ) + curY;
714727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_Fixed  x2 = cf2_stack_getReal( opStack, index + 2 ) + x1;
715727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_Fixed  y2 = cf2_stack_getReal( opStack, index + 3 ) + y1;
716727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_Fixed  x3 = cf2_stack_getReal( opStack, index + 4 ) + x2;
717727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_Fixed  y3 = cf2_stack_getReal( opStack, index + 5 ) + y2;
718727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
719727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
720727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
721727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
722727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            curX   = x3;
723727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            curY   = y3;
724727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            index += 6;
725727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          }
726727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
727727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          if ( op1 == cf2_cmdRCURVELINE )
728727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          {
729727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            curX += cf2_stack_getReal( opStack, index + 0 );
730727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            curY += cf2_stack_getReal( opStack, index + 1 );
731727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
732727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            cf2_glyphpath_lineTo( &glyphPath, curX, curY );
733727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          }
734727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
735727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          cf2_stack_clear( opStack );
736727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        }
737727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        continue; /* no need to clear stack again */
738727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
739727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdCALLGSUBR:
740727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdCALLSUBR:
741727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        {
742727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          CF2_UInt  subrIndex;
743727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
744727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
745727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          FT_TRACE4(( op1 == cf2_cmdCALLGSUBR ? " callgsubr"
746727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                              : " callsubr" ));
747727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
748727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          if ( charstringIndex > CF2_MAX_SUBR )
749727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          {
750727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            /* max subr plus one for charstring */
751727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            lastError = FT_THROW( Invalid_Glyph_Format );
752727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            goto exit;                      /* overflow of stack */
753727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          }
754727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
755727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          /* push our current CFF charstring region on subrStack */
756727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          charstring = (CF2_Buffer)
757727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                         cf2_arrstack_getPointer( &subrStack,
758727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                                  charstringIndex + 1 );
759727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
760727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          /* set up the new CFF region and pointer */
761727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          subrIndex = cf2_stack_popInt( opStack );
762727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
763727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          switch ( op1 )
764727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          {
765727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_cmdCALLGSUBR:
766727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( "(%d)\n", subrIndex + decoder->globals_bias ));
767727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
768727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            if ( cf2_initGlobalRegionBuffer( decoder,
769727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                             subrIndex,
770727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                             charstring ) )
771727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            {
772727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              lastError = FT_THROW( Invalid_Glyph_Format );
773727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              goto exit;  /* subroutine lookup or stream error */
774727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            }
775727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            break;
776727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
777727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          default:
778727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            /* cf2_cmdCALLSUBR */
779727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( "(%d)\n", subrIndex + decoder->locals_bias ));
780727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
781727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            if ( cf2_initLocalRegionBuffer( decoder,
782727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                            subrIndex,
783727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                            charstring ) )
784727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            {
785727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              lastError = FT_THROW( Invalid_Glyph_Format );
786727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              goto exit;  /* subroutine lookup or stream error */
787727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            }
788727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          }
789727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
790727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          charstringIndex += 1;       /* entry is valid now */
791727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        }
792727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        continue; /* do not clear the stack */
793727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
794727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdRETURN:
795727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        FT_TRACE4(( " return\n" ));
796727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
797727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( charstringIndex < 1 )
798727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        {
799727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          /* Note: cannot return from top charstring */
800727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          lastError = FT_THROW( Invalid_Glyph_Format );
801727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          goto exit;                      /* underflow of stack */
802727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        }
803727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
804727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* restore position in previous charstring */
805727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        charstring = (CF2_Buffer)
806727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                       cf2_arrstack_getPointer( &subrStack,
807727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                                --charstringIndex );
808727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        continue;     /* do not clear the stack */
809727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
810727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdESC:
811727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        {
812727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          FT_Byte  op2 = (FT_Byte)cf2_buf_readByte( charstring );
813727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
814727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
815727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          switch ( op2 )
816727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          {
817727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escDOTSECTION:
818727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            /* something about `flip type of locking' -- ignore it */
819727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( " dotsection\n" ));
820727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
821727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            break;
822727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
823727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          /* TODO: should these operators be supported? */
824727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escAND: /* in spec */
825727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( " and\n" ));
826727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
827727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_FIXME;
828727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            break;
829727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
830727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escOR: /* in spec */
831727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( " or\n" ));
832727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
833727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_FIXME;
834727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            break;
835727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
836727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escNOT: /* in spec */
837727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( " not\n" ));
838727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
839727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_FIXME;
840727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            break;
841727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
842727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escABS: /* in spec */
843727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( " abs\n" ));
844727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
845727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_FIXME;
846727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            break;
847727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
848727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escADD: /* in spec */
849727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( " add\n" ));
850727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
851727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_FIXME;
852727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            break;
853727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
854727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escSUB: /* in spec */
855727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( " sub\n" ));
856727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
857727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_FIXME;
858727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            break;
859727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
860727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escDIV: /* in spec */
861727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( " div\n" ));
862727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
863727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_FIXME;
864727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            break;
865727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
866727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escNEG: /* in spec */
867727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( " neg\n" ));
868727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
869727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_FIXME;
870727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            break;
871727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
872727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escEQ: /* in spec */
873727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( " eq\n" ));
874727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
875727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_FIXME;
876727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            break;
877727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
878727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escDROP: /* in spec */
879727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( " drop\n" ));
880727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
881727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_FIXME;
882727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            break;
883727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
884727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escPUT: /* in spec */
885727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( " put\n" ));
886727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
887727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_FIXME;
888727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            break;
889727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
890727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escGET: /* in spec */
891727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( " get\n" ));
892727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
893727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_FIXME;
894727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            break;
895727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
896727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escIFELSE: /* in spec */
897727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( " ifelse\n" ));
898727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
899727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_FIXME;
900727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            break;
901727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
902727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escRANDOM: /* in spec */
903727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( " random\n" ));
904727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
905727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_FIXME;
906727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            break;
907727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
908727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escMUL: /* in spec */
909727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( " mul\n" ));
910727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
911727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_FIXME;
912727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            break;
913727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
914727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escSQRT: /* in spec */
915727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( " sqrt\n" ));
916727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
917727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_FIXME;
918727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            break;
919727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
920727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escDUP: /* in spec */
921727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( " dup\n" ));
922727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
923727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_FIXME;
924727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            break;
925727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
926727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escEXCH: /* in spec */
927727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( " exch\n" ));
928727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
929727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_FIXME;
930727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            break;
931727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
932727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escINDEX: /* in spec */
933727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( " index\n" ));
934727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
935727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_FIXME;
936727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            break;
937727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
938727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escROLL: /* in spec */
939727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( " roll\n" ));
940727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
941727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_FIXME;
942727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            break;
943727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
944727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escHFLEX:
945727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            {
946727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              static const FT_Bool  readFromStack[12] =
947727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              {
948727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                TRUE /* dx1 */, FALSE /* dy1 */,
949727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                TRUE /* dx2 */, TRUE  /* dy2 */,
950727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                TRUE /* dx3 */, FALSE /* dy3 */,
951727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                TRUE /* dx4 */, FALSE /* dy4 */,
952727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                TRUE /* dx5 */, FALSE /* dy5 */,
953727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                TRUE /* dx6 */, FALSE /* dy6 */
954727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              };
955727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
956727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
957727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              FT_TRACE4(( " hflex\n" ));
958727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
959727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              cf2_doFlex( opStack,
960727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          &curX,
961727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          &curY,
962727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          &glyphPath,
963727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          readFromStack,
964727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          FALSE /* doConditionalLastRead */ );
965727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            }
966727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            continue;
967727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
968727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escFLEX:
969727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            {
970727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              static const FT_Bool  readFromStack[12] =
971727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              {
972727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                TRUE /* dx1 */, TRUE /* dy1 */,
973727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                TRUE /* dx2 */, TRUE /* dy2 */,
974727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                TRUE /* dx3 */, TRUE /* dy3 */,
975727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                TRUE /* dx4 */, TRUE /* dy4 */,
976727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                TRUE /* dx5 */, TRUE /* dy5 */,
977727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                TRUE /* dx6 */, TRUE /* dy6 */
978727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              };
979727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
980727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
981727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              FT_TRACE4(( " flex\n" ));
982727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
983727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              cf2_doFlex( opStack,
984727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          &curX,
985727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          &curY,
986727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          &glyphPath,
987727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          readFromStack,
988727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          FALSE /* doConditionalLastRead */ );
989727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            }
990727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            break;      /* TODO: why is this not a continue? */
991727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
992727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escHFLEX1:
993727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            {
994727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              static const FT_Bool  readFromStack[12] =
995727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              {
996727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                TRUE /* dx1 */, TRUE  /* dy1 */,
997727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                TRUE /* dx2 */, TRUE  /* dy2 */,
998727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                TRUE /* dx3 */, FALSE /* dy3 */,
999727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                TRUE /* dx4 */, FALSE /* dy4 */,
1000727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                TRUE /* dx5 */, TRUE  /* dy5 */,
1001727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                TRUE /* dx6 */, FALSE /* dy6 */
1002727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              };
1003727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1004727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1005727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              FT_TRACE4(( " hflex1\n" ));
1006727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1007727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              cf2_doFlex( opStack,
1008727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          &curX,
1009727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          &curY,
1010727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          &glyphPath,
1011727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          readFromStack,
1012727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          FALSE /* doConditionalLastRead */ );
1013727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            }
1014727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            continue;
1015727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1016727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escFLEX1:
1017727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            {
1018727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              static const FT_Bool  readFromStack[12] =
1019727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              {
1020727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                TRUE  /* dx1 */, TRUE  /* dy1 */,
1021727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                TRUE  /* dx2 */, TRUE  /* dy2 */,
1022727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                TRUE  /* dx3 */, TRUE  /* dy3 */,
1023727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                TRUE  /* dx4 */, TRUE  /* dy4 */,
1024727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                TRUE  /* dx5 */, TRUE  /* dy5 */,
1025727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                FALSE /* dx6 */, FALSE /* dy6 */
1026727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              };
1027727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1028727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1029727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              FT_TRACE4(( " flex1\n" ));
1030727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1031727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              cf2_doFlex( opStack,
1032727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          &curX,
1033727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          &curY,
1034727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          &glyphPath,
1035727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          readFromStack,
1036727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                          TRUE /* doConditionalLastRead */ );
1037727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            }
1038727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            continue;
1039727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1040727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escRESERVED_1:
1041727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escRESERVED_2:
1042727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escRESERVED_6:
1043727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escRESERVED_7:
1044727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escRESERVED_8:
1045727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escRESERVED_13:
1046727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escRESERVED_16:
1047727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escRESERVED_17:
1048727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escRESERVED_19:
1049727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escRESERVED_25:
1050727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escRESERVED_31:
1051727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escRESERVED_32:
1052727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          case cf2_escRESERVED_33:
1053727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          default:
1054727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
1055727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1056727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          }; /* end of switch statement checking `op2' */
1057727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1058727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        } /* case cf2_cmdESC */
1059727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        break;
1060727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1061727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdENDCHAR:
1062727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        FT_TRACE4(( " endchar\n" ));
1063727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1064727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( cf2_stack_count( opStack ) == 1 ||
1065727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease             cf2_stack_count( opStack ) == 5 )
1066727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        {
1067727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          if ( !haveWidth )
1068727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            *width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX;
1069727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        }
1070727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1071727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* width is defined or default after this */
1072727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        haveWidth = TRUE;
1073727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1074727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( font->decoder->width_only )
1075727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            goto exit;
1076727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1077727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* close path if still open */
1078727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        cf2_glyphpath_closeOpenPath( &glyphPath );
1079727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1080727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( cf2_stack_count( opStack ) > 1 )
1081727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        {
1082727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          /* must be either 4 or 5 --                       */
1083727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          /* this is a (deprecated) implied `seac' operator */
1084727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1085727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          CF2_UInt       achar;
1086727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          CF2_UInt       bchar;
1087727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          CF2_BufferRec  component;
1088727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          CF2_Fixed      dummyWidth;   /* ignore component width */
1089727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          FT_Error       error2;
1090727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1091727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1092727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          if ( doingSeac )
1093727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          {
1094727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            lastError = FT_THROW( Invalid_Glyph_Format );
1095727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            goto exit;      /* nested seac */
1096727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          }
1097727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1098727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          achar = cf2_stack_popInt( opStack );
1099727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          bchar = cf2_stack_popInt( opStack );
1100727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1101727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          curY = cf2_stack_popFixed( opStack );
1102727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          curX = cf2_stack_popFixed( opStack );
1103727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1104727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          error2 = cf2_getSeacComponent( decoder, achar, &component );
1105727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          if ( error2 )
1106727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          {
1107727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease             lastError = error2;      /* pass FreeType error through */
1108727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease             goto exit;
1109727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          }
1110727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          cf2_interpT2CharString( font,
1111727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                  &component,
1112727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                  callbacks,
1113727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                  translation,
1114727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                  TRUE,
1115727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                  curX,
1116727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                  curY,
1117727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                  &dummyWidth );
1118727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          cf2_freeSeacComponent( decoder, &component );
1119727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1120727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          error2 = cf2_getSeacComponent( decoder, bchar, &component );
1121727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          if ( error2 )
1122727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          {
1123727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            lastError = error2;      /* pass FreeType error through */
1124727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            goto exit;
1125727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          }
1126727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          cf2_interpT2CharString( font,
1127727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                  &component,
1128727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                  callbacks,
1129727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                  translation,
1130727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                  TRUE,
1131727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                  0,
1132727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                  0,
1133727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                  &dummyWidth );
1134727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          cf2_freeSeacComponent( decoder, &component );
1135727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        }
1136727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        goto exit;
1137727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1138727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdCNTRMASK:
1139727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdHINTMASK:
1140727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* the final \n in the tracing message gets added in      */
1141727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* `cf2_hintmask_read' (which also traces the mask bytes) */
1142727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        FT_TRACE4(( op1 == cf2_cmdCNTRMASK ? " cntrmask" : " hintmask" ));
1143727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1144727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* if there are arguments on the stack, there this is an */
1145727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* implied cf2_cmdVSTEMHM                                */
1146727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( cf2_stack_count( opStack ) != 0 )
1147727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        {
1148727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          /* never add hints after the mask is computed */
1149727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          if ( cf2_hintmask_isValid( &hintMask ) )
1150727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( "cf2_interpT2CharString: invalid hint mask\n" ));
1151727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        }
1152727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1153727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        cf2_doStems( font,
1154727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                     opStack,
1155727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                     &vStemHintArray,
1156727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                     width,
1157727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                     &haveWidth,
1158727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                     0 );
1159727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1160727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( font->decoder->width_only )
1161727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            goto exit;
1162727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1163727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( op1 == cf2_cmdHINTMASK )
1164727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        {
1165727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          /* consume the hint mask bytes which follow the operator */
1166727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          cf2_hintmask_read( &hintMask,
1167727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                             charstring,
1168727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                             cf2_arrstack_size( &hStemHintArray ) +
1169727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                               cf2_arrstack_size( &vStemHintArray ) );
1170727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        }
1171727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        else
1172727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        {
1173727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          /*
1174727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease           * Consume the counter mask bytes which follow the operator:
1175727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease           * Build a temporary hint map, just to place and lock those
1176727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease           * stems participating in the counter mask.  These are most
1177727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease           * likely the dominant hstems, and are grouped together in a
1178727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease           * few counter groups, not necessarily in correspondence
1179727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease           * with the hint groups.  This reduces the chances of
1180727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease           * conflicts between hstems that are initially placed in
1181727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease           * separate hint groups and then brought together.  The
1182727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease           * positions are copied back to `hStemHintArray', so we can
1183727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease           * discard `counterMask' and `counterHintMap'.
1184727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease           *
1185727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease           */
1186727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          CF2_HintMapRec   counterHintMap;
1187727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          CF2_HintMaskRec  counterMask;
1188727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1189727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1190727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          cf2_hintmap_init( &counterHintMap,
1191727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                            font,
1192727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                            &glyphPath.initialHintMap,
1193727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                            &glyphPath.hintMoves,
1194727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                            scaleY );
1195727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          cf2_hintmask_init( &counterMask, error );
1196727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1197727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          cf2_hintmask_read( &counterMask,
1198727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                             charstring,
1199727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                             cf2_arrstack_size( &hStemHintArray ) +
1200727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                               cf2_arrstack_size( &vStemHintArray ) );
1201727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          cf2_hintmap_build( &counterHintMap,
1202727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                             &hStemHintArray,
1203727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                             &vStemHintArray,
1204727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                             &counterMask,
1205727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                             0,
1206727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                             FALSE );
1207727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        }
1208727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        break;
1209727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1210727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdRMOVETO:
1211727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        FT_TRACE4(( " rmoveto\n" ));
1212727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1213727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( cf2_stack_count( opStack ) > 2 && !haveWidth )
1214727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          *width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX;
1215727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1216727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* width is defined or default after this */
1217727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        haveWidth = TRUE;
1218727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1219727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( font->decoder->width_only )
1220727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            goto exit;
1221727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1222727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        curY += cf2_stack_popFixed( opStack );
1223727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        curX += cf2_stack_popFixed( opStack );
1224727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1225727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        cf2_glyphpath_moveTo( &glyphPath, curX, curY );
1226727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1227727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        break;
1228727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1229727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdHMOVETO:
1230727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        FT_TRACE4(( " hmoveto\n" ));
1231727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1232727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( cf2_stack_count( opStack ) > 1 && !haveWidth )
1233727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          *width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX;
1234727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1235727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* width is defined or default after this */
1236727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        haveWidth = TRUE;
1237727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1238727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( font->decoder->width_only )
1239727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            goto exit;
1240727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1241727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        curX += cf2_stack_popFixed( opStack );
1242727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1243727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        cf2_glyphpath_moveTo( &glyphPath, curX, curY );
1244727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1245727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        break;
1246727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1247727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdRLINECURVE:
1248727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        {
1249727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          CF2_UInt  count = cf2_stack_count( opStack );
1250727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          CF2_UInt  index = 0;
1251727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1252727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1253727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          FT_TRACE4(( " rlinecurve\n" ));
1254727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1255727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          while ( index + 6 < count )
1256727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          {
1257727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            curX += cf2_stack_getReal( opStack, index + 0 );
1258727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            curY += cf2_stack_getReal( opStack, index + 1 );
1259727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1260727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            cf2_glyphpath_lineTo( &glyphPath, curX, curY );
1261727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            index += 2;
1262727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          }
1263727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1264727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          while ( index < count )
1265727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          {
1266727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_Fixed  x1 = cf2_stack_getReal( opStack, index + 0 ) + curX;
1267727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_Fixed  y1 = cf2_stack_getReal( opStack, index + 1 ) + curY;
1268727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_Fixed  x2 = cf2_stack_getReal( opStack, index + 2 ) + x1;
1269727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_Fixed  y2 = cf2_stack_getReal( opStack, index + 3 ) + y1;
1270727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_Fixed  x3 = cf2_stack_getReal( opStack, index + 4 ) + x2;
1271727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_Fixed  y3 = cf2_stack_getReal( opStack, index + 5 ) + y2;
1272727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1273727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1274727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
1275727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1276727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            curX   = x3;
1277727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            curY   = y3;
1278727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            index += 6;
1279727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          }
1280727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1281727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          cf2_stack_clear( opStack );
1282727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        }
1283727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        continue; /* no need to clear stack again */
1284727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1285727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdVVCURVETO:
1286727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        {
1287727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          CF2_UInt  count = cf2_stack_count( opStack );
1288727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          CF2_UInt  index = 0;
1289727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1290727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1291727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          FT_TRACE4(( " vvcurveto\n" ));
1292727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1293727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          while ( index < count )
1294727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          {
1295727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_Fixed  x1, y1, x2, y2, x3, y3;
1296727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1297727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1298727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            if ( ( count - index ) & 1 )
1299727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            {
1300727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              x1 = cf2_stack_getReal( opStack, index ) + curX;
1301727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1302727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              ++index;
1303727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            }
1304727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            else
1305727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              x1 = curX;
1306727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1307727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            y1 = cf2_stack_getReal( opStack, index + 0 ) + curY;
1308727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            x2 = cf2_stack_getReal( opStack, index + 1 ) + x1;
1309727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            y2 = cf2_stack_getReal( opStack, index + 2 ) + y1;
1310727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            x3 = x2;
1311727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            y3 = cf2_stack_getReal( opStack, index + 3 ) + y2;
1312727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1313727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
1314727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1315727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            curX   = x3;
1316727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            curY   = y3;
1317727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            index += 4;
1318727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          }
1319727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1320727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          cf2_stack_clear( opStack );
1321727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        }
1322727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        continue; /* no need to clear stack again */
1323727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1324727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdHHCURVETO:
1325727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        {
1326727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          CF2_UInt  count = cf2_stack_count( opStack );
1327727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          CF2_UInt  index = 0;
1328727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1329727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1330727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          FT_TRACE4(( " hhcurveto\n" ));
1331727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1332727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          while ( index < count )
1333727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          {
1334727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_Fixed  x1, y1, x2, y2, x3, y3;
1335727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1336727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1337727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            if ( ( count - index ) & 1 )
1338727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            {
1339727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              y1 = cf2_stack_getReal( opStack, index ) + curY;
1340727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1341727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              ++index;
1342727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            }
1343727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            else
1344727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              y1 = curY;
1345727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1346727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            x1 = cf2_stack_getReal( opStack, index + 0 ) + curX;
1347727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            x2 = cf2_stack_getReal( opStack, index + 1 ) + x1;
1348727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            y2 = cf2_stack_getReal( opStack, index + 2 ) + y1;
1349727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            x3 = cf2_stack_getReal( opStack, index + 3 ) + x2;
1350727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            y3 = y2;
1351727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1352727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
1353727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1354727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            curX   = x3;
1355727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            curY   = y3;
1356727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            index += 4;
1357727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          }
1358727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1359727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          cf2_stack_clear( opStack );
1360727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        }
1361727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        continue; /* no need to clear stack again */
1362727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1363727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdVHCURVETO:
1364727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdHVCURVETO:
1365727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        {
1366727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          CF2_UInt  count = cf2_stack_count( opStack );
1367727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          CF2_UInt  index = 0;
1368727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1369727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          FT_Bool  alternate = op1 == cf2_cmdHVCURVETO;
1370727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1371727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1372727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          FT_TRACE4(( alternate ? " hvcurveto\n" : " vhcurveto\n" ));
1373727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1374727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          while ( index < count )
1375727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          {
1376727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_Fixed x1, x2, x3, y1, y2, y3;
1377727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1378727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1379727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            if ( alternate )
1380727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            {
1381727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              x1 = cf2_stack_getReal( opStack, index + 0 ) + curX;
1382727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              y1 = curY;
1383727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              x2 = cf2_stack_getReal( opStack, index + 1 ) + x1;
1384727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              y2 = cf2_stack_getReal( opStack, index + 2 ) + y1;
1385727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              y3 = cf2_stack_getReal( opStack, index + 3 ) + y2;
1386727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1387727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              if ( count - index == 5 )
1388727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              {
1389727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                x3 = cf2_stack_getReal( opStack, index + 4 ) + x2;
1390727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1391727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                ++index;
1392727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              }
1393727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              else
1394727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                x3 = x2;
1395727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1396727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              alternate = FALSE;
1397727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            }
1398727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            else
1399727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            {
1400727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              x1 = curX;
1401727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              y1 = cf2_stack_getReal( opStack, index + 0 ) + curY;
1402727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              x2 = cf2_stack_getReal( opStack, index + 1 ) + x1;
1403727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              y2 = cf2_stack_getReal( opStack, index + 2 ) + y1;
1404727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              x3 = cf2_stack_getReal( opStack, index + 3 ) + x2;
1405727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1406727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              if ( count - index == 5 )
1407727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              {
1408727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                y3 = cf2_stack_getReal( opStack, index + 4 ) + y2;
1409727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1410727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                ++index;
1411727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              }
1412727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              else
1413727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                y3 = y2;
1414727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1415727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              alternate = TRUE;
1416727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            }
1417727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1418727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
1419727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1420727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            curX   = x3;
1421727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            curY   = y3;
1422727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            index += 4;
1423727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          }
1424727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1425727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          cf2_stack_clear( opStack );
1426727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        }
1427727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        continue;     /* no need to clear stack again */
1428727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1429727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      case cf2_cmdEXTENDEDNMBR:
1430727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        {
1431727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          CF2_Int  v;
1432727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1433727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1434727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          v = (FT_Short)( ( cf2_buf_readByte( charstring ) << 8 ) |
1435727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                            cf2_buf_readByte( charstring )        );
1436727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1437727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          FT_TRACE4(( " %d", v ));
1438727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1439727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          cf2_stack_pushInt( opStack, v );
1440727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        }
1441727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        continue;
1442727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1443727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      default:
1444727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* numbers */
1445727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        {
1446727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          if ( /* op1 >= 32 && */ op1 <= 246 )
1447727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          {
1448727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_Int  v;
1449727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1450727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1451727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            v = op1 - 139;
1452727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1453727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( " %d", v ));
1454727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1455727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            /* -107 .. 107 */
1456727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            cf2_stack_pushInt( opStack, v );
1457727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          }
1458727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1459727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          else if ( /* op1 >= 247 && */ op1 <= 250 )
1460727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          {
1461727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_Int  v;
1462727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1463727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1464727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            v  = op1;
1465727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            v -= 247;
1466727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            v *= 256;
1467727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            v += cf2_buf_readByte( charstring );
1468727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            v += 108;
1469727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1470727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( " %d", v ));
1471727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1472727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            /* 108 .. 1131 */
1473727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            cf2_stack_pushInt( opStack, v );
1474727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          }
1475727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1476727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          else if ( /* op1 >= 251 && */ op1 <= 254 )
1477727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          {
1478727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_Int  v;
1479727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1480727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1481727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            v  = op1;
1482727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            v -= 251;
1483727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            v *= 256;
1484727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            v += cf2_buf_readByte( charstring );
1485727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            v  = -v - 108;
1486727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1487727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( " %d", v ));
1488727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1489727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            /* -1131 .. -108 */
1490727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            cf2_stack_pushInt( opStack, v );
1491727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          }
1492727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1493727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          else /* op1 == 255 */
1494727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          {
1495727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            CF2_Fixed  v;
1496727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1497727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1498727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            v = (CF2_Fixed)
1499727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                  ( ( (FT_UInt32)cf2_buf_readByte( charstring ) << 24 ) |
1500727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                    ( (FT_UInt32)cf2_buf_readByte( charstring ) << 16 ) |
1501727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                    ( (FT_UInt32)cf2_buf_readByte( charstring ) <<  8 ) |
1502727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                      (FT_UInt32)cf2_buf_readByte( charstring )         );
1503727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1504727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_TRACE4(( " %.2f", v / 65536.0 ));
1505727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1506727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            cf2_stack_pushFixed( opStack, v );
1507727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          }
1508727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        }
1509727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        continue;   /* don't clear stack */
1510727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1511727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      } /* end of switch statement checking `op1' */
1512727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1513727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      cf2_stack_clear( opStack );
1514727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1515727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    } /* end of main interpreter loop */
1516727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1517727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* we get here if the charstring ends without cf2_cmdENDCHAR */
1518727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_TRACE4(( "cf2_interpT2CharString:"
1519727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                "  charstring ends without ENDCHAR\n" ));
1520727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1521727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  exit:
1522727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* check whether last error seen is also the first one */
1523727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_setError( error, lastError );
1524727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1525727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* free resources from objects we've used */
1526727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_glyphpath_finalize( &glyphPath );
1527727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_arrstack_finalize( &vStemHintArray );
1528727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_arrstack_finalize( &hStemHintArray );
1529727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_arrstack_finalize( &subrStack );
1530727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cf2_stack_free( opStack );
1531727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1532727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_TRACE4(( "\n" ));
1533727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1534727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return;
1535727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  }
1536727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1537727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1538727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/* END */
1539