psconv.c

Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  psconv.c                                                               */
00004 /*                                                                         */
00005 /*    Some convenience conversions (body).                                 */
00006 /*                                                                         */
00007 /*  Copyright 2006, 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 FT_INTERNAL_POSTSCRIPT_AUX_H
00021 
00022 #include "psconv.h"
00023 #include "psauxerr.h"
00024 
00025 
00026   /* The following array is used by various functions to quickly convert */
00027   /* digits (both decimal and non-decimal) into numbers.                 */
00028 
00029 #if 'A' == 65
00030   /* ASCII */
00031 
00032   static const FT_Char  ft_char_table[128] =
00033   {
00034     /* 0x00 */
00035     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00036     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00037     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00038      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,
00039     -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
00040     25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
00041     -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
00042     25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
00043   };
00044 
00045   /* no character >= 0x80 can represent a valid number */
00046 #define OP  >=
00047 
00048 #endif /* 'A' == 65 */
00049 
00050 #if 'A' == 193
00051   /* EBCDIC */
00052 
00053   static const FT_Char  ft_char_table[128] =
00054   {
00055     /* 0x80 */
00056     -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1,
00057     -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1,
00058     -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1,
00059     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00060     -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1,
00061     -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1,
00062     -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1,
00063      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,
00064   };
00065 
00066   /* no character < 0x80 can represent a valid number */
00067 #define OP  <
00068 
00069 #endif /* 'A' == 193 */
00070 
00071 
00072   FT_LOCAL_DEF( FT_Int )
00073   PS_Conv_Strtol( FT_Byte**  cursor,
00074                   FT_Byte*   limit,
00075                   FT_Int     base )
00076   {
00077     FT_Byte*  p = *cursor;
00078     FT_Int    num = 0;
00079     FT_Bool   sign = 0;
00080 
00081 
00082     if ( p == limit || base < 2 || base > 36 )
00083       return 0;
00084 
00085     if ( *p == '-' || *p == '+' )
00086     {
00087       sign = FT_BOOL( *p == '-' );
00088 
00089       p++;
00090       if ( p == limit )
00091         return 0;
00092     }
00093 
00094     for ( ; p < limit; p++ )
00095     {
00096       FT_Char  c;
00097 
00098 
00099       if ( IS_PS_SPACE( *p ) || *p OP 0x80 )
00100         break;
00101 
00102       c = ft_char_table[*p & 0x7f];
00103 
00104       if ( c < 0 || c >= base )
00105         break;
00106 
00107       num = num * base + c;
00108     }
00109 
00110     if ( sign )
00111       num = -num;
00112 
00113     *cursor = p;
00114 
00115     return num;
00116   }
00117 
00118 
00119   FT_LOCAL_DEF( FT_Int )
00120   PS_Conv_ToInt( FT_Byte**  cursor,
00121                  FT_Byte*   limit )
00122 
00123   {
00124     FT_Byte*  p;
00125     FT_Int    num;
00126 
00127 
00128     num = PS_Conv_Strtol( cursor, limit, 10 );
00129     p   = *cursor;
00130 
00131     if ( p < limit && *p == '#' )
00132     {
00133       *cursor = p + 1;
00134 
00135       return PS_Conv_Strtol( cursor, limit, num );
00136     }
00137     else
00138       return num;
00139   }
00140 
00141 
00142   FT_LOCAL_DEF( FT_Fixed )
00143   PS_Conv_ToFixed( FT_Byte**  cursor,
00144                    FT_Byte*   limit,
00145                    FT_Int     power_ten )
00146   {
00147     FT_Byte*  p = *cursor;
00148     FT_Fixed  integral;
00149     FT_Long   decimal = 0, divider = 1;
00150     FT_Bool   sign = 0;
00151 
00152 
00153     if ( p == limit )
00154       return 0;
00155 
00156     if ( *p == '-' || *p == '+' )
00157     {
00158       sign = FT_BOOL( *p == '-' );
00159 
00160       p++;
00161       if ( p == limit )
00162         return 0;
00163     }
00164 
00165     if ( *p != '.' )
00166       integral = PS_Conv_ToInt( &p, limit ) << 16;
00167     else
00168       integral = 0;
00169 
00170     /* read the decimal part */
00171     if ( p < limit && *p == '.' )
00172     {
00173       p++;
00174 
00175       for ( ; p < limit; p++ )
00176       {
00177         FT_Char  c;
00178 
00179 
00180         if ( IS_PS_SPACE( *p ) || *p OP 0x80 )
00181           break;
00182 
00183         c = ft_char_table[*p & 0x7f];
00184 
00185         if ( c < 0 || c >= 10 )
00186           break;
00187 
00188         if ( !integral && power_ten > 0 )
00189         {
00190           power_ten--;
00191           decimal = decimal * 10 + c;
00192         }
00193         else
00194         {
00195           if ( divider < 10000000L )
00196           {
00197             decimal = decimal * 10 + c;
00198             divider *= 10;
00199           }
00200         }
00201       }
00202     }
00203 
00204     /* read exponent, if any */
00205     if ( p + 1 < limit && ( *p == 'e' || *p == 'E' ) )
00206     {
00207       p++;
00208       power_ten += PS_Conv_ToInt( &p, limit );
00209     }
00210 
00211     while ( power_ten > 0 )
00212     {
00213       integral *= 10;
00214       decimal  *= 10;
00215       power_ten--;
00216     }
00217 
00218     while ( power_ten < 0 )
00219     {
00220       integral /= 10;
00221       divider  *= 10;
00222       power_ten++;
00223     }
00224 
00225     if ( decimal )
00226       integral += FT_DivFix( decimal, divider );
00227 
00228     if ( sign )
00229       integral = -integral;
00230 
00231     *cursor = p;
00232 
00233     return integral;
00234   }
00235 
00236 
00237 #if 0
00238   FT_LOCAL_DEF( FT_UInt )
00239   PS_Conv_StringDecode( FT_Byte**  cursor,
00240                         FT_Byte*   limit,
00241                         FT_Byte*   buffer,
00242                         FT_Offset  n )
00243   {
00244     FT_Byte*  p;
00245     FT_UInt   r = 0;
00246 
00247 
00248     for ( p = *cursor; r < n && p < limit; p++ )
00249     {
00250       FT_Byte  b;
00251 
00252 
00253       if ( *p != '\\' )
00254       {
00255         buffer[r++] = *p;
00256 
00257         continue;
00258       }
00259 
00260       p++;
00261 
00262       switch ( *p )
00263       {
00264       case 'n':
00265         b = '\n';
00266         break;
00267       case 'r':
00268         b = '\r';
00269         break;
00270       case 't':
00271         b = '\t';
00272         break;
00273       case 'b':
00274         b = '\b';
00275         break;
00276       case 'f':
00277         b = '\f';
00278         break;
00279       case '\r':
00280         p++;
00281         if ( *p != '\n' )
00282         {
00283           b = *p;
00284 
00285           break;
00286         }
00287         /* no break */
00288       case '\n':
00289         continue;
00290         break;
00291       default:
00292         if ( IS_PS_DIGIT( *p ) )
00293         {
00294           b = *p - '0';
00295 
00296           p++;
00297 
00298           if ( IS_PS_DIGIT( *p ) )
00299           {
00300             b = b * 8 + *p - '0';
00301 
00302             p++;
00303 
00304             if ( IS_PS_DIGIT( *p ) )
00305               b = b * 8 + *p - '0';
00306             else
00307             {
00308               buffer[r++] = b;
00309               b = *p;
00310             }
00311           }
00312           else
00313           {
00314             buffer[r++] = b;
00315             b = *p;
00316           }
00317         }
00318         else
00319           b = *p;
00320         break;
00321       }
00322 
00323       buffer[r++] = b;
00324     }
00325 
00326     *cursor = p;
00327 
00328     return r;
00329   }
00330 #endif /* 0 */
00331 
00332 
00333   FT_LOCAL_DEF( FT_UInt )
00334   PS_Conv_ASCIIHexDecode( FT_Byte**  cursor,
00335                           FT_Byte*   limit,
00336                           FT_Byte*   buffer,
00337                           FT_Offset  n )
00338   {
00339     FT_Byte*  p;
00340     FT_UInt   r   = 0;
00341     FT_UInt   w   = 0;
00342     FT_UInt   pad = 0x01;
00343 
00344 
00345     n *= 2;
00346 
00347 #if 1
00348 
00349     p  = *cursor;
00350     if ( n > (FT_UInt)( limit - p ) )
00351       n = (FT_UInt)( limit - p );
00352 
00353     /* we try to process two nibbles at a time to be as fast as possible */
00354     for ( ; r < n; r++ )
00355     {
00356       FT_UInt  c = p[r];
00357 
00358 
00359       if ( IS_PS_SPACE( c ) )
00360         continue;
00361 
00362       if ( c OP 0x80 )
00363         break;
00364 
00365       c = ft_char_table[c & 0x7F];
00366       if ( (unsigned)c >= 16 )
00367         break;
00368 
00369       pad = ( pad << 4 ) | c;
00370       if ( pad & 0x100 )
00371       {
00372         buffer[w++] = (FT_Byte)pad;
00373         pad         = 0x01;
00374       }
00375     }
00376 
00377     if ( pad != 0x01 )
00378       buffer[w++] = (FT_Byte)( pad << 4 );
00379 
00380     *cursor = p + r;
00381 
00382     return w;
00383 
00384 #else /* 0 */
00385 
00386     for ( r = 0; r < n; r++ )
00387     {
00388       FT_Char  c;
00389 
00390 
00391       if ( IS_PS_SPACE( *p ) )
00392         continue;
00393 
00394       if ( *p OP 0x80 )
00395         break;
00396 
00397       c = ft_char_table[*p & 0x7f];
00398 
00399       if ( (unsigned)c >= 16 )
00400         break;
00401 
00402       if ( r & 1 )
00403       {
00404         *buffer = (FT_Byte)(*buffer + c);
00405         buffer++;
00406       }
00407       else
00408         *buffer = (FT_Byte)(c << 4);
00409 
00410       r++;
00411     }
00412 
00413     *cursor = p;
00414 
00415     return ( r + 1 ) / 2;
00416 
00417 #endif /* 0 */
00418 
00419   }
00420 
00421 
00422   FT_LOCAL_DEF( FT_UInt )
00423   PS_Conv_EexecDecode( FT_Byte**   cursor,
00424                        FT_Byte*    limit,
00425                        FT_Byte*    buffer,
00426                        FT_Offset   n,
00427                        FT_UShort*  seed )
00428   {
00429     FT_Byte*  p;
00430     FT_UInt   r;
00431     FT_UInt   s = *seed;
00432 
00433 
00434 #if 1
00435 
00436     p = *cursor;
00437     if ( n > (FT_UInt)(limit - p) )
00438       n = (FT_UInt)(limit - p);
00439 
00440     for ( r = 0; r < n; r++ )
00441     {
00442       FT_UInt  val = p[r];
00443       FT_UInt  b   = ( val ^ ( s >> 8 ) );
00444 
00445 
00446       s         = ( (val + s)*52845U + 22719 ) & 0xFFFFU;
00447       buffer[r] = (FT_Byte) b;
00448     }
00449 
00450     *cursor = p + n;
00451     *seed   = (FT_UShort)s;
00452 
00453 #else /* 0 */
00454 
00455     for ( r = 0, p = *cursor; r < n && p < limit; r++, p++ )
00456     {
00457       FT_Byte  b = (FT_Byte)( *p ^ ( s >> 8 ) );
00458 
00459 
00460       s = (FT_UShort)( ( *p + s ) * 52845U + 22719 );
00461       *buffer++ = b;
00462     }
00463     *cursor = p;
00464     *seed   = s;
00465 
00466 #endif /* 0 */
00467 
00468     return r;
00469   }
00470 
00471 
00472 /* END */

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