source: trunk/poppler/freetype-2.1.10/src/cff/cffparse.c @ 2

Last change on this file since 2 was 2, checked in by Eugene Romanenko, 15 years ago

First import

File size: 17.2 KB
Line 
1/***************************************************************************/
2/*                                                                         */
3/*  cffparse.c                                                             */
4/*                                                                         */
5/*    CFF token stream parser (body)                                       */
6/*                                                                         */
7/*  Copyright 1996-2001, 2002, 2003, 2004 by                               */
8/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9/*                                                                         */
10/*  This file is part of the FreeType project, and may only be used,       */
11/*  modified, and distributed under the terms of the FreeType project      */
12/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13/*  this file you indicate that you have read the license and              */
14/*  understand and accept it fully.                                        */
15/*                                                                         */
16/***************************************************************************/
17
18
19#include <ft2build.h>
20#include "cffparse.h"
21#include FT_INTERNAL_STREAM_H
22
23#include "cfferrs.h"
24
25
26  /*************************************************************************/
27  /*                                                                       */
28  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
29  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
30  /* messages during execution.                                            */
31  /*                                                                       */
32#undef  FT_COMPONENT
33#define FT_COMPONENT  trace_cffparse
34
35
36  enum
37  {
38    cff_kind_none = 0,
39    cff_kind_num,
40    cff_kind_fixed,
41    cff_kind_fixed_thousand,
42    cff_kind_string,
43    cff_kind_bool,
44    cff_kind_delta,
45    cff_kind_callback,
46
47    cff_kind_max  /* do not remove */
48  };
49
50
51  /* now generate handlers for the most simple fields */
52  typedef FT_Error  (*CFF_Field_Reader)( CFF_Parser  parser );
53
54  typedef struct  CFF_Field_Handler_
55  {
56    int               kind;
57    int               code;
58    FT_UInt           offset;
59    FT_Byte           size;
60    CFF_Field_Reader  reader;
61    FT_UInt           array_max;
62    FT_UInt           count_offset;
63
64  } CFF_Field_Handler;
65
66
67  FT_LOCAL_DEF( void )
68  cff_parser_init( CFF_Parser  parser,
69                   FT_UInt     code,
70                   void*       object )
71  {
72    FT_MEM_ZERO( parser, sizeof ( *parser ) );
73
74    parser->top         = parser->stack;
75    parser->object_code = code;
76    parser->object      = object;
77  }
78
79
80  /* read an integer */
81  static FT_Long
82  cff_parse_integer( FT_Byte*  start,
83                     FT_Byte*  limit )
84  {
85    FT_Byte*  p   = start;
86    FT_Int    v   = *p++;
87    FT_Long   val = 0;
88
89
90    if ( v == 28 )
91    {
92      if ( p + 2 > limit )
93        goto Bad;
94
95      val = (FT_Short)( ( (FT_Int)p[0] << 8 ) | p[1] );
96      p  += 2;
97    }
98    else if ( v == 29 )
99    {
100      if ( p + 4 > limit )
101        goto Bad;
102
103      val = ( (FT_Long)p[0] << 24 ) |
104            ( (FT_Long)p[1] << 16 ) |
105            ( (FT_Long)p[2] <<  8 ) |
106                       p[3];
107      p += 4;
108    }
109    else if ( v < 247 )
110    {
111      val = v - 139;
112    }
113    else if ( v < 251 )
114    {
115      if ( p + 1 > limit )
116        goto Bad;
117
118      val = ( v - 247 ) * 256 + p[0] + 108;
119      p++;
120    }
121    else
122    {
123      if ( p + 1 > limit )
124        goto Bad;
125
126      val = -( v - 251 ) * 256 - p[0] - 108;
127      p++;
128    }
129
130  Exit:
131    return val;
132
133  Bad:
134    val = 0;
135    goto Exit;
136  }
137
138
139  /* read a real */
140  static FT_Fixed
141  cff_parse_real( FT_Byte*  start,
142                  FT_Byte*  limit,
143                  FT_Int    power_ten )
144  {
145    FT_Byte*  p    = start;
146    FT_Long   num, divider, result, exponent;
147    FT_Int    sign = 0, exponent_sign = 0;
148    FT_UInt   nib;
149    FT_UInt   phase;
150
151
152    result  = 0;
153    num     = 0;
154    divider = 1;
155
156    /* first of all, read the integer part */
157    phase = 4;
158
159    for (;;)
160    {
161      /* If we entered this iteration with phase == 4, we need to */
162      /* read a new byte.  This also skips past the intial 0x1E.  */
163      if ( phase )
164      {
165        p++;
166
167        /* Make sure we don't read past the end. */
168        if ( p >= limit )
169          goto Bad;
170      }
171
172      /* Get the nibble. */
173      nib   = ( p[0] >> phase ) & 0xF;
174      phase = 4 - phase;
175
176      if ( nib == 0xE )
177        sign = 1;
178      else if ( nib > 9 )
179        break;
180      else
181        result = result * 10 + nib;
182    }
183
184    /* read decimal part, if any */
185    if ( nib == 0xa )
186      for (;;)
187      {
188        /* If we entered this iteration with phase == 4, we need */
189        /* to read a new byte.                                   */
190        if ( phase )
191        {
192          p++;
193
194          /* Make sure we don't read past the end. */
195          if ( p >= limit )
196            goto Bad;
197        }
198
199        /* Get the nibble. */
200        nib   = ( p[0] >> phase ) & 0xF;
201        phase = 4 - phase;
202        if ( nib >= 10 )
203          break;
204
205        if ( divider < 10000000L )
206        {
207          num      = num * 10 + nib;
208          divider *= 10;
209        }
210      }
211
212    /* read exponent, if any */
213    if ( nib == 12 )
214    {
215      exponent_sign = 1;
216      nib           = 11;
217    }
218
219    if ( nib == 11 )
220    {
221      exponent = 0;
222
223      for (;;)
224      {
225        /* If we entered this iteration with phase == 4, we need */
226        /* to read a new byte.                                   */
227        if ( phase )
228        {
229          p++;
230
231          /* Make sure we don't read past the end. */
232          if ( p >= limit )
233            goto Bad;
234        }
235
236        /* Get the nibble. */
237        nib   = ( p[0] >> phase ) & 0xF;
238        phase = 4 - phase;
239        if ( nib >= 10 )
240          break;
241
242        exponent = exponent * 10 + nib;
243      }
244
245      if ( exponent_sign )
246        exponent = -exponent;
247
248      power_ten += (FT_Int)exponent;
249    }
250
251    /* raise to power of ten if needed */
252    while ( power_ten > 0 )
253    {
254      result = result * 10;
255      num    = num * 10;
256
257      power_ten--;
258    }
259
260    while ( power_ten < 0 )
261    {
262      result  = result / 10;
263      divider = divider * 10;
264
265      power_ten++;
266    }
267
268    /* Move the integer part into the high 16 bits. */
269    result <<= 16;
270
271    /* Place the decimal part into the low 16 bits. */
272    if ( num )
273      result |= FT_DivFix( num, divider );
274
275    if ( sign )
276      result = -result;
277
278  Exit:
279    return result;
280
281  Bad:
282    result = 0;
283    goto Exit;
284  }
285
286
287  /* read a number, either integer or real */
288  static FT_Long
289  cff_parse_num( FT_Byte**  d )
290  {
291    return ( **d == 30 ? ( cff_parse_real   ( d[0], d[1], 0 ) >> 16 )
292                       :   cff_parse_integer( d[0], d[1] ) );
293  }
294
295
296  /* read a floating point number, either integer or real */
297  static FT_Fixed
298  cff_parse_fixed( FT_Byte**  d )
299  {
300    return ( **d == 30 ? cff_parse_real   ( d[0], d[1], 0 )
301                       : cff_parse_integer( d[0], d[1] ) << 16 );
302  }
303
304  /* read a floating point number, either integer or real, */
305  /* but return 1000 times the number read in.             */
306  static FT_Fixed
307  cff_parse_fixed_thousand( FT_Byte**  d )
308  {
309    return **d ==
310      30 ? cff_parse_real     ( d[0], d[1], 3 )
311         : (FT_Fixed)FT_MulFix( cff_parse_integer( d[0], d[1] ) << 16, 1000 );
312  }
313
314  static FT_Error
315  cff_parse_font_matrix( CFF_Parser  parser )
316  {
317    CFF_FontRecDict  dict   = (CFF_FontRecDict)parser->object;
318    FT_Matrix*       matrix = &dict->font_matrix;
319    FT_Vector*       offset = &dict->font_offset;
320    FT_UShort*       upm    = &dict->units_per_em;
321    FT_Byte**        data   = parser->stack;
322    FT_Error         error;
323    FT_Fixed         temp;
324
325
326    error = CFF_Err_Stack_Underflow;
327
328    if ( parser->top >= parser->stack + 6 )
329    {
330      matrix->xx = cff_parse_fixed_thousand( data++ );
331      matrix->yx = cff_parse_fixed_thousand( data++ );
332      matrix->xy = cff_parse_fixed_thousand( data++ );
333      matrix->yy = cff_parse_fixed_thousand( data++ );
334      offset->= cff_parse_fixed_thousand( data++ );
335      offset->= cff_parse_fixed_thousand( data   );
336
337      temp = FT_ABS( matrix->yy );
338
339      *upm = (FT_UShort)FT_DivFix( 0x10000L, FT_DivFix( temp, 1000 ) );
340
341      if ( temp != 0x10000L )
342      {
343        matrix->xx = FT_DivFix( matrix->xx, temp );
344        matrix->yx = FT_DivFix( matrix->yx, temp );
345        matrix->xy = FT_DivFix( matrix->xy, temp );
346        matrix->yy = FT_DivFix( matrix->yy, temp );
347        offset->= FT_DivFix( offset->x,  temp );
348        offset->= FT_DivFix( offset->y,  temp );
349      }
350
351      /* note that the offsets must be expressed in integer font units */
352      offset->x >>= 16;
353      offset->y >>= 16;
354
355      error = CFF_Err_Ok;
356    }
357
358    return error;
359  }
360
361
362  static FT_Error
363  cff_parse_font_bbox( CFF_Parser  parser )
364  {
365    CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
366    FT_BBox*         bbox = &dict->font_bbox;
367    FT_Byte**        data = parser->stack;
368    FT_Error         error;
369
370
371    error = CFF_Err_Stack_Underflow;
372
373    if ( parser->top >= parser->stack + 4 )
374    {
375      bbox->xMin = FT_RoundFix( cff_parse_fixed( data++ ) );
376      bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) );
377      bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) );
378      bbox->yMax = FT_RoundFix( cff_parse_fixed( data   ) );
379      error = CFF_Err_Ok;
380    }
381
382    return error;
383  }
384
385
386  static FT_Error
387  cff_parse_private_dict( CFF_Parser  parser )
388  {
389    CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
390    FT_Byte**        data = parser->stack;
391    FT_Error         error;
392
393
394    error = CFF_Err_Stack_Underflow;
395
396    if ( parser->top >= parser->stack + 2 )
397    {
398      dict->private_size   = cff_parse_num( data++ );
399      dict->private_offset = cff_parse_num( data   );
400      error = CFF_Err_Ok;
401    }
402
403    return error;
404  }
405
406
407  static FT_Error
408  cff_parse_cid_ros( CFF_Parser  parser )
409  {
410    CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
411    FT_Byte**        data = parser->stack;
412    FT_Error         error;
413
414
415    error = CFF_Err_Stack_Underflow;
416
417    if ( parser->top >= parser->stack + 3 )
418    {
419      dict->cid_registry   = (FT_UInt)cff_parse_num ( data++ );
420      dict->cid_ordering   = (FT_UInt)cff_parse_num ( data++ );
421      dict->cid_supplement = (FT_ULong)cff_parse_num( data );
422      error = CFF_Err_Ok;
423    }
424
425    return error;
426  }
427
428
429#define CFF_FIELD_NUM( code, name ) \
430          CFF_FIELD( code, name, cff_kind_num )
431#define CFF_FIELD_FIXED( code, name ) \
432          CFF_FIELD( code, name, cff_kind_fixed )
433#define CFF_FIELD_FIXED_1000( code, name ) \
434          CFF_FIELD( code, name, cff_kind_fixed_thousand )
435#define CFF_FIELD_STRING( code, name ) \
436          CFF_FIELD( code, name, cff_kind_string )
437#define CFF_FIELD_BOOL( code, name ) \
438          CFF_FIELD( code, name, cff_kind_bool )
439#define CFF_FIELD_DELTA( code, name, max ) \
440          CFF_FIELD( code, name, cff_kind_delta )
441
442#define CFF_FIELD_CALLBACK( code, name ) \
443          {                              \
444            cff_kind_callback,           \
445            code | CFFCODE,              \
446            0, 0,                        \
447            cff_parse_ ## name,          \
448            0, 0                         \
449          },
450
451#undef  CFF_FIELD
452#define CFF_FIELD( code, name, kind ) \
453          {                          \
454            kind,                    \
455            code | CFFCODE,          \
456            FT_FIELD_OFFSET( name ), \
457            FT_FIELD_SIZE( name ),   \
458            0, 0, 0                  \
459          },
460
461#undef  CFF_FIELD_DELTA
462#define CFF_FIELD_DELTA( code, name, max ) \
463        {                                  \
464          cff_kind_delta,                  \
465          code | CFFCODE,                  \
466          FT_FIELD_OFFSET( name ),         \
467          FT_FIELD_SIZE_DELTA( name ),     \
468          0,                               \
469          max,                             \
470          FT_FIELD_OFFSET( num_ ## name )  \
471        },
472
473#define CFFCODE_TOPDICT  0x1000
474#define CFFCODE_PRIVATE  0x2000
475
476  static const CFF_Field_Handler  cff_field_handlers[] =
477  {
478
479#include "cfftoken.h"
480
481    { 0, 0, 0, 0, 0, 0, 0 }
482  };
483
484
485  FT_LOCAL_DEF( FT_Error )
486  cff_parser_run( CFF_Parser  parser,
487                  FT_Byte*    start,
488                  FT_Byte*    limit )
489  {
490    FT_Byte*  p     = start;
491    FT_Error  error = CFF_Err_Ok;
492
493
494    parser->top    = parser->stack;
495    parser->start  = start;
496    parser->limit  = limit;
497    parser->cursor = start;
498
499    while ( p < limit )
500    {
501      FT_UInt  v = *p;
502
503
504      if ( v >= 27 && v != 31 )
505      {
506        /* it's a number; we will push its position on the stack */
507        if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )
508          goto Stack_Overflow;
509
510        *parser->top ++ = p;
511
512        /* now, skip it */
513        if ( v == 30 )
514        {
515          /* skip real number */
516          p++;
517          for (;;)
518          {
519            if ( p >= limit )
520              goto Syntax_Error;
521            v = p[0] >> 4;
522            if ( v == 15 )
523              break;
524            v = p[0] & 0xF;
525            if ( v == 15 )
526              break;
527            p++;
528          }
529        }
530        else if ( v == 28 )
531          p += 2;
532        else if ( v == 29 )
533          p += 4;
534        else if ( v > 246 )
535          p += 1;
536      }
537      else
538      {
539        /* This is not a number, hence it's an operator.  Compute its code */
540        /* and look for it in our current list.                            */
541
542        FT_UInt                   code;
543        FT_UInt                   num_args = (FT_UInt)
544                                             ( parser->top - parser->stack );
545        const CFF_Field_Handler*  field;
546
547
548        *parser->top = p;
549        code = v;
550        if ( v == 12 )
551        {
552          /* two byte operator */
553          p++;
554          if ( p >= limit )
555            goto Syntax_Error;
556
557          code = 0x100 | p[0];
558        }
559        code = code | parser->object_code;
560
561        for ( field = cff_field_handlers; field->kind; field++ )
562        {
563          if ( field->code == (FT_Int)code )
564          {
565            /* we found our field's handler; read it */
566            FT_Long   val;
567            FT_Byte*  q = (FT_Byte*)parser->object + field->offset;
568
569
570            /* check that we have enough arguments -- except for */
571            /* delta encoded arrays, which can be empty          */
572            if ( field->kind != cff_kind_delta && num_args < 1 )
573              goto Stack_Underflow;
574
575            switch ( field->kind )
576            {
577            case cff_kind_bool:
578            case cff_kind_string:
579            case cff_kind_num:
580              val = cff_parse_num( parser->stack );
581              goto Store_Number;
582
583            case cff_kind_fixed:
584              val = cff_parse_fixed( parser->stack );
585              goto Store_Number;
586
587            case cff_kind_fixed_thousand:
588              val = cff_parse_fixed_thousand( parser->stack );
589
590            Store_Number:
591              switch ( field->size )
592              {
593              case (8 / FT_CHAR_BIT):
594                *(FT_Byte*)q = (FT_Byte)val;
595                break;
596
597              case (16 / FT_CHAR_BIT):
598                *(FT_Short*)q = (FT_Short)val;
599                break;
600
601              case (32 / FT_CHAR_BIT):
602                *(FT_Int32*)q = (FT_Int)val;
603                break;
604
605              default:  /* for 64-bit systems */
606                *(FT_Long*)q = val;
607              }
608              break;
609
610            case cff_kind_delta:
611              {
612                FT_Byte*   qcount = (FT_Byte*)parser->object +
613                                      field->count_offset;
614
615                FT_Byte**  data = parser->stack;
616
617
618                if ( num_args > field->array_max )
619                  num_args = field->array_max;
620
621                /* store count */
622                *qcount = (FT_Byte)num_args;
623
624                val = 0;
625                while ( num_args > 0 )
626                {
627                  val += cff_parse_num( data++ );
628                  switch ( field->size )
629                  {
630                  case (8 / FT_CHAR_BIT):
631                    *(FT_Byte*)q = (FT_Byte)val;
632                    break;
633
634                  case (16 / FT_CHAR_BIT):
635                    *(FT_Short*)q = (FT_Short)val;
636                    break;
637
638                  case (32 / FT_CHAR_BIT):
639                    *(FT_Int32*)q = (FT_Int)val;
640                    break;
641
642                  default:  /* for 64-bit systems */
643                    *(FT_Long*)q = val;
644                  }
645
646                  q += field->size;
647                  num_args--;
648                }
649              }
650              break;
651
652            default:  /* callback */
653              error = field->reader( parser );
654              if ( error )
655                goto Exit;
656            }
657            goto Found;
658          }
659        }
660
661        /* this is an unknown operator, or it is unsupported; */
662        /* we will ignore it for now.                         */
663
664      Found:
665        /* clear stack */
666        parser->top = parser->stack;
667      }
668      p++;
669    }
670
671  Exit:
672    return error;
673
674  Stack_Overflow:
675    error = CFF_Err_Invalid_Argument;
676    goto Exit;
677
678  Stack_Underflow:
679    error = CFF_Err_Invalid_Argument;
680    goto Exit;
681
682  Syntax_Error:
683    error = CFF_Err_Invalid_Argument;
684    goto Exit;
685  }
686
687
688/* END */
Note: See TracBrowser for help on using the repository browser.