• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 )
PS_Conv_Strtol(FT_Byte ** cursor,FT_Byte * limit,FT_Int base)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 )
PS_Conv_ToInt(FT_Byte ** cursor,FT_Byte * limit)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 )
PS_Conv_ToFixed(FT_Byte ** cursor,FT_Byte * limit,FT_Int power_ten)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 )
PS_Conv_ASCIIHexDecode(FT_Byte ** cursor,FT_Byte * limit,FT_Byte * buffer,FT_Offset n)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 )
PS_Conv_EexecDecode(FT_Byte ** cursor,FT_Byte * limit,FT_Byte * buffer,FT_Offset n,FT_UShort * seed)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 */
481