PageRenderTime 67ms CodeModel.GetById 36ms app.highlight 25ms RepoModel.GetById 2ms app.codeStats 0ms

/src/freetype/src/psaux/psconv.c

https://bitbucket.org/cabalistic/ogredeps/
C | 480 lines | 329 code | 122 blank | 29 comment | 80 complexity | 33e82531950fbcba12e608e6b8d00297 MD5 | raw file
  1/***************************************************************************/
  2/*                                                                         */
  3/*  psconv.c                                                               */
  4/*                                                                         */
  5/*    Some convenience conversions (body).                                 */
  6/*                                                                         */
  7/*  Copyright 2006, 2008, 2009, 2012 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
351    if ( p >= limit )
352      return 0;
353
354    if ( n > (FT_UInt)( limit - p ) )
355      n = (FT_UInt)( limit - p );
356
357    /* we try to process two nibbles at a time to be as fast as possible */
358    for ( ; r < n; r++ )
359    {
360      FT_UInt  c = p[r];
361
362
363      if ( IS_PS_SPACE( c ) )
364        continue;
365
366      if ( c OP 0x80 )
367        break;
368
369      c = ft_char_table[c & 0x7F];
370      if ( (unsigned)c >= 16 )
371        break;
372
373      pad = ( pad << 4 ) | c;
374      if ( pad & 0x100 )
375      {
376        buffer[w++] = (FT_Byte)pad;
377        pad         = 0x01;
378      }
379    }
380
381    if ( pad != 0x01 )
382      buffer[w++] = (FT_Byte)( pad << 4 );
383
384    *cursor = p + r;
385
386    return w;
387
388#else /* 0 */
389
390    for ( r = 0; r < n; r++ )
391    {
392      FT_Char  c;
393
394
395      if ( IS_PS_SPACE( *p ) )
396        continue;
397
398      if ( *p OP 0x80 )
399        break;
400
401      c = ft_char_table[*p & 0x7f];
402
403      if ( (unsigned)c >= 16 )
404        break;
405
406      if ( r & 1 )
407      {
408        *buffer = (FT_Byte)(*buffer + c);
409        buffer++;
410      }
411      else
412        *buffer = (FT_Byte)(c << 4);
413
414      r++;
415    }
416
417    *cursor = p;
418
419    return ( r + 1 ) / 2;
420
421#endif /* 0 */
422
423  }
424
425
426  FT_LOCAL_DEF( FT_UInt )
427  PS_Conv_EexecDecode( FT_Byte**   cursor,
428                       FT_Byte*    limit,
429                       FT_Byte*    buffer,
430                       FT_Offset   n,
431                       FT_UShort*  seed )
432  {
433    FT_Byte*  p;
434    FT_UInt   r;
435    FT_UInt   s = *seed;
436
437
438#if 1
439
440    p = *cursor;
441
442    if ( p >= limit )
443      return 0;
444
445    if ( n > (FT_UInt)(limit - p) )
446      n = (FT_UInt)(limit - p);
447
448    for ( r = 0; r < n; r++ )
449    {
450      FT_UInt  val = p[r];
451      FT_UInt  b   = ( val ^ ( s >> 8 ) );
452
453
454      s         = ( (val + s)*52845U + 22719 ) & 0xFFFFU;
455      buffer[r] = (FT_Byte) b;
456    }
457
458    *cursor = p + n;
459    *seed   = (FT_UShort)s;
460
461#else /* 0 */
462
463    for ( r = 0, p = *cursor; r < n && p < limit; r++, p++ )
464    {
465      FT_Byte  b = (FT_Byte)( *p ^ ( s >> 8 ) );
466
467
468      s = (FT_UShort)( ( *p + s ) * 52845U + 22719 );
469      *buffer++ = b;
470    }
471    *cursor = p;
472    *seed   = s;
473
474#endif /* 0 */
475
476    return r;
477  }
478
479
480/* END */