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