sync with trunk (r46275)
[reactos.git] / lib / 3rdparty / freetype / src / cff / cffparse.c
1 /***************************************************************************/
2 /* */
3 /* cffparse.c */
4 /* */
5 /* CFF token stream parser (body) */
6 /* */
7 /* Copyright 1996-2001, 2002, 2003, 2004, 2007 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 "cffparse.h"
21 #include FT_INTERNAL_STREAM_H
22
23 #include "cfferrs.h"
24
25
26 /*************************************************************************/
27 /* */
28 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
29 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
30 /* messages during execution. */
31 /* */
32 #undef FT_COMPONENT
33 #define FT_COMPONENT trace_cffparse
34
35
36 enum
37 {
38 cff_kind_none = 0,
39 cff_kind_num,
40 cff_kind_fixed,
41 cff_kind_fixed_thousand,
42 cff_kind_string,
43 cff_kind_bool,
44 cff_kind_delta,
45 cff_kind_callback,
46
47 cff_kind_max /* do not remove */
48 };
49
50
51 /* now generate handlers for the most simple fields */
52 typedef FT_Error (*CFF_Field_Reader)( CFF_Parser parser );
53
54 typedef struct CFF_Field_Handler_
55 {
56 int kind;
57 int code;
58 FT_UInt offset;
59 FT_Byte size;
60 CFF_Field_Reader reader;
61 FT_UInt array_max;
62 FT_UInt count_offset;
63
64 } CFF_Field_Handler;
65
66
67 FT_LOCAL_DEF( void )
68 cff_parser_init( CFF_Parser parser,
69 FT_UInt code,
70 void* object )
71 {
72 FT_MEM_ZERO( parser, sizeof ( *parser ) );
73
74 parser->top = parser->stack;
75 parser->object_code = code;
76 parser->object = object;
77 }
78
79
80 /* read an integer */
81 static FT_Long
82 cff_parse_integer( FT_Byte* start,
83 FT_Byte* limit )
84 {
85 FT_Byte* p = start;
86 FT_Int v = *p++;
87 FT_Long val = 0;
88
89
90 if ( v == 28 )
91 {
92 if ( p + 2 > limit )
93 goto Bad;
94
95 val = (FT_Short)( ( (FT_Int)p[0] << 8 ) | p[1] );
96 p += 2;
97 }
98 else if ( v == 29 )
99 {
100 if ( p + 4 > limit )
101 goto Bad;
102
103 val = ( (FT_Long)p[0] << 24 ) |
104 ( (FT_Long)p[1] << 16 ) |
105 ( (FT_Long)p[2] << 8 ) |
106 p[3];
107 p += 4;
108 }
109 else if ( v < 247 )
110 {
111 val = v - 139;
112 }
113 else if ( v < 251 )
114 {
115 if ( p + 1 > limit )
116 goto Bad;
117
118 val = ( v - 247 ) * 256 + p[0] + 108;
119 p++;
120 }
121 else
122 {
123 if ( p + 1 > limit )
124 goto Bad;
125
126 val = -( v - 251 ) * 256 - p[0] - 108;
127 p++;
128 }
129
130 Exit:
131 return val;
132
133 Bad:
134 val = 0;
135 goto Exit;
136 }
137
138
139 /* read a real */
140 static FT_Fixed
141 cff_parse_real( FT_Byte* start,
142 FT_Byte* limit,
143 FT_Int power_ten )
144 {
145 FT_Byte* p = start;
146 FT_Long num, divider, result, exponent;
147 FT_Int sign = 0, exponent_sign = 0;
148 FT_UInt nib;
149 FT_UInt phase;
150
151
152 result = 0;
153 num = 0;
154 divider = 1;
155
156 /* first of all, read the integer part */
157 phase = 4;
158
159 for (;;)
160 {
161 /* If we entered this iteration with phase == 4, we need to */
162 /* read a new byte. This also skips past the initial 0x1E. */
163 if ( phase )
164 {
165 p++;
166
167 /* Make sure we don't read past the end. */
168 if ( p >= limit )
169 goto Bad;
170 }
171
172 /* Get the nibble. */
173 nib = ( p[0] >> phase ) & 0xF;
174 phase = 4 - phase;
175
176 if ( nib == 0xE )
177 sign = 1;
178 else if ( nib > 9 )
179 break;
180 else
181 result = result * 10 + nib;
182 }
183
184 /* read decimal part, if any */
185 if ( nib == 0xa )
186 for (;;)
187 {
188 /* If we entered this iteration with phase == 4, we need */
189 /* to read a new byte. */
190 if ( phase )
191 {
192 p++;
193
194 /* Make sure we don't read past the end. */
195 if ( p >= limit )
196 goto Bad;
197 }
198
199 /* Get the nibble. */
200 nib = ( p[0] >> phase ) & 0xF;
201 phase = 4 - phase;
202 if ( nib >= 10 )
203 break;
204
205 if ( divider < 10000000L )
206 {
207 num = num * 10 + nib;
208 divider *= 10;
209 }
210 }
211
212 /* read exponent, if any */
213 if ( nib == 12 )
214 {
215 exponent_sign = 1;
216 nib = 11;
217 }
218
219 if ( nib == 11 )
220 {
221 exponent = 0;
222
223 for (;;)
224 {
225 /* If we entered this iteration with phase == 4, we need */
226 /* to read a new byte. */
227 if ( phase )
228 {
229 p++;
230
231 /* Make sure we don't read past the end. */
232 if ( p >= limit )
233 goto Bad;
234 }
235
236 /* Get the nibble. */
237 nib = ( p[0] >> phase ) & 0xF;
238 phase = 4 - phase;
239 if ( nib >= 10 )
240 break;
241
242 exponent = exponent * 10 + nib;
243 }
244
245 if ( exponent_sign )
246 exponent = -exponent;
247
248 power_ten += (FT_Int)exponent;
249 }
250
251 /* raise to power of ten if needed */
252 while ( power_ten > 0 )
253 {
254 result = result * 10;
255 num = num * 10;
256
257 power_ten--;
258 }
259
260 while ( power_ten < 0 )
261 {
262 result = result / 10;
263 divider = divider * 10;
264
265 power_ten++;
266 }
267
268 /* Move the integer part into the high 16 bits. */
269 result <<= 16;
270
271 /* Place the decimal part into the low 16 bits. */
272 if ( num )
273 result |= FT_DivFix( num, divider );
274
275 if ( sign )
276 result = -result;
277
278 Exit:
279 return result;
280
281 Bad:
282 result = 0;
283 goto Exit;
284 }
285
286
287 /* read a number, either integer or real */
288 static FT_Long
289 cff_parse_num( FT_Byte** d )
290 {
291 return ( **d == 30 ? ( cff_parse_real ( d[0], d[1], 0 ) >> 16 )
292 : cff_parse_integer( d[0], d[1] ) );
293 }
294
295
296 /* read a floating point number, either integer or real */
297 static FT_Fixed
298 cff_parse_fixed( FT_Byte** d )
299 {
300 return ( **d == 30 ? cff_parse_real ( d[0], d[1], 0 )
301 : cff_parse_integer( d[0], d[1] ) << 16 );
302 }
303
304 /* read a floating point number, either integer or real, */
305 /* but return 1000 times the number read in. */
306 static FT_Fixed
307 cff_parse_fixed_thousand( FT_Byte** d )
308 {
309 return **d ==
310 30 ? cff_parse_real ( d[0], d[1], 3 )
311 : (FT_Fixed)FT_MulFix( cff_parse_integer( d[0], d[1] ) << 16, 1000 );
312 }
313
314 static FT_Error
315 cff_parse_font_matrix( CFF_Parser parser )
316 {
317 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
318 FT_Matrix* matrix = &dict->font_matrix;
319 FT_Vector* offset = &dict->font_offset;
320 FT_UShort* upm = &dict->units_per_em;
321 FT_Byte** data = parser->stack;
322 FT_Error error;
323 FT_Fixed temp;
324
325
326 error = CFF_Err_Stack_Underflow;
327
328 if ( parser->top >= parser->stack + 6 )
329 {
330 matrix->xx = cff_parse_fixed_thousand( data++ );
331 matrix->yx = cff_parse_fixed_thousand( data++ );
332 matrix->xy = cff_parse_fixed_thousand( data++ );
333 matrix->yy = cff_parse_fixed_thousand( data++ );
334 offset->x = cff_parse_fixed_thousand( data++ );
335 offset->y = cff_parse_fixed_thousand( data );
336
337 temp = FT_ABS( matrix->yy );
338
339 *upm = (FT_UShort)FT_DivFix( 0x10000L, FT_DivFix( temp, 1000 ) );
340
341 if ( temp != 0x10000L )
342 {
343 matrix->xx = FT_DivFix( matrix->xx, temp );
344 matrix->yx = FT_DivFix( matrix->yx, temp );
345 matrix->xy = FT_DivFix( matrix->xy, temp );
346 matrix->yy = FT_DivFix( matrix->yy, temp );
347 offset->x = FT_DivFix( offset->x, temp );
348 offset->y = FT_DivFix( offset->y, temp );
349 }
350
351 /* note that the offsets must be expressed in integer font units */
352 offset->x >>= 16;
353 offset->y >>= 16;
354
355 error = CFF_Err_Ok;
356 }
357
358 return error;
359 }
360
361
362 static FT_Error
363 cff_parse_font_bbox( CFF_Parser parser )
364 {
365 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
366 FT_BBox* bbox = &dict->font_bbox;
367 FT_Byte** data = parser->stack;
368 FT_Error error;
369
370
371 error = CFF_Err_Stack_Underflow;
372
373 if ( parser->top >= parser->stack + 4 )
374 {
375 bbox->xMin = FT_RoundFix( cff_parse_fixed( data++ ) );
376 bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) );
377 bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) );
378 bbox->yMax = FT_RoundFix( cff_parse_fixed( data ) );
379 error = CFF_Err_Ok;
380 }
381
382 return error;
383 }
384
385
386 static FT_Error
387 cff_parse_private_dict( CFF_Parser parser )
388 {
389 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
390 FT_Byte** data = parser->stack;
391 FT_Error error;
392
393
394 error = CFF_Err_Stack_Underflow;
395
396 if ( parser->top >= parser->stack + 2 )
397 {
398 dict->private_size = cff_parse_num( data++ );
399 dict->private_offset = cff_parse_num( data );
400 error = CFF_Err_Ok;
401 }
402
403 return error;
404 }
405
406
407 static FT_Error
408 cff_parse_cid_ros( CFF_Parser parser )
409 {
410 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
411 FT_Byte** data = parser->stack;
412 FT_Error error;
413
414
415 error = CFF_Err_Stack_Underflow;
416
417 if ( parser->top >= parser->stack + 3 )
418 {
419 dict->cid_registry = (FT_UInt)cff_parse_num ( data++ );
420 dict->cid_ordering = (FT_UInt)cff_parse_num ( data++ );
421 dict->cid_supplement = (FT_ULong)cff_parse_num( data );
422 error = CFF_Err_Ok;
423 }
424
425 return error;
426 }
427
428
429 #define CFF_FIELD_NUM( code, name ) \
430 CFF_FIELD( code, name, cff_kind_num )
431 #define CFF_FIELD_FIXED( code, name ) \
432 CFF_FIELD( code, name, cff_kind_fixed )
433 #define CFF_FIELD_FIXED_1000( code, name ) \
434 CFF_FIELD( code, name, cff_kind_fixed_thousand )
435 #define CFF_FIELD_STRING( code, name ) \
436 CFF_FIELD( code, name, cff_kind_string )
437 #define CFF_FIELD_BOOL( code, name ) \
438 CFF_FIELD( code, name, cff_kind_bool )
439 #define CFF_FIELD_DELTA( code, name, max ) \
440 CFF_FIELD( code, name, cff_kind_delta )
441
442 #define CFF_FIELD_CALLBACK( code, name ) \
443 { \
444 cff_kind_callback, \
445 code | CFFCODE, \
446 0, 0, \
447 cff_parse_ ## name, \
448 0, 0 \
449 },
450
451 #undef CFF_FIELD
452 #define CFF_FIELD( code, name, kind ) \
453 { \
454 kind, \
455 code | CFFCODE, \
456 FT_FIELD_OFFSET( name ), \
457 FT_FIELD_SIZE( name ), \
458 0, 0, 0 \
459 },
460
461 #undef CFF_FIELD_DELTA
462 #define CFF_FIELD_DELTA( code, name, max ) \
463 { \
464 cff_kind_delta, \
465 code | CFFCODE, \
466 FT_FIELD_OFFSET( name ), \
467 FT_FIELD_SIZE_DELTA( name ), \
468 0, \
469 max, \
470 FT_FIELD_OFFSET( num_ ## name ) \
471 },
472
473 #define CFFCODE_TOPDICT 0x1000
474 #define CFFCODE_PRIVATE 0x2000
475
476 static const CFF_Field_Handler cff_field_handlers[] =
477 {
478
479 #include "cfftoken.h"
480
481 { 0, 0, 0, 0, 0, 0, 0 }
482 };
483
484
485 FT_LOCAL_DEF( FT_Error )
486 cff_parser_run( CFF_Parser parser,
487 FT_Byte* start,
488 FT_Byte* limit )
489 {
490 FT_Byte* p = start;
491 FT_Error error = CFF_Err_Ok;
492
493
494 parser->top = parser->stack;
495 parser->start = start;
496 parser->limit = limit;
497 parser->cursor = start;
498
499 while ( p < limit )
500 {
501 FT_UInt v = *p;
502
503
504 if ( v >= 27 && v != 31 )
505 {
506 /* it's a number; we will push its position on the stack */
507 if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )
508 goto Stack_Overflow;
509
510 *parser->top ++ = p;
511
512 /* now, skip it */
513 if ( v == 30 )
514 {
515 /* skip real number */
516 p++;
517 for (;;)
518 {
519 if ( p >= limit )
520 goto Syntax_Error;
521 v = p[0] >> 4;
522 if ( v == 15 )
523 break;
524 v = p[0] & 0xF;
525 if ( v == 15 )
526 break;
527 p++;
528 }
529 }
530 else if ( v == 28 )
531 p += 2;
532 else if ( v == 29 )
533 p += 4;
534 else if ( v > 246 )
535 p += 1;
536 }
537 else
538 {
539 /* This is not a number, hence it's an operator. Compute its code */
540 /* and look for it in our current list. */
541
542 FT_UInt code;
543 FT_UInt num_args = (FT_UInt)
544 ( parser->top - parser->stack );
545 const CFF_Field_Handler* field;
546
547
548 *parser->top = p;
549 code = v;
550 if ( v == 12 )
551 {
552 /* two byte operator */
553 p++;
554 if ( p >= limit )
555 goto Syntax_Error;
556
557 code = 0x100 | p[0];
558 }
559 code = code | parser->object_code;
560
561 for ( field = cff_field_handlers; field->kind; field++ )
562 {
563 if ( field->code == (FT_Int)code )
564 {
565 /* we found our field's handler; read it */
566 FT_Long val;
567 FT_Byte* q = (FT_Byte*)parser->object + field->offset;
568
569
570 /* check that we have enough arguments -- except for */
571 /* delta encoded arrays, which can be empty */
572 if ( field->kind != cff_kind_delta && num_args < 1 )
573 goto Stack_Underflow;
574
575 switch ( field->kind )
576 {
577 case cff_kind_bool:
578 case cff_kind_string:
579 case cff_kind_num:
580 val = cff_parse_num( parser->stack );
581 goto Store_Number;
582
583 case cff_kind_fixed:
584 val = cff_parse_fixed( parser->stack );
585 goto Store_Number;
586
587 case cff_kind_fixed_thousand:
588 val = cff_parse_fixed_thousand( parser->stack );
589
590 Store_Number:
591 switch ( field->size )
592 {
593 case (8 / FT_CHAR_BIT):
594 *(FT_Byte*)q = (FT_Byte)val;
595 break;
596
597 case (16 / FT_CHAR_BIT):
598 *(FT_Short*)q = (FT_Short)val;
599 break;
600
601 case (32 / FT_CHAR_BIT):
602 *(FT_Int32*)q = (FT_Int)val;
603 break;
604
605 default: /* for 64-bit systems */
606 *(FT_Long*)q = val;
607 }
608 break;
609
610 case cff_kind_delta:
611 {
612 FT_Byte* qcount = (FT_Byte*)parser->object +
613 field->count_offset;
614
615 FT_Byte** data = parser->stack;
616
617
618 if ( num_args > field->array_max )
619 num_args = field->array_max;
620
621 /* store count */
622 *qcount = (FT_Byte)num_args;
623
624 val = 0;
625 while ( num_args > 0 )
626 {
627 val += cff_parse_num( data++ );
628 switch ( field->size )
629 {
630 case (8 / FT_CHAR_BIT):
631 *(FT_Byte*)q = (FT_Byte)val;
632 break;
633
634 case (16 / FT_CHAR_BIT):
635 *(FT_Short*)q = (FT_Short)val;
636 break;
637
638 case (32 / FT_CHAR_BIT):
639 *(FT_Int32*)q = (FT_Int)val;
640 break;
641
642 default: /* for 64-bit systems */
643 *(FT_Long*)q = val;
644 }
645
646 q += field->size;
647 num_args--;
648 }
649 }
650 break;
651
652 default: /* callback */
653 error = field->reader( parser );
654 if ( error )
655 goto Exit;
656 }
657 goto Found;
658 }
659 }
660
661 /* this is an unknown operator, or it is unsupported; */
662 /* we will ignore it for now. */
663
664 Found:
665 /* clear stack */
666 parser->top = parser->stack;
667 }
668 p++;
669 }
670
671 Exit:
672 return error;
673
674 Stack_Overflow:
675 error = CFF_Err_Invalid_Argument;
676 goto Exit;
677
678 Stack_Underflow:
679 error = CFF_Err_Invalid_Argument;
680 goto Exit;
681
682 Syntax_Error:
683 error = CFF_Err_Invalid_Argument;
684 goto Exit;
685 }
686
687
688 /* END */