xref: /inferno-os/libfreetype/cffparse.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsyth /***************************************************************************/
2*37da2899SCharles.Forsyth /*                                                                         */
3*37da2899SCharles.Forsyth /*  cffparse.c                                                             */
4*37da2899SCharles.Forsyth /*                                                                         */
5*37da2899SCharles.Forsyth /*    CFF token stream parser (body)                                       */
6*37da2899SCharles.Forsyth /*                                                                         */
7*37da2899SCharles.Forsyth /*  Copyright 1996-2001, 2002 by                                           */
8*37da2899SCharles.Forsyth /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9*37da2899SCharles.Forsyth /*                                                                         */
10*37da2899SCharles.Forsyth /*  This file is part of the FreeType project, and may only be used,       */
11*37da2899SCharles.Forsyth /*  modified, and distributed under the terms of the FreeType project      */
12*37da2899SCharles.Forsyth /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13*37da2899SCharles.Forsyth /*  this file you indicate that you have read the license and              */
14*37da2899SCharles.Forsyth /*  understand and accept it fully.                                        */
15*37da2899SCharles.Forsyth /*                                                                         */
16*37da2899SCharles.Forsyth /***************************************************************************/
17*37da2899SCharles.Forsyth 
18*37da2899SCharles.Forsyth 
19*37da2899SCharles.Forsyth #include <ft2build.h>
20*37da2899SCharles.Forsyth #include "cffparse.h"
21*37da2899SCharles.Forsyth #include FT_INTERNAL_STREAM_H
22*37da2899SCharles.Forsyth 
23*37da2899SCharles.Forsyth #include "cfferrs.h"
24*37da2899SCharles.Forsyth 
25*37da2899SCharles.Forsyth 
26*37da2899SCharles.Forsyth   /*************************************************************************/
27*37da2899SCharles.Forsyth   /*                                                                       */
28*37da2899SCharles.Forsyth   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
29*37da2899SCharles.Forsyth   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
30*37da2899SCharles.Forsyth   /* messages during execution.                                            */
31*37da2899SCharles.Forsyth   /*                                                                       */
32*37da2899SCharles.Forsyth #undef  FT_COMPONENT
33*37da2899SCharles.Forsyth #define FT_COMPONENT  trace_cffparse
34*37da2899SCharles.Forsyth 
35*37da2899SCharles.Forsyth 
36*37da2899SCharles.Forsyth   enum
37*37da2899SCharles.Forsyth   {
38*37da2899SCharles.Forsyth     cff_kind_none = 0,
39*37da2899SCharles.Forsyth     cff_kind_num,
40*37da2899SCharles.Forsyth     cff_kind_fixed,
41*37da2899SCharles.Forsyth     cff_kind_string,
42*37da2899SCharles.Forsyth     cff_kind_bool,
43*37da2899SCharles.Forsyth     cff_kind_delta,
44*37da2899SCharles.Forsyth     cff_kind_callback,
45*37da2899SCharles.Forsyth 
46*37da2899SCharles.Forsyth     cff_kind_max  /* do not remove */
47*37da2899SCharles.Forsyth   };
48*37da2899SCharles.Forsyth 
49*37da2899SCharles.Forsyth 
50*37da2899SCharles.Forsyth   /* now generate handlers for the most simple fields */
51*37da2899SCharles.Forsyth   typedef FT_Error  (*CFF_Field_Reader)( CFF_Parser  parser );
52*37da2899SCharles.Forsyth 
53*37da2899SCharles.Forsyth   typedef struct  CFF_Field_Handler_
54*37da2899SCharles.Forsyth   {
55*37da2899SCharles.Forsyth     int               kind;
56*37da2899SCharles.Forsyth     int               code;
57*37da2899SCharles.Forsyth     FT_UInt           offset;
58*37da2899SCharles.Forsyth     FT_Byte           size;
59*37da2899SCharles.Forsyth     CFF_Field_Reader  reader;
60*37da2899SCharles.Forsyth     FT_UInt           array_max;
61*37da2899SCharles.Forsyth     FT_UInt           count_offset;
62*37da2899SCharles.Forsyth 
63*37da2899SCharles.Forsyth   } CFF_Field_Handler;
64*37da2899SCharles.Forsyth 
65*37da2899SCharles.Forsyth 
66*37da2899SCharles.Forsyth   FT_LOCAL_DEF( void )
cff_parser_init(CFF_Parser parser,FT_UInt code,void * object)67*37da2899SCharles.Forsyth   cff_parser_init( CFF_Parser  parser,
68*37da2899SCharles.Forsyth                    FT_UInt     code,
69*37da2899SCharles.Forsyth                    void*       object )
70*37da2899SCharles.Forsyth   {
71*37da2899SCharles.Forsyth     FT_MEM_ZERO( parser, sizeof ( *parser ) );
72*37da2899SCharles.Forsyth 
73*37da2899SCharles.Forsyth     parser->top         = parser->stack;
74*37da2899SCharles.Forsyth     parser->object_code = code;
75*37da2899SCharles.Forsyth     parser->object      = object;
76*37da2899SCharles.Forsyth   }
77*37da2899SCharles.Forsyth 
78*37da2899SCharles.Forsyth 
79*37da2899SCharles.Forsyth   /* read an integer */
80*37da2899SCharles.Forsyth   static FT_Long
cff_parse_integer(FT_Byte * start,FT_Byte * limit)81*37da2899SCharles.Forsyth   cff_parse_integer( FT_Byte*  start,
82*37da2899SCharles.Forsyth                      FT_Byte*  limit )
83*37da2899SCharles.Forsyth   {
84*37da2899SCharles.Forsyth     FT_Byte*  p   = start;
85*37da2899SCharles.Forsyth     FT_Int    v   = *p++;
86*37da2899SCharles.Forsyth     FT_Long   val = 0;
87*37da2899SCharles.Forsyth 
88*37da2899SCharles.Forsyth 
89*37da2899SCharles.Forsyth     if ( v == 28 )
90*37da2899SCharles.Forsyth     {
91*37da2899SCharles.Forsyth       if ( p + 2 > limit )
92*37da2899SCharles.Forsyth         goto Bad;
93*37da2899SCharles.Forsyth 
94*37da2899SCharles.Forsyth       val = (FT_Short)( ( (FT_Int)p[0] << 8 ) | p[1] );
95*37da2899SCharles.Forsyth       p  += 2;
96*37da2899SCharles.Forsyth     }
97*37da2899SCharles.Forsyth     else if ( v == 29 )
98*37da2899SCharles.Forsyth     {
99*37da2899SCharles.Forsyth       if ( p + 4 > limit )
100*37da2899SCharles.Forsyth         goto Bad;
101*37da2899SCharles.Forsyth 
102*37da2899SCharles.Forsyth       val = ( (FT_Long)p[0] << 24 ) |
103*37da2899SCharles.Forsyth             ( (FT_Long)p[1] << 16 ) |
104*37da2899SCharles.Forsyth             ( (FT_Long)p[2] <<  8 ) |
105*37da2899SCharles.Forsyth                        p[3];
106*37da2899SCharles.Forsyth       p += 4;
107*37da2899SCharles.Forsyth     }
108*37da2899SCharles.Forsyth     else if ( v < 247 )
109*37da2899SCharles.Forsyth     {
110*37da2899SCharles.Forsyth       val = v - 139;
111*37da2899SCharles.Forsyth     }
112*37da2899SCharles.Forsyth     else if ( v < 251 )
113*37da2899SCharles.Forsyth     {
114*37da2899SCharles.Forsyth       if ( p + 1 > limit )
115*37da2899SCharles.Forsyth         goto Bad;
116*37da2899SCharles.Forsyth 
117*37da2899SCharles.Forsyth       val = ( v - 247 ) * 256 + p[0] + 108;
118*37da2899SCharles.Forsyth       p++;
119*37da2899SCharles.Forsyth     }
120*37da2899SCharles.Forsyth     else
121*37da2899SCharles.Forsyth     {
122*37da2899SCharles.Forsyth       if ( p + 1 > limit )
123*37da2899SCharles.Forsyth         goto Bad;
124*37da2899SCharles.Forsyth 
125*37da2899SCharles.Forsyth       val = -( v - 251 ) * 256 - p[0] - 108;
126*37da2899SCharles.Forsyth       p++;
127*37da2899SCharles.Forsyth     }
128*37da2899SCharles.Forsyth 
129*37da2899SCharles.Forsyth   Exit:
130*37da2899SCharles.Forsyth     return val;
131*37da2899SCharles.Forsyth 
132*37da2899SCharles.Forsyth   Bad:
133*37da2899SCharles.Forsyth     val = 0;
134*37da2899SCharles.Forsyth     goto Exit;
135*37da2899SCharles.Forsyth   }
136*37da2899SCharles.Forsyth 
137*37da2899SCharles.Forsyth 
138*37da2899SCharles.Forsyth   /* read a real */
139*37da2899SCharles.Forsyth   static FT_Fixed
cff_parse_real(FT_Byte * start,FT_Byte * limit,FT_Int power_ten)140*37da2899SCharles.Forsyth   cff_parse_real( FT_Byte*  start,
141*37da2899SCharles.Forsyth                   FT_Byte*  limit,
142*37da2899SCharles.Forsyth                   FT_Int    power_ten )
143*37da2899SCharles.Forsyth   {
144*37da2899SCharles.Forsyth     FT_Byte*  p    = start;
145*37da2899SCharles.Forsyth     FT_Long   num, divider, result, exp;
146*37da2899SCharles.Forsyth     FT_Int    sign = 0, exp_sign = 0;
147*37da2899SCharles.Forsyth     FT_UInt   nib;
148*37da2899SCharles.Forsyth     FT_UInt   phase;
149*37da2899SCharles.Forsyth 
150*37da2899SCharles.Forsyth 
151*37da2899SCharles.Forsyth     result  = 0;
152*37da2899SCharles.Forsyth     num     = 0;
153*37da2899SCharles.Forsyth     divider = 1;
154*37da2899SCharles.Forsyth 
155*37da2899SCharles.Forsyth     /* first of all, read the integer part */
156*37da2899SCharles.Forsyth     phase = 4;
157*37da2899SCharles.Forsyth 
158*37da2899SCharles.Forsyth     for (;;)
159*37da2899SCharles.Forsyth     {
160*37da2899SCharles.Forsyth       /* If we entered this iteration with phase == 4, we need to */
161*37da2899SCharles.Forsyth       /* read a new byte.  This also skips past the intial 0x1E.  */
162*37da2899SCharles.Forsyth       if ( phase )
163*37da2899SCharles.Forsyth       {
164*37da2899SCharles.Forsyth         p++;
165*37da2899SCharles.Forsyth 
166*37da2899SCharles.Forsyth         /* Make sure we don't read past the end. */
167*37da2899SCharles.Forsyth         if ( p >= limit )
168*37da2899SCharles.Forsyth           goto Bad;
169*37da2899SCharles.Forsyth       }
170*37da2899SCharles.Forsyth 
171*37da2899SCharles.Forsyth       /* Get the nibble. */
172*37da2899SCharles.Forsyth       nib   = ( p[0] >> phase ) & 0xF;
173*37da2899SCharles.Forsyth       phase = 4 - phase;
174*37da2899SCharles.Forsyth 
175*37da2899SCharles.Forsyth       if ( nib == 0xE )
176*37da2899SCharles.Forsyth         sign = 1;
177*37da2899SCharles.Forsyth       else if ( nib > 9 )
178*37da2899SCharles.Forsyth         break;
179*37da2899SCharles.Forsyth       else
180*37da2899SCharles.Forsyth         result = result * 10 + nib;
181*37da2899SCharles.Forsyth     }
182*37da2899SCharles.Forsyth 
183*37da2899SCharles.Forsyth     /* read decimal part, if any */
184*37da2899SCharles.Forsyth     if ( nib == 0xa )
185*37da2899SCharles.Forsyth       for (;;)
186*37da2899SCharles.Forsyth       {
187*37da2899SCharles.Forsyth         /* If we entered this iteration with phase == 4, we need */
188*37da2899SCharles.Forsyth         /* to read a new byte.                                   */
189*37da2899SCharles.Forsyth         if ( phase )
190*37da2899SCharles.Forsyth         {
191*37da2899SCharles.Forsyth           p++;
192*37da2899SCharles.Forsyth 
193*37da2899SCharles.Forsyth           /* Make sure we don't read past the end. */
194*37da2899SCharles.Forsyth           if ( p >= limit )
195*37da2899SCharles.Forsyth             goto Bad;
196*37da2899SCharles.Forsyth         }
197*37da2899SCharles.Forsyth 
198*37da2899SCharles.Forsyth         /* Get the nibble. */
199*37da2899SCharles.Forsyth         nib   = ( p[0] >> phase ) & 0xF;
200*37da2899SCharles.Forsyth         phase = 4 - phase;
201*37da2899SCharles.Forsyth         if ( nib >= 10 )
202*37da2899SCharles.Forsyth           break;
203*37da2899SCharles.Forsyth 
204*37da2899SCharles.Forsyth         if ( divider < 10000000L )
205*37da2899SCharles.Forsyth         {
206*37da2899SCharles.Forsyth           num      = num * 10 + nib;
207*37da2899SCharles.Forsyth           divider *= 10;
208*37da2899SCharles.Forsyth         }
209*37da2899SCharles.Forsyth       }
210*37da2899SCharles.Forsyth 
211*37da2899SCharles.Forsyth     /* read exponent, if any */
212*37da2899SCharles.Forsyth     if ( nib == 12 )
213*37da2899SCharles.Forsyth     {
214*37da2899SCharles.Forsyth       exp_sign = 1;
215*37da2899SCharles.Forsyth       nib      = 11;
216*37da2899SCharles.Forsyth     }
217*37da2899SCharles.Forsyth 
218*37da2899SCharles.Forsyth     if ( nib == 11 )
219*37da2899SCharles.Forsyth     {
220*37da2899SCharles.Forsyth       exp = 0;
221*37da2899SCharles.Forsyth 
222*37da2899SCharles.Forsyth       for (;;)
223*37da2899SCharles.Forsyth       {
224*37da2899SCharles.Forsyth         /* If we entered this iteration with phase == 4, we need */
225*37da2899SCharles.Forsyth         /* to read a new byte.                                   */
226*37da2899SCharles.Forsyth         if ( phase )
227*37da2899SCharles.Forsyth         {
228*37da2899SCharles.Forsyth           p++;
229*37da2899SCharles.Forsyth 
230*37da2899SCharles.Forsyth           /* Make sure we don't read past the end. */
231*37da2899SCharles.Forsyth           if ( p >= limit )
232*37da2899SCharles.Forsyth             goto Bad;
233*37da2899SCharles.Forsyth         }
234*37da2899SCharles.Forsyth 
235*37da2899SCharles.Forsyth         /* Get the nibble. */
236*37da2899SCharles.Forsyth         nib   = ( p[0] >> phase ) & 0xF;
237*37da2899SCharles.Forsyth         phase = 4 - phase;
238*37da2899SCharles.Forsyth         if ( nib >= 10 )
239*37da2899SCharles.Forsyth           break;
240*37da2899SCharles.Forsyth 
241*37da2899SCharles.Forsyth         exp = exp * 10 + nib;
242*37da2899SCharles.Forsyth       }
243*37da2899SCharles.Forsyth 
244*37da2899SCharles.Forsyth       if ( exp_sign )
245*37da2899SCharles.Forsyth         exp = -exp;
246*37da2899SCharles.Forsyth 
247*37da2899SCharles.Forsyth       power_ten += (FT_Int)exp;
248*37da2899SCharles.Forsyth     }
249*37da2899SCharles.Forsyth 
250*37da2899SCharles.Forsyth     /* raise to power of ten if needed */
251*37da2899SCharles.Forsyth     while ( power_ten > 0 )
252*37da2899SCharles.Forsyth     {
253*37da2899SCharles.Forsyth       result = result * 10;
254*37da2899SCharles.Forsyth       num    = num * 10;
255*37da2899SCharles.Forsyth 
256*37da2899SCharles.Forsyth       power_ten--;
257*37da2899SCharles.Forsyth     }
258*37da2899SCharles.Forsyth 
259*37da2899SCharles.Forsyth     while ( power_ten < 0 )
260*37da2899SCharles.Forsyth     {
261*37da2899SCharles.Forsyth       result  = result / 10;
262*37da2899SCharles.Forsyth       divider = divider * 10;
263*37da2899SCharles.Forsyth 
264*37da2899SCharles.Forsyth       power_ten++;
265*37da2899SCharles.Forsyth     }
266*37da2899SCharles.Forsyth 
267*37da2899SCharles.Forsyth     /* Move the integer part into the high 16 bits. */
268*37da2899SCharles.Forsyth     result <<= 16;
269*37da2899SCharles.Forsyth 
270*37da2899SCharles.Forsyth     /* Place the decimal part into the low 16 bits. */
271*37da2899SCharles.Forsyth     if ( num )
272*37da2899SCharles.Forsyth       result |= FT_DivFix( num, divider );
273*37da2899SCharles.Forsyth 
274*37da2899SCharles.Forsyth     if ( sign )
275*37da2899SCharles.Forsyth       result = -result;
276*37da2899SCharles.Forsyth 
277*37da2899SCharles.Forsyth   Exit:
278*37da2899SCharles.Forsyth     return result;
279*37da2899SCharles.Forsyth 
280*37da2899SCharles.Forsyth   Bad:
281*37da2899SCharles.Forsyth     result = 0;
282*37da2899SCharles.Forsyth     goto Exit;
283*37da2899SCharles.Forsyth   }
284*37da2899SCharles.Forsyth 
285*37da2899SCharles.Forsyth 
286*37da2899SCharles.Forsyth   /* read a number, either integer or real */
287*37da2899SCharles.Forsyth   static FT_Long
cff_parse_num(FT_Byte ** d)288*37da2899SCharles.Forsyth   cff_parse_num( FT_Byte**  d )
289*37da2899SCharles.Forsyth   {
290*37da2899SCharles.Forsyth     return ( **d == 30 ? ( cff_parse_real   ( d[0], d[1], 0 ) >> 16 )
291*37da2899SCharles.Forsyth                        :   cff_parse_integer( d[0], d[1] ) );
292*37da2899SCharles.Forsyth   }
293*37da2899SCharles.Forsyth 
294*37da2899SCharles.Forsyth 
295*37da2899SCharles.Forsyth   /* read a floating point number, either integer or real */
296*37da2899SCharles.Forsyth   static FT_Fixed
cff_parse_fixed(FT_Byte ** d)297*37da2899SCharles.Forsyth   cff_parse_fixed( FT_Byte**  d )
298*37da2899SCharles.Forsyth   {
299*37da2899SCharles.Forsyth     return ( **d == 30 ? cff_parse_real   ( d[0], d[1], 0 )
300*37da2899SCharles.Forsyth                        : cff_parse_integer( d[0], d[1] ) << 16 );
301*37da2899SCharles.Forsyth   }
302*37da2899SCharles.Forsyth 
303*37da2899SCharles.Forsyth   /* read a floating point number, either integer or real, */
304*37da2899SCharles.Forsyth   /* but return 1000 times the number read in.             */
305*37da2899SCharles.Forsyth   static FT_Fixed
cff_parse_fixed_thousand(FT_Byte ** d)306*37da2899SCharles.Forsyth   cff_parse_fixed_thousand( FT_Byte**  d )
307*37da2899SCharles.Forsyth   {
308*37da2899SCharles.Forsyth     return **d ==
309*37da2899SCharles.Forsyth       30 ? cff_parse_real     ( d[0], d[1], 3 )
310*37da2899SCharles.Forsyth          : (FT_Fixed)FT_MulFix( cff_parse_integer( d[0], d[1] ) << 16, 1000 );
311*37da2899SCharles.Forsyth   }
312*37da2899SCharles.Forsyth 
313*37da2899SCharles.Forsyth   static FT_Error
cff_parse_font_matrix(CFF_Parser parser)314*37da2899SCharles.Forsyth   cff_parse_font_matrix( CFF_Parser  parser )
315*37da2899SCharles.Forsyth   {
316*37da2899SCharles.Forsyth     CFF_FontRecDict  dict   = (CFF_FontRecDict)parser->object;
317*37da2899SCharles.Forsyth     FT_Matrix*       matrix = &dict->font_matrix;
318*37da2899SCharles.Forsyth     FT_Vector*       offset = &dict->font_offset;
319*37da2899SCharles.Forsyth     FT_UShort*       upm    = &dict->units_per_em;
320*37da2899SCharles.Forsyth     FT_Byte**        data   = parser->stack;
321*37da2899SCharles.Forsyth     FT_Error         error;
322*37da2899SCharles.Forsyth     FT_Fixed         temp;
323*37da2899SCharles.Forsyth 
324*37da2899SCharles.Forsyth 
325*37da2899SCharles.Forsyth     error = CFF_Err_Stack_Underflow;
326*37da2899SCharles.Forsyth 
327*37da2899SCharles.Forsyth     if ( parser->top >= parser->stack + 6 )
328*37da2899SCharles.Forsyth     {
329*37da2899SCharles.Forsyth       matrix->xx = cff_parse_fixed_thousand( data++ );
330*37da2899SCharles.Forsyth       matrix->yx = cff_parse_fixed_thousand( data++ );
331*37da2899SCharles.Forsyth       matrix->xy = cff_parse_fixed_thousand( data++ );
332*37da2899SCharles.Forsyth       matrix->yy = cff_parse_fixed_thousand( data++ );
333*37da2899SCharles.Forsyth       offset->x  = cff_parse_fixed_thousand( data++ );
334*37da2899SCharles.Forsyth       offset->y  = cff_parse_fixed_thousand( data   );
335*37da2899SCharles.Forsyth 
336*37da2899SCharles.Forsyth       temp = ABS( matrix->yy );
337*37da2899SCharles.Forsyth 
338*37da2899SCharles.Forsyth       *upm = (FT_UShort)FT_DivFix( 0x10000L, FT_DivFix( temp, 1000 ) );
339*37da2899SCharles.Forsyth 
340*37da2899SCharles.Forsyth       if ( temp != 0x10000L )
341*37da2899SCharles.Forsyth       {
342*37da2899SCharles.Forsyth         matrix->xx = FT_DivFix( matrix->xx, temp );
343*37da2899SCharles.Forsyth         matrix->yx = FT_DivFix( matrix->yx, temp );
344*37da2899SCharles.Forsyth         matrix->xy = FT_DivFix( matrix->xy, temp );
345*37da2899SCharles.Forsyth         matrix->yy = FT_DivFix( matrix->yy, temp );
346*37da2899SCharles.Forsyth         offset->x  = FT_DivFix( offset->x,  temp );
347*37da2899SCharles.Forsyth         offset->y  = FT_DivFix( offset->y,  temp );
348*37da2899SCharles.Forsyth       }
349*37da2899SCharles.Forsyth 
350*37da2899SCharles.Forsyth       /* note that the offsets must be expressed in integer font units */
351*37da2899SCharles.Forsyth       offset->x >>= 16;
352*37da2899SCharles.Forsyth       offset->y >>= 16;
353*37da2899SCharles.Forsyth 
354*37da2899SCharles.Forsyth       error = CFF_Err_Ok;
355*37da2899SCharles.Forsyth     }
356*37da2899SCharles.Forsyth 
357*37da2899SCharles.Forsyth     return error;
358*37da2899SCharles.Forsyth   }
359*37da2899SCharles.Forsyth 
360*37da2899SCharles.Forsyth 
361*37da2899SCharles.Forsyth   static FT_Error
cff_parse_font_bbox(CFF_Parser parser)362*37da2899SCharles.Forsyth   cff_parse_font_bbox( CFF_Parser  parser )
363*37da2899SCharles.Forsyth   {
364*37da2899SCharles.Forsyth     CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
365*37da2899SCharles.Forsyth     FT_BBox*         bbox = &dict->font_bbox;
366*37da2899SCharles.Forsyth     FT_Byte**        data = parser->stack;
367*37da2899SCharles.Forsyth     FT_Error         error;
368*37da2899SCharles.Forsyth 
369*37da2899SCharles.Forsyth 
370*37da2899SCharles.Forsyth     error = CFF_Err_Stack_Underflow;
371*37da2899SCharles.Forsyth 
372*37da2899SCharles.Forsyth     if ( parser->top >= parser->stack + 4 )
373*37da2899SCharles.Forsyth     {
374*37da2899SCharles.Forsyth       bbox->xMin = FT_RoundFix( cff_parse_fixed( data++ ) );
375*37da2899SCharles.Forsyth       bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) );
376*37da2899SCharles.Forsyth       bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) );
377*37da2899SCharles.Forsyth       bbox->yMax = FT_RoundFix( cff_parse_fixed( data   ) );
378*37da2899SCharles.Forsyth       error = CFF_Err_Ok;
379*37da2899SCharles.Forsyth     }
380*37da2899SCharles.Forsyth 
381*37da2899SCharles.Forsyth     return error;
382*37da2899SCharles.Forsyth   }
383*37da2899SCharles.Forsyth 
384*37da2899SCharles.Forsyth 
385*37da2899SCharles.Forsyth   static FT_Error
cff_parse_private_dict(CFF_Parser parser)386*37da2899SCharles.Forsyth   cff_parse_private_dict( CFF_Parser  parser )
387*37da2899SCharles.Forsyth   {
388*37da2899SCharles.Forsyth     CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
389*37da2899SCharles.Forsyth     FT_Byte**        data = parser->stack;
390*37da2899SCharles.Forsyth     FT_Error         error;
391*37da2899SCharles.Forsyth 
392*37da2899SCharles.Forsyth 
393*37da2899SCharles.Forsyth     error = CFF_Err_Stack_Underflow;
394*37da2899SCharles.Forsyth 
395*37da2899SCharles.Forsyth     if ( parser->top >= parser->stack + 2 )
396*37da2899SCharles.Forsyth     {
397*37da2899SCharles.Forsyth       dict->private_size   = cff_parse_num( data++ );
398*37da2899SCharles.Forsyth       dict->private_offset = cff_parse_num( data   );
399*37da2899SCharles.Forsyth       error = CFF_Err_Ok;
400*37da2899SCharles.Forsyth     }
401*37da2899SCharles.Forsyth 
402*37da2899SCharles.Forsyth     return error;
403*37da2899SCharles.Forsyth   }
404*37da2899SCharles.Forsyth 
405*37da2899SCharles.Forsyth 
406*37da2899SCharles.Forsyth   static FT_Error
cff_parse_cid_ros(CFF_Parser parser)407*37da2899SCharles.Forsyth   cff_parse_cid_ros( CFF_Parser  parser )
408*37da2899SCharles.Forsyth   {
409*37da2899SCharles.Forsyth     CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
410*37da2899SCharles.Forsyth     FT_Byte**        data = parser->stack;
411*37da2899SCharles.Forsyth     FT_Error         error;
412*37da2899SCharles.Forsyth 
413*37da2899SCharles.Forsyth 
414*37da2899SCharles.Forsyth     error = CFF_Err_Stack_Underflow;
415*37da2899SCharles.Forsyth 
416*37da2899SCharles.Forsyth     if ( parser->top >= parser->stack + 3 )
417*37da2899SCharles.Forsyth     {
418*37da2899SCharles.Forsyth       dict->cid_registry   = (FT_UInt)cff_parse_num ( data++ );
419*37da2899SCharles.Forsyth       dict->cid_ordering   = (FT_UInt)cff_parse_num ( data++ );
420*37da2899SCharles.Forsyth       dict->cid_supplement = (FT_ULong)cff_parse_num( data );
421*37da2899SCharles.Forsyth       error = CFF_Err_Ok;
422*37da2899SCharles.Forsyth     }
423*37da2899SCharles.Forsyth 
424*37da2899SCharles.Forsyth     return error;
425*37da2899SCharles.Forsyth   }
426*37da2899SCharles.Forsyth 
427*37da2899SCharles.Forsyth 
428*37da2899SCharles.Forsyth #define CFF_FIELD_NUM( code, name ) \
429*37da2899SCharles.Forsyth           CFF_FIELD( code, name, cff_kind_num )
430*37da2899SCharles.Forsyth #define CFF_FIELD_FIXED( code, name ) \
431*37da2899SCharles.Forsyth           CFF_FIELD( code, name, cff_kind_fixed )
432*37da2899SCharles.Forsyth #define CFF_FIELD_STRING( code, name ) \
433*37da2899SCharles.Forsyth           CFF_FIELD( code, name, cff_kind_string )
434*37da2899SCharles.Forsyth #define CFF_FIELD_BOOL( code, name ) \
435*37da2899SCharles.Forsyth           CFF_FIELD( code, name, cff_kind_bool )
436*37da2899SCharles.Forsyth #define CFF_FIELD_DELTA( code, name, max ) \
437*37da2899SCharles.Forsyth           CFF_FIELD( code, name, cff_kind_delta )
438*37da2899SCharles.Forsyth 
439*37da2899SCharles.Forsyth #define CFF_FIELD_CALLBACK( code, name ) \
440*37da2899SCharles.Forsyth           {                              \
441*37da2899SCharles.Forsyth             cff_kind_callback,           \
442*37da2899SCharles.Forsyth             code | CFFCODE,              \
443*37da2899SCharles.Forsyth             0, 0,                        \
444*37da2899SCharles.Forsyth             cff_parse_ ## name,          \
445*37da2899SCharles.Forsyth             0, 0                         \
446*37da2899SCharles.Forsyth           },
447*37da2899SCharles.Forsyth 
448*37da2899SCharles.Forsyth #undef  CFF_FIELD
449*37da2899SCharles.Forsyth #define CFF_FIELD( code, name, kind ) \
450*37da2899SCharles.Forsyth           {                          \
451*37da2899SCharles.Forsyth             kind,                    \
452*37da2899SCharles.Forsyth             code | CFFCODE,          \
453*37da2899SCharles.Forsyth             FT_FIELD_OFFSET( name ), \
454*37da2899SCharles.Forsyth             FT_FIELD_SIZE( name ),   \
455*37da2899SCharles.Forsyth             0, 0, 0                  \
456*37da2899SCharles.Forsyth           },
457*37da2899SCharles.Forsyth 
458*37da2899SCharles.Forsyth #undef  CFF_FIELD_DELTA
459*37da2899SCharles.Forsyth #define CFF_FIELD_DELTA( code, name, max ) \
460*37da2899SCharles.Forsyth         {                                  \
461*37da2899SCharles.Forsyth           cff_kind_delta,                  \
462*37da2899SCharles.Forsyth           code | CFFCODE,                  \
463*37da2899SCharles.Forsyth           FT_FIELD_OFFSET( name ),         \
464*37da2899SCharles.Forsyth           FT_FIELD_SIZE_DELTA( name ),     \
465*37da2899SCharles.Forsyth           0,                               \
466*37da2899SCharles.Forsyth           max,                             \
467*37da2899SCharles.Forsyth           FT_FIELD_OFFSET( num_ ## name )  \
468*37da2899SCharles.Forsyth         },
469*37da2899SCharles.Forsyth 
470*37da2899SCharles.Forsyth #define CFFCODE_TOPDICT  0x1000
471*37da2899SCharles.Forsyth #define CFFCODE_PRIVATE  0x2000
472*37da2899SCharles.Forsyth 
473*37da2899SCharles.Forsyth   static const CFF_Field_Handler  cff_field_handlers[] =
474*37da2899SCharles.Forsyth   {
475*37da2899SCharles.Forsyth 
476*37da2899SCharles.Forsyth #include "cfftoken.h"
477*37da2899SCharles.Forsyth 
478*37da2899SCharles.Forsyth     { 0, 0, 0, 0, 0, 0, 0 }
479*37da2899SCharles.Forsyth   };
480*37da2899SCharles.Forsyth 
481*37da2899SCharles.Forsyth 
482*37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_Error )
cff_parser_run(CFF_Parser parser,FT_Byte * start,FT_Byte * limit)483*37da2899SCharles.Forsyth   cff_parser_run( CFF_Parser  parser,
484*37da2899SCharles.Forsyth                   FT_Byte*    start,
485*37da2899SCharles.Forsyth                   FT_Byte*    limit )
486*37da2899SCharles.Forsyth   {
487*37da2899SCharles.Forsyth     FT_Byte*  p     = start;
488*37da2899SCharles.Forsyth     FT_Error  error = CFF_Err_Ok;
489*37da2899SCharles.Forsyth 
490*37da2899SCharles.Forsyth 
491*37da2899SCharles.Forsyth     parser->top    = parser->stack;
492*37da2899SCharles.Forsyth     parser->start  = start;
493*37da2899SCharles.Forsyth     parser->limit  = limit;
494*37da2899SCharles.Forsyth     parser->cursor = start;
495*37da2899SCharles.Forsyth 
496*37da2899SCharles.Forsyth     while ( p < limit )
497*37da2899SCharles.Forsyth     {
498*37da2899SCharles.Forsyth       FT_UInt  v = *p;
499*37da2899SCharles.Forsyth 
500*37da2899SCharles.Forsyth 
501*37da2899SCharles.Forsyth       if ( v >= 27 && v != 31 )
502*37da2899SCharles.Forsyth       {
503*37da2899SCharles.Forsyth         /* it's a number; we will push its position on the stack */
504*37da2899SCharles.Forsyth         if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )
505*37da2899SCharles.Forsyth           goto Stack_Overflow;
506*37da2899SCharles.Forsyth 
507*37da2899SCharles.Forsyth         *parser->top ++ = p;
508*37da2899SCharles.Forsyth 
509*37da2899SCharles.Forsyth         /* now, skip it */
510*37da2899SCharles.Forsyth         if ( v == 30 )
511*37da2899SCharles.Forsyth         {
512*37da2899SCharles.Forsyth           /* skip real number */
513*37da2899SCharles.Forsyth           p++;
514*37da2899SCharles.Forsyth           for (;;)
515*37da2899SCharles.Forsyth           {
516*37da2899SCharles.Forsyth             if ( p >= limit )
517*37da2899SCharles.Forsyth               goto Syntax_Error;
518*37da2899SCharles.Forsyth             v = p[0] >> 4;
519*37da2899SCharles.Forsyth             if ( v == 15 )
520*37da2899SCharles.Forsyth               break;
521*37da2899SCharles.Forsyth             v = p[0] & 0xF;
522*37da2899SCharles.Forsyth             if ( v == 15 )
523*37da2899SCharles.Forsyth               break;
524*37da2899SCharles.Forsyth             p++;
525*37da2899SCharles.Forsyth           }
526*37da2899SCharles.Forsyth         }
527*37da2899SCharles.Forsyth         else if ( v == 28 )
528*37da2899SCharles.Forsyth           p += 2;
529*37da2899SCharles.Forsyth         else if ( v == 29 )
530*37da2899SCharles.Forsyth           p += 4;
531*37da2899SCharles.Forsyth         else if ( v > 246 )
532*37da2899SCharles.Forsyth           p += 1;
533*37da2899SCharles.Forsyth       }
534*37da2899SCharles.Forsyth       else
535*37da2899SCharles.Forsyth       {
536*37da2899SCharles.Forsyth         /* This is not a number, hence it's an operator.  Compute its code */
537*37da2899SCharles.Forsyth         /* and look for it in our current list.                            */
538*37da2899SCharles.Forsyth 
539*37da2899SCharles.Forsyth         FT_UInt                   code;
540*37da2899SCharles.Forsyth         FT_UInt                   num_args = (FT_UInt)
541*37da2899SCharles.Forsyth                                              ( parser->top - parser->stack );
542*37da2899SCharles.Forsyth         const CFF_Field_Handler*  field;
543*37da2899SCharles.Forsyth 
544*37da2899SCharles.Forsyth 
545*37da2899SCharles.Forsyth         *parser->top = p;
546*37da2899SCharles.Forsyth         code = v;
547*37da2899SCharles.Forsyth         if ( v == 12 )
548*37da2899SCharles.Forsyth         {
549*37da2899SCharles.Forsyth           /* two byte operator */
550*37da2899SCharles.Forsyth           p++;
551*37da2899SCharles.Forsyth           if ( p >= limit )
552*37da2899SCharles.Forsyth             goto Syntax_Error;
553*37da2899SCharles.Forsyth 
554*37da2899SCharles.Forsyth           code = 0x100 | p[0];
555*37da2899SCharles.Forsyth         }
556*37da2899SCharles.Forsyth         code = code | parser->object_code;
557*37da2899SCharles.Forsyth 
558*37da2899SCharles.Forsyth         for ( field = cff_field_handlers; field->kind; field++ )
559*37da2899SCharles.Forsyth         {
560*37da2899SCharles.Forsyth           if ( field->code == (FT_Int)code )
561*37da2899SCharles.Forsyth           {
562*37da2899SCharles.Forsyth             /* we found our field's handler; read it */
563*37da2899SCharles.Forsyth             FT_Long   val;
564*37da2899SCharles.Forsyth             FT_Byte*  q = (FT_Byte*)parser->object + field->offset;
565*37da2899SCharles.Forsyth 
566*37da2899SCharles.Forsyth 
567*37da2899SCharles.Forsyth             /* check that we have enough arguments -- except for */
568*37da2899SCharles.Forsyth             /* delta encoded arrays, which can be empty          */
569*37da2899SCharles.Forsyth             if ( field->kind != cff_kind_delta && num_args < 1 )
570*37da2899SCharles.Forsyth               goto Stack_Underflow;
571*37da2899SCharles.Forsyth 
572*37da2899SCharles.Forsyth             switch ( field->kind )
573*37da2899SCharles.Forsyth             {
574*37da2899SCharles.Forsyth             case cff_kind_bool:
575*37da2899SCharles.Forsyth             case cff_kind_string:
576*37da2899SCharles.Forsyth             case cff_kind_num:
577*37da2899SCharles.Forsyth               val = cff_parse_num( parser->stack );
578*37da2899SCharles.Forsyth               goto Store_Number;
579*37da2899SCharles.Forsyth 
580*37da2899SCharles.Forsyth             case cff_kind_fixed:
581*37da2899SCharles.Forsyth               val = cff_parse_fixed( parser->stack );
582*37da2899SCharles.Forsyth 
583*37da2899SCharles.Forsyth             Store_Number:
584*37da2899SCharles.Forsyth               switch ( field->size )
585*37da2899SCharles.Forsyth               {
586*37da2899SCharles.Forsyth               case 1:
587*37da2899SCharles.Forsyth                 *(FT_Byte*)q = (FT_Byte)val;
588*37da2899SCharles.Forsyth                 break;
589*37da2899SCharles.Forsyth 
590*37da2899SCharles.Forsyth               case 2:
591*37da2899SCharles.Forsyth                 *(FT_Short*)q = (FT_Short)val;
592*37da2899SCharles.Forsyth                 break;
593*37da2899SCharles.Forsyth 
594*37da2899SCharles.Forsyth               case 4:
595*37da2899SCharles.Forsyth                 *(FT_Int32*)q = (FT_Int)val;
596*37da2899SCharles.Forsyth                 break;
597*37da2899SCharles.Forsyth 
598*37da2899SCharles.Forsyth               default:  /* for 64-bit systems where long is 8 bytes */
599*37da2899SCharles.Forsyth                 *(FT_Long*)q = val;
600*37da2899SCharles.Forsyth               }
601*37da2899SCharles.Forsyth               break;
602*37da2899SCharles.Forsyth 
603*37da2899SCharles.Forsyth             case cff_kind_delta:
604*37da2899SCharles.Forsyth               {
605*37da2899SCharles.Forsyth                 FT_Byte*   qcount = (FT_Byte*)parser->object +
606*37da2899SCharles.Forsyth                                       field->count_offset;
607*37da2899SCharles.Forsyth 
608*37da2899SCharles.Forsyth                 FT_Byte**  data = parser->stack;
609*37da2899SCharles.Forsyth 
610*37da2899SCharles.Forsyth 
611*37da2899SCharles.Forsyth                 if ( num_args > field->array_max )
612*37da2899SCharles.Forsyth                   num_args = field->array_max;
613*37da2899SCharles.Forsyth 
614*37da2899SCharles.Forsyth                 /* store count */
615*37da2899SCharles.Forsyth                 *qcount = (FT_Byte)num_args;
616*37da2899SCharles.Forsyth 
617*37da2899SCharles.Forsyth                 val = 0;
618*37da2899SCharles.Forsyth                 while ( num_args > 0 )
619*37da2899SCharles.Forsyth                 {
620*37da2899SCharles.Forsyth                   val += cff_parse_num( data++ );
621*37da2899SCharles.Forsyth                   switch ( field->size )
622*37da2899SCharles.Forsyth                   {
623*37da2899SCharles.Forsyth                   case 1:
624*37da2899SCharles.Forsyth                     *(FT_Byte*)q = (FT_Byte)val;
625*37da2899SCharles.Forsyth                     break;
626*37da2899SCharles.Forsyth 
627*37da2899SCharles.Forsyth                   case 2:
628*37da2899SCharles.Forsyth                     *(FT_Short*)q = (FT_Short)val;
629*37da2899SCharles.Forsyth                     break;
630*37da2899SCharles.Forsyth 
631*37da2899SCharles.Forsyth                   case 4:
632*37da2899SCharles.Forsyth                     *(FT_Int32*)q = (FT_Int)val;
633*37da2899SCharles.Forsyth                     break;
634*37da2899SCharles.Forsyth 
635*37da2899SCharles.Forsyth                   default:  /* for 64-bit systems */
636*37da2899SCharles.Forsyth                     *(FT_Long*)q = val;
637*37da2899SCharles.Forsyth                   }
638*37da2899SCharles.Forsyth 
639*37da2899SCharles.Forsyth                   q += field->size;
640*37da2899SCharles.Forsyth                   num_args--;
641*37da2899SCharles.Forsyth                 }
642*37da2899SCharles.Forsyth               }
643*37da2899SCharles.Forsyth               break;
644*37da2899SCharles.Forsyth 
645*37da2899SCharles.Forsyth             default:  /* callback */
646*37da2899SCharles.Forsyth               error = field->reader( parser );
647*37da2899SCharles.Forsyth               if ( error )
648*37da2899SCharles.Forsyth                 goto Exit;
649*37da2899SCharles.Forsyth             }
650*37da2899SCharles.Forsyth             goto Found;
651*37da2899SCharles.Forsyth           }
652*37da2899SCharles.Forsyth         }
653*37da2899SCharles.Forsyth 
654*37da2899SCharles.Forsyth         /* this is an unknown operator, or it is unsupported; */
655*37da2899SCharles.Forsyth         /* we will ignore it for now.                         */
656*37da2899SCharles.Forsyth 
657*37da2899SCharles.Forsyth       Found:
658*37da2899SCharles.Forsyth         /* clear stack */
659*37da2899SCharles.Forsyth         parser->top = parser->stack;
660*37da2899SCharles.Forsyth       }
661*37da2899SCharles.Forsyth       p++;
662*37da2899SCharles.Forsyth     }
663*37da2899SCharles.Forsyth 
664*37da2899SCharles.Forsyth   Exit:
665*37da2899SCharles.Forsyth     return error;
666*37da2899SCharles.Forsyth 
667*37da2899SCharles.Forsyth   Stack_Overflow:
668*37da2899SCharles.Forsyth     error = CFF_Err_Invalid_Argument;
669*37da2899SCharles.Forsyth     goto Exit;
670*37da2899SCharles.Forsyth 
671*37da2899SCharles.Forsyth   Stack_Underflow:
672*37da2899SCharles.Forsyth     error = CFF_Err_Invalid_Argument;
673*37da2899SCharles.Forsyth     goto Exit;
674*37da2899SCharles.Forsyth 
675*37da2899SCharles.Forsyth   Syntax_Error:
676*37da2899SCharles.Forsyth     error = CFF_Err_Invalid_Argument;
677*37da2899SCharles.Forsyth     goto Exit;
678*37da2899SCharles.Forsyth   }
679*37da2899SCharles.Forsyth 
680*37da2899SCharles.Forsyth 
681*37da2899SCharles.Forsyth /* END */
682