Merge 25584, 25588.
[reactos.git] / reactos / dll / 3rdparty / freetype / src / psaux / psconv.c
1 /***************************************************************************/
2 /* */
3 /* psconv.c */
4 /* */
5 /* Some convenience conversions (body). */
6 /* */
7 /* Copyright 2006 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 )
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 )
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 )
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 ( divider < 10000000L )
191 {
192 decimal = decimal * 10 + c;
193 divider *= 10;
194 }
195 }
196 }
197
198 /* read exponent, if any */
199 if ( p + 1 < limit && ( *p == 'e' || *p == 'E' ) )
200 {
201 p++;
202 power_ten += PS_Conv_ToInt( &p, limit );
203 }
204
205 while ( power_ten > 0 )
206 {
207 integral *= 10;
208 decimal *= 10;
209 power_ten--;
210 }
211
212 while ( power_ten < 0 )
213 {
214 integral /= 10;
215 divider *= 10;
216 power_ten++;
217 }
218
219 if ( decimal )
220 integral += FT_DivFix( decimal, divider );
221
222 if ( sign )
223 integral = -integral;
224
225 *cursor = p;
226
227 return integral;
228 }
229
230
231 #if 0
232 FT_LOCAL_DEF( FT_UInt )
233 PS_Conv_StringDecode( FT_Byte** cursor,
234 FT_Byte* limit,
235 FT_Byte* buffer,
236 FT_UInt n )
237 {
238 FT_Byte* p;
239 FT_UInt r = 0;
240
241
242 for ( p = *cursor; r < n && p < limit; p++ )
243 {
244 FT_Byte b;
245
246
247 if ( *p != '\\' )
248 {
249 buffer[r++] = *p;
250
251 continue;
252 }
253
254 p++;
255
256 switch ( *p )
257 {
258 case 'n':
259 b = '\n';
260 break;
261 case 'r':
262 b = '\r';
263 break;
264 case 't':
265 b = '\t';
266 break;
267 case 'b':
268 b = '\b';
269 break;
270 case 'f':
271 b = '\f';
272 break;
273 case '\r':
274 p++;
275 if ( *p != '\n' )
276 {
277 b = *p;
278
279 break;
280 }
281 /* no break */
282 case '\n':
283 continue;
284 break;
285 default:
286 if ( IS_PS_DIGIT( *p ) )
287 {
288 b = *p - '0';
289
290 p++;
291
292 if ( IS_PS_DIGIT( *p ) )
293 {
294 b = b * 8 + *p - '0';
295
296 p++;
297
298 if ( IS_PS_DIGIT( *p ) )
299 b = b * 8 + *p - '0';
300 else
301 {
302 buffer[r++] = b;
303 b = *p;
304 }
305 }
306 else
307 {
308 buffer[r++] = b;
309 b = *p;
310 }
311 }
312 else
313 b = *p;
314 break;
315 }
316
317 buffer[r++] = b;
318 }
319
320 *cursor = p;
321
322 return r;
323 }
324 #endif /* 0 */
325
326
327 FT_LOCAL_DEF( FT_UInt )
328 PS_Conv_ASCIIHexDecode( FT_Byte** cursor,
329 FT_Byte* limit,
330 FT_Byte* buffer,
331 FT_UInt n )
332 {
333 FT_Byte* p;
334 FT_UInt r = 0;
335 FT_UInt w = 0;
336 FT_UInt pad = 0x01;
337
338
339 n *= 2;
340
341 #if 1
342
343 p = *cursor;
344 if ( n > (FT_UInt)( limit - p ) )
345 n = (FT_UInt)( limit - p );
346
347 /* we try to process two nibbles at a time to be as fast as possible */
348 for ( ; r < n; r++ )
349 {
350 FT_UInt c = p[r];
351
352
353 if ( IS_PS_SPACE( c ) )
354 continue;
355
356 if ( c OP 0x80 )
357 break;
358
359 c = ft_char_table[c & 0x7F];
360 if ( (unsigned)c >= 16 )
361 break;
362
363 pad = ( pad << 4 ) | c;
364 if ( pad & 0x100 )
365 {
366 buffer[w++] = (FT_Byte)pad;
367 pad = 0x01;
368 }
369 }
370
371 if ( pad != 0x01 )
372 buffer[w++] = (FT_Byte)( pad << 4 );
373
374 *cursor = p + r;
375
376 return w;
377
378 #else /* 0 */
379
380 for ( r = 0; r < n; r++ )
381 {
382 FT_Char c;
383
384
385 if ( IS_PS_SPACE( *p ) )
386 continue;
387
388 if ( *p OP 0x80 )
389 break;
390
391 c = ft_char_table[*p & 0x7f];
392
393 if ( (unsigned)c >= 16 )
394 break;
395
396 if ( r & 1 )
397 {
398 *buffer = (FT_Byte)(*buffer + c);
399 buffer++;
400 }
401 else
402 *buffer = (FT_Byte)(c << 4);
403
404 r++;
405 }
406
407 *cursor = p;
408
409 return ( r + 1 ) / 2;
410
411 #endif /* 0 */
412
413 }
414
415
416 FT_LOCAL_DEF( FT_UInt )
417 PS_Conv_EexecDecode( FT_Byte** cursor,
418 FT_Byte* limit,
419 FT_Byte* buffer,
420 FT_UInt n,
421 FT_UShort* seed )
422 {
423 FT_Byte* p;
424 FT_UInt r;
425 FT_UInt s = *seed;
426
427
428 #if 1
429
430 p = *cursor;
431 if ( n > (FT_UInt)(limit - p) )
432 n = (FT_UInt)(limit - p);
433
434 for ( r = 0; r < n; r++ )
435 {
436 FT_UInt val = p[r];
437 FT_UInt b = ( val ^ ( s >> 8 ) );
438
439
440 s = ( (val + s)*52845U + 22719 ) & 0xFFFFU;
441 buffer[r] = (FT_Byte) b;
442 }
443
444 *cursor = p + n;
445 *seed = (FT_UShort)s;
446
447 #else /* 0 */
448
449 for ( r = 0, p = *cursor; r < n && p < limit; r++, p++ )
450 {
451 FT_Byte b = (FT_Byte)( *p ^ ( s >> 8 ) );
452
453
454 s = (FT_UShort)( ( *p + s ) * 52845U + 22719 );
455 *buffer++ = b;
456 }
457 *cursor = p;
458 *seed = s;
459
460 #endif /* 0 */
461
462 return r;
463 }
464
465
466 /* END */