misc/libfreetype/src/psaux/psconv.c
changeset 9372 915436ff64ab
parent 9371 f3840de881bd
child 9373 b769a8e38cbd
equal deleted inserted replaced
9371:f3840de881bd 9372:915436ff64ab
     1 /***************************************************************************/
       
     2 /*                                                                         */
       
     3 /*  psconv.c                                                               */
       
     4 /*                                                                         */
       
     5 /*    Some convenience conversions (body).                                 */
       
     6 /*                                                                         */
       
     7 /*  Copyright 2006, 2008, 2009 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 FT_INTERNAL_POSTSCRIPT_AUX_H
       
    21 
       
    22 #include "psconv.h"
       
    23 #include "psauxerr.h"
       
    24 
       
    25 
       
    26   /* The following array is used by various functions to quickly convert */
       
    27   /* digits (both decimal and non-decimal) into numbers.                 */
       
    28 
       
    29 #if 'A' == 65
       
    30   /* ASCII */
       
    31 
       
    32   static const FT_Char  ft_char_table[128] =
       
    33   {
       
    34     /* 0x00 */
       
    35     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
       
    36     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
       
    37     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
       
    38      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,
       
    39     -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
       
    40     25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
       
    41     -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
       
    42     25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
       
    43   };
       
    44 
       
    45   /* no character >= 0x80 can represent a valid number */
       
    46 #define OP  >=
       
    47 
       
    48 #endif /* 'A' == 65 */
       
    49 
       
    50 #if 'A' == 193
       
    51   /* EBCDIC */
       
    52 
       
    53   static const FT_Char  ft_char_table[128] =
       
    54   {
       
    55     /* 0x80 */
       
    56     -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1,
       
    57     -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1,
       
    58     -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1,
       
    59     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
       
    60     -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1,
       
    61     -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1,
       
    62     -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1,
       
    63      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,
       
    64   };
       
    65 
       
    66   /* no character < 0x80 can represent a valid number */
       
    67 #define OP  <
       
    68 
       
    69 #endif /* 'A' == 193 */
       
    70 
       
    71 
       
    72   FT_LOCAL_DEF( FT_Int )
       
    73   PS_Conv_Strtol( FT_Byte**  cursor,
       
    74                   FT_Byte*   limit,
       
    75                   FT_Int     base )
       
    76   {
       
    77     FT_Byte*  p = *cursor;
       
    78     FT_Int    num = 0;
       
    79     FT_Bool   sign = 0;
       
    80 
       
    81 
       
    82     if ( p == limit || base < 2 || base > 36 )
       
    83       return 0;
       
    84 
       
    85     if ( *p == '-' || *p == '+' )
       
    86     {
       
    87       sign = FT_BOOL( *p == '-' );
       
    88 
       
    89       p++;
       
    90       if ( p == limit )
       
    91         return 0;
       
    92     }
       
    93 
       
    94     for ( ; p < limit; p++ )
       
    95     {
       
    96       FT_Char  c;
       
    97 
       
    98 
       
    99       if ( IS_PS_SPACE( *p ) || *p OP 0x80 )
       
   100         break;
       
   101 
       
   102       c = ft_char_table[*p & 0x7f];
       
   103 
       
   104       if ( c < 0 || c >= base )
       
   105         break;
       
   106 
       
   107       num = num * base + c;
       
   108     }
       
   109 
       
   110     if ( sign )
       
   111       num = -num;
       
   112 
       
   113     *cursor = p;
       
   114 
       
   115     return num;
       
   116   }
       
   117 
       
   118 
       
   119   FT_LOCAL_DEF( FT_Int )
       
   120   PS_Conv_ToInt( FT_Byte**  cursor,
       
   121                  FT_Byte*   limit )
       
   122 
       
   123   {
       
   124     FT_Byte*  p;
       
   125     FT_Int    num;
       
   126 
       
   127 
       
   128     num = PS_Conv_Strtol( cursor, limit, 10 );
       
   129     p   = *cursor;
       
   130 
       
   131     if ( p < limit && *p == '#' )
       
   132     {
       
   133       *cursor = p + 1;
       
   134 
       
   135       return PS_Conv_Strtol( cursor, limit, num );
       
   136     }
       
   137     else
       
   138       return num;
       
   139   }
       
   140 
       
   141 
       
   142   FT_LOCAL_DEF( FT_Fixed )
       
   143   PS_Conv_ToFixed( FT_Byte**  cursor,
       
   144                    FT_Byte*   limit,
       
   145                    FT_Int     power_ten )
       
   146   {
       
   147     FT_Byte*  p = *cursor;
       
   148     FT_Fixed  integral;
       
   149     FT_Long   decimal = 0, divider = 1;
       
   150     FT_Bool   sign = 0;
       
   151 
       
   152 
       
   153     if ( p == limit )
       
   154       return 0;
       
   155 
       
   156     if ( *p == '-' || *p == '+' )
       
   157     {
       
   158       sign = FT_BOOL( *p == '-' );
       
   159 
       
   160       p++;
       
   161       if ( p == limit )
       
   162         return 0;
       
   163     }
       
   164 
       
   165     if ( *p != '.' )
       
   166       integral = PS_Conv_ToInt( &p, limit ) << 16;
       
   167     else
       
   168       integral = 0;
       
   169 
       
   170     /* read the decimal part */
       
   171     if ( p < limit && *p == '.' )
       
   172     {
       
   173       p++;
       
   174 
       
   175       for ( ; p < limit; p++ )
       
   176       {
       
   177         FT_Char  c;
       
   178 
       
   179 
       
   180         if ( IS_PS_SPACE( *p ) || *p OP 0x80 )
       
   181           break;
       
   182 
       
   183         c = ft_char_table[*p & 0x7f];
       
   184 
       
   185         if ( c < 0 || c >= 10 )
       
   186           break;
       
   187 
       
   188         if ( !integral && power_ten > 0 )
       
   189         {
       
   190           power_ten--;
       
   191           decimal = decimal * 10 + c;
       
   192         }
       
   193         else
       
   194         {
       
   195           if ( divider < 10000000L )
       
   196           {
       
   197             decimal = decimal * 10 + c;
       
   198             divider *= 10;
       
   199           }
       
   200         }
       
   201       }
       
   202     }
       
   203 
       
   204     /* read exponent, if any */
       
   205     if ( p + 1 < limit && ( *p == 'e' || *p == 'E' ) )
       
   206     {
       
   207       p++;
       
   208       power_ten += PS_Conv_ToInt( &p, limit );
       
   209     }
       
   210 
       
   211     while ( power_ten > 0 )
       
   212     {
       
   213       integral *= 10;
       
   214       decimal  *= 10;
       
   215       power_ten--;
       
   216     }
       
   217 
       
   218     while ( power_ten < 0 )
       
   219     {
       
   220       integral /= 10;
       
   221       divider  *= 10;
       
   222       power_ten++;
       
   223     }
       
   224 
       
   225     if ( decimal )
       
   226       integral += FT_DivFix( decimal, divider );
       
   227 
       
   228     if ( sign )
       
   229       integral = -integral;
       
   230 
       
   231     *cursor = p;
       
   232 
       
   233     return integral;
       
   234   }
       
   235 
       
   236 
       
   237 #if 0
       
   238   FT_LOCAL_DEF( FT_UInt )
       
   239   PS_Conv_StringDecode( FT_Byte**  cursor,
       
   240                         FT_Byte*   limit,
       
   241                         FT_Byte*   buffer,
       
   242                         FT_Offset  n )
       
   243   {
       
   244     FT_Byte*  p;
       
   245     FT_UInt   r = 0;
       
   246 
       
   247 
       
   248     for ( p = *cursor; r < n && p < limit; p++ )
       
   249     {
       
   250       FT_Byte  b;
       
   251 
       
   252 
       
   253       if ( *p != '\\' )
       
   254       {
       
   255         buffer[r++] = *p;
       
   256 
       
   257         continue;
       
   258       }
       
   259 
       
   260       p++;
       
   261 
       
   262       switch ( *p )
       
   263       {
       
   264       case 'n':
       
   265         b = '\n';
       
   266         break;
       
   267       case 'r':
       
   268         b = '\r';
       
   269         break;
       
   270       case 't':
       
   271         b = '\t';
       
   272         break;
       
   273       case 'b':
       
   274         b = '\b';
       
   275         break;
       
   276       case 'f':
       
   277         b = '\f';
       
   278         break;
       
   279       case '\r':
       
   280         p++;
       
   281         if ( *p != '\n' )
       
   282         {
       
   283           b = *p;
       
   284 
       
   285           break;
       
   286         }
       
   287         /* no break */
       
   288       case '\n':
       
   289         continue;
       
   290         break;
       
   291       default:
       
   292         if ( IS_PS_DIGIT( *p ) )
       
   293         {
       
   294           b = *p - '0';
       
   295 
       
   296           p++;
       
   297 
       
   298           if ( IS_PS_DIGIT( *p ) )
       
   299           {
       
   300             b = b * 8 + *p - '0';
       
   301 
       
   302             p++;
       
   303 
       
   304             if ( IS_PS_DIGIT( *p ) )
       
   305               b = b * 8 + *p - '0';
       
   306             else
       
   307             {
       
   308               buffer[r++] = b;
       
   309               b = *p;
       
   310             }
       
   311           }
       
   312           else
       
   313           {
       
   314             buffer[r++] = b;
       
   315             b = *p;
       
   316           }
       
   317         }
       
   318         else
       
   319           b = *p;
       
   320         break;
       
   321       }
       
   322 
       
   323       buffer[r++] = b;
       
   324     }
       
   325 
       
   326     *cursor = p;
       
   327 
       
   328     return r;
       
   329   }
       
   330 #endif /* 0 */
       
   331 
       
   332 
       
   333   FT_LOCAL_DEF( FT_UInt )
       
   334   PS_Conv_ASCIIHexDecode( FT_Byte**  cursor,
       
   335                           FT_Byte*   limit,
       
   336                           FT_Byte*   buffer,
       
   337                           FT_Offset  n )
       
   338   {
       
   339     FT_Byte*  p;
       
   340     FT_UInt   r   = 0;
       
   341     FT_UInt   w   = 0;
       
   342     FT_UInt   pad = 0x01;
       
   343 
       
   344 
       
   345     n *= 2;
       
   346 
       
   347 #if 1
       
   348 
       
   349     p  = *cursor;
       
   350     if ( n > (FT_UInt)( limit - p ) )
       
   351       n = (FT_UInt)( limit - p );
       
   352 
       
   353     /* we try to process two nibbles at a time to be as fast as possible */
       
   354     for ( ; r < n; r++ )
       
   355     {
       
   356       FT_UInt  c = p[r];
       
   357 
       
   358 
       
   359       if ( IS_PS_SPACE( c ) )
       
   360         continue;
       
   361 
       
   362       if ( c OP 0x80 )
       
   363         break;
       
   364 
       
   365       c = ft_char_table[c & 0x7F];
       
   366       if ( (unsigned)c >= 16 )
       
   367         break;
       
   368 
       
   369       pad = ( pad << 4 ) | c;
       
   370       if ( pad & 0x100 )
       
   371       {
       
   372         buffer[w++] = (FT_Byte)pad;
       
   373         pad         = 0x01;
       
   374       }
       
   375     }
       
   376 
       
   377     if ( pad != 0x01 )
       
   378       buffer[w++] = (FT_Byte)( pad << 4 );
       
   379 
       
   380     *cursor = p + r;
       
   381 
       
   382     return w;
       
   383 
       
   384 #else /* 0 */
       
   385 
       
   386     for ( r = 0; r < n; r++ )
       
   387     {
       
   388       FT_Char  c;
       
   389 
       
   390 
       
   391       if ( IS_PS_SPACE( *p ) )
       
   392         continue;
       
   393 
       
   394       if ( *p OP 0x80 )
       
   395         break;
       
   396 
       
   397       c = ft_char_table[*p & 0x7f];
       
   398 
       
   399       if ( (unsigned)c >= 16 )
       
   400         break;
       
   401 
       
   402       if ( r & 1 )
       
   403       {
       
   404         *buffer = (FT_Byte)(*buffer + c);
       
   405         buffer++;
       
   406       }
       
   407       else
       
   408         *buffer = (FT_Byte)(c << 4);
       
   409 
       
   410       r++;
       
   411     }
       
   412 
       
   413     *cursor = p;
       
   414 
       
   415     return ( r + 1 ) / 2;
       
   416 
       
   417 #endif /* 0 */
       
   418 
       
   419   }
       
   420 
       
   421 
       
   422   FT_LOCAL_DEF( FT_UInt )
       
   423   PS_Conv_EexecDecode( FT_Byte**   cursor,
       
   424                        FT_Byte*    limit,
       
   425                        FT_Byte*    buffer,
       
   426                        FT_Offset   n,
       
   427                        FT_UShort*  seed )
       
   428   {
       
   429     FT_Byte*  p;
       
   430     FT_UInt   r;
       
   431     FT_UInt   s = *seed;
       
   432 
       
   433 
       
   434 #if 1
       
   435 
       
   436     p = *cursor;
       
   437     if ( n > (FT_UInt)(limit - p) )
       
   438       n = (FT_UInt)(limit - p);
       
   439 
       
   440     for ( r = 0; r < n; r++ )
       
   441     {
       
   442       FT_UInt  val = p[r];
       
   443       FT_UInt  b   = ( val ^ ( s >> 8 ) );
       
   444 
       
   445 
       
   446       s         = ( (val + s)*52845U + 22719 ) & 0xFFFFU;
       
   447       buffer[r] = (FT_Byte) b;
       
   448     }
       
   449 
       
   450     *cursor = p + n;
       
   451     *seed   = (FT_UShort)s;
       
   452 
       
   453 #else /* 0 */
       
   454 
       
   455     for ( r = 0, p = *cursor; r < n && p < limit; r++, p++ )
       
   456     {
       
   457       FT_Byte  b = (FT_Byte)( *p ^ ( s >> 8 ) );
       
   458 
       
   459 
       
   460       s = (FT_UShort)( ( *p + s ) * 52845U + 22719 );
       
   461       *buffer++ = b;
       
   462     }
       
   463     *cursor = p;
       
   464     *seed   = s;
       
   465 
       
   466 #endif /* 0 */
       
   467 
       
   468     return r;
       
   469   }
       
   470 
       
   471 
       
   472 /* END */