xref: /inferno-os/libfreetype/psobjs.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsyth /***************************************************************************/
2*37da2899SCharles.Forsyth /*                                                                         */
3*37da2899SCharles.Forsyth /*  psobjs.c                                                               */
4*37da2899SCharles.Forsyth /*                                                                         */
5*37da2899SCharles.Forsyth /*    Auxiliary functions for PostScript fonts (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 FT_INTERNAL_POSTSCRIPT_AUX_H
21*37da2899SCharles.Forsyth #include FT_INTERNAL_DEBUG_H
22*37da2899SCharles.Forsyth 
23*37da2899SCharles.Forsyth #include "psobjs.h"
24*37da2899SCharles.Forsyth 
25*37da2899SCharles.Forsyth #include "psauxerr.h"
26*37da2899SCharles.Forsyth 
27*37da2899SCharles.Forsyth 
28*37da2899SCharles.Forsyth   /*************************************************************************/
29*37da2899SCharles.Forsyth   /*************************************************************************/
30*37da2899SCharles.Forsyth   /*****                                                               *****/
31*37da2899SCharles.Forsyth   /*****                             PS_TABLE                          *****/
32*37da2899SCharles.Forsyth   /*****                                                               *****/
33*37da2899SCharles.Forsyth   /*************************************************************************/
34*37da2899SCharles.Forsyth   /*************************************************************************/
35*37da2899SCharles.Forsyth 
36*37da2899SCharles.Forsyth   /*************************************************************************/
37*37da2899SCharles.Forsyth   /*                                                                       */
38*37da2899SCharles.Forsyth   /* <Function>                                                            */
39*37da2899SCharles.Forsyth   /*    ps_table_new                                                       */
40*37da2899SCharles.Forsyth   /*                                                                       */
41*37da2899SCharles.Forsyth   /* <Description>                                                         */
42*37da2899SCharles.Forsyth   /*    Initializes a PS_Table.                                            */
43*37da2899SCharles.Forsyth   /*                                                                       */
44*37da2899SCharles.Forsyth   /* <InOut>                                                               */
45*37da2899SCharles.Forsyth   /*    table  :: The address of the target table.                         */
46*37da2899SCharles.Forsyth   /*                                                                       */
47*37da2899SCharles.Forsyth   /* <Input>                                                               */
48*37da2899SCharles.Forsyth   /*    count  :: The table size = the maximum number of elements.         */
49*37da2899SCharles.Forsyth   /*                                                                       */
50*37da2899SCharles.Forsyth   /*    memory :: The memory object to use for all subsequent              */
51*37da2899SCharles.Forsyth   /*              reallocations.                                           */
52*37da2899SCharles.Forsyth   /*                                                                       */
53*37da2899SCharles.Forsyth   /* <Return>                                                              */
54*37da2899SCharles.Forsyth   /*    FreeType error code.  0 means success.                             */
55*37da2899SCharles.Forsyth   /*                                                                       */
56*37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_Error )
ps_table_new(PS_Table table,FT_Int count,FT_Memory memory)57*37da2899SCharles.Forsyth   ps_table_new( PS_Table   table,
58*37da2899SCharles.Forsyth                 FT_Int     count,
59*37da2899SCharles.Forsyth                 FT_Memory  memory )
60*37da2899SCharles.Forsyth   {
61*37da2899SCharles.Forsyth     FT_Error  error;
62*37da2899SCharles.Forsyth 
63*37da2899SCharles.Forsyth 
64*37da2899SCharles.Forsyth     table->memory = memory;
65*37da2899SCharles.Forsyth     if ( FT_NEW_ARRAY( table->elements, count ) ||
66*37da2899SCharles.Forsyth          FT_NEW_ARRAY( table->lengths,  count ) )
67*37da2899SCharles.Forsyth       goto Exit;
68*37da2899SCharles.Forsyth 
69*37da2899SCharles.Forsyth     table->max_elems = count;
70*37da2899SCharles.Forsyth     table->init      = 0xDEADBEEFUL;
71*37da2899SCharles.Forsyth     table->num_elems = 0;
72*37da2899SCharles.Forsyth     table->block     = 0;
73*37da2899SCharles.Forsyth     table->capacity  = 0;
74*37da2899SCharles.Forsyth     table->cursor    = 0;
75*37da2899SCharles.Forsyth 
76*37da2899SCharles.Forsyth     *(PS_Table_FuncsRec*)&table->funcs = ps_table_funcs;
77*37da2899SCharles.Forsyth 
78*37da2899SCharles.Forsyth   Exit:
79*37da2899SCharles.Forsyth     if ( error )
80*37da2899SCharles.Forsyth       FT_FREE( table->elements );
81*37da2899SCharles.Forsyth 
82*37da2899SCharles.Forsyth     return error;
83*37da2899SCharles.Forsyth   }
84*37da2899SCharles.Forsyth 
85*37da2899SCharles.Forsyth 
86*37da2899SCharles.Forsyth   static void
shift_elements(PS_Table table,FT_Byte * old_base)87*37da2899SCharles.Forsyth   shift_elements( PS_Table  table,
88*37da2899SCharles.Forsyth                   FT_Byte*  old_base )
89*37da2899SCharles.Forsyth   {
90*37da2899SCharles.Forsyth     FT_Long    delta  = (FT_Long)( table->block - old_base );
91*37da2899SCharles.Forsyth     FT_Byte**  offset = table->elements;
92*37da2899SCharles.Forsyth     FT_Byte**  limit  = offset + table->max_elems;
93*37da2899SCharles.Forsyth 
94*37da2899SCharles.Forsyth 
95*37da2899SCharles.Forsyth     for ( ; offset < limit; offset++ )
96*37da2899SCharles.Forsyth     {
97*37da2899SCharles.Forsyth       if ( offset[0] )
98*37da2899SCharles.Forsyth         offset[0] += delta;
99*37da2899SCharles.Forsyth     }
100*37da2899SCharles.Forsyth   }
101*37da2899SCharles.Forsyth 
102*37da2899SCharles.Forsyth 
103*37da2899SCharles.Forsyth   static FT_Error
reallocate_t1_table(PS_Table table,FT_Long new_size)104*37da2899SCharles.Forsyth   reallocate_t1_table( PS_Table  table,
105*37da2899SCharles.Forsyth                        FT_Long   new_size )
106*37da2899SCharles.Forsyth   {
107*37da2899SCharles.Forsyth     FT_Memory  memory   = table->memory;
108*37da2899SCharles.Forsyth     FT_Byte*   old_base = table->block;
109*37da2899SCharles.Forsyth     FT_Error   error;
110*37da2899SCharles.Forsyth 
111*37da2899SCharles.Forsyth 
112*37da2899SCharles.Forsyth     /* allocate new base block */
113*37da2899SCharles.Forsyth     if ( FT_ALLOC( table->block, new_size ) )
114*37da2899SCharles.Forsyth       return error;
115*37da2899SCharles.Forsyth 
116*37da2899SCharles.Forsyth     /* copy elements and shift offsets */
117*37da2899SCharles.Forsyth     if (old_base )
118*37da2899SCharles.Forsyth     {
119*37da2899SCharles.Forsyth       FT_MEM_COPY( table->block, old_base, table->capacity );
120*37da2899SCharles.Forsyth       shift_elements( table, old_base );
121*37da2899SCharles.Forsyth       FT_FREE( old_base );
122*37da2899SCharles.Forsyth     }
123*37da2899SCharles.Forsyth 
124*37da2899SCharles.Forsyth     table->capacity = new_size;
125*37da2899SCharles.Forsyth 
126*37da2899SCharles.Forsyth     return PSaux_Err_Ok;
127*37da2899SCharles.Forsyth   }
128*37da2899SCharles.Forsyth 
129*37da2899SCharles.Forsyth 
130*37da2899SCharles.Forsyth   /*************************************************************************/
131*37da2899SCharles.Forsyth   /*                                                                       */
132*37da2899SCharles.Forsyth   /* <Function>                                                            */
133*37da2899SCharles.Forsyth   /*    ps_table_add                                                       */
134*37da2899SCharles.Forsyth   /*                                                                       */
135*37da2899SCharles.Forsyth   /* <Description>                                                         */
136*37da2899SCharles.Forsyth   /*    Adds an object to a PS_Table, possibly growing its memory block.   */
137*37da2899SCharles.Forsyth   /*                                                                       */
138*37da2899SCharles.Forsyth   /* <InOut>                                                               */
139*37da2899SCharles.Forsyth   /*    table  :: The target table.                                        */
140*37da2899SCharles.Forsyth   /*                                                                       */
141*37da2899SCharles.Forsyth   /* <Input>                                                               */
142*37da2899SCharles.Forsyth   /*    idx  :: The index of the object in the table.                      */
143*37da2899SCharles.Forsyth   /*                                                                       */
144*37da2899SCharles.Forsyth   /*    object :: The address of the object to copy in memory.             */
145*37da2899SCharles.Forsyth   /*                                                                       */
146*37da2899SCharles.Forsyth   /*    length :: The length in bytes of the source object.                */
147*37da2899SCharles.Forsyth   /*                                                                       */
148*37da2899SCharles.Forsyth   /* <Return>                                                              */
149*37da2899SCharles.Forsyth   /*    FreeType error code.  0 means success.  An error is returned if a  */
150*37da2899SCharles.Forsyth   /*    reallocation fails.                                                */
151*37da2899SCharles.Forsyth   /*                                                                       */
152*37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_Error )
ps_table_add(PS_Table table,FT_Int idx,void * object,FT_Int length)153*37da2899SCharles.Forsyth   ps_table_add( PS_Table  table,
154*37da2899SCharles.Forsyth                 FT_Int    idx,
155*37da2899SCharles.Forsyth                 void*     object,
156*37da2899SCharles.Forsyth                 FT_Int    length )
157*37da2899SCharles.Forsyth   {
158*37da2899SCharles.Forsyth     if ( idx < 0 || idx > table->max_elems )
159*37da2899SCharles.Forsyth     {
160*37da2899SCharles.Forsyth       FT_ERROR(( "ps_table_add: invalid index\n" ));
161*37da2899SCharles.Forsyth       return PSaux_Err_Invalid_Argument;
162*37da2899SCharles.Forsyth     }
163*37da2899SCharles.Forsyth 
164*37da2899SCharles.Forsyth     /* grow the base block if needed */
165*37da2899SCharles.Forsyth     if ( table->cursor + length > table->capacity )
166*37da2899SCharles.Forsyth     {
167*37da2899SCharles.Forsyth       FT_Error   error;
168*37da2899SCharles.Forsyth       FT_Offset  new_size  = table->capacity;
169*37da2899SCharles.Forsyth       FT_Long    in_offset;
170*37da2899SCharles.Forsyth 
171*37da2899SCharles.Forsyth 
172*37da2899SCharles.Forsyth       in_offset = (FT_Long)((FT_Byte*)object - table->block);
173*37da2899SCharles.Forsyth       if ( (FT_ULong)in_offset >= table->capacity )
174*37da2899SCharles.Forsyth         in_offset = -1;
175*37da2899SCharles.Forsyth 
176*37da2899SCharles.Forsyth       while ( new_size < table->cursor + length )
177*37da2899SCharles.Forsyth       {
178*37da2899SCharles.Forsyth         /* increase size by 25% and round up to the nearest multiple of 1024 */
179*37da2899SCharles.Forsyth         new_size += (new_size >> 2) + 1;
180*37da2899SCharles.Forsyth         new_size  = ( new_size + 1023 ) & -1024;
181*37da2899SCharles.Forsyth       }
182*37da2899SCharles.Forsyth 
183*37da2899SCharles.Forsyth       error = reallocate_t1_table( table, new_size );
184*37da2899SCharles.Forsyth       if ( error )
185*37da2899SCharles.Forsyth         return error;
186*37da2899SCharles.Forsyth 
187*37da2899SCharles.Forsyth       if ( in_offset >= 0 )
188*37da2899SCharles.Forsyth         object = table->block + in_offset;
189*37da2899SCharles.Forsyth     }
190*37da2899SCharles.Forsyth 
191*37da2899SCharles.Forsyth     /* add the object to the base block and adjust offset */
192*37da2899SCharles.Forsyth     table->elements[idx] = table->block + table->cursor;
193*37da2899SCharles.Forsyth     table->lengths [idx] = length;
194*37da2899SCharles.Forsyth     FT_MEM_COPY( table->block + table->cursor, object, length );
195*37da2899SCharles.Forsyth 
196*37da2899SCharles.Forsyth     table->cursor += length;
197*37da2899SCharles.Forsyth     return PSaux_Err_Ok;
198*37da2899SCharles.Forsyth   }
199*37da2899SCharles.Forsyth 
200*37da2899SCharles.Forsyth 
201*37da2899SCharles.Forsyth   /*************************************************************************/
202*37da2899SCharles.Forsyth   /*                                                                       */
203*37da2899SCharles.Forsyth   /* <Function>                                                            */
204*37da2899SCharles.Forsyth   /*    ps_table_done                                                      */
205*37da2899SCharles.Forsyth   /*                                                                       */
206*37da2899SCharles.Forsyth   /* <Description>                                                         */
207*37da2899SCharles.Forsyth   /*    Finalizes a PS_TableRec (i.e., reallocate it to its current        */
208*37da2899SCharles.Forsyth   /*    cursor).                                                           */
209*37da2899SCharles.Forsyth   /*                                                                       */
210*37da2899SCharles.Forsyth   /* <InOut>                                                               */
211*37da2899SCharles.Forsyth   /*    table :: The target table.                                         */
212*37da2899SCharles.Forsyth   /*                                                                       */
213*37da2899SCharles.Forsyth   /* <Note>                                                                */
214*37da2899SCharles.Forsyth   /*    This function does NOT release the heap's memory block.  It is up  */
215*37da2899SCharles.Forsyth   /*    to the caller to clean it, or reference it in its own structures.  */
216*37da2899SCharles.Forsyth   /*                                                                       */
217*37da2899SCharles.Forsyth   FT_LOCAL_DEF( void )
ps_table_done(PS_Table table)218*37da2899SCharles.Forsyth   ps_table_done( PS_Table  table )
219*37da2899SCharles.Forsyth   {
220*37da2899SCharles.Forsyth     FT_Memory  memory = table->memory;
221*37da2899SCharles.Forsyth     FT_Error   error;
222*37da2899SCharles.Forsyth     FT_Byte*   old_base = table->block;
223*37da2899SCharles.Forsyth 
224*37da2899SCharles.Forsyth 
225*37da2899SCharles.Forsyth     /* should never fail, because rec.cursor <= rec.size */
226*37da2899SCharles.Forsyth     if ( !old_base )
227*37da2899SCharles.Forsyth       return;
228*37da2899SCharles.Forsyth 
229*37da2899SCharles.Forsyth     if ( FT_ALLOC( table->block, table->cursor ) )
230*37da2899SCharles.Forsyth       return;
231*37da2899SCharles.Forsyth     FT_MEM_COPY( table->block, old_base, table->cursor );
232*37da2899SCharles.Forsyth     shift_elements( table, old_base );
233*37da2899SCharles.Forsyth 
234*37da2899SCharles.Forsyth     table->capacity = table->cursor;
235*37da2899SCharles.Forsyth     FT_FREE( old_base );
236*37da2899SCharles.Forsyth 
237*37da2899SCharles.Forsyth     FT_UNUSED( error );
238*37da2899SCharles.Forsyth   }
239*37da2899SCharles.Forsyth 
240*37da2899SCharles.Forsyth 
241*37da2899SCharles.Forsyth   FT_LOCAL_DEF( void )
ps_table_release(PS_Table table)242*37da2899SCharles.Forsyth   ps_table_release( PS_Table  table )
243*37da2899SCharles.Forsyth   {
244*37da2899SCharles.Forsyth     FT_Memory  memory = table->memory;
245*37da2899SCharles.Forsyth 
246*37da2899SCharles.Forsyth 
247*37da2899SCharles.Forsyth     if ( (FT_ULong)table->init == 0xDEADBEEFUL )
248*37da2899SCharles.Forsyth     {
249*37da2899SCharles.Forsyth       FT_FREE( table->block );
250*37da2899SCharles.Forsyth       FT_FREE( table->elements );
251*37da2899SCharles.Forsyth       FT_FREE( table->lengths );
252*37da2899SCharles.Forsyth       table->init = 0;
253*37da2899SCharles.Forsyth     }
254*37da2899SCharles.Forsyth   }
255*37da2899SCharles.Forsyth 
256*37da2899SCharles.Forsyth 
257*37da2899SCharles.Forsyth   /*************************************************************************/
258*37da2899SCharles.Forsyth   /*************************************************************************/
259*37da2899SCharles.Forsyth   /*****                                                               *****/
260*37da2899SCharles.Forsyth   /*****                            T1 PARSER                          *****/
261*37da2899SCharles.Forsyth   /*****                                                               *****/
262*37da2899SCharles.Forsyth   /*************************************************************************/
263*37da2899SCharles.Forsyth   /*************************************************************************/
264*37da2899SCharles.Forsyth 
265*37da2899SCharles.Forsyth 
266*37da2899SCharles.Forsyth #define IS_T1_WHITESPACE( c )  ( (c) == ' '  || (c) == '\t' )
267*37da2899SCharles.Forsyth #define IS_T1_LINESPACE( c )   ( (c) == '\r' || (c) == '\n' )
268*37da2899SCharles.Forsyth 
269*37da2899SCharles.Forsyth #define IS_T1_SPACE( c )  ( IS_T1_WHITESPACE( c ) || IS_T1_LINESPACE( c ) )
270*37da2899SCharles.Forsyth 
271*37da2899SCharles.Forsyth 
272*37da2899SCharles.Forsyth   FT_LOCAL_DEF( void )
ps_parser_skip_spaces(PS_Parser parser)273*37da2899SCharles.Forsyth   ps_parser_skip_spaces( PS_Parser  parser )
274*37da2899SCharles.Forsyth   {
275*37da2899SCharles.Forsyth     FT_Byte* cur   = parser->cursor;
276*37da2899SCharles.Forsyth     FT_Byte* limit = parser->limit;
277*37da2899SCharles.Forsyth 
278*37da2899SCharles.Forsyth 
279*37da2899SCharles.Forsyth     while ( cur < limit )
280*37da2899SCharles.Forsyth     {
281*37da2899SCharles.Forsyth       FT_Byte  c = *cur;
282*37da2899SCharles.Forsyth 
283*37da2899SCharles.Forsyth 
284*37da2899SCharles.Forsyth       if ( !IS_T1_SPACE( c ) )
285*37da2899SCharles.Forsyth         break;
286*37da2899SCharles.Forsyth       cur++;
287*37da2899SCharles.Forsyth     }
288*37da2899SCharles.Forsyth     parser->cursor = cur;
289*37da2899SCharles.Forsyth   }
290*37da2899SCharles.Forsyth 
291*37da2899SCharles.Forsyth 
292*37da2899SCharles.Forsyth   FT_LOCAL_DEF( void )
ps_parser_skip_alpha(PS_Parser parser)293*37da2899SCharles.Forsyth   ps_parser_skip_alpha( PS_Parser  parser )
294*37da2899SCharles.Forsyth   {
295*37da2899SCharles.Forsyth     FT_Byte* cur   = parser->cursor;
296*37da2899SCharles.Forsyth     FT_Byte* limit = parser->limit;
297*37da2899SCharles.Forsyth 
298*37da2899SCharles.Forsyth 
299*37da2899SCharles.Forsyth     while ( cur < limit )
300*37da2899SCharles.Forsyth     {
301*37da2899SCharles.Forsyth       FT_Byte  c = *cur;
302*37da2899SCharles.Forsyth 
303*37da2899SCharles.Forsyth 
304*37da2899SCharles.Forsyth       if ( IS_T1_SPACE( c ) )
305*37da2899SCharles.Forsyth         break;
306*37da2899SCharles.Forsyth       cur++;
307*37da2899SCharles.Forsyth     }
308*37da2899SCharles.Forsyth     parser->cursor = cur;
309*37da2899SCharles.Forsyth   }
310*37da2899SCharles.Forsyth 
311*37da2899SCharles.Forsyth 
312*37da2899SCharles.Forsyth   FT_LOCAL_DEF( void )
ps_parser_to_token(PS_Parser parser,T1_Token token)313*37da2899SCharles.Forsyth   ps_parser_to_token( PS_Parser  parser,
314*37da2899SCharles.Forsyth                       T1_Token   token )
315*37da2899SCharles.Forsyth   {
316*37da2899SCharles.Forsyth     FT_Byte*  cur;
317*37da2899SCharles.Forsyth     FT_Byte*  limit;
318*37da2899SCharles.Forsyth     FT_Byte   starter, ender;
319*37da2899SCharles.Forsyth     FT_Int    embed;
320*37da2899SCharles.Forsyth 
321*37da2899SCharles.Forsyth 
322*37da2899SCharles.Forsyth     token->type  = T1_TOKEN_TYPE_NONE;
323*37da2899SCharles.Forsyth     token->start = 0;
324*37da2899SCharles.Forsyth     token->limit = 0;
325*37da2899SCharles.Forsyth 
326*37da2899SCharles.Forsyth     /* first of all, skip space */
327*37da2899SCharles.Forsyth     ps_parser_skip_spaces( parser );
328*37da2899SCharles.Forsyth 
329*37da2899SCharles.Forsyth     cur   = parser->cursor;
330*37da2899SCharles.Forsyth     limit = parser->limit;
331*37da2899SCharles.Forsyth 
332*37da2899SCharles.Forsyth     if ( cur < limit )
333*37da2899SCharles.Forsyth     {
334*37da2899SCharles.Forsyth       switch ( *cur )
335*37da2899SCharles.Forsyth       {
336*37da2899SCharles.Forsyth         /************* check for strings ***********************/
337*37da2899SCharles.Forsyth       case '(':
338*37da2899SCharles.Forsyth         token->type = T1_TOKEN_TYPE_STRING;
339*37da2899SCharles.Forsyth         ender = ')';
340*37da2899SCharles.Forsyth         goto Lookup_Ender;
341*37da2899SCharles.Forsyth 
342*37da2899SCharles.Forsyth         /************* check for programs/array ****************/
343*37da2899SCharles.Forsyth       case '{':
344*37da2899SCharles.Forsyth         token->type = T1_TOKEN_TYPE_ARRAY;
345*37da2899SCharles.Forsyth         ender = '}';
346*37da2899SCharles.Forsyth         goto Lookup_Ender;
347*37da2899SCharles.Forsyth 
348*37da2899SCharles.Forsyth         /************* check for table/array ******************/
349*37da2899SCharles.Forsyth       case '[':
350*37da2899SCharles.Forsyth         token->type = T1_TOKEN_TYPE_ARRAY;
351*37da2899SCharles.Forsyth         ender = ']';
352*37da2899SCharles.Forsyth 
353*37da2899SCharles.Forsyth       Lookup_Ender:
354*37da2899SCharles.Forsyth         embed   = 1;
355*37da2899SCharles.Forsyth         starter = *cur++;
356*37da2899SCharles.Forsyth         token->start = cur;
357*37da2899SCharles.Forsyth         while ( cur < limit )
358*37da2899SCharles.Forsyth         {
359*37da2899SCharles.Forsyth           if ( *cur == starter )
360*37da2899SCharles.Forsyth             embed++;
361*37da2899SCharles.Forsyth           else if ( *cur == ender )
362*37da2899SCharles.Forsyth           {
363*37da2899SCharles.Forsyth             embed--;
364*37da2899SCharles.Forsyth             if ( embed <= 0 )
365*37da2899SCharles.Forsyth             {
366*37da2899SCharles.Forsyth               token->limit = cur++;
367*37da2899SCharles.Forsyth               break;
368*37da2899SCharles.Forsyth             }
369*37da2899SCharles.Forsyth           }
370*37da2899SCharles.Forsyth           cur++;
371*37da2899SCharles.Forsyth         }
372*37da2899SCharles.Forsyth         break;
373*37da2899SCharles.Forsyth 
374*37da2899SCharles.Forsyth         /* **************** otherwise, it's any token **********/
375*37da2899SCharles.Forsyth       default:
376*37da2899SCharles.Forsyth         token->start = cur++;
377*37da2899SCharles.Forsyth         token->type  = T1_TOKEN_TYPE_ANY;
378*37da2899SCharles.Forsyth         while ( cur < limit && !IS_T1_SPACE( *cur ) )
379*37da2899SCharles.Forsyth           cur++;
380*37da2899SCharles.Forsyth 
381*37da2899SCharles.Forsyth         token->limit = cur;
382*37da2899SCharles.Forsyth       }
383*37da2899SCharles.Forsyth 
384*37da2899SCharles.Forsyth       if ( !token->limit )
385*37da2899SCharles.Forsyth       {
386*37da2899SCharles.Forsyth         token->start = 0;
387*37da2899SCharles.Forsyth         token->type  = T1_TOKEN_TYPE_NONE;
388*37da2899SCharles.Forsyth       }
389*37da2899SCharles.Forsyth 
390*37da2899SCharles.Forsyth       parser->cursor = cur;
391*37da2899SCharles.Forsyth     }
392*37da2899SCharles.Forsyth   }
393*37da2899SCharles.Forsyth 
394*37da2899SCharles.Forsyth 
395*37da2899SCharles.Forsyth   FT_LOCAL_DEF( void )
ps_parser_to_token_array(PS_Parser parser,T1_Token tokens,FT_UInt max_tokens,FT_Int * pnum_tokens)396*37da2899SCharles.Forsyth   ps_parser_to_token_array( PS_Parser  parser,
397*37da2899SCharles.Forsyth                             T1_Token   tokens,
398*37da2899SCharles.Forsyth                             FT_UInt    max_tokens,
399*37da2899SCharles.Forsyth                             FT_Int*    pnum_tokens )
400*37da2899SCharles.Forsyth   {
401*37da2899SCharles.Forsyth     T1_TokenRec  master;
402*37da2899SCharles.Forsyth 
403*37da2899SCharles.Forsyth 
404*37da2899SCharles.Forsyth     *pnum_tokens = -1;
405*37da2899SCharles.Forsyth 
406*37da2899SCharles.Forsyth     ps_parser_to_token( parser, &master );
407*37da2899SCharles.Forsyth     if ( master.type == T1_TOKEN_TYPE_ARRAY )
408*37da2899SCharles.Forsyth     {
409*37da2899SCharles.Forsyth       FT_Byte*  old_cursor = parser->cursor;
410*37da2899SCharles.Forsyth       FT_Byte*  old_limit  = parser->limit;
411*37da2899SCharles.Forsyth       T1_Token  cur        = tokens;
412*37da2899SCharles.Forsyth       T1_Token  limit      = cur + max_tokens;
413*37da2899SCharles.Forsyth 
414*37da2899SCharles.Forsyth 
415*37da2899SCharles.Forsyth       parser->cursor = master.start;
416*37da2899SCharles.Forsyth       parser->limit  = master.limit;
417*37da2899SCharles.Forsyth 
418*37da2899SCharles.Forsyth       while ( parser->cursor < parser->limit )
419*37da2899SCharles.Forsyth       {
420*37da2899SCharles.Forsyth         T1_TokenRec  token;
421*37da2899SCharles.Forsyth 
422*37da2899SCharles.Forsyth 
423*37da2899SCharles.Forsyth         ps_parser_to_token( parser, &token );
424*37da2899SCharles.Forsyth         if ( !token.type )
425*37da2899SCharles.Forsyth           break;
426*37da2899SCharles.Forsyth 
427*37da2899SCharles.Forsyth         if ( cur < limit )
428*37da2899SCharles.Forsyth           *cur = token;
429*37da2899SCharles.Forsyth 
430*37da2899SCharles.Forsyth         cur++;
431*37da2899SCharles.Forsyth       }
432*37da2899SCharles.Forsyth 
433*37da2899SCharles.Forsyth       *pnum_tokens = (FT_Int)( cur - tokens );
434*37da2899SCharles.Forsyth 
435*37da2899SCharles.Forsyth       parser->cursor = old_cursor;
436*37da2899SCharles.Forsyth       parser->limit  = old_limit;
437*37da2899SCharles.Forsyth     }
438*37da2899SCharles.Forsyth   }
439*37da2899SCharles.Forsyth 
440*37da2899SCharles.Forsyth 
441*37da2899SCharles.Forsyth   static FT_Long
T1Radix(FT_Long radixBase,FT_Byte ** cur,FT_Byte * limit)442*37da2899SCharles.Forsyth   T1Radix( FT_Long    radixBase,
443*37da2899SCharles.Forsyth            FT_Byte**  cur,
444*37da2899SCharles.Forsyth            FT_Byte*   limit )
445*37da2899SCharles.Forsyth   {
446*37da2899SCharles.Forsyth     FT_Long  result = 0;
447*37da2899SCharles.Forsyth     FT_Byte  radixEndChar0 =
448*37da2899SCharles.Forsyth                (FT_Byte)( radixBase > 10 ? '9' + 1 : '0' + radixBase );
449*37da2899SCharles.Forsyth     FT_Byte  radixEndChar1 =
450*37da2899SCharles.Forsyth                (FT_Byte)( 'A' + radixBase - 10 );
451*37da2899SCharles.Forsyth     FT_Byte  radixEndChar2 =
452*37da2899SCharles.Forsyth                (FT_Byte)( 'a' + radixBase - 10 );
453*37da2899SCharles.Forsyth 
454*37da2899SCharles.Forsyth 
455*37da2899SCharles.Forsyth     while( *cur < limit )
456*37da2899SCharles.Forsyth     {
457*37da2899SCharles.Forsyth       if ( (*cur)[0] >= '0' && (*cur)[0] < radixEndChar0 )
458*37da2899SCharles.Forsyth         result = result * radixBase + (*cur)[0] - '0';
459*37da2899SCharles.Forsyth 
460*37da2899SCharles.Forsyth       else if ( radixBase > 10 &&
461*37da2899SCharles.Forsyth                 (*cur)[0] >= 'A' && (*cur)[0] < radixEndChar1 )
462*37da2899SCharles.Forsyth         result = result * radixBase + ( (*cur)[0] - 'A' + 10 );
463*37da2899SCharles.Forsyth 
464*37da2899SCharles.Forsyth       else if ( radixBase > 10 &&
465*37da2899SCharles.Forsyth                 (*cur)[0] >= 'a' && (*cur)[0] < radixEndChar2 )
466*37da2899SCharles.Forsyth         result = result * radixBase + ( (*cur)[0] - 'a' + 10 );
467*37da2899SCharles.Forsyth 
468*37da2899SCharles.Forsyth       else
469*37da2899SCharles.Forsyth         return result;
470*37da2899SCharles.Forsyth 
471*37da2899SCharles.Forsyth       (*cur)++;
472*37da2899SCharles.Forsyth     }
473*37da2899SCharles.Forsyth 
474*37da2899SCharles.Forsyth     return result;
475*37da2899SCharles.Forsyth   }
476*37da2899SCharles.Forsyth 
477*37da2899SCharles.Forsyth 
478*37da2899SCharles.Forsyth   static FT_Long
t1_toint(FT_Byte ** cursor,FT_Byte * limit)479*37da2899SCharles.Forsyth   t1_toint( FT_Byte**  cursor,
480*37da2899SCharles.Forsyth             FT_Byte*   limit )
481*37da2899SCharles.Forsyth   {
482*37da2899SCharles.Forsyth     FT_Long   result = 0;
483*37da2899SCharles.Forsyth     FT_Byte*  cur    = *cursor;
484*37da2899SCharles.Forsyth     FT_Byte   c      = '\0', d;
485*37da2899SCharles.Forsyth 
486*37da2899SCharles.Forsyth 
487*37da2899SCharles.Forsyth     for ( ; cur < limit; cur++ )
488*37da2899SCharles.Forsyth     {
489*37da2899SCharles.Forsyth       c = *cur;
490*37da2899SCharles.Forsyth       d = (FT_Byte)( c - '0' );
491*37da2899SCharles.Forsyth       if ( d < 10 )
492*37da2899SCharles.Forsyth         break;
493*37da2899SCharles.Forsyth 
494*37da2899SCharles.Forsyth       if ( c == '-' )
495*37da2899SCharles.Forsyth       {
496*37da2899SCharles.Forsyth         cur++;
497*37da2899SCharles.Forsyth         break;
498*37da2899SCharles.Forsyth       }
499*37da2899SCharles.Forsyth     }
500*37da2899SCharles.Forsyth 
501*37da2899SCharles.Forsyth     if ( cur < limit )
502*37da2899SCharles.Forsyth     {
503*37da2899SCharles.Forsyth       do
504*37da2899SCharles.Forsyth       {
505*37da2899SCharles.Forsyth         d = (FT_Byte)( cur[0] - '0' );
506*37da2899SCharles.Forsyth         if ( d >= 10 )
507*37da2899SCharles.Forsyth         {
508*37da2899SCharles.Forsyth           if ( cur[0] == '#' )
509*37da2899SCharles.Forsyth           {
510*37da2899SCharles.Forsyth             cur++;
511*37da2899SCharles.Forsyth             result = T1Radix( result, &cur, limit );
512*37da2899SCharles.Forsyth           }
513*37da2899SCharles.Forsyth           break;
514*37da2899SCharles.Forsyth         }
515*37da2899SCharles.Forsyth 
516*37da2899SCharles.Forsyth         result = result * 10 + d;
517*37da2899SCharles.Forsyth         cur++;
518*37da2899SCharles.Forsyth 
519*37da2899SCharles.Forsyth       } while ( cur < limit );
520*37da2899SCharles.Forsyth 
521*37da2899SCharles.Forsyth       if ( c == '-' )
522*37da2899SCharles.Forsyth         result = -result;
523*37da2899SCharles.Forsyth     }
524*37da2899SCharles.Forsyth 
525*37da2899SCharles.Forsyth     *cursor = cur;
526*37da2899SCharles.Forsyth     return result;
527*37da2899SCharles.Forsyth   }
528*37da2899SCharles.Forsyth 
529*37da2899SCharles.Forsyth 
530*37da2899SCharles.Forsyth   static FT_Long
t1_tofixed(FT_Byte ** cursor,FT_Byte * limit,FT_Long power_ten)531*37da2899SCharles.Forsyth   t1_tofixed( FT_Byte**  cursor,
532*37da2899SCharles.Forsyth               FT_Byte*   limit,
533*37da2899SCharles.Forsyth               FT_Long    power_ten )
534*37da2899SCharles.Forsyth   {
535*37da2899SCharles.Forsyth     FT_Byte*  cur  = *cursor;
536*37da2899SCharles.Forsyth     FT_Long   num, divider, result;
537*37da2899SCharles.Forsyth     FT_Int    sign = 0;
538*37da2899SCharles.Forsyth     FT_Byte   d;
539*37da2899SCharles.Forsyth 
540*37da2899SCharles.Forsyth 
541*37da2899SCharles.Forsyth     if ( cur >= limit )
542*37da2899SCharles.Forsyth       return 0;
543*37da2899SCharles.Forsyth 
544*37da2899SCharles.Forsyth     /* first of all, check the sign */
545*37da2899SCharles.Forsyth     if ( *cur == '-' )
546*37da2899SCharles.Forsyth     {
547*37da2899SCharles.Forsyth       sign = 1;
548*37da2899SCharles.Forsyth       cur++;
549*37da2899SCharles.Forsyth     }
550*37da2899SCharles.Forsyth 
551*37da2899SCharles.Forsyth     /* then, read the integer part, if any */
552*37da2899SCharles.Forsyth     if ( *cur != '.' )
553*37da2899SCharles.Forsyth       result = t1_toint( &cur, limit ) << 16;
554*37da2899SCharles.Forsyth     else
555*37da2899SCharles.Forsyth       result = 0;
556*37da2899SCharles.Forsyth 
557*37da2899SCharles.Forsyth     num     = 0;
558*37da2899SCharles.Forsyth     divider = 1;
559*37da2899SCharles.Forsyth 
560*37da2899SCharles.Forsyth     if ( cur >= limit )
561*37da2899SCharles.Forsyth       goto Exit;
562*37da2899SCharles.Forsyth 
563*37da2899SCharles.Forsyth     /* read decimal part, if any */
564*37da2899SCharles.Forsyth     if ( *cur == '.' && cur + 1 < limit )
565*37da2899SCharles.Forsyth     {
566*37da2899SCharles.Forsyth       cur++;
567*37da2899SCharles.Forsyth 
568*37da2899SCharles.Forsyth       for (;;)
569*37da2899SCharles.Forsyth       {
570*37da2899SCharles.Forsyth         d = (FT_Byte)( *cur - '0' );
571*37da2899SCharles.Forsyth         if ( d >= 10 )
572*37da2899SCharles.Forsyth           break;
573*37da2899SCharles.Forsyth 
574*37da2899SCharles.Forsyth         if ( divider < 10000000L )
575*37da2899SCharles.Forsyth         {
576*37da2899SCharles.Forsyth           num      = num * 10 + d;
577*37da2899SCharles.Forsyth           divider *= 10;
578*37da2899SCharles.Forsyth         }
579*37da2899SCharles.Forsyth 
580*37da2899SCharles.Forsyth         cur++;
581*37da2899SCharles.Forsyth         if ( cur >= limit )
582*37da2899SCharles.Forsyth           break;
583*37da2899SCharles.Forsyth       }
584*37da2899SCharles.Forsyth     }
585*37da2899SCharles.Forsyth 
586*37da2899SCharles.Forsyth     /* read exponent, if any */
587*37da2899SCharles.Forsyth     if ( cur + 1 < limit && ( *cur == 'e' || *cur == 'E' ) )
588*37da2899SCharles.Forsyth     {
589*37da2899SCharles.Forsyth       cur++;
590*37da2899SCharles.Forsyth       power_ten += t1_toint( &cur, limit );
591*37da2899SCharles.Forsyth     }
592*37da2899SCharles.Forsyth 
593*37da2899SCharles.Forsyth   Exit:
594*37da2899SCharles.Forsyth     /* raise to power of ten if needed */
595*37da2899SCharles.Forsyth     while ( power_ten > 0 )
596*37da2899SCharles.Forsyth     {
597*37da2899SCharles.Forsyth       result = result * 10;
598*37da2899SCharles.Forsyth       num    = num * 10;
599*37da2899SCharles.Forsyth       power_ten--;
600*37da2899SCharles.Forsyth     }
601*37da2899SCharles.Forsyth 
602*37da2899SCharles.Forsyth     while ( power_ten < 0 )
603*37da2899SCharles.Forsyth     {
604*37da2899SCharles.Forsyth       result  = result / 10;
605*37da2899SCharles.Forsyth       divider = divider * 10;
606*37da2899SCharles.Forsyth       power_ten++;
607*37da2899SCharles.Forsyth     }
608*37da2899SCharles.Forsyth 
609*37da2899SCharles.Forsyth     if ( num )
610*37da2899SCharles.Forsyth       result += FT_DivFix( num, divider );
611*37da2899SCharles.Forsyth 
612*37da2899SCharles.Forsyth     if ( sign )
613*37da2899SCharles.Forsyth       result = -result;
614*37da2899SCharles.Forsyth 
615*37da2899SCharles.Forsyth     *cursor = cur;
616*37da2899SCharles.Forsyth     return result;
617*37da2899SCharles.Forsyth   }
618*37da2899SCharles.Forsyth 
619*37da2899SCharles.Forsyth 
620*37da2899SCharles.Forsyth   static FT_Int
t1_tocoordarray(FT_Byte ** cursor,FT_Byte * limit,FT_Int max_coords,FT_Short * coords)621*37da2899SCharles.Forsyth   t1_tocoordarray( FT_Byte**  cursor,
622*37da2899SCharles.Forsyth                    FT_Byte*   limit,
623*37da2899SCharles.Forsyth                    FT_Int     max_coords,
624*37da2899SCharles.Forsyth                    FT_Short*  coords )
625*37da2899SCharles.Forsyth   {
626*37da2899SCharles.Forsyth     FT_Byte*  cur   = *cursor;
627*37da2899SCharles.Forsyth     FT_Int    count = 0;
628*37da2899SCharles.Forsyth     FT_Byte   c, ender;
629*37da2899SCharles.Forsyth 
630*37da2899SCharles.Forsyth 
631*37da2899SCharles.Forsyth     if ( cur >= limit )
632*37da2899SCharles.Forsyth       goto Exit;
633*37da2899SCharles.Forsyth 
634*37da2899SCharles.Forsyth     /* check for the beginning of an array; if not, only one number will */
635*37da2899SCharles.Forsyth     /* be read                                                           */
636*37da2899SCharles.Forsyth     c     = *cur;
637*37da2899SCharles.Forsyth     ender = 0;
638*37da2899SCharles.Forsyth 
639*37da2899SCharles.Forsyth     if ( c == '[' )
640*37da2899SCharles.Forsyth       ender = ']';
641*37da2899SCharles.Forsyth 
642*37da2899SCharles.Forsyth     if ( c == '{' )
643*37da2899SCharles.Forsyth       ender = '}';
644*37da2899SCharles.Forsyth 
645*37da2899SCharles.Forsyth     if ( ender )
646*37da2899SCharles.Forsyth       cur++;
647*37da2899SCharles.Forsyth 
648*37da2899SCharles.Forsyth     /* now, read the coordinates */
649*37da2899SCharles.Forsyth     for ( ; cur < limit; )
650*37da2899SCharles.Forsyth     {
651*37da2899SCharles.Forsyth       /* skip whitespace in front of data */
652*37da2899SCharles.Forsyth       for (;;)
653*37da2899SCharles.Forsyth       {
654*37da2899SCharles.Forsyth         c = *cur;
655*37da2899SCharles.Forsyth         if ( c != ' ' && c != '\t' )
656*37da2899SCharles.Forsyth           break;
657*37da2899SCharles.Forsyth 
658*37da2899SCharles.Forsyth         cur++;
659*37da2899SCharles.Forsyth         if ( cur >= limit )
660*37da2899SCharles.Forsyth           goto Exit;
661*37da2899SCharles.Forsyth       }
662*37da2899SCharles.Forsyth 
663*37da2899SCharles.Forsyth       if ( count >= max_coords || c == ender )
664*37da2899SCharles.Forsyth         break;
665*37da2899SCharles.Forsyth 
666*37da2899SCharles.Forsyth       coords[count] = (FT_Short)( t1_tofixed( &cur, limit, 0 ) >> 16 );
667*37da2899SCharles.Forsyth       count++;
668*37da2899SCharles.Forsyth 
669*37da2899SCharles.Forsyth       if ( !ender )
670*37da2899SCharles.Forsyth         break;
671*37da2899SCharles.Forsyth     }
672*37da2899SCharles.Forsyth 
673*37da2899SCharles.Forsyth   Exit:
674*37da2899SCharles.Forsyth     *cursor = cur;
675*37da2899SCharles.Forsyth     return count;
676*37da2899SCharles.Forsyth   }
677*37da2899SCharles.Forsyth 
678*37da2899SCharles.Forsyth 
679*37da2899SCharles.Forsyth   static FT_Int
t1_tofixedarray(FT_Byte ** cursor,FT_Byte * limit,FT_Int max_values,FT_Fixed * values,FT_Int power_ten)680*37da2899SCharles.Forsyth   t1_tofixedarray( FT_Byte**  cursor,
681*37da2899SCharles.Forsyth                    FT_Byte*   limit,
682*37da2899SCharles.Forsyth                    FT_Int     max_values,
683*37da2899SCharles.Forsyth                    FT_Fixed*  values,
684*37da2899SCharles.Forsyth                    FT_Int     power_ten )
685*37da2899SCharles.Forsyth   {
686*37da2899SCharles.Forsyth     FT_Byte*  cur   = *cursor;
687*37da2899SCharles.Forsyth     FT_Int    count = 0;
688*37da2899SCharles.Forsyth     FT_Byte   c, ender;
689*37da2899SCharles.Forsyth 
690*37da2899SCharles.Forsyth 
691*37da2899SCharles.Forsyth     if ( cur >= limit ) goto Exit;
692*37da2899SCharles.Forsyth 
693*37da2899SCharles.Forsyth     /* check for the beginning of an array. If not, only one number will */
694*37da2899SCharles.Forsyth     /* be read                                                           */
695*37da2899SCharles.Forsyth     c     = *cur;
696*37da2899SCharles.Forsyth     ender = 0;
697*37da2899SCharles.Forsyth 
698*37da2899SCharles.Forsyth     if ( c == '[' )
699*37da2899SCharles.Forsyth       ender = ']';
700*37da2899SCharles.Forsyth 
701*37da2899SCharles.Forsyth     if ( c == '{' )
702*37da2899SCharles.Forsyth       ender = '}';
703*37da2899SCharles.Forsyth 
704*37da2899SCharles.Forsyth     if ( ender )
705*37da2899SCharles.Forsyth       cur++;
706*37da2899SCharles.Forsyth 
707*37da2899SCharles.Forsyth     /* now, read the values */
708*37da2899SCharles.Forsyth     for ( ; cur < limit; )
709*37da2899SCharles.Forsyth     {
710*37da2899SCharles.Forsyth       /* skip whitespace in front of data */
711*37da2899SCharles.Forsyth       for (;;)
712*37da2899SCharles.Forsyth       {
713*37da2899SCharles.Forsyth         c = *cur;
714*37da2899SCharles.Forsyth         if ( c != ' ' && c != '\t' )
715*37da2899SCharles.Forsyth           break;
716*37da2899SCharles.Forsyth 
717*37da2899SCharles.Forsyth         cur++;
718*37da2899SCharles.Forsyth         if ( cur >= limit )
719*37da2899SCharles.Forsyth           goto Exit;
720*37da2899SCharles.Forsyth       }
721*37da2899SCharles.Forsyth 
722*37da2899SCharles.Forsyth       if ( count >= max_values || c == ender )
723*37da2899SCharles.Forsyth         break;
724*37da2899SCharles.Forsyth 
725*37da2899SCharles.Forsyth       values[count] = t1_tofixed( &cur, limit, power_ten );
726*37da2899SCharles.Forsyth       count++;
727*37da2899SCharles.Forsyth 
728*37da2899SCharles.Forsyth       if ( !ender )
729*37da2899SCharles.Forsyth         break;
730*37da2899SCharles.Forsyth     }
731*37da2899SCharles.Forsyth 
732*37da2899SCharles.Forsyth   Exit:
733*37da2899SCharles.Forsyth     *cursor = cur;
734*37da2899SCharles.Forsyth     return count;
735*37da2899SCharles.Forsyth   }
736*37da2899SCharles.Forsyth 
737*37da2899SCharles.Forsyth 
738*37da2899SCharles.Forsyth #if 0
739*37da2899SCharles.Forsyth 
740*37da2899SCharles.Forsyth   static FT_String*
741*37da2899SCharles.Forsyth   t1_tostring( FT_Byte**  cursor,
742*37da2899SCharles.Forsyth                FT_Byte*   limit,
743*37da2899SCharles.Forsyth                FT_Memory  memory )
744*37da2899SCharles.Forsyth   {
745*37da2899SCharles.Forsyth     FT_Byte*    cur = *cursor;
746*37da2899SCharles.Forsyth     FT_PtrDist  len = 0;
747*37da2899SCharles.Forsyth     FT_Int      count;
748*37da2899SCharles.Forsyth     FT_String*  result;
749*37da2899SCharles.Forsyth     FT_Error    error;
750*37da2899SCharles.Forsyth 
751*37da2899SCharles.Forsyth 
752*37da2899SCharles.Forsyth     /* XXX: some stupid fonts have a `Notice' or `Copyright' string     */
753*37da2899SCharles.Forsyth     /*      that simply doesn't begin with an opening parenthesis, even */
754*37da2899SCharles.Forsyth     /*      though they have a closing one!  E.g. "amuncial.pfb"        */
755*37da2899SCharles.Forsyth     /*                                                                  */
756*37da2899SCharles.Forsyth     /*      We must deal with these ill-fated cases there.  Note that   */
757*37da2899SCharles.Forsyth     /*      these fonts didn't work with the old Type 1 driver as the   */
758*37da2899SCharles.Forsyth     /*      notice/copyright was not recognized as a valid string token */
759*37da2899SCharles.Forsyth     /*      and made the old token parser commit errors.                */
760*37da2899SCharles.Forsyth 
761*37da2899SCharles.Forsyth     while ( cur < limit && ( *cur == ' ' || *cur == '\t' ) )
762*37da2899SCharles.Forsyth       cur++;
763*37da2899SCharles.Forsyth     if ( cur + 1 >= limit )
764*37da2899SCharles.Forsyth       return 0;
765*37da2899SCharles.Forsyth 
766*37da2899SCharles.Forsyth     if ( *cur == '(' )
767*37da2899SCharles.Forsyth       cur++;  /* skip the opening parenthesis, if there is one */
768*37da2899SCharles.Forsyth 
769*37da2899SCharles.Forsyth     *cursor = cur;
770*37da2899SCharles.Forsyth     count   = 0;
771*37da2899SCharles.Forsyth 
772*37da2899SCharles.Forsyth     /* then, count its length */
773*37da2899SCharles.Forsyth     for ( ; cur < limit; cur++ )
774*37da2899SCharles.Forsyth     {
775*37da2899SCharles.Forsyth       if ( *cur == '(' )
776*37da2899SCharles.Forsyth         count++;
777*37da2899SCharles.Forsyth 
778*37da2899SCharles.Forsyth       else if ( *cur == ')' )
779*37da2899SCharles.Forsyth       {
780*37da2899SCharles.Forsyth         count--;
781*37da2899SCharles.Forsyth         if ( count < 0 )
782*37da2899SCharles.Forsyth           break;
783*37da2899SCharles.Forsyth       }
784*37da2899SCharles.Forsyth     }
785*37da2899SCharles.Forsyth 
786*37da2899SCharles.Forsyth     len = cur - *cursor;
787*37da2899SCharles.Forsyth     if ( cur >= limit || FT_ALLOC( result, len + 1 ) )
788*37da2899SCharles.Forsyth       return 0;
789*37da2899SCharles.Forsyth 
790*37da2899SCharles.Forsyth     /* now copy the string */
791*37da2899SCharles.Forsyth     FT_MEM_COPY( result, *cursor, len );
792*37da2899SCharles.Forsyth     result[len] = '\0';
793*37da2899SCharles.Forsyth     *cursor = cur;
794*37da2899SCharles.Forsyth     return result;
795*37da2899SCharles.Forsyth   }
796*37da2899SCharles.Forsyth 
797*37da2899SCharles.Forsyth #endif /* 0 */
798*37da2899SCharles.Forsyth 
799*37da2899SCharles.Forsyth 
800*37da2899SCharles.Forsyth   static int
t1_tobool(FT_Byte ** cursor,FT_Byte * limit)801*37da2899SCharles.Forsyth   t1_tobool( FT_Byte**  cursor,
802*37da2899SCharles.Forsyth              FT_Byte*   limit )
803*37da2899SCharles.Forsyth   {
804*37da2899SCharles.Forsyth     FT_Byte*  cur    = *cursor;
805*37da2899SCharles.Forsyth     FT_Bool   result = 0;
806*37da2899SCharles.Forsyth 
807*37da2899SCharles.Forsyth 
808*37da2899SCharles.Forsyth     /* return 1 if we find `true', 0 otherwise */
809*37da2899SCharles.Forsyth     if ( cur + 3 < limit &&
810*37da2899SCharles.Forsyth          cur[0] == 't' &&
811*37da2899SCharles.Forsyth          cur[1] == 'r' &&
812*37da2899SCharles.Forsyth          cur[2] == 'u' &&
813*37da2899SCharles.Forsyth          cur[3] == 'e' )
814*37da2899SCharles.Forsyth     {
815*37da2899SCharles.Forsyth       result = 1;
816*37da2899SCharles.Forsyth       cur   += 5;
817*37da2899SCharles.Forsyth     }
818*37da2899SCharles.Forsyth     else if ( cur + 4 < limit &&
819*37da2899SCharles.Forsyth               cur[0] == 'f' &&
820*37da2899SCharles.Forsyth               cur[1] == 'a' &&
821*37da2899SCharles.Forsyth               cur[2] == 'l' &&
822*37da2899SCharles.Forsyth               cur[3] == 's' &&
823*37da2899SCharles.Forsyth               cur[4] == 'e' )
824*37da2899SCharles.Forsyth     {
825*37da2899SCharles.Forsyth       result = 0;
826*37da2899SCharles.Forsyth       cur   += 6;
827*37da2899SCharles.Forsyth     }
828*37da2899SCharles.Forsyth 
829*37da2899SCharles.Forsyth     *cursor = cur;
830*37da2899SCharles.Forsyth     return result;
831*37da2899SCharles.Forsyth   }
832*37da2899SCharles.Forsyth 
833*37da2899SCharles.Forsyth 
834*37da2899SCharles.Forsyth   /* Load a simple field (i.e. non-table) into the current list of objects */
835*37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_Error )
ps_parser_load_field(PS_Parser parser,const T1_Field field,void ** objects,FT_UInt max_objects,FT_ULong * pflags)836*37da2899SCharles.Forsyth   ps_parser_load_field( PS_Parser       parser,
837*37da2899SCharles.Forsyth                         const T1_Field  field,
838*37da2899SCharles.Forsyth                         void**          objects,
839*37da2899SCharles.Forsyth                         FT_UInt         max_objects,
840*37da2899SCharles.Forsyth                         FT_ULong*       pflags )
841*37da2899SCharles.Forsyth   {
842*37da2899SCharles.Forsyth     T1_TokenRec  token;
843*37da2899SCharles.Forsyth     FT_Byte*     cur;
844*37da2899SCharles.Forsyth     FT_Byte*     limit;
845*37da2899SCharles.Forsyth     FT_UInt      count;
846*37da2899SCharles.Forsyth     FT_UInt      idx;
847*37da2899SCharles.Forsyth     FT_Error     error;
848*37da2899SCharles.Forsyth 
849*37da2899SCharles.Forsyth 
850*37da2899SCharles.Forsyth     ps_parser_to_token( parser, &token );
851*37da2899SCharles.Forsyth     if ( !token.type )
852*37da2899SCharles.Forsyth       goto Fail;
853*37da2899SCharles.Forsyth 
854*37da2899SCharles.Forsyth     count = 1;
855*37da2899SCharles.Forsyth     idx   = 0;
856*37da2899SCharles.Forsyth     cur   = token.start;
857*37da2899SCharles.Forsyth     limit = token.limit;
858*37da2899SCharles.Forsyth 
859*37da2899SCharles.Forsyth     /* we must detect arrays */
860*37da2899SCharles.Forsyth     if ( field->type == T1_FIELD_TYPE_BBOX )
861*37da2899SCharles.Forsyth     {
862*37da2899SCharles.Forsyth       T1_TokenRec  token2;
863*37da2899SCharles.Forsyth       FT_Byte*     old_cur   = parser->cursor;
864*37da2899SCharles.Forsyth       FT_Byte*     old_limit = parser->limit;
865*37da2899SCharles.Forsyth 
866*37da2899SCharles.Forsyth 
867*37da2899SCharles.Forsyth       parser->cursor = token.start;
868*37da2899SCharles.Forsyth       parser->limit  = token.limit;
869*37da2899SCharles.Forsyth 
870*37da2899SCharles.Forsyth       ps_parser_to_token( parser, &token2 );
871*37da2899SCharles.Forsyth       parser->cursor = old_cur;
872*37da2899SCharles.Forsyth       parser->limit  = old_limit;
873*37da2899SCharles.Forsyth 
874*37da2899SCharles.Forsyth       if ( token2.type == T1_TOKEN_TYPE_ARRAY )
875*37da2899SCharles.Forsyth         goto FieldArray;
876*37da2899SCharles.Forsyth     }
877*37da2899SCharles.Forsyth     else if ( token.type == T1_TOKEN_TYPE_ARRAY )
878*37da2899SCharles.Forsyth     {
879*37da2899SCharles.Forsyth     FieldArray:
880*37da2899SCharles.Forsyth       /* if this is an array, and we have no blend, an error occurs */
881*37da2899SCharles.Forsyth       if ( max_objects == 0 )
882*37da2899SCharles.Forsyth         goto Fail;
883*37da2899SCharles.Forsyth 
884*37da2899SCharles.Forsyth       count = max_objects;
885*37da2899SCharles.Forsyth       idx = 1;
886*37da2899SCharles.Forsyth     }
887*37da2899SCharles.Forsyth 
888*37da2899SCharles.Forsyth     for ( ; count > 0; count--, idx++ )
889*37da2899SCharles.Forsyth     {
890*37da2899SCharles.Forsyth       FT_Byte*    q = (FT_Byte*)objects[idx] + field->offset;
891*37da2899SCharles.Forsyth       FT_Long     val;
892*37da2899SCharles.Forsyth       FT_String*  string;
893*37da2899SCharles.Forsyth 
894*37da2899SCharles.Forsyth 
895*37da2899SCharles.Forsyth       switch ( field->type )
896*37da2899SCharles.Forsyth       {
897*37da2899SCharles.Forsyth       case T1_FIELD_TYPE_BOOL:
898*37da2899SCharles.Forsyth         val = t1_tobool( &cur, limit );
899*37da2899SCharles.Forsyth         goto Store_Integer;
900*37da2899SCharles.Forsyth 
901*37da2899SCharles.Forsyth       case T1_FIELD_TYPE_FIXED:
902*37da2899SCharles.Forsyth         val = t1_tofixed( &cur, limit, 3 );
903*37da2899SCharles.Forsyth         goto Store_Integer;
904*37da2899SCharles.Forsyth 
905*37da2899SCharles.Forsyth       case T1_FIELD_TYPE_INTEGER:
906*37da2899SCharles.Forsyth         val = t1_toint( &cur, limit );
907*37da2899SCharles.Forsyth 
908*37da2899SCharles.Forsyth       Store_Integer:
909*37da2899SCharles.Forsyth         switch ( field->size )
910*37da2899SCharles.Forsyth         {
911*37da2899SCharles.Forsyth         case 1:
912*37da2899SCharles.Forsyth           *(FT_Byte*)q = (FT_Byte)val;
913*37da2899SCharles.Forsyth           break;
914*37da2899SCharles.Forsyth 
915*37da2899SCharles.Forsyth         case 2:
916*37da2899SCharles.Forsyth           *(FT_UShort*)q = (FT_UShort)val;
917*37da2899SCharles.Forsyth           break;
918*37da2899SCharles.Forsyth 
919*37da2899SCharles.Forsyth         case 4:
920*37da2899SCharles.Forsyth           *(FT_UInt32*)q = (FT_UInt32)val;
921*37da2899SCharles.Forsyth           break;
922*37da2899SCharles.Forsyth 
923*37da2899SCharles.Forsyth         default:                /* for 64-bit systems */
924*37da2899SCharles.Forsyth           *(FT_Long*)q = val;
925*37da2899SCharles.Forsyth         }
926*37da2899SCharles.Forsyth         break;
927*37da2899SCharles.Forsyth 
928*37da2899SCharles.Forsyth       case T1_FIELD_TYPE_STRING:
929*37da2899SCharles.Forsyth         {
930*37da2899SCharles.Forsyth           FT_Memory  memory = parser->memory;
931*37da2899SCharles.Forsyth           FT_UInt    len    = (FT_UInt)( limit - cur );
932*37da2899SCharles.Forsyth 
933*37da2899SCharles.Forsyth 
934*37da2899SCharles.Forsyth           if ( *(FT_String**)q )
935*37da2899SCharles.Forsyth             /* with synthetic fonts, it's possible to find a field twice */
936*37da2899SCharles.Forsyth             break;
937*37da2899SCharles.Forsyth 
938*37da2899SCharles.Forsyth           if ( FT_ALLOC( string, len + 1 ) )
939*37da2899SCharles.Forsyth             goto Exit;
940*37da2899SCharles.Forsyth 
941*37da2899SCharles.Forsyth           FT_MEM_COPY( string, cur, len );
942*37da2899SCharles.Forsyth           string[len] = 0;
943*37da2899SCharles.Forsyth 
944*37da2899SCharles.Forsyth           *(FT_String**)q = string;
945*37da2899SCharles.Forsyth         }
946*37da2899SCharles.Forsyth         break;
947*37da2899SCharles.Forsyth 
948*37da2899SCharles.Forsyth       case T1_FIELD_TYPE_BBOX:
949*37da2899SCharles.Forsyth         {
950*37da2899SCharles.Forsyth           FT_Fixed  temp[4];
951*37da2899SCharles.Forsyth           FT_BBox*  bbox = (FT_BBox*)q;
952*37da2899SCharles.Forsyth 
953*37da2899SCharles.Forsyth 
954*37da2899SCharles.Forsyth           /* we need the '[' and ']' delimiters */
955*37da2899SCharles.Forsyth           token.start--;
956*37da2899SCharles.Forsyth           token.limit++;
957*37da2899SCharles.Forsyth           (void)t1_tofixedarray( &token.start, token.limit, 4, temp, 0 );
958*37da2899SCharles.Forsyth 
959*37da2899SCharles.Forsyth           bbox->xMin = FT_RoundFix( temp[0] );
960*37da2899SCharles.Forsyth           bbox->yMin = FT_RoundFix( temp[1] );
961*37da2899SCharles.Forsyth           bbox->xMax = FT_RoundFix( temp[2] );
962*37da2899SCharles.Forsyth           bbox->yMax = FT_RoundFix( temp[3] );
963*37da2899SCharles.Forsyth         }
964*37da2899SCharles.Forsyth         break;
965*37da2899SCharles.Forsyth 
966*37da2899SCharles.Forsyth       default:
967*37da2899SCharles.Forsyth         /* an error occured */
968*37da2899SCharles.Forsyth         goto Fail;
969*37da2899SCharles.Forsyth       }
970*37da2899SCharles.Forsyth     }
971*37da2899SCharles.Forsyth 
972*37da2899SCharles.Forsyth #if 0  /* obsolete - keep for reference */
973*37da2899SCharles.Forsyth     if ( pflags )
974*37da2899SCharles.Forsyth       *pflags |= 1L << field->flag_bit;
975*37da2899SCharles.Forsyth #else
976*37da2899SCharles.Forsyth     FT_UNUSED( pflags );
977*37da2899SCharles.Forsyth #endif
978*37da2899SCharles.Forsyth 
979*37da2899SCharles.Forsyth     error = PSaux_Err_Ok;
980*37da2899SCharles.Forsyth 
981*37da2899SCharles.Forsyth   Exit:
982*37da2899SCharles.Forsyth     return error;
983*37da2899SCharles.Forsyth 
984*37da2899SCharles.Forsyth   Fail:
985*37da2899SCharles.Forsyth     error = PSaux_Err_Invalid_File_Format;
986*37da2899SCharles.Forsyth     goto Exit;
987*37da2899SCharles.Forsyth   }
988*37da2899SCharles.Forsyth 
989*37da2899SCharles.Forsyth 
990*37da2899SCharles.Forsyth #define T1_MAX_TABLE_ELEMENTS  32
991*37da2899SCharles.Forsyth 
992*37da2899SCharles.Forsyth 
993*37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_Error )
ps_parser_load_field_table(PS_Parser parser,const T1_Field field,void ** objects,FT_UInt max_objects,FT_ULong * pflags)994*37da2899SCharles.Forsyth   ps_parser_load_field_table( PS_Parser       parser,
995*37da2899SCharles.Forsyth                               const T1_Field  field,
996*37da2899SCharles.Forsyth                               void**          objects,
997*37da2899SCharles.Forsyth                               FT_UInt         max_objects,
998*37da2899SCharles.Forsyth                               FT_ULong*       pflags )
999*37da2899SCharles.Forsyth   {
1000*37da2899SCharles.Forsyth     T1_TokenRec  elements[T1_MAX_TABLE_ELEMENTS];
1001*37da2899SCharles.Forsyth     T1_Token     token;
1002*37da2899SCharles.Forsyth     FT_Int       num_elements;
1003*37da2899SCharles.Forsyth     FT_Error     error = 0;
1004*37da2899SCharles.Forsyth     FT_Byte*     old_cursor;
1005*37da2899SCharles.Forsyth     FT_Byte*     old_limit;
1006*37da2899SCharles.Forsyth     T1_FieldRec  fieldrec = *(T1_Field)field;
1007*37da2899SCharles.Forsyth 
1008*37da2899SCharles.Forsyth 
1009*37da2899SCharles.Forsyth #if 1
1010*37da2899SCharles.Forsyth     fieldrec.type = T1_FIELD_TYPE_INTEGER;
1011*37da2899SCharles.Forsyth     if ( field->type == T1_FIELD_TYPE_FIXED_ARRAY )
1012*37da2899SCharles.Forsyth       fieldrec.type = T1_FIELD_TYPE_FIXED;
1013*37da2899SCharles.Forsyth #endif
1014*37da2899SCharles.Forsyth 
1015*37da2899SCharles.Forsyth     ps_parser_to_token_array( parser, elements, 32, &num_elements );
1016*37da2899SCharles.Forsyth     if ( num_elements < 0 )
1017*37da2899SCharles.Forsyth       goto Fail;
1018*37da2899SCharles.Forsyth 
1019*37da2899SCharles.Forsyth     if ( num_elements > T1_MAX_TABLE_ELEMENTS )
1020*37da2899SCharles.Forsyth       num_elements = T1_MAX_TABLE_ELEMENTS;
1021*37da2899SCharles.Forsyth 
1022*37da2899SCharles.Forsyth     old_cursor = parser->cursor;
1023*37da2899SCharles.Forsyth     old_limit  = parser->limit;
1024*37da2899SCharles.Forsyth 
1025*37da2899SCharles.Forsyth     /* we store the elements count */
1026*37da2899SCharles.Forsyth     *(FT_Byte*)( (FT_Byte*)objects[0] + field->count_offset ) =
1027*37da2899SCharles.Forsyth       (FT_Byte)num_elements;
1028*37da2899SCharles.Forsyth 
1029*37da2899SCharles.Forsyth     /* we now load each element, adjusting the field.offset on each one */
1030*37da2899SCharles.Forsyth     token = elements;
1031*37da2899SCharles.Forsyth     for ( ; num_elements > 0; num_elements--, token++ )
1032*37da2899SCharles.Forsyth     {
1033*37da2899SCharles.Forsyth       parser->cursor = token->start;
1034*37da2899SCharles.Forsyth       parser->limit  = token->limit;
1035*37da2899SCharles.Forsyth       ps_parser_load_field( parser, &fieldrec, objects, max_objects, 0 );
1036*37da2899SCharles.Forsyth       fieldrec.offset += fieldrec.size;
1037*37da2899SCharles.Forsyth     }
1038*37da2899SCharles.Forsyth 
1039*37da2899SCharles.Forsyth #if 0  /* obsolete -- keep for reference */
1040*37da2899SCharles.Forsyth     if ( pflags )
1041*37da2899SCharles.Forsyth       *pflags |= 1L << field->flag_bit;
1042*37da2899SCharles.Forsyth #else
1043*37da2899SCharles.Forsyth     FT_UNUSED( pflags );
1044*37da2899SCharles.Forsyth #endif
1045*37da2899SCharles.Forsyth 
1046*37da2899SCharles.Forsyth     parser->cursor = old_cursor;
1047*37da2899SCharles.Forsyth     parser->limit  = old_limit;
1048*37da2899SCharles.Forsyth 
1049*37da2899SCharles.Forsyth   Exit:
1050*37da2899SCharles.Forsyth     return error;
1051*37da2899SCharles.Forsyth 
1052*37da2899SCharles.Forsyth   Fail:
1053*37da2899SCharles.Forsyth     error = PSaux_Err_Invalid_File_Format;
1054*37da2899SCharles.Forsyth     goto Exit;
1055*37da2899SCharles.Forsyth   }
1056*37da2899SCharles.Forsyth 
1057*37da2899SCharles.Forsyth 
1058*37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_Long )
ps_parser_to_int(PS_Parser parser)1059*37da2899SCharles.Forsyth   ps_parser_to_int( PS_Parser  parser )
1060*37da2899SCharles.Forsyth   {
1061*37da2899SCharles.Forsyth     return t1_toint( &parser->cursor, parser->limit );
1062*37da2899SCharles.Forsyth   }
1063*37da2899SCharles.Forsyth 
1064*37da2899SCharles.Forsyth 
1065*37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_Fixed )
ps_parser_to_fixed(PS_Parser parser,FT_Int power_ten)1066*37da2899SCharles.Forsyth   ps_parser_to_fixed( PS_Parser  parser,
1067*37da2899SCharles.Forsyth                       FT_Int     power_ten )
1068*37da2899SCharles.Forsyth   {
1069*37da2899SCharles.Forsyth     return t1_tofixed( &parser->cursor, parser->limit, power_ten );
1070*37da2899SCharles.Forsyth   }
1071*37da2899SCharles.Forsyth 
1072*37da2899SCharles.Forsyth 
1073*37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_Int )
ps_parser_to_coord_array(PS_Parser parser,FT_Int max_coords,FT_Short * coords)1074*37da2899SCharles.Forsyth   ps_parser_to_coord_array( PS_Parser  parser,
1075*37da2899SCharles.Forsyth                             FT_Int     max_coords,
1076*37da2899SCharles.Forsyth                             FT_Short*  coords )
1077*37da2899SCharles.Forsyth   {
1078*37da2899SCharles.Forsyth     return t1_tocoordarray( &parser->cursor, parser->limit,
1079*37da2899SCharles.Forsyth                             max_coords, coords );
1080*37da2899SCharles.Forsyth   }
1081*37da2899SCharles.Forsyth 
1082*37da2899SCharles.Forsyth 
1083*37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_Int )
ps_parser_to_fixed_array(PS_Parser parser,FT_Int max_values,FT_Fixed * values,FT_Int power_ten)1084*37da2899SCharles.Forsyth   ps_parser_to_fixed_array( PS_Parser  parser,
1085*37da2899SCharles.Forsyth                             FT_Int     max_values,
1086*37da2899SCharles.Forsyth                             FT_Fixed*  values,
1087*37da2899SCharles.Forsyth                             FT_Int     power_ten )
1088*37da2899SCharles.Forsyth   {
1089*37da2899SCharles.Forsyth     return t1_tofixedarray( &parser->cursor, parser->limit,
1090*37da2899SCharles.Forsyth                             max_values, values, power_ten );
1091*37da2899SCharles.Forsyth   }
1092*37da2899SCharles.Forsyth 
1093*37da2899SCharles.Forsyth 
1094*37da2899SCharles.Forsyth #if 0
1095*37da2899SCharles.Forsyth 
1096*37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_String* )
1097*37da2899SCharles.Forsyth   T1_ToString( PS_Parser  parser )
1098*37da2899SCharles.Forsyth   {
1099*37da2899SCharles.Forsyth     return t1_tostring( &parser->cursor, parser->limit, parser->memory );
1100*37da2899SCharles.Forsyth   }
1101*37da2899SCharles.Forsyth 
1102*37da2899SCharles.Forsyth 
1103*37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_Bool )
1104*37da2899SCharles.Forsyth   T1_ToBool( PS_Parser  parser )
1105*37da2899SCharles.Forsyth   {
1106*37da2899SCharles.Forsyth     return t1_tobool( &parser->cursor, parser->limit );
1107*37da2899SCharles.Forsyth   }
1108*37da2899SCharles.Forsyth 
1109*37da2899SCharles.Forsyth #endif /* 0 */
1110*37da2899SCharles.Forsyth 
1111*37da2899SCharles.Forsyth 
1112*37da2899SCharles.Forsyth   FT_LOCAL_DEF( void )
ps_parser_init(PS_Parser parser,FT_Byte * base,FT_Byte * limit,FT_Memory memory)1113*37da2899SCharles.Forsyth   ps_parser_init( PS_Parser  parser,
1114*37da2899SCharles.Forsyth                   FT_Byte*   base,
1115*37da2899SCharles.Forsyth                   FT_Byte*   limit,
1116*37da2899SCharles.Forsyth                   FT_Memory  memory )
1117*37da2899SCharles.Forsyth   {
1118*37da2899SCharles.Forsyth     parser->error  = 0;
1119*37da2899SCharles.Forsyth     parser->base   = base;
1120*37da2899SCharles.Forsyth     parser->limit  = limit;
1121*37da2899SCharles.Forsyth     parser->cursor = base;
1122*37da2899SCharles.Forsyth     parser->memory = memory;
1123*37da2899SCharles.Forsyth     parser->funcs  = ps_parser_funcs;
1124*37da2899SCharles.Forsyth   }
1125*37da2899SCharles.Forsyth 
1126*37da2899SCharles.Forsyth 
1127*37da2899SCharles.Forsyth   FT_LOCAL_DEF( void )
ps_parser_done(PS_Parser parser)1128*37da2899SCharles.Forsyth   ps_parser_done( PS_Parser  parser )
1129*37da2899SCharles.Forsyth   {
1130*37da2899SCharles.Forsyth     FT_UNUSED( parser );
1131*37da2899SCharles.Forsyth   }
1132*37da2899SCharles.Forsyth 
1133*37da2899SCharles.Forsyth 
1134*37da2899SCharles.Forsyth   /*************************************************************************/
1135*37da2899SCharles.Forsyth   /*************************************************************************/
1136*37da2899SCharles.Forsyth   /*****                                                               *****/
1137*37da2899SCharles.Forsyth   /*****                            T1 BUILDER                         *****/
1138*37da2899SCharles.Forsyth   /*****                                                               *****/
1139*37da2899SCharles.Forsyth   /*************************************************************************/
1140*37da2899SCharles.Forsyth   /*************************************************************************/
1141*37da2899SCharles.Forsyth 
1142*37da2899SCharles.Forsyth   /*************************************************************************/
1143*37da2899SCharles.Forsyth   /*                                                                       */
1144*37da2899SCharles.Forsyth   /* <Function>                                                            */
1145*37da2899SCharles.Forsyth   /*    t1_builder_init                                                    */
1146*37da2899SCharles.Forsyth   /*                                                                       */
1147*37da2899SCharles.Forsyth   /* <Description>                                                         */
1148*37da2899SCharles.Forsyth   /*    Initializes a given glyph builder.                                 */
1149*37da2899SCharles.Forsyth   /*                                                                       */
1150*37da2899SCharles.Forsyth   /* <InOut>                                                               */
1151*37da2899SCharles.Forsyth   /*    builder :: A pointer to the glyph builder to initialize.           */
1152*37da2899SCharles.Forsyth   /*                                                                       */
1153*37da2899SCharles.Forsyth   /* <Input>                                                               */
1154*37da2899SCharles.Forsyth   /*    face    :: The current face object.                                */
1155*37da2899SCharles.Forsyth   /*                                                                       */
1156*37da2899SCharles.Forsyth   /*    size    :: The current size object.                                */
1157*37da2899SCharles.Forsyth   /*                                                                       */
1158*37da2899SCharles.Forsyth   /*    glyph   :: The current glyph object.                               */
1159*37da2899SCharles.Forsyth   /*                                                                       */
1160*37da2899SCharles.Forsyth   /*    hinting :: Whether hinting should be applied.                      */
1161*37da2899SCharles.Forsyth   /*                                                                       */
1162*37da2899SCharles.Forsyth   FT_LOCAL_DEF( void )
t1_builder_init(T1_Builder builder,FT_Face face,FT_Size size,FT_GlyphSlot glyph,FT_Bool hinting)1163*37da2899SCharles.Forsyth   t1_builder_init( T1_Builder    builder,
1164*37da2899SCharles.Forsyth                    FT_Face       face,
1165*37da2899SCharles.Forsyth                    FT_Size       size,
1166*37da2899SCharles.Forsyth                    FT_GlyphSlot  glyph,
1167*37da2899SCharles.Forsyth                    FT_Bool       hinting )
1168*37da2899SCharles.Forsyth   {
1169*37da2899SCharles.Forsyth     builder->path_begun  = 0;
1170*37da2899SCharles.Forsyth     builder->load_points = 1;
1171*37da2899SCharles.Forsyth 
1172*37da2899SCharles.Forsyth     builder->face   = face;
1173*37da2899SCharles.Forsyth     builder->glyph  = glyph;
1174*37da2899SCharles.Forsyth     builder->memory = face->memory;
1175*37da2899SCharles.Forsyth 
1176*37da2899SCharles.Forsyth     if ( glyph )
1177*37da2899SCharles.Forsyth     {
1178*37da2899SCharles.Forsyth       FT_GlyphLoader  loader = glyph->internal->loader;
1179*37da2899SCharles.Forsyth 
1180*37da2899SCharles.Forsyth 
1181*37da2899SCharles.Forsyth       builder->loader  = loader;
1182*37da2899SCharles.Forsyth       builder->base    = &loader->base.outline;
1183*37da2899SCharles.Forsyth       builder->current = &loader->current.outline;
1184*37da2899SCharles.Forsyth       FT_GlyphLoader_Rewind( loader );
1185*37da2899SCharles.Forsyth 
1186*37da2899SCharles.Forsyth       builder->hints_globals = size->internal;
1187*37da2899SCharles.Forsyth       builder->hints_funcs   = 0;
1188*37da2899SCharles.Forsyth 
1189*37da2899SCharles.Forsyth       if ( hinting )
1190*37da2899SCharles.Forsyth         builder->hints_funcs = glyph->internal->glyph_hints;
1191*37da2899SCharles.Forsyth     }
1192*37da2899SCharles.Forsyth 
1193*37da2899SCharles.Forsyth     if ( size )
1194*37da2899SCharles.Forsyth     {
1195*37da2899SCharles.Forsyth       builder->scale_x = size->metrics.x_scale;
1196*37da2899SCharles.Forsyth       builder->scale_y = size->metrics.y_scale;
1197*37da2899SCharles.Forsyth     }
1198*37da2899SCharles.Forsyth 
1199*37da2899SCharles.Forsyth     builder->pos_x = 0;
1200*37da2899SCharles.Forsyth     builder->pos_y = 0;
1201*37da2899SCharles.Forsyth 
1202*37da2899SCharles.Forsyth     builder->left_bearing.x = 0;
1203*37da2899SCharles.Forsyth     builder->left_bearing.y = 0;
1204*37da2899SCharles.Forsyth     builder->advance.x      = 0;
1205*37da2899SCharles.Forsyth     builder->advance.y      = 0;
1206*37da2899SCharles.Forsyth 
1207*37da2899SCharles.Forsyth     builder->funcs = t1_builder_funcs;
1208*37da2899SCharles.Forsyth   }
1209*37da2899SCharles.Forsyth 
1210*37da2899SCharles.Forsyth 
1211*37da2899SCharles.Forsyth   /*************************************************************************/
1212*37da2899SCharles.Forsyth   /*                                                                       */
1213*37da2899SCharles.Forsyth   /* <Function>                                                            */
1214*37da2899SCharles.Forsyth   /*    t1_builder_done                                                    */
1215*37da2899SCharles.Forsyth   /*                                                                       */
1216*37da2899SCharles.Forsyth   /* <Description>                                                         */
1217*37da2899SCharles.Forsyth   /*    Finalizes a given glyph builder.  Its contents can still be used   */
1218*37da2899SCharles.Forsyth   /*    after the call, but the function saves important information       */
1219*37da2899SCharles.Forsyth   /*    within the corresponding glyph slot.                               */
1220*37da2899SCharles.Forsyth   /*                                                                       */
1221*37da2899SCharles.Forsyth   /* <Input>                                                               */
1222*37da2899SCharles.Forsyth   /*    builder :: A pointer to the glyph builder to finalize.             */
1223*37da2899SCharles.Forsyth   /*                                                                       */
1224*37da2899SCharles.Forsyth   FT_LOCAL_DEF( void )
t1_builder_done(T1_Builder builder)1225*37da2899SCharles.Forsyth   t1_builder_done( T1_Builder  builder )
1226*37da2899SCharles.Forsyth   {
1227*37da2899SCharles.Forsyth     FT_GlyphSlot  glyph = builder->glyph;
1228*37da2899SCharles.Forsyth 
1229*37da2899SCharles.Forsyth 
1230*37da2899SCharles.Forsyth     if ( glyph )
1231*37da2899SCharles.Forsyth       glyph->outline = *builder->base;
1232*37da2899SCharles.Forsyth   }
1233*37da2899SCharles.Forsyth 
1234*37da2899SCharles.Forsyth 
1235*37da2899SCharles.Forsyth   /* check that there is enough space for `count' more points */
1236*37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_Error )
t1_builder_check_points(T1_Builder builder,FT_Int count)1237*37da2899SCharles.Forsyth   t1_builder_check_points( T1_Builder  builder,
1238*37da2899SCharles.Forsyth                            FT_Int      count )
1239*37da2899SCharles.Forsyth   {
1240*37da2899SCharles.Forsyth     return FT_GlyphLoader_CheckPoints( builder->loader, count, 0 );
1241*37da2899SCharles.Forsyth   }
1242*37da2899SCharles.Forsyth 
1243*37da2899SCharles.Forsyth 
1244*37da2899SCharles.Forsyth   /* add a new point, do not check space */
1245*37da2899SCharles.Forsyth   FT_LOCAL_DEF( void )
t1_builder_add_point(T1_Builder builder,FT_Pos x,FT_Pos y,FT_Byte flag)1246*37da2899SCharles.Forsyth   t1_builder_add_point( T1_Builder  builder,
1247*37da2899SCharles.Forsyth                         FT_Pos      x,
1248*37da2899SCharles.Forsyth                         FT_Pos      y,
1249*37da2899SCharles.Forsyth                         FT_Byte     flag )
1250*37da2899SCharles.Forsyth   {
1251*37da2899SCharles.Forsyth     FT_Outline*  outline = builder->current;
1252*37da2899SCharles.Forsyth 
1253*37da2899SCharles.Forsyth 
1254*37da2899SCharles.Forsyth     if ( builder->load_points )
1255*37da2899SCharles.Forsyth     {
1256*37da2899SCharles.Forsyth       FT_Vector*  point   = outline->points + outline->n_points;
1257*37da2899SCharles.Forsyth       FT_Byte*    control = (FT_Byte*)outline->tags + outline->n_points;
1258*37da2899SCharles.Forsyth 
1259*37da2899SCharles.Forsyth 
1260*37da2899SCharles.Forsyth       if ( builder->shift )
1261*37da2899SCharles.Forsyth       {
1262*37da2899SCharles.Forsyth         x >>= 16;
1263*37da2899SCharles.Forsyth         y >>= 16;
1264*37da2899SCharles.Forsyth       }
1265*37da2899SCharles.Forsyth       point->x = x;
1266*37da2899SCharles.Forsyth       point->y = y;
1267*37da2899SCharles.Forsyth       *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC );
1268*37da2899SCharles.Forsyth 
1269*37da2899SCharles.Forsyth       builder->last = *point;
1270*37da2899SCharles.Forsyth     }
1271*37da2899SCharles.Forsyth     outline->n_points++;
1272*37da2899SCharles.Forsyth   }
1273*37da2899SCharles.Forsyth 
1274*37da2899SCharles.Forsyth 
1275*37da2899SCharles.Forsyth   /* check space for a new on-curve point, then add it */
1276*37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_Error )
t1_builder_add_point1(T1_Builder builder,FT_Pos x,FT_Pos y)1277*37da2899SCharles.Forsyth   t1_builder_add_point1( T1_Builder  builder,
1278*37da2899SCharles.Forsyth                          FT_Pos      x,
1279*37da2899SCharles.Forsyth                          FT_Pos      y )
1280*37da2899SCharles.Forsyth   {
1281*37da2899SCharles.Forsyth     FT_Error  error;
1282*37da2899SCharles.Forsyth 
1283*37da2899SCharles.Forsyth 
1284*37da2899SCharles.Forsyth     error = t1_builder_check_points( builder, 1 );
1285*37da2899SCharles.Forsyth     if ( !error )
1286*37da2899SCharles.Forsyth       t1_builder_add_point( builder, x, y, 1 );
1287*37da2899SCharles.Forsyth 
1288*37da2899SCharles.Forsyth     return error;
1289*37da2899SCharles.Forsyth   }
1290*37da2899SCharles.Forsyth 
1291*37da2899SCharles.Forsyth 
1292*37da2899SCharles.Forsyth   /* check room for a new contour, then add it */
1293*37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_Error )
t1_builder_add_contour(T1_Builder builder)1294*37da2899SCharles.Forsyth   t1_builder_add_contour( T1_Builder  builder )
1295*37da2899SCharles.Forsyth   {
1296*37da2899SCharles.Forsyth     FT_Outline*  outline = builder->current;
1297*37da2899SCharles.Forsyth     FT_Error     error;
1298*37da2899SCharles.Forsyth 
1299*37da2899SCharles.Forsyth 
1300*37da2899SCharles.Forsyth     if ( !builder->load_points )
1301*37da2899SCharles.Forsyth     {
1302*37da2899SCharles.Forsyth       outline->n_contours++;
1303*37da2899SCharles.Forsyth       return PSaux_Err_Ok;
1304*37da2899SCharles.Forsyth     }
1305*37da2899SCharles.Forsyth 
1306*37da2899SCharles.Forsyth     error = FT_GlyphLoader_CheckPoints( builder->loader, 0, 1 );
1307*37da2899SCharles.Forsyth     if ( !error )
1308*37da2899SCharles.Forsyth     {
1309*37da2899SCharles.Forsyth       if ( outline->n_contours > 0 )
1310*37da2899SCharles.Forsyth         outline->contours[outline->n_contours - 1] =
1311*37da2899SCharles.Forsyth           (short)( outline->n_points - 1 );
1312*37da2899SCharles.Forsyth 
1313*37da2899SCharles.Forsyth       outline->n_contours++;
1314*37da2899SCharles.Forsyth     }
1315*37da2899SCharles.Forsyth 
1316*37da2899SCharles.Forsyth     return error;
1317*37da2899SCharles.Forsyth   }
1318*37da2899SCharles.Forsyth 
1319*37da2899SCharles.Forsyth 
1320*37da2899SCharles.Forsyth   /* if a path was begun, add its first on-curve point */
1321*37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_Error )
t1_builder_start_point(T1_Builder builder,FT_Pos x,FT_Pos y)1322*37da2899SCharles.Forsyth   t1_builder_start_point( T1_Builder  builder,
1323*37da2899SCharles.Forsyth                           FT_Pos      x,
1324*37da2899SCharles.Forsyth                           FT_Pos      y )
1325*37da2899SCharles.Forsyth   {
1326*37da2899SCharles.Forsyth     FT_Error  error = 0;
1327*37da2899SCharles.Forsyth 
1328*37da2899SCharles.Forsyth 
1329*37da2899SCharles.Forsyth     /* test whether we are building a new contour */
1330*37da2899SCharles.Forsyth     if ( !builder->path_begun )
1331*37da2899SCharles.Forsyth     {
1332*37da2899SCharles.Forsyth       builder->path_begun = 1;
1333*37da2899SCharles.Forsyth       error = t1_builder_add_contour( builder );
1334*37da2899SCharles.Forsyth       if ( !error )
1335*37da2899SCharles.Forsyth         error = t1_builder_add_point1( builder, x, y );
1336*37da2899SCharles.Forsyth     }
1337*37da2899SCharles.Forsyth     return error;
1338*37da2899SCharles.Forsyth   }
1339*37da2899SCharles.Forsyth 
1340*37da2899SCharles.Forsyth 
1341*37da2899SCharles.Forsyth   /* close the current contour */
1342*37da2899SCharles.Forsyth   FT_LOCAL_DEF( void )
t1_builder_close_contour(T1_Builder builder)1343*37da2899SCharles.Forsyth   t1_builder_close_contour( T1_Builder  builder )
1344*37da2899SCharles.Forsyth   {
1345*37da2899SCharles.Forsyth     FT_Outline*  outline = builder->current;
1346*37da2899SCharles.Forsyth 
1347*37da2899SCharles.Forsyth 
1348*37da2899SCharles.Forsyth     /* XXXX: We must not include the last point in the path if it */
1349*37da2899SCharles.Forsyth     /*       is located on the first point.                       */
1350*37da2899SCharles.Forsyth     if ( outline->n_points > 1 )
1351*37da2899SCharles.Forsyth     {
1352*37da2899SCharles.Forsyth       FT_Int      first   = 0;
1353*37da2899SCharles.Forsyth       FT_Vector*  p1      = outline->points + first;
1354*37da2899SCharles.Forsyth       FT_Vector*  p2      = outline->points + outline->n_points - 1;
1355*37da2899SCharles.Forsyth       FT_Byte*    control = (FT_Byte*)outline->tags + outline->n_points - 1;
1356*37da2899SCharles.Forsyth 
1357*37da2899SCharles.Forsyth 
1358*37da2899SCharles.Forsyth       if ( outline->n_contours > 1 )
1359*37da2899SCharles.Forsyth       {
1360*37da2899SCharles.Forsyth         first = outline->contours[outline->n_contours - 2] + 1;
1361*37da2899SCharles.Forsyth         p1    = outline->points + first;
1362*37da2899SCharles.Forsyth       }
1363*37da2899SCharles.Forsyth 
1364*37da2899SCharles.Forsyth       /* `delete' last point only if it coincides with the first */
1365*37da2899SCharles.Forsyth       /* point and it is not a control point (which can happen). */
1366*37da2899SCharles.Forsyth       if ( p1->x == p2->x && p1->y == p2->y )
1367*37da2899SCharles.Forsyth         if ( *control == FT_CURVE_TAG_ON )
1368*37da2899SCharles.Forsyth           outline->n_points--;
1369*37da2899SCharles.Forsyth     }
1370*37da2899SCharles.Forsyth 
1371*37da2899SCharles.Forsyth     if ( outline->n_contours > 0 )
1372*37da2899SCharles.Forsyth       outline->contours[outline->n_contours - 1] =
1373*37da2899SCharles.Forsyth         (short)( outline->n_points - 1 );
1374*37da2899SCharles.Forsyth   }
1375*37da2899SCharles.Forsyth 
1376*37da2899SCharles.Forsyth 
1377*37da2899SCharles.Forsyth   /*************************************************************************/
1378*37da2899SCharles.Forsyth   /*************************************************************************/
1379*37da2899SCharles.Forsyth   /*****                                                               *****/
1380*37da2899SCharles.Forsyth   /*****                            OTHER                              *****/
1381*37da2899SCharles.Forsyth   /*****                                                               *****/
1382*37da2899SCharles.Forsyth   /*************************************************************************/
1383*37da2899SCharles.Forsyth   /*************************************************************************/
1384*37da2899SCharles.Forsyth 
1385*37da2899SCharles.Forsyth   FT_LOCAL_DEF( void )
t1_decrypt(FT_Byte * buffer,FT_Offset length,FT_UShort seed)1386*37da2899SCharles.Forsyth   t1_decrypt( FT_Byte*   buffer,
1387*37da2899SCharles.Forsyth               FT_Offset  length,
1388*37da2899SCharles.Forsyth               FT_UShort  seed )
1389*37da2899SCharles.Forsyth   {
1390*37da2899SCharles.Forsyth     while ( length > 0 )
1391*37da2899SCharles.Forsyth     {
1392*37da2899SCharles.Forsyth       FT_Byte  plain;
1393*37da2899SCharles.Forsyth 
1394*37da2899SCharles.Forsyth 
1395*37da2899SCharles.Forsyth       plain     = (FT_Byte)( *buffer ^ ( seed >> 8 ) );
1396*37da2899SCharles.Forsyth       seed      = (FT_UShort)( ( *buffer + seed ) * 52845U + 22719 );
1397*37da2899SCharles.Forsyth       *buffer++ = plain;
1398*37da2899SCharles.Forsyth       length--;
1399*37da2899SCharles.Forsyth     }
1400*37da2899SCharles.Forsyth   }
1401*37da2899SCharles.Forsyth 
1402*37da2899SCharles.Forsyth 
1403*37da2899SCharles.Forsyth /* END */
1404