cffparse.c revision 295ffce55e0198e7a9f7d46b33f5c2b4147bf821
1086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org/***************************************************************************/
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org/*                                                                         */
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org/*  cffparse.c                                                             */
4086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org/*                                                                         */
5086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org/*    CFF token stream parser (body)                                       */
6086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org/*                                                                         */
7086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org/*  Copyright 1996-2001, 2002, 2003, 2004, 2007, 2008, 2009 by             */
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org/*                                                                         */
10086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org/*  This file is part of the FreeType project, and may only be used,       */
11086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org/*  modified, and distributed under the terms of the FreeType project      */
12086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org/*  this file you indicate that you have read the license and              */
14cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org/*  understand and accept it fully.                                        */
1593a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org/*                                                                         */
16cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org/***************************************************************************/
17dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org
18dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org
19c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org#include <ft2build.h>
2093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#include "cffparse.h"
2125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org#include FT_INTERNAL_STREAM_H
22cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org#include FT_INTERNAL_DEBUG_H
23cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org
249dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#include "cfferrs.h"
25dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org#include "cffpic.h"
263a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
276b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org
282c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org  /*************************************************************************/
292c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org  /*                                                                       */
30cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
31cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
32357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  /* messages during execution.                                            */
33357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  /*                                                                       */
34357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org#undef  FT_COMPONENT
35357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org#define FT_COMPONENT  trace_cffparse
36357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
37357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
38357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
39086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
40086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  FT_LOCAL_DEF( void )
41086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  cff_parser_init( CFF_Parser  parser,
42c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org                   FT_UInt     code,
43c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org                   void*       object,
44c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org                   FT_Library  library)
45086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  {
46f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    FT_MEM_ZERO( parser, sizeof ( *parser ) );
472c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org
48086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    parser->top         = parser->stack;
49086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    parser->object_code = code;
50086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    parser->object      = object;
51086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    parser->library     = library;
52  }
53
54
55  /* read an integer */
56  static FT_Long
57  cff_parse_integer( FT_Byte*  start,
58                     FT_Byte*  limit )
59  {
60    FT_Byte*  p   = start;
61    FT_Int    v   = *p++;
62    FT_Long   val = 0;
63
64
65    if ( v == 28 )
66    {
67      if ( p + 2 > limit )
68        goto Bad;
69
70      val = (FT_Short)( ( (FT_Int)p[0] << 8 ) | p[1] );
71      p  += 2;
72    }
73    else if ( v == 29 )
74    {
75      if ( p + 4 > limit )
76        goto Bad;
77
78      val = ( (FT_Long)p[0] << 24 ) |
79            ( (FT_Long)p[1] << 16 ) |
80            ( (FT_Long)p[2] <<  8 ) |
81                       p[3];
82      p += 4;
83    }
84    else if ( v < 247 )
85    {
86      val = v - 139;
87    }
88    else if ( v < 251 )
89    {
90      if ( p + 1 > limit )
91        goto Bad;
92
93      val = ( v - 247 ) * 256 + p[0] + 108;
94      p++;
95    }
96    else
97    {
98      if ( p + 1 > limit )
99        goto Bad;
100
101      val = -( v - 251 ) * 256 - p[0] - 108;
102      p++;
103    }
104
105  Exit:
106    return val;
107
108  Bad:
109    val = 0;
110    goto Exit;
111  }
112
113
114  static const FT_Long power_tens[] =
115  {
116    1L,
117    10L,
118    100L,
119    1000L,
120    10000L,
121    100000L,
122    1000000L,
123    10000000L,
124    100000000L,
125    1000000000L
126  };
127
128
129  /* read a real */
130  static FT_Fixed
131  cff_parse_real( FT_Byte*  start,
132                  FT_Byte*  limit,
133                  FT_Long   power_ten,
134                  FT_Long*  scaling )
135  {
136    FT_Byte*  p = start;
137    FT_UInt   nib;
138    FT_UInt   phase;
139
140    FT_Long   result, number, rest, exponent;
141    FT_Int    sign = 0, exponent_sign = 0;
142    FT_Long   exponent_add, integer_length, fraction_length;
143
144
145    if ( scaling )
146      *scaling  = 0;
147
148    result = 0;
149
150    number   = 0;
151    rest     = 0;
152    exponent = 0;
153
154    exponent_add    = 0;
155    integer_length  = 0;
156    fraction_length = 0;
157
158    FT_UNUSED( rest );
159
160    /* First of all, read the integer part. */
161    phase = 4;
162
163    for (;;)
164    {
165      /* If we entered this iteration with phase == 4, we need to */
166      /* read a new byte.  This also skips past the initial 0x1E. */
167      if ( phase )
168      {
169        p++;
170
171        /* Make sure we don't read past the end. */
172        if ( p >= limit )
173          goto Exit;
174      }
175
176      /* Get the nibble. */
177      nib   = ( p[0] >> phase ) & 0xF;
178      phase = 4 - phase;
179
180      if ( nib == 0xE )
181        sign = 1;
182      else if ( nib > 9 )
183        break;
184      else
185      {
186        /* Increase exponent if we can't add the digit. */
187        if ( number >= 0xCCCCCCCL )
188          exponent_add++;
189        /* Skip leading zeros. */
190        else if ( nib || number )
191        {
192          integer_length++;
193          number = number * 10 + nib;
194        }
195      }
196    }
197
198    /* Read fraction part, if any. */
199    if ( nib == 0xa )
200      for (;;)
201      {
202        /* If we entered this iteration with phase == 4, we need */
203        /* to read a new byte.                                   */
204        if ( phase )
205        {
206          p++;
207
208          /* Make sure we don't read past the end. */
209          if ( p >= limit )
210            goto Exit;
211        }
212
213        /* Get the nibble. */
214        nib   = ( p[0] >> phase ) & 0xF;
215        phase = 4 - phase;
216        if ( nib >= 10 )
217          break;
218
219        /* Skip leading zeros if possible. */
220        if ( !nib && !number )
221          exponent_add--;
222        /* Only add digit if we don't overflow. */
223        else if ( number < 0xCCCCCCCL && fraction_length < 9 )
224        {
225          fraction_length++;
226          number = number * 10 + nib;
227        }
228      }
229
230    /* Read exponent, if any. */
231    if ( nib == 12 )
232    {
233      exponent_sign = 1;
234      nib           = 11;
235    }
236
237    if ( nib == 11 )
238    {
239      for (;;)
240      {
241        /* If we entered this iteration with phase == 4, */
242        /* we need to read a new byte.                   */
243        if ( phase )
244        {
245          p++;
246
247          /* Make sure we don't read past the end. */
248          if ( p >= limit )
249            goto Exit;
250        }
251
252        /* Get the nibble. */
253        nib   = ( p[0] >> phase ) & 0xF;
254        phase = 4 - phase;
255        if ( nib >= 10 )
256          break;
257
258        exponent = exponent * 10 + nib;
259
260        /* Arbitrarily limit exponent. */
261        if ( exponent > 1000 )
262          goto Exit;
263      }
264
265      if ( exponent_sign )
266        exponent = -exponent;
267    }
268
269    /* We don't check `power_ten' and `exponent_add'. */
270    exponent += power_ten + exponent_add;
271
272    if ( scaling )
273    {
274      /* Only use `fraction_length'. */
275      fraction_length += integer_length;
276      exponent        += integer_length;
277
278      if ( fraction_length <= 5 )
279      {
280        if ( number > 0x7FFFL )
281        {
282          result   = FT_DivFix( number, 10 );
283          *scaling = exponent - fraction_length + 1;
284        }
285        else
286        {
287          if ( exponent > 0 )
288          {
289            FT_Long  new_fraction_length, shift;
290
291
292            /* Make `scaling' as small as possible. */
293            new_fraction_length = FT_MIN( exponent, 5 );
294            exponent           -= new_fraction_length;
295            shift               = new_fraction_length - fraction_length;
296
297            number *= power_tens[shift];
298            if ( number > 0x7FFFL )
299            {
300              number   /= 10;
301              exponent += 1;
302            }
303          }
304          else
305            exponent -= fraction_length;
306
307          result   = number << 16;
308          *scaling = exponent;
309        }
310      }
311      else
312      {
313        if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL )
314        {
315          result   = FT_DivFix( number, power_tens[fraction_length - 4] );
316          *scaling = exponent - 4;
317        }
318        else
319        {
320          result   = FT_DivFix( number, power_tens[fraction_length - 5] );
321          *scaling = exponent - 5;
322        }
323      }
324    }
325    else
326    {
327      integer_length  += exponent;
328      fraction_length -= exponent;
329
330      /* Check for overflow and underflow. */
331      if ( FT_ABS( integer_length ) > 5 )
332        goto Exit;
333
334      /* Remove non-significant digits. */
335      if ( integer_length < 0 ) {
336        number          /= power_tens[-integer_length];
337        fraction_length += integer_length;
338      }
339
340      /* Convert into 16.16 format. */
341      if ( fraction_length > 0 )
342      {
343        if ( ( number / power_tens[fraction_length] ) > 0x7FFFL )
344          goto Exit;
345
346        result = FT_DivFix( number, power_tens[fraction_length] );
347      }
348      else
349      {
350        number *= power_tens[-fraction_length];
351
352        if ( number > 0x7FFFL )
353          goto Exit;
354
355        result = number << 16;
356      }
357    }
358
359    if ( sign )
360      result = -result;
361
362  Exit:
363    return result;
364  }
365
366
367  /* read a number, either integer or real */
368  static FT_Long
369  cff_parse_num( FT_Byte**  d )
370  {
371    return **d == 30 ? ( cff_parse_real( d[0], d[1], 0, NULL ) >> 16 )
372                     :   cff_parse_integer( d[0], d[1] );
373  }
374
375
376  /* read a floating point number, either integer or real */
377  static FT_Fixed
378  cff_parse_fixed( FT_Byte**  d )
379  {
380    return **d == 30 ? cff_parse_real( d[0], d[1], 0, NULL )
381                     : cff_parse_integer( d[0], d[1] ) << 16;
382  }
383
384
385  /* read a floating point number, either integer or real, */
386  /* but return `10^scaling' times the number read in      */
387  static FT_Fixed
388  cff_parse_fixed_scaled( FT_Byte**  d,
389                          FT_Long    scaling )
390  {
391    return **d == 30 ? cff_parse_real( d[0], d[1], scaling, NULL )
392                     : ( cff_parse_integer( d[0], d[1] ) *
393                           power_tens[scaling] ) << 16;
394  }
395
396
397  /* read a floating point number, either integer or real,     */
398  /* and return it as precise as possible -- `scaling' returns */
399  /* the scaling factor (as a power of 10)                     */
400  static FT_Fixed
401  cff_parse_fixed_dynamic( FT_Byte**  d,
402                           FT_Long*   scaling )
403  {
404    FT_ASSERT( scaling );
405
406    if ( **d == 30 )
407      return cff_parse_real( d[0], d[1], 0, scaling );
408    else
409    {
410      FT_Long  number;
411      FT_Int   integer_length;
412
413
414      number = cff_parse_integer( d[0], d[1] );
415
416      if ( number > 0x7FFFL )
417      {
418        for ( integer_length = 5; integer_length < 10; integer_length++ )
419          if ( number < power_tens[integer_length] )
420            break;
421
422        if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL )
423        {
424          *scaling = integer_length - 4;
425          return FT_DivFix( number, power_tens[integer_length - 4] );
426        }
427        else
428        {
429          *scaling = integer_length - 5;
430          return FT_DivFix( number, power_tens[integer_length - 5] );
431        }
432      }
433      else
434      {
435        *scaling = 0;
436        return number << 16;
437      }
438    }
439  }
440
441
442  static FT_Error
443  cff_parse_font_matrix( CFF_Parser  parser )
444  {
445    CFF_FontRecDict  dict   = (CFF_FontRecDict)parser->object;
446    FT_Matrix*       matrix = &dict->font_matrix;
447    FT_Vector*       offset = &dict->font_offset;
448    FT_ULong*        upm    = &dict->units_per_em;
449    FT_Byte**        data   = parser->stack;
450    FT_Error         error  = CFF_Err_Stack_Underflow;
451
452
453    if ( parser->top >= parser->stack + 6 )
454    {
455      FT_Long  scaling;
456
457
458      error = CFF_Err_Ok;
459
460      /* We expect a well-formed font matrix, this is, the matrix elements */
461      /* `xx' and `yy' are of approximately the same magnitude.  To avoid  */
462      /* loss of precision, we use the magnitude of element `xx' to scale  */
463      /* all other elements.  The scaling factor is then contained in the  */
464      /* `units_per_em' value.                                             */
465
466      matrix->xx = cff_parse_fixed_dynamic( data++, &scaling );
467
468      scaling = -scaling;
469
470      if ( scaling < 0 || scaling > 9 )
471      {
472        /* Return default matrix in case of unlikely values. */
473        matrix->xx = 0x10000L;
474        matrix->yx = 0;
475        matrix->yx = 0;
476        matrix->yy = 0x10000L;
477        offset->x  = 0;
478        offset->y  = 0;
479        *upm       = 1;
480
481        goto Exit;
482      }
483
484      matrix->yx = cff_parse_fixed_scaled( data++, scaling );
485      matrix->xy = cff_parse_fixed_scaled( data++, scaling );
486      matrix->yy = cff_parse_fixed_scaled( data++, scaling );
487      offset->x  = cff_parse_fixed_scaled( data++, scaling );
488      offset->y  = cff_parse_fixed_scaled( data,   scaling );
489
490      *upm = power_tens[scaling];
491    }
492
493  Exit:
494    return error;
495  }
496
497
498  static FT_Error
499  cff_parse_font_bbox( CFF_Parser  parser )
500  {
501    CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
502    FT_BBox*         bbox = &dict->font_bbox;
503    FT_Byte**        data = parser->stack;
504    FT_Error         error;
505
506
507    error = CFF_Err_Stack_Underflow;
508
509    if ( parser->top >= parser->stack + 4 )
510    {
511      bbox->xMin = FT_RoundFix( cff_parse_fixed( data++ ) );
512      bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) );
513      bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) );
514      bbox->yMax = FT_RoundFix( cff_parse_fixed( data   ) );
515      error = CFF_Err_Ok;
516    }
517
518    return error;
519  }
520
521
522  static FT_Error
523  cff_parse_private_dict( CFF_Parser  parser )
524  {
525    CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
526    FT_Byte**        data = parser->stack;
527    FT_Error         error;
528
529
530    error = CFF_Err_Stack_Underflow;
531
532    if ( parser->top >= parser->stack + 2 )
533    {
534      dict->private_size   = cff_parse_num( data++ );
535      dict->private_offset = cff_parse_num( data   );
536      error = CFF_Err_Ok;
537    }
538
539    return error;
540  }
541
542
543  static FT_Error
544  cff_parse_cid_ros( CFF_Parser  parser )
545  {
546    CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
547    FT_Byte**        data = parser->stack;
548    FT_Error         error;
549
550
551    error = CFF_Err_Stack_Underflow;
552
553    if ( parser->top >= parser->stack + 3 )
554    {
555      dict->cid_registry   = (FT_UInt)cff_parse_num ( data++ );
556      dict->cid_ordering   = (FT_UInt)cff_parse_num ( data++ );
557      if ( **data == 30 )
558        FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" ));
559      dict->cid_supplement = cff_parse_num( data );
560      if ( dict->cid_supplement < 0 )
561        FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n",
562                   dict->cid_supplement ));
563      error = CFF_Err_Ok;
564    }
565
566    return error;
567  }
568
569
570#define CFF_FIELD_NUM( code, name ) \
571          CFF_FIELD( code, name, cff_kind_num )
572#define CFF_FIELD_FIXED( code, name ) \
573          CFF_FIELD( code, name, cff_kind_fixed )
574#define CFF_FIELD_FIXED_1000( code, name ) \
575          CFF_FIELD( code, name, cff_kind_fixed_thousand )
576#define CFF_FIELD_STRING( code, name ) \
577          CFF_FIELD( code, name, cff_kind_string )
578#define CFF_FIELD_BOOL( code, name ) \
579          CFF_FIELD( code, name, cff_kind_bool )
580#define CFF_FIELD_DELTA( code, name, max ) \
581          CFF_FIELD( code, name, cff_kind_delta )
582
583#define CFFCODE_TOPDICT  0x1000
584#define CFFCODE_PRIVATE  0x2000
585
586#ifndef FT_CONFIG_OPTION_PIC
587
588#define CFF_FIELD_CALLBACK( code, name ) \
589          {                              \
590            cff_kind_callback,           \
591            code | CFFCODE,              \
592            0, 0,                        \
593            cff_parse_ ## name,          \
594            0, 0                         \
595          },
596
597#undef  CFF_FIELD
598#define CFF_FIELD( code, name, kind ) \
599          {                          \
600            kind,                    \
601            code | CFFCODE,          \
602            FT_FIELD_OFFSET( name ), \
603            FT_FIELD_SIZE( name ),   \
604            0, 0, 0                  \
605          },
606
607#undef  CFF_FIELD_DELTA
608#define CFF_FIELD_DELTA( code, name, max ) \
609        {                                  \
610          cff_kind_delta,                  \
611          code | CFFCODE,                  \
612          FT_FIELD_OFFSET( name ),         \
613          FT_FIELD_SIZE_DELTA( name ),     \
614          0,                               \
615          max,                             \
616          FT_FIELD_OFFSET( num_ ## name )  \
617        },
618
619  static const CFF_Field_Handler  cff_field_handlers[] =
620  {
621
622#include "cfftoken.h"
623
624    { 0, 0, 0, 0, 0, 0, 0 }
625  };
626
627
628#else /* FT_CONFIG_OPTION_PIC */
629
630  void FT_Destroy_Class_cff_field_handlers(FT_Library library, CFF_Field_Handler* clazz)
631  {
632    FT_Memory memory = library->memory;
633    if ( clazz )
634      FT_FREE( clazz );
635  }
636
637  FT_Error FT_Create_Class_cff_field_handlers(FT_Library library, CFF_Field_Handler** output_class)
638  {
639    CFF_Field_Handler*  clazz;
640    FT_Error          error;
641    FT_Memory memory = library->memory;
642    int i=0;
643
644#undef CFF_FIELD
645#undef CFF_FIELD_DELTA
646#undef CFF_FIELD_CALLBACK
647#define CFF_FIELD_CALLBACK( code, name ) i++;
648#define CFF_FIELD( code, name, kind ) i++;
649#define CFF_FIELD_DELTA( code, name, max ) i++;
650
651#include "cfftoken.h"
652    i++;/*{ 0, 0, 0, 0, 0, 0, 0 }*/
653
654    if ( FT_ALLOC( clazz, sizeof(CFF_Field_Handler)*i ) )
655      return error;
656
657    i=0;
658#undef CFF_FIELD
659#undef CFF_FIELD_DELTA
660#undef CFF_FIELD_CALLBACK
661
662#define CFF_FIELD_CALLBACK( code_, name_ )                                   \
663    clazz[i].kind = cff_kind_callback;                                       \
664    clazz[i].code = code_ | CFFCODE;                                         \
665    clazz[i].offset = 0;                                                     \
666    clazz[i].size = 0;                                                       \
667    clazz[i].reader = cff_parse_ ## name_;                                   \
668    clazz[i].array_max = 0;                                                  \
669    clazz[i].count_offset = 0;                                               \
670    i++;
671
672#undef  CFF_FIELD
673#define CFF_FIELD( code_, name_, kind_ )                                     \
674    clazz[i].kind = kind_;                                                   \
675    clazz[i].code = code_ | CFFCODE;                                         \
676    clazz[i].offset = FT_FIELD_OFFSET( name_ );                              \
677    clazz[i].size = FT_FIELD_SIZE( name_ );                                  \
678    clazz[i].reader = 0;                                                     \
679    clazz[i].array_max = 0;                                                  \
680    clazz[i].count_offset = 0;                                               \
681    i++;                                                                     \
682
683#undef  CFF_FIELD_DELTA
684#define CFF_FIELD_DELTA( code_, name_, max_ )                                \
685    clazz[i].kind = cff_kind_delta;                                          \
686    clazz[i].code = code_ | CFFCODE;                                         \
687    clazz[i].offset = FT_FIELD_OFFSET( name_ );                              \
688    clazz[i].size = FT_FIELD_SIZE_DELTA( name_ );                            \
689    clazz[i].reader = 0;                                                     \
690    clazz[i].array_max = max_;                                               \
691    clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ );                \
692    i++;
693
694#include "cfftoken.h"
695
696    clazz[i].kind = 0;
697    clazz[i].code = 0;
698    clazz[i].offset = 0;
699    clazz[i].size = 0;
700    clazz[i].reader = 0;
701    clazz[i].array_max = 0;
702    clazz[i].count_offset = 0;
703
704    *output_class = clazz;
705    return FT_Err_Ok;
706  }
707
708
709#endif /* FT_CONFIG_OPTION_PIC */
710
711
712  FT_LOCAL_DEF( FT_Error )
713  cff_parser_run( CFF_Parser  parser,
714                  FT_Byte*    start,
715                  FT_Byte*    limit )
716  {
717    FT_Byte*    p       = start;
718    FT_Error    error   = CFF_Err_Ok;
719    FT_Library  library = parser->library;
720    FT_UNUSED(library);
721
722
723    parser->top    = parser->stack;
724    parser->start  = start;
725    parser->limit  = limit;
726    parser->cursor = start;
727
728    while ( p < limit )
729    {
730      FT_UInt  v = *p;
731
732
733      if ( v >= 27 && v != 31 )
734      {
735        /* it's a number; we will push its position on the stack */
736        if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )
737          goto Stack_Overflow;
738
739        *parser->top ++ = p;
740
741        /* now, skip it */
742        if ( v == 30 )
743        {
744          /* skip real number */
745          p++;
746          for (;;)
747          {
748            /* An unterminated floating point number at the */
749            /* end of a dictionary is invalid but harmless. */
750            if ( p >= limit )
751              goto Exit;
752            v = p[0] >> 4;
753            if ( v == 15 )
754              break;
755            v = p[0] & 0xF;
756            if ( v == 15 )
757              break;
758            p++;
759          }
760        }
761        else if ( v == 28 )
762          p += 2;
763        else if ( v == 29 )
764          p += 4;
765        else if ( v > 246 )
766          p += 1;
767      }
768      else
769      {
770        /* This is not a number, hence it's an operator.  Compute its code */
771        /* and look for it in our current list.                            */
772
773        FT_UInt                   code;
774        FT_UInt                   num_args = (FT_UInt)
775                                             ( parser->top - parser->stack );
776        const CFF_Field_Handler*  field;
777
778
779        *parser->top = p;
780        code = v;
781        if ( v == 12 )
782        {
783          /* two byte operator */
784          p++;
785          if ( p >= limit )
786            goto Syntax_Error;
787
788          code = 0x100 | p[0];
789        }
790        code = code | parser->object_code;
791
792        for ( field = FT_CFF_FIELD_HANDLERS_GET; field->kind; field++ )
793        {
794          if ( field->code == (FT_Int)code )
795          {
796            /* we found our field's handler; read it */
797            FT_Long   val;
798            FT_Byte*  q = (FT_Byte*)parser->object + field->offset;
799
800
801            /* check that we have enough arguments -- except for */
802            /* delta encoded arrays, which can be empty          */
803            if ( field->kind != cff_kind_delta && num_args < 1 )
804              goto Stack_Underflow;
805
806            switch ( field->kind )
807            {
808            case cff_kind_bool:
809            case cff_kind_string:
810            case cff_kind_num:
811              val = cff_parse_num( parser->stack );
812              goto Store_Number;
813
814            case cff_kind_fixed:
815              val = cff_parse_fixed( parser->stack );
816              goto Store_Number;
817
818            case cff_kind_fixed_thousand:
819              val = cff_parse_fixed_scaled( parser->stack, 3 );
820
821            Store_Number:
822              switch ( field->size )
823              {
824              case (8 / FT_CHAR_BIT):
825                *(FT_Byte*)q = (FT_Byte)val;
826                break;
827
828              case (16 / FT_CHAR_BIT):
829                *(FT_Short*)q = (FT_Short)val;
830                break;
831
832              case (32 / FT_CHAR_BIT):
833                *(FT_Int32*)q = (FT_Int)val;
834                break;
835
836              default:  /* for 64-bit systems */
837                *(FT_Long*)q = val;
838              }
839              break;
840
841            case cff_kind_delta:
842              {
843                FT_Byte*   qcount = (FT_Byte*)parser->object +
844                                      field->count_offset;
845
846                FT_Byte**  data = parser->stack;
847
848
849                if ( num_args > field->array_max )
850                  num_args = field->array_max;
851
852                /* store count */
853                *qcount = (FT_Byte)num_args;
854
855                val = 0;
856                while ( num_args > 0 )
857                {
858                  val += cff_parse_num( data++ );
859                  switch ( field->size )
860                  {
861                  case (8 / FT_CHAR_BIT):
862                    *(FT_Byte*)q = (FT_Byte)val;
863                    break;
864
865                  case (16 / FT_CHAR_BIT):
866                    *(FT_Short*)q = (FT_Short)val;
867                    break;
868
869                  case (32 / FT_CHAR_BIT):
870                    *(FT_Int32*)q = (FT_Int)val;
871                    break;
872
873                  default:  /* for 64-bit systems */
874                    *(FT_Long*)q = val;
875                  }
876
877                  q += field->size;
878                  num_args--;
879                }
880              }
881              break;
882
883            default:  /* callback */
884              error = field->reader( parser );
885              if ( error )
886                goto Exit;
887            }
888            goto Found;
889          }
890        }
891
892        /* this is an unknown operator, or it is unsupported; */
893        /* we will ignore it for now.                         */
894
895      Found:
896        /* clear stack */
897        parser->top = parser->stack;
898      }
899      p++;
900    }
901
902  Exit:
903    return error;
904
905  Stack_Overflow:
906    error = CFF_Err_Invalid_Argument;
907    goto Exit;
908
909  Stack_Underflow:
910    error = CFF_Err_Invalid_Argument;
911    goto Exit;
912
913  Syntax_Error:
914    error = CFF_Err_Invalid_Argument;
915    goto Exit;
916  }
917
918
919/* END */
920