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/*                                                                         */
7727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  Copyright 1996-2004, 2007-2013 by                                      */
8049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  This file is part of the FreeType project, and may only be used,       */
11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  modified, and distributed under the terms of the FreeType project      */
12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  this file you indicate that you have read the license and              */
14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  understand and accept it fully.                                        */
15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
19049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <ft2build.h>
20049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "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
68727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      val = (FT_Short)( ( (FT_UShort)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
76727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      val = (FT_Long)( ( (FT_ULong)p[0] << 24 ) |
77727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                       ( (FT_ULong)p[1] << 16 ) |
78727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                       ( (FT_ULong)p[2] <<  8 ) |
79727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                         (FT_ULong)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;
108727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_TRACE4(( "!!!END OF DATA:!!!" ));
109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    goto Exit;
110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static const FT_Long power_tens[] =
114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    1L,
116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    10L,
117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    100L,
118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    1000L,
119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    10000L,
120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    100000L,
121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    1000000L,
122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    10000000L,
123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    100000000L,
124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    1000000000L
125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  };
126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* read a real */
129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Fixed
130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_parse_real( FT_Byte*  start,
131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Byte*  limit,
132295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                  FT_Long   power_ten,
133295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                  FT_Long*  scaling )
134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  p = start;
136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt   nib;
137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt   phase;
138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
139aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Long   result, number, exponent;
140727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Int    sign = 0, exponent_sign = 0, have_overflow = 0;
141295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_Long   exponent_add, integer_length, fraction_length;
142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( scaling )
145aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      *scaling = 0;
146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    result = 0;
148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    number   = 0;
150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    exponent = 0;
151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    exponent_add    = 0;
153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    integer_length  = 0;
154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    fraction_length = 0;
155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* First of all, read the integer part. */
157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    phase = 4;
158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for (;;)
160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* If we entered this iteration with phase == 4, we need to */
162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* read a new byte.  This also skips past the initial 0x1E. */
163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( phase )
164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p++;
166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Make sure we don't read past the end. */
168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( p >= limit )
169727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          goto Bad;
170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* Get the nibble. */
173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      nib   = ( p[0] >> phase ) & 0xF;
174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      phase = 4 - phase;
175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( nib == 0xE )
177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        sign = 1;
178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else if ( nib > 9 )
179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Increase exponent if we can't add the digit. */
183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( number >= 0xCCCCCCCL )
184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          exponent_add++;
185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Skip leading zeros. */
186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else if ( nib || number )
187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          integer_length++;
189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          number = number * 10 + nib;
190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Read fraction part, if any. */
195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( nib == 0xa )
196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for (;;)
197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* If we entered this iteration with phase == 4, we need */
199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* to read a new byte.                                   */
200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( phase )
201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          p++;
203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* Make sure we don't read past the end. */
205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( p >= limit )
206727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            goto Bad;
207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Get the nibble. */
210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        nib   = ( p[0] >> phase ) & 0xF;
211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        phase = 4 - phase;
212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( nib >= 10 )
213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Skip leading zeros if possible. */
216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( !nib && !number )
217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          exponent_add--;
218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Only add digit if we don't overflow. */
21977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        else if ( number < 0xCCCCCCCL && fraction_length < 9 )
220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          fraction_length++;
222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          number = number * 10 + nib;
223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Read exponent, if any. */
227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( nib == 12 )
228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      exponent_sign = 1;
230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      nib           = 11;
231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( nib == 11 )
234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for (;;)
236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* If we entered this iteration with phase == 4, */
238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* we need to read a new byte.                   */
239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( phase )
240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          p++;
242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* Make sure we don't read past the end. */
244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( p >= limit )
245727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            goto Bad;
246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Get the nibble. */
249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        nib   = ( p[0] >> phase ) & 0xF;
250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        phase = 4 - phase;
251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( nib >= 10 )
252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Arbitrarily limit exponent. */
255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( exponent > 1000 )
256727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          have_overflow = 1;
257727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        else
258727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          exponent = exponent * 10 + nib;
259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( exponent_sign )
262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        exponent = -exponent;
263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
265727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( !number )
266727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      goto Exit;
267727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
268727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( have_overflow )
269727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
270727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( exponent_sign )
271727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        goto Underflow;
272727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      else
273727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        goto Overflow;
274727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
275727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* We don't check `power_ten' and `exponent_add'. */
277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    exponent += power_ten + exponent_add;
278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( scaling )
280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* Only use `fraction_length'. */
282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      fraction_length += integer_length;
283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      exponent        += integer_length;
284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( fraction_length <= 5 )
286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( number > 0x7FFFL )
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          result   = FT_DivFix( number, 10 );
290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *scaling = exponent - fraction_length + 1;
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( exponent > 0 )
295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
296295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            FT_Long  new_fraction_length, shift;
297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* Make `scaling' as small as possible. */
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            new_fraction_length = FT_MIN( exponent, 5 );
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            shift               = new_fraction_length - fraction_length;
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
303727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            if ( shift > 0 )
304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
305727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              exponent -= new_fraction_length;
306727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              number   *= power_tens[shift];
307727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              if ( number > 0x7FFFL )
308727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              {
309727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                number   /= 10;
310727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                exponent += 1;
311727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              }
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
313727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            else
314727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              exponent -= fraction_length;
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          else
317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            exponent -= fraction_length;
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
319727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          result   = (FT_Long)( (FT_ULong)number << 16 );
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *scaling = exponent;
321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL )
326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          result   = FT_DivFix( number, power_tens[fraction_length - 4] );
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *scaling = exponent - 4;
329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          result   = FT_DivFix( number, power_tens[fraction_length - 5] );
333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *scaling = exponent - 5;
334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      integer_length  += exponent;
340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      fraction_length -= exponent;
341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
342727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( integer_length > 5 )
343727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        goto Overflow;
344727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( integer_length < -5 )
345727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        goto Underflow;
346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
34777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      /* Remove non-significant digits. */
348aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( integer_length < 0 )
349aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      {
35077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        number          /= power_tens[-integer_length];
35177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        fraction_length += integer_length;
35277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      }
35377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
354aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      /* this can only happen if exponent was non-zero */
355aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( fraction_length == 10 )
356aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      {
357aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        number          /= 10;
358aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        fraction_length -= 1;
359aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      }
360aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* Convert into 16.16 format. */
362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( fraction_length > 0 )
363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( ( number / power_tens[fraction_length] ) > 0x7FFFL )
365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = FT_DivFix( number, power_tens[fraction_length] );
368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        number *= power_tens[-fraction_length];
372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( number > 0x7FFFL )
374727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          goto Overflow;
375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
376727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        result = (FT_Long)( (FT_ULong)number << 16 );
377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
380727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  Exit:
381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( sign )
382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      result = -result;
383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
385727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
386727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  Overflow:
387727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    result = 0x7FFFFFFFL;
388727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_TRACE4(( "!!!OVERFLOW:!!!" ));
389727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    goto Exit;
390727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
391727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  Underflow:
392727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    result = 0;
393727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_TRACE4(( "!!!UNDERFLOW:!!!" ));
394727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    goto Exit;
395727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
396727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  Bad:
397727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    result = 0;
398727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_TRACE4(( "!!!END OF DATA:!!!" ));
399727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    goto Exit;
400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* read a number, either integer or real */
404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Long
405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_parse_num( FT_Byte**  d )
406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return **d == 30 ? ( cff_parse_real( d[0], d[1], 0, NULL ) >> 16 )
408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     :   cff_parse_integer( d[0], d[1] );
409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* read a floating point number, either integer or real */
413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Fixed
414727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  do_fixed( FT_Byte**  d,
415727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_Long    scaling )
416727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  {
417727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( **d == 30 )
418727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return cff_parse_real( d[0], d[1], scaling, NULL );
419727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    else
420727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
421727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_Long  val = cff_parse_integer( d[0], d[1] );
422727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
423727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
424727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( scaling )
425727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        val *= power_tens[scaling];
426727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
427727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( val > 0x7FFF )
428727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      {
429727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        val = 0x7FFFFFFFL;
430727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        goto Overflow;
431727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      }
432727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      else if ( val < -0x7FFF )
433727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      {
434727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        val = -0x7FFFFFFFL;
435727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        goto Overflow;
436727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      }
437727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
438727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return (FT_Long)( (FT_ULong)val << 16 );
439727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
440727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    Overflow:
441727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_TRACE4(( "!!!OVERFLOW:!!!" ));
442727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return val;
443727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
444727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  }
445727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
446727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
447727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /* read a floating point number, either integer or real */
448727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  static FT_Fixed
449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_parse_fixed( FT_Byte**  d )
450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
451727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return do_fixed( d, 0 );
452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* read a floating point number, either integer or real, */
456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* but return `10^scaling' times the number read in      */
457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Fixed
458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_parse_fixed_scaled( FT_Byte**  d,
459295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                          FT_Long    scaling )
460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
461727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return do_fixed( d, scaling );
462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* read a floating point number, either integer or real,     */
466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* and return it as precise as possible -- `scaling' returns */
467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* the scaling factor (as a power of 10)                     */
468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Fixed
469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_parse_fixed_dynamic( FT_Byte**  d,
470295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                           FT_Long*   scaling )
471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( scaling );
473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( **d == 30 )
475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return cff_parse_real( d[0], d[1], 0, scaling );
476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Long  number;
479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int   integer_length;
480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      number = cff_parse_integer( d[0], d[1] );
483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( number > 0x7FFFL )
485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( integer_length = 5; integer_length < 10; integer_length++ )
487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( number < power_tens[integer_length] )
488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            break;
489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL )
491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *scaling = integer_length - 4;
493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          return FT_DivFix( number, power_tens[integer_length - 4] );
494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *scaling = integer_length - 5;
498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          return FT_DivFix( number, power_tens[integer_length - 5] );
499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *scaling = 0;
504727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        return (FT_Long)( (FT_ULong)number << 16 );
505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_parse_font_matrix( CFF_Parser  parser )
512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    CFF_FontRecDict  dict   = (CFF_FontRecDict)parser->object;
514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Matrix*       matrix = &dict->font_matrix;
515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector*       offset = &dict->font_offset;
516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong*        upm    = &dict->units_per_em;
517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte**        data   = parser->stack;
518727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Error         error  = FT_ERR( Stack_Underflow );
519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( parser->top >= parser->stack + 6 )
522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
523295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_Long  scaling;
524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
526727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_Err_Ok;
527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
528bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      dict->has_font_matrix = TRUE;
529bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* We expect a well-formed font matrix, this is, the matrix elements */
531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* `xx' and `yy' are of approximately the same magnitude.  To avoid  */
532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* loss of precision, we use the magnitude of element `xx' to scale  */
533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* all other elements.  The scaling factor is then contained in the  */
534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* `units_per_em' value.                                             */
535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      matrix->xx = cff_parse_fixed_dynamic( data++, &scaling );
537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      scaling = -scaling;
539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( scaling < 0 || scaling > 9 )
541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Return default matrix in case of unlikely values. */
543aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
544aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner        FT_TRACE1(( "cff_parse_font_matrix:"
545aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                    " strange scaling value for xx element (%d),\n"
546aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                    "                      "
547aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                    " using default matrix\n", scaling ));
548aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        matrix->xx = 0x10000L;
550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        matrix->yx = 0;
551aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner        matrix->xy = 0;
552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        matrix->yy = 0x10000L;
553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        offset->x  = 0;
554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        offset->y  = 0;
555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *upm       = 1;
556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      matrix->yx = cff_parse_fixed_scaled( data++, scaling );
561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      matrix->xy = cff_parse_fixed_scaled( data++, scaling );
562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      matrix->yy = cff_parse_fixed_scaled( data++, scaling );
563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      offset->x  = cff_parse_fixed_scaled( data++, scaling );
564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      offset->y  = cff_parse_fixed_scaled( data,   scaling );
565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *upm = power_tens[scaling];
567aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
568bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      FT_TRACE4(( " [%f %f %f %f %f %f]\n",
569aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                  (double)matrix->xx / *upm / 65536,
570aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                  (double)matrix->xy / *upm / 65536,
571aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                  (double)matrix->yx / *upm / 65536,
572bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                  (double)matrix->yy / *upm / 65536,
573bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                  (double)offset->x  / *upm / 65536,
574bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                  (double)offset->y  / *upm / 65536 ));
575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_parse_font_bbox( CFF_Parser  parser )
584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_BBox*         bbox = &dict->font_bbox;
587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte**        data = parser->stack;
588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error         error;
589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
591727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    error = FT_ERR( Stack_Underflow );
592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( parser->top >= parser->stack + 4 )
594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bbox->xMin = FT_RoundFix( cff_parse_fixed( data++ ) );
596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) );
597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) );
598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bbox->yMax = FT_RoundFix( cff_parse_fixed( data   ) );
599727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_Err_Ok;
600aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
601bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      FT_TRACE4(( " [%d %d %d %d]\n",
602aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                  bbox->xMin / 65536,
603aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                  bbox->yMin / 65536,
604aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                  bbox->xMax / 65536,
605aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                  bbox->yMax / 65536 ));
606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_parse_private_dict( CFF_Parser  parser )
614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte**        data = parser->stack;
617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error         error;
618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
620727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    error = FT_ERR( Stack_Underflow );
621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( parser->top >= parser->stack + 2 )
623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      dict->private_size   = cff_parse_num( data++ );
625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      dict->private_offset = cff_parse_num( data   );
626bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      FT_TRACE4(( " %lu %lu\n",
627bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                  dict->private_size, dict->private_offset ));
628bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
629727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_Err_Ok;
630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_parse_cid_ros( CFF_Parser  parser )
638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte**        data = parser->stack;
641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error         error;
642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
644727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    error = FT_ERR( Stack_Underflow );
645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( parser->top >= parser->stack + 3 )
647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
648bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      dict->cid_registry = (FT_UInt)cff_parse_num( data++ );
649bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      dict->cid_ordering = (FT_UInt)cff_parse_num( data++ );
650295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      if ( **data == 30 )
651295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" ));
652295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      dict->cid_supplement = cff_parse_num( data );
653295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      if ( dict->cid_supplement < 0 )
654295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n",
655295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                   dict->cid_supplement ));
656727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_Err_Ok;
657aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
658bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      FT_TRACE4(( " %d %d %d\n",
659aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                  dict->cid_registry,
660aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                  dict->cid_ordering,
661aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                  dict->cid_supplement ));
662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
668bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_NUM( code, name, id )             \
669bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          CFF_FIELD( code, name, id, cff_kind_num )
670bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_FIXED( code, name, id )             \
671bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          CFF_FIELD( code, name, id, cff_kind_fixed )
672bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_FIXED_1000( code, name, id )                 \
673bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          CFF_FIELD( code, name, id, cff_kind_fixed_thousand )
674bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_STRING( code, name, id )             \
675bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          CFF_FIELD( code, name, id, cff_kind_string )
676bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_BOOL( code, name, id )             \
677bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          CFF_FIELD( code, name, id, cff_kind_bool )
678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
679295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#define CFFCODE_TOPDICT  0x1000
680295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#define CFFCODE_PRIVATE  0x2000
681295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
682bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
683295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifndef FT_CONFIG_OPTION_PIC
684295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  CFF_FIELD
687bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#undef  CFF_FIELD_DELTA
688bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
689bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
690bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#ifndef FT_DEBUG_LEVEL_TRACE
691bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
692bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
693bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_CALLBACK( code, name, id ) \
694bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          {                                  \
695bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            cff_kind_callback,               \
696bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            code | CFFCODE,                  \
697bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            0, 0,                            \
698bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            cff_parse_ ## name,              \
699bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            0, 0                             \
700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          },
701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
702bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD( code, name, id, kind ) \
703bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          {                               \
704bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            kind,                         \
705bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            code | CFFCODE,               \
706bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            FT_FIELD_OFFSET( name ),      \
707bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            FT_FIELD_SIZE( name ),        \
708bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            0, 0, 0                       \
709bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          },
710bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
711bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_DELTA( code, name, max, id ) \
712bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          {                                    \
713bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            cff_kind_delta,                    \
714bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            code | CFFCODE,                    \
715bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            FT_FIELD_OFFSET( name ),           \
716bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            FT_FIELD_SIZE_DELTA( name ),       \
717bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            0,                                 \
718bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            max,                               \
719bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            FT_FIELD_OFFSET( num_ ## name )    \
720bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          },
721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static const CFF_Field_Handler  cff_field_handlers[] =
723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "cfftoken.h"
726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    { 0, 0, 0, 0, 0, 0, 0 }
728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  };
729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
731bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#else /* FT_DEBUG_LEVEL_TRACE */
732bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
733bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
734bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
735bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_CALLBACK( code, name, id ) \
736bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          {                                  \
737bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            cff_kind_callback,               \
738bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            code | CFFCODE,                  \
739bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            0, 0,                            \
740bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            cff_parse_ ## name,              \
741bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            0, 0,                            \
742bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            id                               \
743bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          },
744bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
745bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD( code, name, id, kind ) \
746bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          {                               \
747bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            kind,                         \
748bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            code | CFFCODE,               \
749bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            FT_FIELD_OFFSET( name ),      \
750bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            FT_FIELD_SIZE( name ),        \
751bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            0, 0, 0,                      \
752bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            id                            \
753bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          },
754bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
755bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_DELTA( code, name, max, id ) \
756bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          {                                    \
757bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            cff_kind_delta,                    \
758bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            code | CFFCODE,                    \
759bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            FT_FIELD_OFFSET( name ),           \
760bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            FT_FIELD_SIZE_DELTA( name ),       \
761bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            0,                                 \
762bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            max,                               \
763bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            FT_FIELD_OFFSET( num_ ## name ),   \
764bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            id                                 \
765bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          },
766bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
767bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  static const CFF_Field_Handler  cff_field_handlers[] =
768bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  {
769bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
770bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#include "cfftoken.h"
771bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
772bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    { 0, 0, 0, 0, 0, 0, 0, 0 }
773bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  };
774bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
775bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
776bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#endif /* FT_DEBUG_LEVEL_TRACE */
777bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
778bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
779295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#else /* FT_CONFIG_OPTION_PIC */
780295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
781bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
782bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  void
783bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  FT_Destroy_Class_cff_field_handlers( FT_Library          library,
784bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                                       CFF_Field_Handler*  clazz )
785295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  {
786bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_Memory  memory = library->memory;
787bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
788bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
789295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    if ( clazz )
790295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_FREE( clazz );
791295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  }
792295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
793bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
794bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  FT_Error
795bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly  FT_Create_Class_cff_field_handlers( FT_Library           library,
796bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                                      CFF_Field_Handler**  output_class )
797295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  {
798727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    CFF_Field_Handler*  clazz  = NULL;
799bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_Error            error;
800bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_Memory           memory = library->memory;
801bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
802bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    int  i = 0;
803bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
804295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
805295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#undef CFF_FIELD
806bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD( code, name, id, kind ) i++;
807295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#undef CFF_FIELD_DELTA
808bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_DELTA( code, name, max, id ) i++;
809295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#undef CFF_FIELD_CALLBACK
810bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_CALLBACK( code, name, id ) i++;
811295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
812295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#include "cfftoken.h"
813295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
814bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    i++; /* { 0, 0, 0, 0, 0, 0, 0 } */
815bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
816bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    if ( FT_ALLOC( clazz, sizeof ( CFF_Field_Handler ) * i ) )
817295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      return error;
818295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
819bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    i = 0;
820bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
821bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
822bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#ifndef FT_DEBUG_LEVEL_TRACE
823bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
824bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
825295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#undef CFF_FIELD_CALLBACK
826bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_CALLBACK( code_, name_, id_ )        \
827bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].kind         = cff_kind_callback;   \
828bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].code         = code_ | CFFCODE;     \
829bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].offset       = 0;                   \
830bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].size         = 0;                   \
831bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].reader       = cff_parse_ ## name_; \
832bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].array_max    = 0;                   \
833bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].count_offset = 0;                   \
834bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          i++;
835bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
836bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#undef  CFF_FIELD
837bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD( code_, name_, id_, kind_ )               \
838bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].kind         = kind_;                    \
839bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].code         = code_ | CFFCODE;          \
840bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].offset       = FT_FIELD_OFFSET( name_ ); \
841bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].size         = FT_FIELD_SIZE( name_ );   \
842bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].reader       = 0;                        \
843bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].array_max    = 0;                        \
844bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].count_offset = 0;                        \
845bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          i++;                                              \
846bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
847bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#undef  CFF_FIELD_DELTA
848bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_DELTA( code_, name_, max_, id_ )                  \
849bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].kind         = cff_kind_delta;                   \
850bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].code         = code_ | CFFCODE;                  \
851bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].offset       = FT_FIELD_OFFSET( name_ );         \
852bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].size         = FT_FIELD_SIZE_DELTA( name_ );     \
853bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].reader       = 0;                                \
854bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].array_max    = max_;                             \
855bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \
856bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          i++;
857295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
858bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#include "cfftoken.h"
859bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
860bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].kind         = 0;
861bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].code         = 0;
862bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].offset       = 0;
863bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].size         = 0;
864bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].reader       = 0;
865bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].array_max    = 0;
866bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].count_offset = 0;
867bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
868bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
869bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#else /* FT_DEBUG_LEVEL_TRACE */
870bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
871bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
872bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#undef CFF_FIELD_CALLBACK
873bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_CALLBACK( code_, name_, id_ )        \
874bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].kind         = cff_kind_callback;   \
875bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].code         = code_ | CFFCODE;     \
876bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].offset       = 0;                   \
877bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].size         = 0;                   \
878bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].reader       = cff_parse_ ## name_; \
879bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].array_max    = 0;                   \
880bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].count_offset = 0;                   \
881bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].id           = id_;                 \
882bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          i++;
883295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
884295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#undef  CFF_FIELD
885bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD( code_, name_, id_, kind_ )               \
886bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].kind         = kind_;                    \
887bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].code         = code_ | CFFCODE;          \
888bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].offset       = FT_FIELD_OFFSET( name_ ); \
889bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].size         = FT_FIELD_SIZE( name_ );   \
890bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].reader       = 0;                        \
891bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].array_max    = 0;                        \
892bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].count_offset = 0;                        \
893bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].id           = id_;                      \
894bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          i++;                                              \
895295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
896295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#undef  CFF_FIELD_DELTA
897bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#define CFF_FIELD_DELTA( code_, name_, max_, id_ )                  \
898bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].kind         = cff_kind_delta;                   \
899bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].code         = code_ | CFFCODE;                  \
900bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].offset       = FT_FIELD_OFFSET( name_ );         \
901bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].size         = FT_FIELD_SIZE_DELTA( name_ );     \
902bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].reader       = 0;                                \
903bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].array_max    = max_;                             \
904bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \
905bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          clazz[i].id           = id_;                              \
906bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          i++;
907295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
908295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#include "cfftoken.h"
909295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
910bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].kind         = 0;
911bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].code         = 0;
912bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].offset       = 0;
913bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].size         = 0;
914bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].reader       = 0;
915bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].array_max    = 0;
916295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    clazz[i].count_offset = 0;
917bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    clazz[i].id           = 0;
918bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
919bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
920bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#endif /* FT_DEBUG_LEVEL_TRACE */
921bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
922295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
923295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    *output_class = clazz;
924bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
925727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return FT_Err_Ok;
926295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  }
927295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
928295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
929295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif /* FT_CONFIG_OPTION_PIC */
930295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
931295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_parser_run( CFF_Parser  parser,
934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Byte*    start,
935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Byte*    limit )
936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
937295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_Byte*    p       = start;
938727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Error    error   = FT_Err_Ok;
939295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_Library  library = parser->library;
940bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_UNUSED( library );
941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    parser->top    = parser->stack;
944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    parser->start  = start;
945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    parser->limit  = limit;
946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    parser->cursor = start;
947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( p < limit )
949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt  v = *p;
951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( v >= 27 && v != 31 )
954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* it's a number; we will push its position on the stack */
956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )
957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Stack_Overflow;
958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *parser->top ++ = p;
960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* now, skip it */
962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( v == 30 )
963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* skip real number */
965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          p++;
966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          for (;;)
967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
968295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            /* An unterminated floating point number at the */
969295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            /* end of a dictionary is invalid but harmless. */
970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( p >= limit )
971295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner              goto Exit;
972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            v = p[0] >> 4;
973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( v == 15 )
974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              break;
975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            v = p[0] & 0xF;
976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( v == 15 )
977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              break;
978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            p++;
979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else if ( v == 28 )
982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          p += 2;
983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else if ( v == 29 )
984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          p += 4;
985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else if ( v > 246 )
986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          p += 1;
987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* This is not a number, hence it's an operator.  Compute its code */
991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* and look for it in our current list.                            */
992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_UInt                   code;
994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_UInt                   num_args = (FT_UInt)
995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                             ( parser->top - parser->stack );
996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        const CFF_Field_Handler*  field;
997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *parser->top = p;
1000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        code = v;
1001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( v == 12 )
1002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* two byte operator */
1004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          p++;
1005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( p >= limit )
1006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Syntax_Error;
1007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          code = 0x100 | p[0];
1009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        code = code | parser->object_code;
1011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1012727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        for ( field = CFF_FIELD_HANDLERS_GET; field->kind; field++ )
1013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( field->code == (FT_Int)code )
1015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
1016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* we found our field's handler; read it */
1017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Long   val;
1018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Byte*  q = (FT_Byte*)parser->object + field->offset;
1019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1021bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#ifdef FT_DEBUG_LEVEL_TRACE
1022bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            FT_TRACE4(( "  %s", field->id ));
1023bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#endif
1024bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
1025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* check that we have enough arguments -- except for */
1026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* delta encoded arrays, which can be empty          */
1027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( field->kind != cff_kind_delta && num_args < 1 )
1028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              goto Stack_Underflow;
1029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            switch ( field->kind )
1031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
1032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            case cff_kind_bool:
1033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            case cff_kind_string:
1034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            case cff_kind_num:
1035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              val = cff_parse_num( parser->stack );
1036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              goto Store_Number;
1037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            case cff_kind_fixed:
1039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              val = cff_parse_fixed( parser->stack );
1040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              goto Store_Number;
1041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            case cff_kind_fixed_thousand:
1043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              val = cff_parse_fixed_scaled( parser->stack, 3 );
1044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            Store_Number:
1046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              switch ( field->size )
1047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              {
1048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              case (8 / FT_CHAR_BIT):
1049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                *(FT_Byte*)q = (FT_Byte)val;
1050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                break;
1051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              case (16 / FT_CHAR_BIT):
1053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                *(FT_Short*)q = (FT_Short)val;
1054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                break;
1055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              case (32 / FT_CHAR_BIT):
1057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                *(FT_Int32*)q = (FT_Int)val;
1058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                break;
1059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              default:  /* for 64-bit systems */
1061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                *(FT_Long*)q = val;
1062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              }
1063bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
1064bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#ifdef FT_DEBUG_LEVEL_TRACE
1065bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly              switch ( field->kind )
1066bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly              {
1067bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly              case cff_kind_bool:
1068bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                FT_TRACE4(( " %s\n", val ? "true" : "false" ));
1069bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                break;
1070bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
1071bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly              case cff_kind_string:
1072bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                FT_TRACE4(( " %ld (SID)\n", val ));
1073bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                break;
1074bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
1075bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly              case cff_kind_num:
1076bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                FT_TRACE4(( " %ld\n", val ));
1077bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                break;
1078bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
1079bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly              case cff_kind_fixed:
1080bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                FT_TRACE4(( " %f\n", (double)val / 65536 ));
1081bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                break;
1082bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
1083bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly              case cff_kind_fixed_thousand:
1084bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                FT_TRACE4(( " %f\n", (double)val / 65536 / 1000 ));
1085bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
1086bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly              default:
1087bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                ; /* never reached */
1088bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly              }
1089bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#endif
1090bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
1091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              break;
1092049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            case cff_kind_delta:
1094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              {
1095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Byte*   qcount = (FT_Byte*)parser->object +
1096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      field->count_offset;
1097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1098049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Byte**  data = parser->stack;
1099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                if ( num_args > field->array_max )
1102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  num_args = field->array_max;
1103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1104bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                FT_TRACE4(( " [" ));
1105bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
1106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                /* store count */
1107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                *qcount = (FT_Byte)num_args;
1108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                val = 0;
1110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                while ( num_args > 0 )
1111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                {
1112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  val += cff_parse_num( data++ );
1113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  switch ( field->size )
1114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  {
1115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  case (8 / FT_CHAR_BIT):
1116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    *(FT_Byte*)q = (FT_Byte)val;
1117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    break;
1118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  case (16 / FT_CHAR_BIT):
1120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    *(FT_Short*)q = (FT_Short)val;
1121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    break;
1122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  case (32 / FT_CHAR_BIT):
1124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    *(FT_Int32*)q = (FT_Int)val;
1125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    break;
1126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  default:  /* for 64-bit systems */
1128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    *(FT_Long*)q = val;
1129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  }
1130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1131bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                  FT_TRACE4(( " %ld", val ));
1132bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
1133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  q += field->size;
1134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  num_args--;
1135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                }
1136bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
1137bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                FT_TRACE4(( "]\n" ));
1138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              }
1139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              break;
1140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            default:  /* callback */
1142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              error = field->reader( parser );
1143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              if ( error )
1144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                goto Exit;
1145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
1146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Found;
1147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* this is an unknown operator, or it is unsupported; */
1151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* we will ignore it for now.                         */
1152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      Found:
1154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* clear stack */
1155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        parser->top = parser->stack;
1156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p++;
1158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Stack_Overflow:
1164727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    error = FT_THROW( Invalid_Argument );
1165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    goto Exit;
1166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Stack_Underflow:
1168727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    error = FT_THROW( Invalid_Argument );
1169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    goto Exit;
1170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Syntax_Error:
1172727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    error = FT_THROW( Invalid_Argument );
1173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    goto Exit;
1174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
1178