cffparse.c

Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  cffparse.c                                                             */
00004 /*                                                                         */
00005 /*    CFF token stream parser (body)                                       */
00006 /*                                                                         */
00007 /*  Copyright 1996-2001, 2002, 2003, 2004, 2007, 2008, 2009 by             */
00008 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
00009 /*                                                                         */
00010 /*  This file is part of the FreeType project, and may only be used,       */
00011 /*  modified, and distributed under the terms of the FreeType project      */
00012 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
00013 /*  this file you indicate that you have read the license and              */
00014 /*  understand and accept it fully.                                        */
00015 /*                                                                         */
00016 /***************************************************************************/
00017 
00018 
00019 #include <ft2build.h>
00020 #include "cffparse.h"
00021 #include FT_INTERNAL_STREAM_H
00022 #include FT_INTERNAL_DEBUG_H
00023 
00024 #include "cfferrs.h"
00025 #include "cffpic.h"
00026 
00027 
00028   /*************************************************************************/
00029   /*                                                                       */
00030   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
00031   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
00032   /* messages during execution.                                            */
00033   /*                                                                       */
00034 #undef  FT_COMPONENT
00035 #define FT_COMPONENT  trace_cffparse
00036 
00037 
00038 
00039 
00040   FT_LOCAL_DEF( void )
00041   cff_parser_init( CFF_Parser  parser,
00042                    FT_UInt     code,
00043                    void*       object,
00044                    FT_Library  library)
00045   {
00046     FT_MEM_ZERO( parser, sizeof ( *parser ) );
00047 
00048     parser->top         = parser->stack;
00049     parser->object_code = code;
00050     parser->object      = object;
00051     parser->library     = library;
00052   }
00053 
00054 
00055   /* read an integer */
00056   static FT_Long
00057   cff_parse_integer( FT_Byte*  start,
00058                      FT_Byte*  limit )
00059   {
00060     FT_Byte*  p   = start;
00061     FT_Int    v   = *p++;
00062     FT_Long   val = 0;
00063 
00064 
00065     if ( v == 28 )
00066     {
00067       if ( p + 2 > limit )
00068         goto Bad;
00069 
00070       val = (FT_Short)( ( (FT_Int)p[0] << 8 ) | p[1] );
00071       p  += 2;
00072     }
00073     else if ( v == 29 )
00074     {
00075       if ( p + 4 > limit )
00076         goto Bad;
00077 
00078       val = ( (FT_Long)p[0] << 24 ) |
00079             ( (FT_Long)p[1] << 16 ) |
00080             ( (FT_Long)p[2] <<  8 ) |
00081                        p[3];
00082       p += 4;
00083     }
00084     else if ( v < 247 )
00085     {
00086       val = v - 139;
00087     }
00088     else if ( v < 251 )
00089     {
00090       if ( p + 1 > limit )
00091         goto Bad;
00092 
00093       val = ( v - 247 ) * 256 + p[0] + 108;
00094       p++;
00095     }
00096     else
00097     {
00098       if ( p + 1 > limit )
00099         goto Bad;
00100 
00101       val = -( v - 251 ) * 256 - p[0] - 108;
00102       p++;
00103     }
00104 
00105   Exit:
00106     return val;
00107 
00108   Bad:
00109     val = 0;
00110     goto Exit;
00111   }
00112 
00113 
00114   static const FT_Long power_tens[] =
00115   {
00116     1L,
00117     10L,
00118     100L,
00119     1000L,
00120     10000L,
00121     100000L,
00122     1000000L,
00123     10000000L,
00124     100000000L,
00125     1000000000L
00126   };
00127 
00128 
00129   /* read a real */
00130   static FT_Fixed
00131   cff_parse_real( FT_Byte*  start,
00132                   FT_Byte*  limit,
00133                   FT_Long   power_ten,
00134                   FT_Long*  scaling )
00135   {
00136     FT_Byte*  p = start;
00137     FT_UInt   nib;
00138     FT_UInt   phase;
00139 
00140     FT_Long   result, number, rest, exponent;
00141     FT_Int    sign = 0, exponent_sign = 0;
00142     FT_Long   exponent_add, integer_length, fraction_length;
00143 
00144 
00145     if ( scaling )
00146       *scaling  = 0;
00147 
00148     result = 0;
00149 
00150     number   = 0;
00151     rest     = 0;
00152     exponent = 0;
00153 
00154     exponent_add    = 0;
00155     integer_length  = 0;
00156     fraction_length = 0;
00157 
00158     FT_UNUSED( rest );
00159 
00160     /* First of all, read the integer part. */
00161     phase = 4;
00162 
00163     for (;;)
00164     {
00165       /* If we entered this iteration with phase == 4, we need to */
00166       /* read a new byte.  This also skips past the initial 0x1E. */
00167       if ( phase )
00168       {
00169         p++;
00170 
00171         /* Make sure we don't read past the end. */
00172         if ( p >= limit )
00173           goto Exit;
00174       }
00175 
00176       /* Get the nibble. */
00177       nib   = ( p[0] >> phase ) & 0xF;
00178       phase = 4 - phase;
00179 
00180       if ( nib == 0xE )
00181         sign = 1;
00182       else if ( nib > 9 )
00183         break;
00184       else
00185       {
00186         /* Increase exponent if we can't add the digit. */
00187         if ( number >= 0xCCCCCCCL )
00188           exponent_add++;
00189         /* Skip leading zeros. */
00190         else if ( nib || number )
00191         {
00192           integer_length++;
00193           number = number * 10 + nib;
00194         }
00195       }
00196     }
00197 
00198     /* Read fraction part, if any. */
00199     if ( nib == 0xa )
00200       for (;;)
00201       {
00202         /* If we entered this iteration with phase == 4, we need */
00203         /* to read a new byte.                                   */
00204         if ( phase )
00205         {
00206           p++;
00207 
00208           /* Make sure we don't read past the end. */
00209           if ( p >= limit )
00210             goto Exit;
00211         }
00212 
00213         /* Get the nibble. */
00214         nib   = ( p[0] >> phase ) & 0xF;
00215         phase = 4 - phase;
00216         if ( nib >= 10 )
00217           break;
00218 
00219         /* Skip leading zeros if possible. */
00220         if ( !nib && !number )
00221           exponent_add--;
00222         /* Only add digit if we don't overflow. */
00223         else if ( number < 0xCCCCCCCL && fraction_length < 9 )
00224         {
00225           fraction_length++;
00226           number = number * 10 + nib;
00227         }
00228       }
00229 
00230     /* Read exponent, if any. */
00231     if ( nib == 12 )
00232     {
00233       exponent_sign = 1;
00234       nib           = 11;
00235     }
00236 
00237     if ( nib == 11 )
00238     {
00239       for (;;)
00240       {
00241         /* If we entered this iteration with phase == 4, */
00242         /* we need to read a new byte.                   */
00243         if ( phase )
00244         {
00245           p++;
00246 
00247           /* Make sure we don't read past the end. */
00248           if ( p >= limit )
00249             goto Exit;
00250         }
00251 
00252         /* Get the nibble. */
00253         nib   = ( p[0] >> phase ) & 0xF;
00254         phase = 4 - phase;
00255         if ( nib >= 10 )
00256           break;
00257 
00258         exponent = exponent * 10 + nib;
00259 
00260         /* Arbitrarily limit exponent. */
00261         if ( exponent > 1000 )
00262           goto Exit;
00263       }
00264 
00265       if ( exponent_sign )
00266         exponent = -exponent;
00267     }
00268 
00269     /* We don't check `power_ten' and `exponent_add'. */
00270     exponent += power_ten + exponent_add;
00271 
00272     if ( scaling )
00273     {
00274       /* Only use `fraction_length'. */
00275       fraction_length += integer_length;
00276       exponent        += integer_length;
00277 
00278       if ( fraction_length <= 5 )
00279       {
00280         if ( number > 0x7FFFL )
00281         {
00282           result   = FT_DivFix( number, 10 );
00283           *scaling = exponent - fraction_length + 1;
00284         }
00285         else
00286         {
00287           if ( exponent > 0 )
00288           {
00289             FT_Long  new_fraction_length, shift;
00290 
00291 
00292             /* Make `scaling' as small as possible. */
00293             new_fraction_length = FT_MIN( exponent, 5 );
00294             exponent           -= new_fraction_length;
00295             shift               = new_fraction_length - fraction_length;
00296 
00297             number *= power_tens[shift];
00298             if ( number > 0x7FFFL )
00299             {
00300               number   /= 10;
00301               exponent += 1;
00302             }
00303           }
00304           else
00305             exponent -= fraction_length;
00306 
00307           result   = number << 16;
00308           *scaling = exponent;
00309         }
00310       }
00311       else
00312       {
00313         if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL )
00314         {
00315           result   = FT_DivFix( number, power_tens[fraction_length - 4] );
00316           *scaling = exponent - 4;
00317         }
00318         else
00319         {
00320           result   = FT_DivFix( number, power_tens[fraction_length - 5] );
00321           *scaling = exponent - 5;
00322         }
00323       }
00324     }
00325     else
00326     {
00327       integer_length  += exponent;
00328       fraction_length -= exponent;
00329 
00330       /* Check for overflow and underflow. */
00331       if ( FT_ABS( integer_length ) > 5 )
00332         goto Exit;
00333 
00334       /* Remove non-significant digits. */
00335       if ( integer_length < 0 ) {
00336         number          /= power_tens[-integer_length];
00337         fraction_length += integer_length;
00338       }
00339 
00340       /* Convert into 16.16 format. */
00341       if ( fraction_length > 0 )
00342       {
00343         if ( ( number / power_tens[fraction_length] ) > 0x7FFFL )
00344           goto Exit;
00345 
00346         result = FT_DivFix( number, power_tens[fraction_length] );
00347       }
00348       else
00349       {
00350         number *= power_tens[-fraction_length];
00351 
00352         if ( number > 0x7FFFL )
00353           goto Exit;
00354 
00355         result = number << 16;
00356       }
00357     }
00358 
00359     if ( sign )
00360       result = -result;
00361 
00362   Exit:
00363     return result;
00364   }
00365 
00366 
00367   /* read a number, either integer or real */
00368   static FT_Long
00369   cff_parse_num( FT_Byte**  d )
00370   {
00371     return **d == 30 ? ( cff_parse_real( d[0], d[1], 0, NULL ) >> 16 )
00372                      :   cff_parse_integer( d[0], d[1] );
00373   }
00374 
00375 
00376   /* read a floating point number, either integer or real */
00377   static FT_Fixed
00378   cff_parse_fixed( FT_Byte**  d )
00379   {
00380     return **d == 30 ? cff_parse_real( d[0], d[1], 0, NULL )
00381                      : cff_parse_integer( d[0], d[1] ) << 16;
00382   }
00383 
00384 
00385   /* read a floating point number, either integer or real, */
00386   /* but return `10^scaling' times the number read in      */
00387   static FT_Fixed
00388   cff_parse_fixed_scaled( FT_Byte**  d,
00389                           FT_Long    scaling )
00390   {
00391     return **d == 30 ? cff_parse_real( d[0], d[1], scaling, NULL )
00392                      : ( cff_parse_integer( d[0], d[1] ) *
00393                            power_tens[scaling] ) << 16;
00394   }
00395 
00396 
00397   /* read a floating point number, either integer or real,     */
00398   /* and return it as precise as possible -- `scaling' returns */
00399   /* the scaling factor (as a power of 10)                     */
00400   static FT_Fixed
00401   cff_parse_fixed_dynamic( FT_Byte**  d,
00402                            FT_Long*   scaling )
00403   {
00404     FT_ASSERT( scaling );
00405 
00406     if ( **d == 30 )
00407       return cff_parse_real( d[0], d[1], 0, scaling );
00408     else
00409     {
00410       FT_Long  number;
00411       FT_Int   integer_length;
00412 
00413 
00414       number = cff_parse_integer( d[0], d[1] );
00415 
00416       if ( number > 0x7FFFL )
00417       {
00418         for ( integer_length = 5; integer_length < 10; integer_length++ )
00419           if ( number < power_tens[integer_length] )
00420             break;
00421 
00422         if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL )
00423         {
00424           *scaling = integer_length - 4;
00425           return FT_DivFix( number, power_tens[integer_length - 4] );
00426         }
00427         else
00428         {
00429           *scaling = integer_length - 5;
00430           return FT_DivFix( number, power_tens[integer_length - 5] );
00431         }
00432       }
00433       else
00434       {
00435         *scaling = 0;
00436         return number << 16;
00437       }
00438     }
00439   }
00440 
00441 
00442   static FT_Error
00443   cff_parse_font_matrix( CFF_Parser  parser )
00444   {
00445     CFF_FontRecDict  dict   = (CFF_FontRecDict)parser->object;
00446     FT_Matrix*       matrix = &dict->font_matrix;
00447     FT_Vector*       offset = &dict->font_offset;
00448     FT_ULong*        upm    = &dict->units_per_em;
00449     FT_Byte**        data   = parser->stack;
00450     FT_Error         error  = CFF_Err_Stack_Underflow;
00451 
00452 
00453     if ( parser->top >= parser->stack + 6 )
00454     {
00455       FT_Long  scaling;
00456 
00457 
00458       error = CFF_Err_Ok;
00459 
00460       /* We expect a well-formed font matrix, this is, the matrix elements */
00461       /* `xx' and `yy' are of approximately the same magnitude.  To avoid  */
00462       /* loss of precision, we use the magnitude of element `xx' to scale  */
00463       /* all other elements.  The scaling factor is then contained in the  */
00464       /* `units_per_em' value.                                             */
00465 
00466       matrix->xx = cff_parse_fixed_dynamic( data++, &scaling );
00467 
00468       scaling = -scaling;
00469 
00470       if ( scaling < 0 || scaling > 9 )
00471       {
00472         /* Return default matrix in case of unlikely values. */
00473         matrix->xx = 0x10000L;
00474         matrix->yx = 0;
00475         matrix->yx = 0;
00476         matrix->yy = 0x10000L;
00477         offset->x  = 0;
00478         offset->y  = 0;
00479         *upm       = 1;
00480 
00481         goto Exit;
00482       }
00483 
00484       matrix->yx = cff_parse_fixed_scaled( data++, scaling );
00485       matrix->xy = cff_parse_fixed_scaled( data++, scaling );
00486       matrix->yy = cff_parse_fixed_scaled( data++, scaling );
00487       offset->x  = cff_parse_fixed_scaled( data++, scaling );
00488       offset->y  = cff_parse_fixed_scaled( data,   scaling );
00489 
00490       *upm = power_tens[scaling];
00491     }
00492 
00493   Exit:
00494     return error;
00495   }
00496 
00497 
00498   static FT_Error
00499   cff_parse_font_bbox( CFF_Parser  parser )
00500   {
00501     CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
00502     FT_BBox*         bbox = &dict->font_bbox;
00503     FT_Byte**        data = parser->stack;
00504     FT_Error         error;
00505 
00506 
00507     error = CFF_Err_Stack_Underflow;
00508 
00509     if ( parser->top >= parser->stack + 4 )
00510     {
00511       bbox->xMin = FT_RoundFix( cff_parse_fixed( data++ ) );
00512       bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) );
00513       bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) );
00514       bbox->yMax = FT_RoundFix( cff_parse_fixed( data   ) );
00515       error = CFF_Err_Ok;
00516     }
00517 
00518     return error;
00519   }
00520 
00521 
00522   static FT_Error
00523   cff_parse_private_dict( CFF_Parser  parser )
00524   {
00525     CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
00526     FT_Byte**        data = parser->stack;
00527     FT_Error         error;
00528 
00529 
00530     error = CFF_Err_Stack_Underflow;
00531 
00532     if ( parser->top >= parser->stack + 2 )
00533     {
00534       dict->private_size   = cff_parse_num( data++ );
00535       dict->private_offset = cff_parse_num( data   );
00536       error = CFF_Err_Ok;
00537     }
00538 
00539     return error;
00540   }
00541 
00542 
00543   static FT_Error
00544   cff_parse_cid_ros( CFF_Parser  parser )
00545   {
00546     CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
00547     FT_Byte**        data = parser->stack;
00548     FT_Error         error;
00549 
00550 
00551     error = CFF_Err_Stack_Underflow;
00552 
00553     if ( parser->top >= parser->stack + 3 )
00554     {
00555       dict->cid_registry   = (FT_UInt)cff_parse_num ( data++ );
00556       dict->cid_ordering   = (FT_UInt)cff_parse_num ( data++ );
00557       if ( **data == 30 )
00558         FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" ));
00559       dict->cid_supplement = cff_parse_num( data );
00560       if ( dict->cid_supplement < 0 )
00561         FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n",
00562                    dict->cid_supplement ));
00563       error = CFF_Err_Ok;
00564     }
00565 
00566     return error;
00567   }
00568 
00569 
00570 #define CFF_FIELD_NUM( code, name ) \
00571           CFF_FIELD( code, name, cff_kind_num )
00572 #define CFF_FIELD_FIXED( code, name ) \
00573           CFF_FIELD( code, name, cff_kind_fixed )
00574 #define CFF_FIELD_FIXED_1000( code, name ) \
00575           CFF_FIELD( code, name, cff_kind_fixed_thousand )
00576 #define CFF_FIELD_STRING( code, name ) \
00577           CFF_FIELD( code, name, cff_kind_string )
00578 #define CFF_FIELD_BOOL( code, name ) \
00579           CFF_FIELD( code, name, cff_kind_bool )
00580 #define CFF_FIELD_DELTA( code, name, max ) \
00581           CFF_FIELD( code, name, cff_kind_delta )
00582 
00583 #define CFFCODE_TOPDICT  0x1000
00584 #define CFFCODE_PRIVATE  0x2000
00585 
00586 #ifndef FT_CONFIG_OPTION_PIC
00587 
00588 #define CFF_FIELD_CALLBACK( code, name ) \
00589           {                              \
00590             cff_kind_callback,           \
00591             code | CFFCODE,              \
00592             0, 0,                        \
00593             cff_parse_ ## name,          \
00594             0, 0                         \
00595           },
00596 
00597 #undef  CFF_FIELD
00598 #define CFF_FIELD( code, name, kind ) \
00599           {                          \
00600             kind,                    \
00601             code | CFFCODE,          \
00602             FT_FIELD_OFFSET( name ), \
00603             FT_FIELD_SIZE( name ),   \
00604             0, 0, 0                  \
00605           },
00606 
00607 #undef  CFF_FIELD_DELTA
00608 #define CFF_FIELD_DELTA( code, name, max ) \
00609         {                                  \
00610           cff_kind_delta,                  \
00611           code | CFFCODE,                  \
00612           FT_FIELD_OFFSET( name ),         \
00613           FT_FIELD_SIZE_DELTA( name ),     \
00614           0,                               \
00615           max,                             \
00616           FT_FIELD_OFFSET( num_ ## name )  \
00617         },
00618 
00619   static const CFF_Field_Handler  cff_field_handlers[] =
00620   {
00621 
00622 #include "cfftoken.h"
00623 
00624     { 0, 0, 0, 0, 0, 0, 0 }
00625   };
00626 
00627 
00628 #else /* FT_CONFIG_OPTION_PIC */
00629 
00630   void FT_Destroy_Class_cff_field_handlers(FT_Library library, CFF_Field_Handler* clazz)
00631   {
00632     FT_Memory memory = library->memory;
00633     if ( clazz )
00634       FT_FREE( clazz );
00635   }
00636 
00637   FT_Error FT_Create_Class_cff_field_handlers(FT_Library library, CFF_Field_Handler** output_class)
00638   {
00639     CFF_Field_Handler*  clazz;
00640     FT_Error          error;
00641     FT_Memory memory = library->memory;
00642     int i=0;
00643 
00644 #undef CFF_FIELD
00645 #undef CFF_FIELD_DELTA
00646 #undef CFF_FIELD_CALLBACK
00647 #define CFF_FIELD_CALLBACK( code, name ) i++;
00648 #define CFF_FIELD( code, name, kind ) i++;
00649 #define CFF_FIELD_DELTA( code, name, max ) i++;
00650 
00651 #include "cfftoken.h"
00652     i++;/*{ 0, 0, 0, 0, 0, 0, 0 }*/
00653 
00654     if ( FT_ALLOC( clazz, sizeof(CFF_Field_Handler)*i ) )
00655       return error;
00656 
00657     i=0;
00658 #undef CFF_FIELD
00659 #undef CFF_FIELD_DELTA
00660 #undef CFF_FIELD_CALLBACK
00661 
00662 #define CFF_FIELD_CALLBACK( code_, name_ )                                   \
00663     clazz[i].kind = cff_kind_callback;                                       \
00664     clazz[i].code = code_ | CFFCODE;                                         \
00665     clazz[i].offset = 0;                                                     \
00666     clazz[i].size = 0;                                                       \
00667     clazz[i].reader = cff_parse_ ## name_;                                   \
00668     clazz[i].array_max = 0;                                                  \
00669     clazz[i].count_offset = 0;                                               \
00670     i++;
00671 
00672 #undef  CFF_FIELD
00673 #define CFF_FIELD( code_, name_, kind_ )                                     \
00674     clazz[i].kind = kind_;                                                   \
00675     clazz[i].code = code_ | CFFCODE;                                         \
00676     clazz[i].offset = FT_FIELD_OFFSET( name_ );                              \
00677     clazz[i].size = FT_FIELD_SIZE( name_ );                                  \
00678     clazz[i].reader = 0;                                                     \
00679     clazz[i].array_max = 0;                                                  \
00680     clazz[i].count_offset = 0;                                               \
00681     i++;                                                                     \
00682 
00683 #undef  CFF_FIELD_DELTA
00684 #define CFF_FIELD_DELTA( code_, name_, max_ )                                \
00685     clazz[i].kind = cff_kind_delta;                                          \
00686     clazz[i].code = code_ | CFFCODE;                                         \
00687     clazz[i].offset = FT_FIELD_OFFSET( name_ );                              \
00688     clazz[i].size = FT_FIELD_SIZE_DELTA( name_ );                            \
00689     clazz[i].reader = 0;                                                     \
00690     clazz[i].array_max = max_;                                               \
00691     clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ );                \
00692     i++;
00693 
00694 #include "cfftoken.h"
00695 
00696     clazz[i].kind = 0;
00697     clazz[i].code = 0;
00698     clazz[i].offset = 0;
00699     clazz[i].size = 0;
00700     clazz[i].reader = 0;
00701     clazz[i].array_max = 0;
00702     clazz[i].count_offset = 0;
00703 
00704     *output_class = clazz;
00705     return FT_Err_Ok;
00706   }
00707 
00708 
00709 #endif /* FT_CONFIG_OPTION_PIC */
00710 
00711 
00712   FT_LOCAL_DEF( FT_Error )
00713   cff_parser_run( CFF_Parser  parser,
00714                   FT_Byte*    start,
00715                   FT_Byte*    limit )
00716   {
00717     FT_Byte*    p       = start;
00718     FT_Error    error   = CFF_Err_Ok;
00719     FT_Library  library = parser->library;
00720     FT_UNUSED(library);
00721 
00722 
00723     parser->top    = parser->stack;
00724     parser->start  = start;
00725     parser->limit  = limit;
00726     parser->cursor = start;
00727 
00728     while ( p < limit )
00729     {
00730       FT_UInt  v = *p;
00731 
00732 
00733       if ( v >= 27 && v != 31 )
00734       {
00735         /* it's a number; we will push its position on the stack */
00736         if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )
00737           goto Stack_Overflow;
00738 
00739         *parser->top ++ = p;
00740 
00741         /* now, skip it */
00742         if ( v == 30 )
00743         {
00744           /* skip real number */
00745           p++;
00746           for (;;)
00747           {
00748             /* An unterminated floating point number at the */
00749             /* end of a dictionary is invalid but harmless. */
00750             if ( p >= limit )
00751               goto Exit;
00752             v = p[0] >> 4;
00753             if ( v == 15 )
00754               break;
00755             v = p[0] & 0xF;
00756             if ( v == 15 )
00757               break;
00758             p++;
00759           }
00760         }
00761         else if ( v == 28 )
00762           p += 2;
00763         else if ( v == 29 )
00764           p += 4;
00765         else if ( v > 246 )
00766           p += 1;
00767       }
00768       else
00769       {
00770         /* This is not a number, hence it's an operator.  Compute its code */
00771         /* and look for it in our current list.                            */
00772 
00773         FT_UInt                   code;
00774         FT_UInt                   num_args = (FT_UInt)
00775                                              ( parser->top - parser->stack );
00776         const CFF_Field_Handler*  field;
00777 
00778 
00779         *parser->top = p;
00780         code = v;
00781         if ( v == 12 )
00782         {
00783           /* two byte operator */
00784           p++;
00785           if ( p >= limit )
00786             goto Syntax_Error;
00787 
00788           code = 0x100 | p[0];
00789         }
00790         code = code | parser->object_code;
00791 
00792         for ( field = FT_CFF_FIELD_HANDLERS_GET; field->kind; field++ )
00793         {
00794           if ( field->code == (FT_Int)code )
00795           {
00796             /* we found our field's handler; read it */
00797             FT_Long   val;
00798             FT_Byte*  q = (FT_Byte*)parser->object + field->offset;
00799 
00800 
00801             /* check that we have enough arguments -- except for */
00802             /* delta encoded arrays, which can be empty          */
00803             if ( field->kind != cff_kind_delta && num_args < 1 )
00804               goto Stack_Underflow;
00805 
00806             switch ( field->kind )
00807             {
00808             case cff_kind_bool:
00809             case cff_kind_string:
00810             case cff_kind_num:
00811               val = cff_parse_num( parser->stack );
00812               goto Store_Number;
00813 
00814             case cff_kind_fixed:
00815               val = cff_parse_fixed( parser->stack );
00816               goto Store_Number;
00817 
00818             case cff_kind_fixed_thousand:
00819               val = cff_parse_fixed_scaled( parser->stack, 3 );
00820 
00821             Store_Number:
00822               switch ( field->size )
00823               {
00824               case (8 / FT_CHAR_BIT):
00825                 *(FT_Byte*)q = (FT_Byte)val;
00826                 break;
00827 
00828               case (16 / FT_CHAR_BIT):
00829                 *(FT_Short*)q = (FT_Short)val;
00830                 break;
00831 
00832               case (32 / FT_CHAR_BIT):
00833                 *(FT_Int32*)q = (FT_Int)val;
00834                 break;
00835 
00836               default:  /* for 64-bit systems */
00837                 *(FT_Long*)q = val;
00838               }
00839               break;
00840 
00841             case cff_kind_delta:
00842               {
00843                 FT_Byte*   qcount = (FT_Byte*)parser->object +
00844                                       field->count_offset;
00845 
00846                 FT_Byte**  data = parser->stack;
00847 
00848 
00849                 if ( num_args > field->array_max )
00850                   num_args = field->array_max;
00851 
00852                 /* store count */
00853                 *qcount = (FT_Byte)num_args;
00854 
00855                 val = 0;
00856                 while ( num_args > 0 )
00857                 {
00858                   val += cff_parse_num( data++ );
00859                   switch ( field->size )
00860                   {
00861                   case (8 / FT_CHAR_BIT):
00862                     *(FT_Byte*)q = (FT_Byte)val;
00863                     break;
00864 
00865                   case (16 / FT_CHAR_BIT):
00866                     *(FT_Short*)q = (FT_Short)val;
00867                     break;
00868 
00869                   case (32 / FT_CHAR_BIT):
00870                     *(FT_Int32*)q = (FT_Int)val;
00871                     break;
00872 
00873                   default:  /* for 64-bit systems */
00874                     *(FT_Long*)q = val;
00875                   }
00876 
00877                   q += field->size;
00878                   num_args--;
00879                 }
00880               }
00881               break;
00882 
00883             default:  /* callback */
00884               error = field->reader( parser );
00885               if ( error )
00886                 goto Exit;
00887             }
00888             goto Found;
00889           }
00890         }
00891 
00892         /* this is an unknown operator, or it is unsupported; */
00893         /* we will ignore it for now.                         */
00894 
00895       Found:
00896         /* clear stack */
00897         parser->top = parser->stack;
00898       }
00899       p++;
00900     }
00901 
00902   Exit:
00903     return error;
00904 
00905   Stack_Overflow:
00906     error = CFF_Err_Invalid_Argument;
00907     goto Exit;
00908 
00909   Stack_Underflow:
00910     error = CFF_Err_Invalid_Argument;
00911     goto Exit;
00912 
00913   Syntax_Error:
00914     error = CFF_Err_Invalid_Argument;
00915     goto Exit;
00916   }
00917 
00918 
00919 /* END */

Generated on Tue Jul 5 14:13:46 2011 for ROOT_528-00b_version by  doxygen 1.5.1