1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  psobjs.c                                                               */
4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*    Auxiliary functions for PostScript fonts (body).                     */
6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
7a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang/*  Copyright 1996-2013 by                                                 */
8049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  This file is part of the FreeType project, and may only be used,       */
11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  modified, and distributed under the terms of the FreeType project      */
12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  this file you indicate that you have read the license and              */
14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  understand and accept it fully.                                        */
15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
19049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <ft2build.h>
20049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_POSTSCRIPT_AUX_H
21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_DEBUG_H
22295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#include FT_INTERNAL_CALC_H
23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "psobjs.h"
25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "psconv.h"
26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "psauxerr.h"
28049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
30049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* messages during execution.                                            */
35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_psobjs
38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*****                                                               *****/
43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*****                             PS_TABLE                          *****/
44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*****                                                               *****/
45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    ps_table_new                                                       */
52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Initializes a PS_Table.                                            */
55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <InOut>                                                               */
57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    table  :: The address of the target table.                         */
58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    count  :: The table size = the maximum number of elements.         */
61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    memory :: The memory object to use for all subsequent              */
63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*              reallocations.                                           */
64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means success.                             */
67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_table_new( PS_Table   table,
70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Int     count,
71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Memory  memory )
72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error;
74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->memory = memory;
77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW_ARRAY( table->elements, count ) ||
78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         FT_NEW_ARRAY( table->lengths,  count ) )
79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->max_elems = count;
82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->init      = 0xDEADBEEFUL;
83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->num_elems = 0;
84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->block     = 0;
85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->capacity  = 0;
86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->cursor    = 0;
87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *(PS_Table_FuncsRec*)&table->funcs = ps_table_funcs;
89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( table->elements );
93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  shift_elements( PS_Table  table,
100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Byte*  old_base )
101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_PtrDist  delta  = table->block - old_base;
103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte**   offset = table->elements;
104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte**   limit  = offset + table->max_elems;
105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; offset < limit; offset++ )
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( offset[0] )
110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        offset[0] += delta;
111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
116a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang  reallocate_t1_table( PS_Table   table,
117a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang                       FT_Offset  new_size )
118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory   = table->memory;
120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*   old_base = table->block;
121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* allocate new base block */
125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_ALLOC( table->block, new_size ) )
126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      table->block = old_base;
128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* copy elements and shift offsets */
132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( old_base )
133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_MEM_COPY( table->block, old_base, table->capacity );
135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      shift_elements( table, old_base );
136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( old_base );
137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->capacity = new_size;
140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
141a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    return FT_Err_Ok;
142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    ps_table_add                                                       */
149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Adds an object to a PS_Table, possibly growing its memory block.   */
152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <InOut>                                                               */
154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    table  :: The target table.                                        */
155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    idx    :: The index of the object in the table.                    */
158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    object :: The address of the object to copy in memory.             */
160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    length :: The length in bytes of the source object.                */
162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means success.  An error is returned if a  */
165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    reallocation fails.                                                */
166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_table_add( PS_Table    table,
169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Int      idx,
170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                void*       object,
171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_PtrDist  length )
172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( idx < 0 || idx >= table->max_elems )
174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ERROR(( "ps_table_add: invalid index\n" ));
176a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      return FT_THROW( Invalid_Argument );
177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1790a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( length < 0 )
1800a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    {
1810a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      FT_ERROR(( "ps_table_add: invalid length\n" ));
182a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      return FT_THROW( Invalid_Argument );
1830a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    }
1840a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* grow the base block if needed */
186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( table->cursor + length > table->capacity )
187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
188e3b631da8034f7c6ecc6d809cd9e46d306215c32Xianzhu Wang      FT_Error    error;
189e3b631da8034f7c6ecc6d809cd9e46d306215c32Xianzhu Wang      FT_Offset   new_size = table->capacity;
190c3ee10bfa1f76a18500b487de9c85757375b48f3David 'Digit' Turner      FT_PtrDist  in_offset;
191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
193c3ee10bfa1f76a18500b487de9c85757375b48f3David 'Digit' Turner      in_offset = (FT_Byte*)object - table->block;
194c3ee10bfa1f76a18500b487de9c85757375b48f3David 'Digit' Turner      if ( in_offset < 0 || (FT_Offset)in_offset >= table->capacity )
195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        in_offset = -1;
196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      while ( new_size < table->cursor + length )
198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* increase size by 25% and round up to the nearest multiple
200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           of 1024 */
201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        new_size += ( new_size >> 2 ) + 1;
202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        new_size  = FT_PAD_CEIL( new_size, 1024 );
203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = reallocate_t1_table( table, new_size );
206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return error;
208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( in_offset >= 0 )
210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        object = table->block + in_offset;
211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* add the object to the base block and adjust offset */
214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->elements[idx] = table->block + table->cursor;
215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->lengths [idx] = length;
216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MEM_COPY( table->block + table->cursor, object, length );
217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->cursor += length;
219a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    return FT_Err_Ok;
220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    ps_table_done                                                      */
227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Finalizes a PS_TableRec (i.e., reallocate it to its current        */
230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    cursor).                                                           */
231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <InOut>                                                               */
233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    table :: The target table.                                         */
234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Note>                                                                */
236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    This function does NOT release the heap's memory block.  It is up  */
237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    to the caller to clean it, or reference it in its own structures.  */
238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( void )
240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_table_done( PS_Table  table )
241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = table->memory;
243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*   old_base = table->block;
245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* should never fail, because rec.cursor <= rec.size */
248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !old_base )
249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_ALLOC( table->block, table->cursor ) )
252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MEM_COPY( table->block, old_base, table->cursor );
254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    shift_elements( table, old_base );
255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->capacity = table->cursor;
257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( old_base );
258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( error );
260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( void )
264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_table_release( PS_Table  table )
265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = table->memory;
267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( (FT_ULong)table->init == 0xDEADBEEFUL )
270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( table->block );
272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( table->elements );
273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( table->lengths );
274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      table->init = 0;
275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*****                                                               *****/
282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*****                            T1 PARSER                          *****/
283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*****                                                               *****/
284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* first character must be already part of the comment */
289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  skip_comment( FT_Byte*  *acur,
292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Byte*   limit )
293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  cur = *acur;
295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( cur < limit )
298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( IS_PS_NEWLINE( *cur ) )
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur++;
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *acur = cur;
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  skip_spaces( FT_Byte*  *acur,
310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_Byte*   limit )
311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  cur = *acur;
313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( cur < limit )
316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !IS_PS_SPACE( *cur ) )
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( *cur == '%' )
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* According to the PLRM, a comment is equal to a space. */
321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          skip_comment( &cur, limit );
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur++;
326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *acur = cur;
329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define IS_OCTAL_DIGIT( c ) ( '0' <= (c) && (c) <= '7' )
333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* first character must be `(';                               */
336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* *acur is positioned at the character after the closing `)' */
337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  skip_literal_string( FT_Byte*  *acur,
340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                       FT_Byte*   limit )
341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*      cur   = *acur;
343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int        embed = 0;
344a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    FT_Error      error = FT_ERR( Invalid_File_Format );
345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    unsigned int  i;
346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( cur < limit )
349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Byte  c = *cur;
351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ++cur;
354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( c == '\\' )
356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Red Book 3rd ed., section `Literal Text Strings', p. 29:     */
358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* A backslash can introduce three different types              */
359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* of escape sequences:                                         */
360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /*   - a special escaped char like \r, \n, etc.                 */
361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /*   - a one-, two-, or three-digit octal number                */
362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /*   - none of the above in which case the backslash is ignored */
363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( cur == limit )
365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* error (or to be ignored?) */
366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        switch ( *cur )
369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* skip `special' escape */
371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        case 'n':
372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        case 'r':
373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        case 't':
374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        case 'b':
375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        case 'f':
376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        case '\\':
377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        case '(':
378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        case ')':
379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ++cur;
380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        default:
383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* skip octal escape or ignore backslash */
384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          for ( i = 0; i < 3 && cur < limit; ++i )
385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
3860a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            if ( !IS_OCTAL_DIGIT( *cur ) )
387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              break;
388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            ++cur;
390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else if ( c == '(' )
394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        embed++;
395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else if ( c == ')' )
396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        embed--;
398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( embed == 0 )
399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
400a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang          error = FT_Err_Ok;
401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *acur = cur;
407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* first character must be `<' */
413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  skip_string( FT_Byte*  *acur,
416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_Byte*   limit )
417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  cur = *acur;
419a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    FT_Error  err =  FT_Err_Ok;
420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( ++cur < limit )
423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* All whitespace characters are ignored. */
425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      skip_spaces( &cur, limit );
426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cur >= limit )
427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !IS_PS_XDIGIT( *cur ) )
430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( cur < limit && *cur != '>' )
434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ERROR(( "skip_string: missing closing delimiter `>'\n" ));
436a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      err = FT_THROW( Invalid_File_Format );
437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur++;
440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *acur = cur;
442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return err;
443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* first character must be the opening brace that */
447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* starts the procedure                           */
448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* NB: [ and ] need not match:                    */
450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* `/foo {[} def' is a valid PostScript fragment, */
451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* even within a Type1 font                       */
452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  skip_procedure( FT_Byte*  *acur,
455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Byte*   limit )
456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  cur;
458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int    embed = 0;
459a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    FT_Error  error = FT_Err_Ok;
460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( **acur == '{' );
463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
464a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    for ( cur = *acur; cur < limit && error == FT_Err_Ok; ++cur )
465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      switch ( *cur )
467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case '{':
469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ++embed;
470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case '}':
473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        --embed;
474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( embed == 0 )
475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ++cur;
477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto end;
478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case '(':
482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = skip_literal_string( &cur, limit );
483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case '<':
486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = skip_string( &cur, limit );
487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case '%':
490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        skip_comment( &cur, limit );
491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  end:
496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( embed != 0 )
497a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      error = FT_THROW( Invalid_File_Format );
498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *acur = cur;
500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /***********************************************************************/
506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                     */
507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* All exported parsing routines handle leading whitespace and stop at */
508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* the first character which isn't part of the just handled token.     */
509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                     */
510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /***********************************************************************/
511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( void )
514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_parser_skip_PS_token( PS_Parser  parser )
515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Note: PostScript allows any non-delimiting, non-whitespace        */
517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*       character in a name (PS Ref Manual, 3rd ed, p31).           */
518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*       PostScript delimiters are (, ), <, >, [, ], {, }, /, and %. */
519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  cur   = parser->cursor;
521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  limit = parser->limit;
522a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    FT_Error  error = FT_Err_Ok;
523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    skip_spaces( &cur, limit );             /* this also skips comments */
526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( cur >= limit )
527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* self-delimiting, single-character tokens */
530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( *cur == '[' || *cur == ']' )
531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur++;
533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* skip balanced expressions (procedures and strings) */
537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( *cur == '{' )                              /* {...} */
539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = skip_procedure( &cur, limit );
541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( *cur == '(' )                              /* (...) */
545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = skip_literal_string( &cur, limit );
547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( *cur == '<' )                              /* <...> */
551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cur + 1 < limit && *(cur + 1) == '<' )   /* << */
553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        cur++;
555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        cur++;
556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = skip_string( &cur, limit );
559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( *cur == '>' )
564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur++;
566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cur >= limit || *cur != '>' )             /* >> */
567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
568295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_ERROR(( "ps_parser_skip_PS_token:"
569295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                   " unexpected closing delimiter `>'\n" ));
570a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang        error = FT_THROW( Invalid_File_Format );
571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur++;
574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( *cur == '/' )
578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur++;
579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* anything else */
581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( cur < limit )
582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* *cur might be invalid (e.g., ')' or '}'), but this   */
584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* is handled by the test `cur == parser->cursor' below */
585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( IS_PS_DELIM( *cur ) )
586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur++;
589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
592e3b631da8034f7c6ecc6d809cd9e46d306215c32Xianzhu Wang    if ( cur < limit && cur == parser->cursor )
593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
594295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_ERROR(( "ps_parser_skip_PS_token:"
595295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                 " current token is `%c' which is self-delimiting\n"
596295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                 "                        "
597295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                 " but invalid at this point\n",
598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 *cur ));
599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
600a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      error = FT_THROW( Invalid_File_Format );
601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    parser->error  = error;
604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    parser->cursor = cur;
605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( void )
609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_parser_skip_spaces( PS_Parser  parser )
610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    skip_spaces( &parser->cursor, parser->limit );
612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* `token' here means either something between balanced delimiters */
616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* or the next token; the delimiters are not removed.              */
617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( void )
619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_parser_to_token( PS_Parser  parser,
620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      T1_Token   token )
621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  cur;
623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  limit;
624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int    embed;
625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    token->type  = T1_TOKEN_TYPE_NONE;
628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    token->start = 0;
629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    token->limit = 0;
630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* first of all, skip leading whitespace */
632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ps_parser_skip_spaces( parser );
633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cur   = parser->cursor;
635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    limit = parser->limit;
636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( cur >= limit )
638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    switch ( *cur )
641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /************* check for literal string *****************/
643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case '(':
644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      token->type  = T1_TOKEN_TYPE_STRING;
645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      token->start = cur;
646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
647a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      if ( skip_literal_string( &cur, limit ) == FT_Err_Ok )
648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        token->limit = cur;
649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /************* check for programs/array *****************/
652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case '{':
653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      token->type  = T1_TOKEN_TYPE_ARRAY;
654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      token->start = cur;
655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
656a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      if ( skip_procedure( &cur, limit ) == FT_Err_Ok )
657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        token->limit = cur;
658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /************* check for table/array ********************/
661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* XXX: in theory we should also look for "<<"          */
662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /*      since this is semantically equivalent to "[";   */
663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /*      in practice it doesn't matter (?)               */
664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case '[':
665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      token->type  = T1_TOKEN_TYPE_ARRAY;
666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      embed        = 1;
667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      token->start = cur++;
668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* we need this to catch `[ ]' */
670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      parser->cursor = cur;
671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ps_parser_skip_spaces( parser );
672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur = parser->cursor;
673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      while ( cur < limit && !parser->error )
675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* XXX: this is wrong because it does not      */
677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /*      skip comments, procedures, and strings */
678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( *cur == '[' )
679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          embed++;
680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else if ( *cur == ']' )
681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          embed--;
683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( embed <= 0 )
684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            token->limit = ++cur;
686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            break;
687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        parser->cursor = cur;
691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ps_parser_skip_PS_token( parser );
692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* we need this to catch `[XXX ]' */
693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ps_parser_skip_spaces  ( parser );
694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        cur = parser->cursor;
695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* ************ otherwise, it is any token **************/
699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    default:
700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      token->start = cur;
701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      token->type  = ( *cur == '/' ? T1_TOKEN_TYPE_KEY : T1_TOKEN_TYPE_ANY );
702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ps_parser_skip_PS_token( parser );
703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur = parser->cursor;
704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !parser->error )
705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        token->limit = cur;
706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !token->limit )
709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      token->start = 0;
711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      token->type  = T1_TOKEN_TYPE_NONE;
712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    parser->cursor = cur;
715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* NB: `tokens' can be NULL if we only want to count */
719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* the number of array elements                      */
720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( void )
722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_parser_to_token_array( PS_Parser  parser,
723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            T1_Token   tokens,
724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            FT_UInt    max_tokens,
725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            FT_Int*    pnum_tokens )
726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    T1_TokenRec  master;
728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *pnum_tokens = -1;
731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* this also handles leading whitespace */
733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ps_parser_to_token( parser, &master );
734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( master.type == T1_TOKEN_TYPE_ARRAY )
736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Byte*  old_cursor = parser->cursor;
738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Byte*  old_limit  = parser->limit;
739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      T1_Token  cur        = tokens;
740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      T1_Token  limit      = cur + max_tokens;
741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* don't include outermost delimiters */
744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      parser->cursor = master.start + 1;
745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      parser->limit  = master.limit - 1;
746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      while ( parser->cursor < parser->limit )
748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        T1_TokenRec  token;
750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ps_parser_to_token( parser, &token );
753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( !token.type )
754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( tokens != NULL && cur < limit )
757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *cur = token;
758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        cur++;
760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *pnum_tokens = (FT_Int)( cur - tokens );
763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      parser->cursor = old_cursor;
765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      parser->limit  = old_limit;
766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* first character must be a delimiter or a part of a number */
771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* NB: `coords' can be NULL if we just want to skip the      */
772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*     array; in this case we ignore `max_coords'            */
773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Int
775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_tocoordarray( FT_Byte*  *acur,
776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Byte*   limit,
777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Int     max_coords,
778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Short*  coords )
779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  cur   = *acur;
781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int    count = 0;
782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte   c, ender;
783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( cur >= limit )
786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* check for the beginning of an array; otherwise, only one number */
789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* will be read                                                    */
790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    c     = *cur;
791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ender = 0;
792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( c == '[' )
794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ender = ']';
795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( c == '{' )
796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ender = '}';
797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ender )
799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur++;
800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* now, read the coordinates */
802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( cur < limit )
803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Short  dummy;
805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Byte*  old_cur;
806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* skip whitespace in front of data */
809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      skip_spaces( &cur, limit );
810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cur >= limit )
811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( *cur == ender )
814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        cur++;
816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      old_cur = cur;
820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( coords != NULL && count >= max_coords )
822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* call PS_Conv_ToFixed() even if coords == NULL */
825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* to properly parse number at `cur'             */
826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *( coords != NULL ? &coords[count] : &dummy ) =
827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        (FT_Short)( PS_Conv_ToFixed( &cur, limit, 0 ) >> 16 );
828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( old_cur == cur )
830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        count = -1;
832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        count++;
836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !ender )
838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *acur = cur;
843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return count;
844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* first character must be a delimiter or a part of a number */
848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* NB: `values' can be NULL if we just want to skip the      */
849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*     array; in this case we ignore `max_values'            */
850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Int
852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_tofixedarray( FT_Byte*  *acur,
853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Byte*   limit,
854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Int     max_values,
855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Fixed*  values,
856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Int     power_ten )
857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  cur   = *acur;
859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int    count = 0;
860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte   c, ender;
861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( cur >= limit )
864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Check for the beginning of an array.  Otherwise, only one number */
867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* will be read.                                                    */
868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    c     = *cur;
869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ender = 0;
870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( c == '[' )
872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ender = ']';
873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( c == '{' )
874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ender = '}';
875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ender )
877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur++;
878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* now, read the values */
880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( cur < limit )
881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Fixed  dummy;
883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Byte*  old_cur;
884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* skip whitespace in front of data */
887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      skip_spaces( &cur, limit );
888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cur >= limit )
889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( *cur == ender )
892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        cur++;
894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      old_cur = cur;
898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( values != NULL && count >= max_values )
900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* call PS_Conv_ToFixed() even if coords == NULL */
903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* to properly parse number at `cur'             */
904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *( values != NULL ? &values[count] : &dummy ) =
905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        PS_Conv_ToFixed( &cur, limit, power_ten );
906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( old_cur == cur )
908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        count = -1;
910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        count++;
914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !ender )
916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *acur = cur;
921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return count;
922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 0
926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_String*
928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_tostring( FT_Byte**  cursor,
929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_Byte*   limit,
930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_Memory  memory )
931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*    cur = *cursor;
933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_PtrDist  len = 0;
934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int      count;
935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_String*  result;
936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error    error;
937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* XXX: some stupid fonts have a `Notice' or `Copyright' string     */
940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*      that simply doesn't begin with an opening parenthesis, even */
941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*      though they have a closing one!  E.g. "amuncial.pfb"        */
942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                  */
943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*      We must deal with these ill-fated cases there.  Note that   */
944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*      these fonts didn't work with the old Type 1 driver as the   */
945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*      notice/copyright was not recognized as a valid string token */
946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*      and made the old token parser commit errors.                */
947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( cur < limit && ( *cur == ' ' || *cur == '\t' ) )
949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur++;
950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( cur + 1 >= limit )
951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( *cur == '(' )
954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur++;  /* skip the opening parenthesis, if there is one */
955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *cursor = cur;
957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    count   = 0;
958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* then, count its length */
960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; cur < limit; cur++ )
961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( *cur == '(' )
963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        count++;
964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else if ( *cur == ')' )
966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        count--;
968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( count < 0 )
969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    len = cur - *cursor;
974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( cur >= limit || FT_ALLOC( result, len + 1 ) )
975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* now copy the string */
978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MEM_COPY( result, *cursor, len );
979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    result[len] = '\0';
980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *cursor = cur;
981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* 0 */
985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static int
988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_tobool( FT_Byte*  *acur,
989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Byte*   limit )
990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  cur    = *acur;
992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Bool   result = 0;
993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* return 1 if we find `true', 0 otherwise */
996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( cur + 3 < limit &&
997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         cur[0] == 't'   &&
998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         cur[1] == 'r'   &&
999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         cur[2] == 'u'   &&
1000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         cur[3] == 'e'   )
1001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      result = 1;
1003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur   += 5;
1004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( cur + 4 < limit &&
1006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              cur[0] == 'f'   &&
1007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              cur[1] == 'a'   &&
1008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              cur[2] == 'l'   &&
1009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              cur[3] == 's'   &&
1010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              cur[4] == 'e'   )
1011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      result = 0;
1013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur   += 6;
1014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *acur = cur;
1017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
1018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* load a simple field (i.e. non-table) into the current list of objects */
1022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
1024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_parser_load_field( PS_Parser       parser,
1025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        const T1_Field  field,
1026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        void**          objects,
1027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_UInt         max_objects,
1028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_ULong*       pflags )
1029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1030a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    T1_TokenRec   token;
1031a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    FT_Byte*      cur;
1032a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    FT_Byte*      limit;
1033a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    FT_UInt       count;
1034a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    FT_UInt       idx;
1035a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    FT_Error      error;
1036a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    T1_FieldType  type;
1037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* this also skips leading whitespace */
1040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ps_parser_to_token( parser, &token );
1041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !token.type )
1042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
1043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    count = 1;
1045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    idx   = 0;
1046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cur   = token.start;
1047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    limit = token.limit;
1048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1049a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    type = field->type;
1050a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
1051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* we must detect arrays in /FontBBox */
1052a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    if ( type == T1_FIELD_TYPE_BBOX )
1053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      T1_TokenRec  token2;
1055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Byte*     old_cur   = parser->cursor;
1056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Byte*     old_limit = parser->limit;
1057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* don't include delimiters */
1060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      parser->cursor = token.start + 1;
1061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      parser->limit  = token.limit - 1;
1062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ps_parser_to_token( parser, &token2 );
1064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      parser->cursor = old_cur;
1065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      parser->limit  = old_limit;
1066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( token2.type == T1_TOKEN_TYPE_ARRAY )
1068a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      {
1069a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang        type = T1_FIELD_TYPE_MM_BBOX;
1070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto FieldArray;
1071a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      }
1072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( token.type == T1_TOKEN_TYPE_ARRAY )
1074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1075a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      count = max_objects;
1076a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
1077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FieldArray:
1078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* if this is an array and we have no blend, an error occurs */
1079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( max_objects == 0 )
1080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Fail;
1081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1082a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      idx = 1;
1083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* don't include delimiters */
1085049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur++;
1086049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      limit--;
1087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1089049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; count > 0; count--, idx++ )
1090049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Byte*    q = (FT_Byte*)objects[idx] + field->offset;
1092049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Long     val;
1093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_String*  string;
1094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      skip_spaces( &cur, limit );
1097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1098a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      switch ( type )
1099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case T1_FIELD_TYPE_BOOL:
1101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        val = ps_tobool( &cur, limit );
1102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Store_Integer;
1103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case T1_FIELD_TYPE_FIXED:
1105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        val = PS_Conv_ToFixed( &cur, limit, 0 );
1106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Store_Integer;
1107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case T1_FIELD_TYPE_FIXED_1000:
1109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        val = PS_Conv_ToFixed( &cur, limit, 3 );
1110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Store_Integer;
1111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case T1_FIELD_TYPE_INTEGER:
1113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        val = PS_Conv_ToInt( &cur, limit );
1114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* fall through */
1115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      Store_Integer:
1117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        switch ( field->size )
1118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        case (8 / FT_CHAR_BIT):
1120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *(FT_Byte*)q = (FT_Byte)val;
1121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
1122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        case (16 / FT_CHAR_BIT):
1124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *(FT_UShort*)q = (FT_UShort)val;
1125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
1126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        case (32 / FT_CHAR_BIT):
1128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *(FT_UInt32*)q = (FT_UInt32)val;
1129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
1130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        default:                /* for 64-bit systems */
1132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *(FT_Long*)q = val;
1133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
1135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case T1_FIELD_TYPE_STRING:
1137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case T1_FIELD_TYPE_KEY:
1138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Memory  memory = parser->memory;
1140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_UInt    len    = (FT_UInt)( limit - cur );
1141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( cur >= limit )
1144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            break;
1145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* we allow both a string or a name   */
1147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* for cases like /FontName (foo) def */
1148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( token.type == T1_TOKEN_TYPE_KEY )
1149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
1150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* don't include leading `/' */
1151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            len--;
1152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            cur++;
1153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          else if ( token.type == T1_TOKEN_TYPE_STRING )
1155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
1156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* don't include delimiting parentheses    */
1157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* XXX we don't handle <<...>> here        */
1158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* XXX should we convert octal escapes?    */
1159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /*     if so, what encoding should we use? */
1160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            cur++;
1161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            len -= 2;
1162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          else
1164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
1165295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            FT_ERROR(( "ps_parser_load_field:"
1166295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                       " expected a name or string\n"
1167295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                       "                     "
1168295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                       " but found token of type %d instead\n",
1169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                       token.type ));
1170a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang            error = FT_THROW( Invalid_File_Format );
1171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Exit;
1172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* for this to work (FT_String**)q must have been */
1175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* initialized to NULL                            */
1176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( *(FT_String**)q != NULL )
1177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
1178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_TRACE0(( "ps_parser_load_field: overwriting field %s\n",
1179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        field->ident ));
1180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_FREE( *(FT_String**)q );
1181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            *(FT_String**)q = NULL;
1182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( FT_ALLOC( string, len + 1 ) )
1185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Exit;
1186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_MEM_COPY( string, cur, len );
1188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          string[len] = 0;
1189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *(FT_String**)q = string;
1191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
1193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case T1_FIELD_TYPE_BBOX:
1195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Fixed  temp[4];
1197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_BBox*  bbox = (FT_BBox*)q;
1198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Int    result;
1199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          result = ps_tofixedarray( &cur, limit, 4, temp, 0 );
1202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( result < 0 )
1204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
1205295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            FT_ERROR(( "ps_parser_load_field:"
1206295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                       " expected four integers in bounding box\n" ));
1207a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang            error = FT_THROW( Invalid_File_Format );
1208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Exit;
1209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          bbox->xMin = FT_RoundFix( temp[0] );
1212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          bbox->yMin = FT_RoundFix( temp[1] );
1213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          bbox->xMax = FT_RoundFix( temp[2] );
1214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          bbox->yMax = FT_RoundFix( temp[3] );
1215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
1217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1218a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      case T1_FIELD_TYPE_MM_BBOX:
1219a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang        {
1220a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang          FT_Memory  memory = parser->memory;
1221a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang          FT_Fixed*  temp;
1222a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang          FT_Int     result;
1223a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang          FT_UInt    i;
1224a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
1225a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
1226a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang          if ( FT_NEW_ARRAY( temp, max_objects * 4 ) )
1227a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang            goto Exit;
1228a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
1229a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang          for ( i = 0; i < 4; i++ )
1230a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang          {
1231a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang            result = ps_tofixedarray( &cur, limit, max_objects,
1232a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang                                      temp + i * max_objects, 0 );
1233a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang            if ( result < 0 )
1234a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang            {
1235a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang              FT_ERROR(( "ps_parser_load_field:"
1236a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang                         " expected %d integers in the %s subarray\n"
1237a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang                         "                     "
1238a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang                         " of /FontBBox in the /Blend dictionary\n",
1239a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang                         max_objects,
1240a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang                         i == 0 ? "first"
1241a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang                                : ( i == 1 ? "second"
1242a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang                                           : ( i == 2 ? "third"
1243a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang                                                      : "fourth" ) ) ));
1244a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang              error = FT_THROW( Invalid_File_Format );
1245a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang              goto Exit;
1246a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang            }
1247a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
1248a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang            skip_spaces( &cur, limit );
1249a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang          }
1250a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
1251a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang          for ( i = 0; i < max_objects; i++ )
1252a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang          {
1253a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang            FT_BBox*  bbox = (FT_BBox*)objects[i];
1254a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
1255a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
1256a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang            bbox->xMin = FT_RoundFix( temp[i                  ] );
1257a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang            bbox->yMin = FT_RoundFix( temp[i +     max_objects] );
1258a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang            bbox->xMax = FT_RoundFix( temp[i + 2 * max_objects] );
1259a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang            bbox->yMax = FT_RoundFix( temp[i + 3 * max_objects] );
1260a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang          }
1261a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
1262a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang          FT_FREE( temp );
1263a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang        }
1264a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang        break;
1265a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang
1266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      default:
1267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* an error occurred */
1268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Fail;
1269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 0  /* obsolete -- keep for reference */
1273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( pflags )
1274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *pflags |= 1L << field->flag_bit;
1275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else
1276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( pflags );
1277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
1278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1279a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    error = FT_Err_Ok;
1280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
1285a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    error = FT_THROW( Invalid_File_Format );
1286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    goto Exit;
1287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define T1_MAX_TABLE_ELEMENTS  32
1291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
1294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_parser_load_field_table( PS_Parser       parser,
1295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              const T1_Field  field,
1296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              void**          objects,
1297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              FT_UInt         max_objects,
1298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              FT_ULong*       pflags )
1299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    T1_TokenRec  elements[T1_MAX_TABLE_ELEMENTS];
1301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    T1_Token     token;
1302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int       num_elements;
1303a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    FT_Error     error = FT_Err_Ok;
1304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*     old_cursor;
1305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*     old_limit;
1306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    T1_FieldRec  fieldrec = *(T1_Field)field;
1307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    fieldrec.type = T1_FIELD_TYPE_INTEGER;
1310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( field->type == T1_FIELD_TYPE_FIXED_ARRAY ||
1311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         field->type == T1_FIELD_TYPE_BBOX        )
1312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      fieldrec.type = T1_FIELD_TYPE_FIXED;
1313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ps_parser_to_token_array( parser, elements,
1315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              T1_MAX_TABLE_ELEMENTS, &num_elements );
1316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( num_elements < 0 )
1317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1318a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      error = FT_ERR( Ignore );
1319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( (FT_UInt)num_elements > field->array_max )
1322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      num_elements = field->array_max;
1323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    old_cursor = parser->cursor;
1325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    old_limit  = parser->limit;
1326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
13270a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /* we store the elements count if necessary;           */
13280a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /* we further assume that `count_offset' can't be zero */
13290a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( field->type != T1_FIELD_TYPE_BBOX && field->count_offset != 0 )
1330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *(FT_Byte*)( (FT_Byte*)objects[0] + field->count_offset ) =
1331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        (FT_Byte)num_elements;
1332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* we now load each element, adjusting the field.offset on each one */
1334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    token = elements;
1335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; num_elements > 0; num_elements--, token++ )
1336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      parser->cursor = token->start;
1338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      parser->limit  = token->limit;
1339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ps_parser_load_field( parser, &fieldrec, objects, max_objects, 0 );
1340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      fieldrec.offset += fieldrec.size;
1341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 0  /* obsolete -- keep for reference */
1344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( pflags )
1345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *pflags |= 1L << field->flag_bit;
1346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else
1347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( pflags );
1348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
1349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    parser->cursor = old_cursor;
1351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    parser->limit  = old_limit;
1352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Long )
1359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_parser_to_int( PS_Parser  parser )
1360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ps_parser_skip_spaces( parser );
1362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return PS_Conv_ToInt( &parser->cursor, parser->limit );
1363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* first character must be `<' if `delimiters' is non-zero */
1367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
1369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_parser_to_bytes( PS_Parser  parser,
1370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Byte*   bytes,
1371295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                      FT_Offset  max_bytes,
1372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Long*   pnum_bytes,
1373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Bool    delimiters )
1374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1375a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    FT_Error  error = FT_Err_Ok;
1376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  cur;
1377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ps_parser_skip_spaces( parser );
1380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cur = parser->cursor;
1381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( cur >= parser->limit )
1383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( delimiters )
1386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( *cur != '<' )
1388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_ERROR(( "ps_parser_to_bytes: Missing starting delimiter `<'\n" ));
1390a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang        error = FT_THROW( Invalid_File_Format );
1391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur++;
1395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *pnum_bytes = PS_Conv_ASCIIHexDecode( &cur,
1398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                          parser->limit,
1399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                          bytes,
1400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                          max_bytes );
1401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( delimiters )
1403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cur < parser->limit && *cur != '>' )
1405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_ERROR(( "ps_parser_to_bytes: Missing closing delimiter `>'\n" ));
1407a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang        error = FT_THROW( Invalid_File_Format );
1408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur++;
1412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    parser->cursor = cur;
1415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Fixed )
1422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_parser_to_fixed( PS_Parser  parser,
1423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Int     power_ten )
1424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ps_parser_skip_spaces( parser );
1426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return PS_Conv_ToFixed( &parser->cursor, parser->limit, power_ten );
1427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Int )
1431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_parser_to_coord_array( PS_Parser  parser,
1432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            FT_Int     max_coords,
1433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            FT_Short*  coords )
1434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ps_parser_skip_spaces( parser );
1436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ps_tocoordarray( &parser->cursor, parser->limit,
1437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            max_coords, coords );
1438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Int )
1442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_parser_to_fixed_array( PS_Parser  parser,
1443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            FT_Int     max_values,
1444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            FT_Fixed*  values,
1445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            FT_Int     power_ten )
1446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ps_parser_skip_spaces( parser );
1448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ps_tofixedarray( &parser->cursor, parser->limit,
1449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            max_values, values, power_ten );
1450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 0
1454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_String* )
1456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  T1_ToString( PS_Parser  parser )
1457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ps_tostring( &parser->cursor, parser->limit, parser->memory );
1459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Bool )
1463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  T1_ToBool( PS_Parser  parser )
1464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ps_tobool( &parser->cursor, parser->limit );
1466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* 0 */
1469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( void )
1472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_parser_init( PS_Parser  parser,
1473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Byte*   base,
1474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Byte*   limit,
1475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Memory  memory )
1476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1477a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    parser->error  = FT_Err_Ok;
1478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    parser->base   = base;
1479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    parser->limit  = limit;
1480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    parser->cursor = base;
1481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    parser->memory = memory;
1482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    parser->funcs  = ps_parser_funcs;
1483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( void )
1487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ps_parser_done( PS_Parser  parser )
1488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( parser );
1490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*****                                                               *****/
1496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*****                            T1 BUILDER                         *****/
1497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*****                                                               *****/
1498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
1504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    t1_builder_init                                                    */
1505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
1507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Initializes a given glyph builder.                                 */
1508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <InOut>                                                               */
1510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    builder :: A pointer to the glyph builder to initialize.           */
1511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
1513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    face    :: The current face object.                                */
1514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    size    :: The current size object.                                */
1516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    glyph   :: The current glyph object.                               */
1518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    hinting :: Whether hinting should be applied.                      */
1520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( void )
1522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  t1_builder_init( T1_Builder    builder,
1523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Face       face,
1524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Size       size,
1525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_GlyphSlot  glyph,
1526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Bool       hinting )
1527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    builder->parse_state = T1_Parse_Start;
1529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    builder->load_points = 1;
1530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    builder->face   = face;
1532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    builder->glyph  = glyph;
1533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    builder->memory = face->memory;
1534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( glyph )
1536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_GlyphLoader  loader = glyph->internal->loader;
1538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      builder->loader  = loader;
1541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      builder->base    = &loader->base.outline;
1542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      builder->current = &loader->current.outline;
1543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_GlyphLoader_Rewind( loader );
1544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      builder->hints_globals = size->internal;
1546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      builder->hints_funcs   = 0;
1547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( hinting )
1549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        builder->hints_funcs = glyph->internal->glyph_hints;
1550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    builder->pos_x = 0;
1553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    builder->pos_y = 0;
1554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    builder->left_bearing.x = 0;
1556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    builder->left_bearing.y = 0;
1557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    builder->advance.x      = 0;
1558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    builder->advance.y      = 0;
1559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    builder->funcs = t1_builder_funcs;
1561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
1567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    t1_builder_done                                                    */
1568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
1570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Finalizes a given glyph builder.  Its contents can still be used   */
1571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    after the call, but the function saves important information       */
1572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    within the corresponding glyph slot.                               */
1573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
1575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    builder :: A pointer to the glyph builder to finalize.             */
1576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( void )
1578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  t1_builder_done( T1_Builder  builder )
1579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GlyphSlot  glyph = builder->glyph;
1581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( glyph )
1584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      glyph->outline = *builder->base;
1585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* check that there is enough space for `count' more points */
1589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
1590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  t1_builder_check_points( T1_Builder  builder,
1591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           FT_Int      count )
1592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_GLYPHLOADER_CHECK_POINTS( builder->loader, count, 0 );
1594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* add a new point, do not check space */
1598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( void )
1599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  t1_builder_add_point( T1_Builder  builder,
1600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Pos      x,
1601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Pos      y,
1602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Byte     flag )
1603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Outline*  outline = builder->current;
1605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( builder->load_points )
1608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Vector*  point   = outline->points + outline->n_points;
1610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Byte*    control = (FT_Byte*)outline->tags + outline->n_points;
1611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1613295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      point->x = FIXED_TO_INT( x );
1614295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      point->y = FIXED_TO_INT( y );
1615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC );
1616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    outline->n_points++;
1618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* check space for a new on-curve point, then add it */
1622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
1623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  t1_builder_add_point1( T1_Builder  builder,
1624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Pos      x,
1625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Pos      y )
1626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error;
1628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = t1_builder_check_points( builder, 1 );
1631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !error )
1632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      t1_builder_add_point( builder, x, y, 1 );
1633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* check space for a new contour, then add it */
1639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
1640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  t1_builder_add_contour( T1_Builder  builder )
1641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Outline*  outline = builder->current;
1643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error     error;
1644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1646aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    /* this might happen in invalid fonts */
1647aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( !outline )
1648aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    {
1649aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      FT_ERROR(( "t1_builder_add_contour: no outline to add points to\n" ));
1650a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      return FT_THROW( Invalid_File_Format );
1651aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    }
1652aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
1653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !builder->load_points )
1654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      outline->n_contours++;
1656a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      return FT_Err_Ok;
1657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 );
1660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !error )
1661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( outline->n_contours > 0 )
1663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        outline->contours[outline->n_contours - 1] =
1664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          (short)( outline->n_points - 1 );
1665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      outline->n_contours++;
1667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* if a path was begun, add its first on-curve point */
1674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
1675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  t1_builder_start_point( T1_Builder  builder,
1676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Pos      x,
1677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Pos      y )
1678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1679a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang    FT_Error  error = FT_ERR( Invalid_File_Format );
1680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* test whether we are building a new contour */
1683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( builder->parse_state == T1_Parse_Have_Path )
1685a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang      error = FT_Err_Ok;
1686aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    else
1687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      builder->parse_state = T1_Parse_Have_Path;
1689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = t1_builder_add_contour( builder );
1690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !error )
1691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = t1_builder_add_point1( builder, x, y );
1692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* close the current contour */
1699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( void )
1700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  t1_builder_close_contour( T1_Builder  builder )
1701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Outline*  outline = builder->current;
17030a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_Int       first;
1704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !outline )
1707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
1708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
17090a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    first = outline->n_contours <= 1
17100a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            ? 0 : outline->contours[outline->n_contours - 2] + 1;
17110a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
17120a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /* We must not include the last point in the path if it */
17130a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /* is located on the first point.                       */
1714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( outline->n_points > 1 )
1715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Vector*  p1      = outline->points + first;
1717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Vector*  p2      = outline->points + outline->n_points - 1;
1718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Byte*    control = (FT_Byte*)outline->tags + outline->n_points - 1;
1719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* `delete' last point only if it coincides with the first */
1722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* point and it is not a control point (which can happen). */
1723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( p1->x == p2->x && p1->y == p2->y )
1724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( *control == FT_CURVE_TAG_ON )
1725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          outline->n_points--;
1726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( outline->n_contours > 0 )
17290a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    {
1730295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      /* Don't add contours only consisting of one point, i.e.,  */
1731295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      /* check whether the first and the last point is the same. */
17320a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      if ( first == outline->n_points - 1 )
17330a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      {
17340a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        outline->n_contours--;
17350a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        outline->n_points--;
17360a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      }
17370a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      else
17380a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        outline->contours[outline->n_contours - 1] =
17390a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          (short)( outline->n_points - 1 );
17400a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    }
1741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*****                                                               *****/
1747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*****                            OTHER                              *****/
1748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*****                                                               *****/
1749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( void )
1753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  t1_decrypt( FT_Byte*   buffer,
1754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              FT_Offset  length,
1755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              FT_UShort  seed )
1756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    PS_Conv_EexecDecode( &buffer,
1758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         buffer + length,
1759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         buffer,
1760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         length,
1761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         &seed );
1762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
1766