1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  cffparse.c                                                             */
4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*    CFF token stream parser (body)                                       */
6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
7aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner/*  Copyright 1996-2004, 2007-2011 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 "cffparse.h"
21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_STREAM_H
22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_DEBUG_H
23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "cfferrs.h"
25295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#include "cffpic.h"
26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
28049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
30049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* messages during execution.                                            */
33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_cffparse
36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( void )
39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_parser_init( CFF_Parser  parser,
40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_UInt     code,
41295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                   void*       object,
42295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                   FT_Library  library)
43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MEM_ZERO( parser, sizeof ( *parser ) );
45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    parser->top         = parser->stack;
47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    parser->object_code = code;
48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    parser->object      = object;
49295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    parser->library     = library;
50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* read an integer */
54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Long
55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_parse_integer( FT_Byte*  start,
56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Byte*  limit )
57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  p   = start;
59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int    v   = *p++;
60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long   val = 0;
61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( v == 28 )
64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( p + 2 > limit )
66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Bad;
67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      val = (FT_Short)( ( (FT_Int)p[0] << 8 ) | p[1] );
69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p  += 2;
70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( v == 29 )
72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( p + 4 > limit )
74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Bad;
75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      val = ( (FT_Long)p[0] << 24 ) |
77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            ( (FT_Long)p[1] << 16 ) |
78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            ( (FT_Long)p[2] <<  8 ) |
79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                       p[3];
80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p += 4;
81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( v < 247 )
83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      val = v - 139;
85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( v < 251 )
87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( p + 1 > limit )
89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Bad;
90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      val = ( v - 247 ) * 256 + p[0] + 108;
92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p++;
93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( p + 1 > limit )
97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Bad;
98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      val = -( v - 251 ) * 256 - p[0] - 108;
100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p++;
101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return val;
105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Bad:
107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    val = 0;
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    goto Exit;
109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static const FT_Long power_tens[] =
113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    1L,
115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    10L,
116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    100L,
117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    1000L,
118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    10000L,
119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    100000L,
120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    1000000L,
121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    10000000L,
122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    100000000L,
123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    1000000000L
124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  };
125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* read a real */
128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Fixed
129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_parse_real( FT_Byte*  start,
130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Byte*  limit,
131295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                  FT_Long   power_ten,
132295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                  FT_Long*  scaling )
133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  p = start;
135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt   nib;
136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt   phase;
137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
138aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Long   result, number, exponent;
139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int    sign = 0, exponent_sign = 0;
140295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_Long   exponent_add, integer_length, fraction_length;
141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( scaling )
144aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      *scaling = 0;
145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    result = 0;
147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    number   = 0;
149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    exponent = 0;
150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    exponent_add    = 0;
152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    integer_length  = 0;
153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    fraction_length = 0;
154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* First of all, read the integer part. */
156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    phase = 4;
157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for (;;)
159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* If we entered this iteration with phase == 4, we need to */
161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* read a new byte.  This also skips past the initial 0x1E. */
162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( phase )
163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p++;
165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Make sure we don't read past the end. */
167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( p >= limit )
168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* Get the nibble. */
172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      nib   = ( p[0] >> phase ) & 0xF;
173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      phase = 4 - phase;
174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( nib == 0xE )
176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        sign = 1;
177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else if ( nib > 9 )
178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Increase exponent if we can't add the digit. */
182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( number >= 0xCCCCCCCL )
183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          exponent_add++;
184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Skip leading zeros. */
185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else if ( nib || number )
186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          integer_length++;
188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          number = number * 10 + nib;
189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Read fraction part, if any. */
194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( nib == 0xa )
195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for (;;)
196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* If we entered this iteration with phase == 4, we need */
198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* to read a new byte.                                   */
199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( phase )
200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          p++;
202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* Make sure we don't read past the end. */
204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( p >= limit )
205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Exit;
206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Get the nibble. */
209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        nib   = ( p[0] >> phase ) & 0xF;
210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        phase = 4 - phase;
211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( nib >= 10 )
212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Skip leading zeros if possible. */
215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( !nib && !number )
216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          exponent_add--;
217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Only add digit if we don't overflow. */
21877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        else if ( number < 0xCCCCCCCL && fraction_length < 9 )
219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          fraction_length++;
221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          number = number * 10 + nib;
222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Read exponent, if any. */
226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( nib == 12 )
227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      exponent_sign = 1;
229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      nib           = 11;
230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( nib == 11 )
233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for (;;)
235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* If we entered this iteration with phase == 4, */
237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* we need to read a new byte.                   */
238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( phase )
239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          p++;
241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* Make sure we don't read past the end. */
243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( p >= limit )
244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Exit;
245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Get the nibble. */
248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        nib   = ( p[0] >> phase ) & 0xF;
249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        phase = 4 - phase;
250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( nib >= 10 )
251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        exponent = exponent * 10 + nib;
254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Arbitrarily limit exponent. */
256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( exponent > 1000 )
257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( exponent_sign )
261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        exponent = -exponent;
262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* We don't check `power_ten' and `exponent_add'. */
265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    exponent += power_ten + exponent_add;
266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( scaling )
268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* Only use `fraction_length'. */
270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      fraction_length += integer_length;
271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      exponent        += integer_length;
272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( fraction_length <= 5 )
274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( number > 0x7FFFL )
276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          result   = FT_DivFix( number, 10 );
278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *scaling = exponent - fraction_length + 1;
279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( exponent > 0 )
283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
284295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            FT_Long  new_fraction_length, shift;
285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* Make `scaling' as small as possible. */
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            new_fraction_length = FT_MIN( exponent, 5 );
289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            exponent           -= new_fraction_length;
290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            shift               = new_fraction_length - fraction_length;
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            number *= power_tens[shift];
293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( number > 0x7FFFL )
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              number   /= 10;
296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              exponent += 1;
297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          else
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            exponent -= fraction_length;
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          result   = number << 16;
303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *scaling = exponent;
304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL )
309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          result   = FT_DivFix( number, power_tens[fraction_length - 4] );
311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *scaling = exponent - 4;
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          result   = FT_DivFix( number, power_tens[fraction_length - 5] );
316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *scaling = exponent - 5;
317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      integer_length  += exponent;
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      fraction_length -= exponent;
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* Check for overflow and underflow. */
326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_ABS( integer_length ) > 5 )
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
32977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      /* Remove non-significant digits. */
330aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( integer_length < 0 )
331aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      {
33277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        number          /= power_tens[-integer_length];
33377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        fraction_length += integer_length;
33477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      }
33577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
336aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      /* this can only happen if exponent was non-zero */
337aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( fraction_length == 10 )
338aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      {
339aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        number          /= 10;
340aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        fraction_length -= 1;
341aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      }
342aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* Convert into 16.16 format. */
344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( fraction_length > 0 )
345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( ( number / power_tens[fraction_length] ) > 0x7FFFL )
347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = FT_DivFix( number, power_tens[fraction_length] );
350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        number *= power_tens[-fraction_length];
354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( number > 0x7FFFL )
356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = number << 16;
359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( sign )
363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      result = -result;
364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* read a number, either integer or real */
371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Long
372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_parse_num( FT_Byte**  d )
373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return **d == 30 ? ( cff_parse_real( d[0], d[1], 0, NULL ) >> 16 )
375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     :   cff_parse_integer( d[0], d[1] );
376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* read a floating point number, either integer or real */
380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Fixed
381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_parse_fixed( FT_Byte**  d )
382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return **d == 30 ? cff_parse_real( d[0], d[1], 0, NULL )
384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     : cff_parse_integer( d[0], d[1] ) << 16;
385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* read a floating point number, either integer or real, */
389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* but return `10^scaling' times the number read in      */
390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Fixed
391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_parse_fixed_scaled( FT_Byte**  d,
392295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                          FT_Long    scaling )
393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
39477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    return **d == 30 ? cff_parse_real( d[0], d[1], scaling, NULL )
39577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                     : ( cff_parse_integer( d[0], d[1] ) *
39677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                           power_tens[scaling] ) << 16;
397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* read a floating point number, either integer or real,     */
401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* and return it as precise as possible -- `scaling' returns */
402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* the scaling factor (as a power of 10)                     */
403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Fixed
404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_parse_fixed_dynamic( FT_Byte**  d,
405295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                           FT_Long*   scaling )
406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( scaling );
408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( **d == 30 )
410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return cff_parse_real( d[0], d[1], 0, scaling );
411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Long  number;
414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int   integer_length;
415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      number = cff_parse_integer( d[0], d[1] );
418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( number > 0x7FFFL )
420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( integer_length = 5; integer_length < 10; integer_length++ )
422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( number < power_tens[integer_length] )
423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            break;
424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL )
426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *scaling = integer_length - 4;
428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          return FT_DivFix( number, power_tens[integer_length - 4] );
429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *scaling = integer_length - 5;
433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          return FT_DivFix( number, power_tens[integer_length - 5] );
434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *scaling = 0;
439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return number << 16;
440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_parse_font_matrix( CFF_Parser  parser )
447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    CFF_FontRecDict  dict   = (CFF_FontRecDict)parser->object;
449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Matrix*       matrix = &dict->font_matrix;
450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector*       offset = &dict->font_offset;
451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong*        upm    = &dict->units_per_em;
452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte**        data   = parser->stack;
453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error         error  = CFF_Err_Stack_Underflow;
454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( parser->top >= parser->stack + 6 )
457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
458295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_Long  scaling;
459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = CFF_Err_Ok;
462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
463bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      dict->has_font_matrix = TRUE;
464bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* We expect a well-formed font matrix, this is, the matrix elements */
466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* `xx' and `yy' are of approximately the same magnitude.  To avoid  */
467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* loss of precision, we use the magnitude of element `xx' to scale  */
468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* all other elements.  The scaling factor is then contained in the  */
469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* `units_per_em' value.                                             */
470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      matrix->xx = cff_parse_fixed_dynamic( data++, &scaling );
472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      scaling = -scaling;
474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( scaling < 0 || scaling > 9 )
476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Return default matrix in case of unlikely values. */
478aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
479aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner        FT_TRACE1(( "cff_parse_font_matrix:"
480aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                    " strange scaling value for xx element (%d),\n"
481aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                    "                      "
482aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                    " using default matrix\n", scaling ));
483aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        matrix->xx = 0x10000L;
485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        matrix->yx = 0;
486aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner        matrix->xy = 0;
487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        matrix->yy = 0x10000L;
488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        offset->x  = 0;
489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        offset->y  = 0;
490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *upm       = 1;
491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      matrix->yx = cff_parse_fixed_scaled( data++, scaling );
496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      matrix->xy = cff_parse_fixed_scaled( data++, scaling );
497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      matrix->yy = cff_parse_fixed_scaled( data++, scaling );
498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      offset->x  = cff_parse_fixed_scaled( data++, scaling );
499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      offset->y  = cff_parse_fixed_scaled( data,   scaling );
500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *upm = power_tens[scaling];
502aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
503bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      FT_TRACE4(( " [%f %f %f %f %f %f]\n",
504aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                  (double)matrix->xx / *upm / 65536,
505aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                  (double)matrix->xy / *upm / 65536,
506aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                  (double)matrix->yx / *upm / 65536,
507bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                  (double)matrix->yy / *upm / 65536,
508bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                  (double)offset->x  / *upm / 65536,
509bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                  (double)offset->y  / *upm / 65536 ));
510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_parse_font_bbox( CFF_Parser  parser )
519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_BBox*         bbox = &dict->font_bbox;
522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte**        data = parser->stack;
523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error         error;
524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = CFF_Err_Stack_Underflow;
527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( parser->top >= parser->stack + 4 )
529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bbox->xMin = FT_RoundFix( cff_parse_fixed( data++ ) );
531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) );
532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) );
533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bbox->yMax = FT_RoundFix( cff_parse_fixed( data   ) );
534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = CFF_Err_Ok;
535aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
536bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      FT_TRACE4(( " [%d %d %d %d]\n",
537aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                  bbox->xMin / 65536,
538aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                  bbox->yMin / 65536,
539aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                  bbox->xMax / 65536,
540aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                  bbox->yMax / 65536 ));
541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_parse_private_dict( CFF_Parser  parser )
549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte**        data = parser->stack;
552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error         error;
553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = CFF_Err_Stack_Underflow;
556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( parser->top >= parser->stack + 2 )
558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      dict->private_size   = cff_parse_num( data++ );
560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      dict->private_offset = cff_parse_num( data   );
561bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      FT_TRACE4(( " %lu %lu\n",
562bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                  dict->private_size, dict->private_offset ));
563bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = CFF_Err_Ok;
565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_parse_cid_ros( CFF_Parser  parser )
573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte**        data = parser->stack;
576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error         error;
577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = CFF_Err_Stack_Underflow;
580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( parser->top >= parser->stack + 3 )
582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
583bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      dict->cid_registry = (FT_UInt)cff_parse_num( data++ );
584bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      dict->cid_ordering = (FT_UInt)cff_parse_num( data++ );
585295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      if ( **data == 30 )
586295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" ));
587295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      dict->cid_supplement = cff_parse_num( data );
588295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      if ( dict->cid_supplement < 0 )
589295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n",
590295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                   dict->cid_supplement ));
591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = CFF_Err_Ok;
592aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
593bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      FT_TRACE4(( " %d %d %d\n",
594aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                  dict->cid_registry,
595aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                  dict->cid_ordering,
596aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                  dict->cid_supplement ));
597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
603bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_NUM( code, name, id )             \
604bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          CFF_FIELD( code, name, id, cff_kind_num )
605bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_FIXED( code, name, id )             \
606bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          CFF_FIELD( code, name, id, cff_kind_fixed )
607bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_FIXED_1000( code, name, id )                 \
608bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          CFF_FIELD( code, name, id, cff_kind_fixed_thousand )
609bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_STRING( code, name, id )             \
610bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          CFF_FIELD( code, name, id, cff_kind_string )
611bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_BOOL( code, name, id )             \
612bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          CFF_FIELD( code, name, id, cff_kind_bool )
613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
614295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#define CFFCODE_TOPDICT  0x1000
615295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#define CFFCODE_PRIVATE  0x2000
616295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
617bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
618295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifndef FT_CONFIG_OPTION_PIC
619295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  CFF_FIELD
622bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#undef  CFF_FIELD_DELTA
623bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
624bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
625bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#ifndef FT_DEBUG_LEVEL_TRACE
626bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
627bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
628bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_CALLBACK( code, name, id ) \
629bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          {                                  \
630bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            cff_kind_callback,               \
631bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            code | CFFCODE,                  \
632bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            0, 0,                            \
633bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            cff_parse_ ## name,              \
634bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            0, 0                             \
635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          },
636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
637bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD( code, name, id, kind ) \
638bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          {                               \
639bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            kind,                         \
640bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            code | CFFCODE,               \
641bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            FT_FIELD_OFFSET( name ),      \
642bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            FT_FIELD_SIZE( name ),        \
643bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            0, 0, 0                       \
644bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          },
645bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
646bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_DELTA( code, name, max, id ) \
647bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          {                                    \
648bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            cff_kind_delta,                    \
649bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            code | CFFCODE,                    \
650bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            FT_FIELD_OFFSET( name ),           \
651bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            FT_FIELD_SIZE_DELTA( name ),       \
652bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            0,                                 \
653bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            max,                               \
654bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            FT_FIELD_OFFSET( num_ ## name )    \
655bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          },
656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static const CFF_Field_Handler  cff_field_handlers[] =
658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "cfftoken.h"
661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    { 0, 0, 0, 0, 0, 0, 0 }
663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  };
664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
666bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#else /* FT_DEBUG_LEVEL_TRACE */
667bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
668bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
669bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
670bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_CALLBACK( code, name, id ) \
671bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          {                                  \
672bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            cff_kind_callback,               \
673bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            code | CFFCODE,                  \
674bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            0, 0,                            \
675bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            cff_parse_ ## name,              \
676bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            0, 0,                            \
677bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            id                               \
678bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          },
679bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
680bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD( code, name, id, kind ) \
681bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          {                               \
682bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            kind,                         \
683bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            code | CFFCODE,               \
684bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            FT_FIELD_OFFSET( name ),      \
685bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            FT_FIELD_SIZE( name ),        \
686bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            0, 0, 0,                      \
687bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            id                            \
688bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          },
689bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
690bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_DELTA( code, name, max, id ) \
691bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          {                                    \
692bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            cff_kind_delta,                    \
693bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            code | CFFCODE,                    \
694bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            FT_FIELD_OFFSET( name ),           \
695bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            FT_FIELD_SIZE_DELTA( name ),       \
696bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            0,                                 \
697bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            max,                               \
698bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            FT_FIELD_OFFSET( num_ ## name ),   \
699bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            id                                 \
700bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          },
701bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
702bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  static const CFF_Field_Handler  cff_field_handlers[] =
703bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  {
704bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
705bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#include "cfftoken.h"
706bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
707bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    { 0, 0, 0, 0, 0, 0, 0, 0 }
708bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  };
709bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
710bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
711bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#endif /* FT_DEBUG_LEVEL_TRACE */
712bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
713bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
714295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#else /* FT_CONFIG_OPTION_PIC */
715295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
716bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
717bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  void
718bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  FT_Destroy_Class_cff_field_handlers( FT_Library          library,
719bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                                       CFF_Field_Handler*  clazz )
720295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  {
721bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_Memory  memory = library->memory;
722bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
723bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
724295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    if ( clazz )
725295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_FREE( clazz );
726295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  }
727295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
728bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
729bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  FT_Error
730bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  FT_Create_Class_cff_field_handlers( FT_Library           library,
731bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                                      CFF_Field_Handler**  output_class )
732295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  {
733295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    CFF_Field_Handler*  clazz;
734bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_Error            error;
735bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_Memory           memory = library->memory;
736bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
737bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    int  i = 0;
738bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
739295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
740295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#undef CFF_FIELD
741bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD( code, name, id, kind ) i++;
742295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#undef CFF_FIELD_DELTA
743bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_DELTA( code, name, max, id ) i++;
744295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#undef CFF_FIELD_CALLBACK
745bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_CALLBACK( code, name, id ) i++;
746295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
747295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#include "cfftoken.h"
748295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
749bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    i++; /* { 0, 0, 0, 0, 0, 0, 0 } */
750bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
751bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    if ( FT_ALLOC( clazz, sizeof ( CFF_Field_Handler ) * i ) )
752295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      return error;
753295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
754bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    i = 0;
755bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
756bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
757bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#ifndef FT_DEBUG_LEVEL_TRACE
758bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
759bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
760295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#undef CFF_FIELD_CALLBACK
761bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_CALLBACK( code_, name_, id_ )        \
762bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].kind         = cff_kind_callback;   \
763bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].code         = code_ | CFFCODE;     \
764bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].offset       = 0;                   \
765bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].size         = 0;                   \
766bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].reader       = cff_parse_ ## name_; \
767bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].array_max    = 0;                   \
768bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].count_offset = 0;                   \
769bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          i++;
770bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
771bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#undef  CFF_FIELD
772bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD( code_, name_, id_, kind_ )               \
773bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].kind         = kind_;                    \
774bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].code         = code_ | CFFCODE;          \
775bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].offset       = FT_FIELD_OFFSET( name_ ); \
776bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].size         = FT_FIELD_SIZE( name_ );   \
777bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].reader       = 0;                        \
778bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].array_max    = 0;                        \
779bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].count_offset = 0;                        \
780bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          i++;                                              \
781bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
782bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#undef  CFF_FIELD_DELTA
783bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_DELTA( code_, name_, max_, id_ )                  \
784bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].kind         = cff_kind_delta;                   \
785bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].code         = code_ | CFFCODE;                  \
786bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].offset       = FT_FIELD_OFFSET( name_ );         \
787bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].size         = FT_FIELD_SIZE_DELTA( name_ );     \
788bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].reader       = 0;                                \
789bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].array_max    = max_;                             \
790bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \
791bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          i++;
792295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
793bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#include "cfftoken.h"
794bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
795bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].kind         = 0;
796bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].code         = 0;
797bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].offset       = 0;
798bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].size         = 0;
799bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].reader       = 0;
800bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].array_max    = 0;
801bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].count_offset = 0;
802bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
803bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
804bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#else /* FT_DEBUG_LEVEL_TRACE */
805bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
806bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
807bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#undef CFF_FIELD_CALLBACK
808bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_CALLBACK( code_, name_, id_ )        \
809bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].kind         = cff_kind_callback;   \
810bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].code         = code_ | CFFCODE;     \
811bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].offset       = 0;                   \
812bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].size         = 0;                   \
813bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].reader       = cff_parse_ ## name_; \
814bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].array_max    = 0;                   \
815bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].count_offset = 0;                   \
816bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].id           = id_;                 \
817bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          i++;
818295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
819295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#undef  CFF_FIELD
820bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD( code_, name_, id_, kind_ )               \
821bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].kind         = kind_;                    \
822bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].code         = code_ | CFFCODE;          \
823bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].offset       = FT_FIELD_OFFSET( name_ ); \
824bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].size         = FT_FIELD_SIZE( name_ );   \
825bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].reader       = 0;                        \
826bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].array_max    = 0;                        \
827bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].count_offset = 0;                        \
828bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].id           = id_;                      \
829bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          i++;                                              \
830295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
831295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#undef  CFF_FIELD_DELTA
832bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_DELTA( code_, name_, max_, id_ )                  \
833bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].kind         = cff_kind_delta;                   \
834bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].code         = code_ | CFFCODE;                  \
835bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].offset       = FT_FIELD_OFFSET( name_ );         \
836bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].size         = FT_FIELD_SIZE_DELTA( name_ );     \
837bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].reader       = 0;                                \
838bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].array_max    = max_;                             \
839bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \
840bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].id           = id_;                              \
841bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          i++;
842295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
843295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#include "cfftoken.h"
844295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
845bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].kind         = 0;
846bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].code         = 0;
847bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].offset       = 0;
848bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].size         = 0;
849bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].reader       = 0;
850bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].array_max    = 0;
851295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    clazz[i].count_offset = 0;
852bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].id           = 0;
853bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
854bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
855bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#endif /* FT_DEBUG_LEVEL_TRACE */
856bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
857295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
858295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    *output_class = clazz;
859bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
860aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    return CFF_Err_Ok;
861295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  }
862295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
863295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
864295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif /* FT_CONFIG_OPTION_PIC */
865295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
866295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_parser_run( CFF_Parser  parser,
869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Byte*    start,
870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Byte*    limit )
871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
872295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_Byte*    p       = start;
873295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_Error    error   = CFF_Err_Ok;
874295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_Library  library = parser->library;
875bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_UNUSED( library );
876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    parser->top    = parser->stack;
879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    parser->start  = start;
880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    parser->limit  = limit;
881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    parser->cursor = start;
882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( p < limit )
884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt  v = *p;
886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( v >= 27 && v != 31 )
889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* it's a number; we will push its position on the stack */
891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )
892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Stack_Overflow;
893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *parser->top ++ = p;
895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* now, skip it */
897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( v == 30 )
898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* skip real number */
900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          p++;
901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          for (;;)
902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
903295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            /* An unterminated floating point number at the */
904295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            /* end of a dictionary is invalid but harmless. */
905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( p >= limit )
906295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner              goto Exit;
907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            v = p[0] >> 4;
908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( v == 15 )
909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              break;
910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            v = p[0] & 0xF;
911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( v == 15 )
912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              break;
913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            p++;
914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else if ( v == 28 )
917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          p += 2;
918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else if ( v == 29 )
919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          p += 4;
920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else if ( v > 246 )
921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          p += 1;
922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* This is not a number, hence it's an operator.  Compute its code */
926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* and look for it in our current list.                            */
927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_UInt                   code;
929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_UInt                   num_args = (FT_UInt)
930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                             ( parser->top - parser->stack );
931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        const CFF_Field_Handler*  field;
932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *parser->top = p;
935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        code = v;
936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( v == 12 )
937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* two byte operator */
939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          p++;
940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( p >= limit )
941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Syntax_Error;
942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          code = 0x100 | p[0];
944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        code = code | parser->object_code;
946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
947295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        for ( field = FT_CFF_FIELD_HANDLERS_GET; field->kind; field++ )
948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( field->code == (FT_Int)code )
950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* we found our field's handler; read it */
952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Long   val;
953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Byte*  q = (FT_Byte*)parser->object + field->offset;
954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
956bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#ifdef FT_DEBUG_LEVEL_TRACE
957bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            FT_TRACE4(( "  %s", field->id ));
958bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#endif
959bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* check that we have enough arguments -- except for */
961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* delta encoded arrays, which can be empty          */
962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( field->kind != cff_kind_delta && num_args < 1 )
963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              goto Stack_Underflow;
964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            switch ( field->kind )
966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            case cff_kind_bool:
968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            case cff_kind_string:
969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            case cff_kind_num:
970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              val = cff_parse_num( parser->stack );
971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              goto Store_Number;
972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            case cff_kind_fixed:
974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              val = cff_parse_fixed( parser->stack );
975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              goto Store_Number;
976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            case cff_kind_fixed_thousand:
978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              val = cff_parse_fixed_scaled( parser->stack, 3 );
979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            Store_Number:
981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              switch ( field->size )
982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              {
983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              case (8 / FT_CHAR_BIT):
984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                *(FT_Byte*)q = (FT_Byte)val;
985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                break;
986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              case (16 / FT_CHAR_BIT):
988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                *(FT_Short*)q = (FT_Short)val;
989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                break;
990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              case (32 / FT_CHAR_BIT):
992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                *(FT_Int32*)q = (FT_Int)val;
993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                break;
994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              default:  /* for 64-bit systems */
996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                *(FT_Long*)q = val;
997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              }
998bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
999bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#ifdef FT_DEBUG_LEVEL_TRACE
1000bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly              switch ( field->kind )
1001bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly              {
1002bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly              case cff_kind_bool:
1003bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                FT_TRACE4(( " %s\n", val ? "true" : "false" ));
1004bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                break;
1005bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
1006bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly              case cff_kind_string:
1007bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                FT_TRACE4(( " %ld (SID)\n", val ));
1008bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                break;
1009bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
1010bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly              case cff_kind_num:
1011bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                FT_TRACE4(( " %ld\n", val ));
1012bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                break;
1013bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
1014bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly              case cff_kind_fixed:
1015bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                FT_TRACE4(( " %f\n", (double)val / 65536 ));
1016bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                break;
1017bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
1018bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly              case cff_kind_fixed_thousand:
1019bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                FT_TRACE4(( " %f\n", (double)val / 65536 / 1000 ));
1020bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
1021bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly              default:
1022bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                ; /* never reached */
1023bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly              }
1024bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#endif
1025bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
1026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              break;
1027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            case cff_kind_delta:
1029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              {
1030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Byte*   qcount = (FT_Byte*)parser->object +
1031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      field->count_offset;
1032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Byte**  data = parser->stack;
1034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                if ( num_args > field->array_max )
1037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  num_args = field->array_max;
1038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1039bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                FT_TRACE4(( " [" ));
1040bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
1041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                /* store count */
1042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                *qcount = (FT_Byte)num_args;
1043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                val = 0;
1045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                while ( num_args > 0 )
1046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                {
1047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  val += cff_parse_num( data++ );
1048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  switch ( field->size )
1049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  {
1050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  case (8 / FT_CHAR_BIT):
1051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    *(FT_Byte*)q = (FT_Byte)val;
1052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    break;
1053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  case (16 / FT_CHAR_BIT):
1055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    *(FT_Short*)q = (FT_Short)val;
1056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    break;
1057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  case (32 / FT_CHAR_BIT):
1059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    *(FT_Int32*)q = (FT_Int)val;
1060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    break;
1061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  default:  /* for 64-bit systems */
1063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    *(FT_Long*)q = val;
1064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  }
1065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1066bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                  FT_TRACE4(( " %ld", val ));
1067bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
1068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  q += field->size;
1069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  num_args--;
1070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                }
1071bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
1072bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                FT_TRACE4(( "]\n" ));
1073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              }
1074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              break;
1075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            default:  /* callback */
1077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              error = field->reader( parser );
1078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              if ( error )
1079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                goto Exit;
1080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
1081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Found;
1082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1085049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* this is an unknown operator, or it is unsupported; */
1086049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* we will ignore it for now.                         */
1087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      Found:
1089049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* clear stack */
1090049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        parser->top = parser->stack;
1091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1092049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p++;
1093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1098049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Stack_Overflow:
1099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = CFF_Err_Invalid_Argument;
1100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    goto Exit;
1101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Stack_Underflow:
1103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = CFF_Err_Invalid_Argument;
1104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    goto Exit;
1105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Syntax_Error:
1107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = CFF_Err_Invalid_Argument;
1108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    goto Exit;
1109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
1113