Add leftover from sync, fixes build.
[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, 2008, 2009 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 #include FT_INTERNAL_DEBUG_H
23
24 #include "cfferrs.h"
25 #include "cffpic.h"
26
27
28 /*************************************************************************/
29 /* */
30 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
31 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
32 /* messages during execution. */
33 /* */
34 #undef FT_COMPONENT
35 #define FT_COMPONENT trace_cffparse
36
37
38
39
40 FT_LOCAL_DEF( void )
41 cff_parser_init( CFF_Parser parser,
42 FT_UInt code,
43 void* object,
44 FT_Library library)
45 {
46 FT_MEM_ZERO( parser, sizeof ( *parser ) );
47
48 parser->top = parser->stack;
49 parser->object_code = code;
50 parser->object = object;
51 parser->library = library;
52 }
53
54
55 /* read an integer */
56 static FT_Long
57 cff_parse_integer( FT_Byte* start,
58 FT_Byte* limit )
59 {
60 FT_Byte* p = start;
61 FT_Int v = *p++;
62 FT_Long val = 0;
63
64
65 if ( v == 28 )
66 {
67 if ( p + 2 > limit )
68 goto Bad;
69
70 val = (FT_Short)( ( (FT_Int)p[0] << 8 ) | p[1] );
71 p += 2;
72 }
73 else if ( v == 29 )
74 {
75 if ( p + 4 > limit )
76 goto Bad;
77
78 val = ( (FT_Long)p[0] << 24 ) |
79 ( (FT_Long)p[1] << 16 ) |
80 ( (FT_Long)p[2] << 8 ) |
81 p[3];
82 p += 4;
83 }
84 else if ( v < 247 )
85 {
86 val = v - 139;
87 }
88 else if ( v < 251 )
89 {
90 if ( p + 1 > limit )
91 goto Bad;
92
93 val = ( v - 247 ) * 256 + p[0] + 108;
94 p++;
95 }
96 else
97 {
98 if ( p + 1 > limit )
99 goto Bad;
100
101 val = -( v - 251 ) * 256 - p[0] - 108;
102 p++;
103 }
104
105 Exit:
106 return val;
107
108 Bad:
109 val = 0;
110 goto Exit;
111 }
112
113
114 static const FT_Long power_tens[] =
115 {
116 1L,
117 10L,
118 100L,
119 1000L,
120 10000L,
121 100000L,
122 1000000L,
123 10000000L,
124 100000000L,
125 1000000000L
126 };
127
128
129 /* read a real */
130 static FT_Fixed
131 cff_parse_real( FT_Byte* start,
132 FT_Byte* limit,
133 FT_Long power_ten,
134 FT_Long* scaling )
135 {
136 FT_Byte* p = start;
137 FT_UInt nib;
138 FT_UInt phase;
139
140 FT_Long result, number, rest, exponent;
141 FT_Int sign = 0, exponent_sign = 0;
142 FT_Long exponent_add, integer_length, fraction_length;
143
144
145 if ( scaling )
146 *scaling = 0;
147
148 result = 0;
149
150 number = 0;
151 rest = 0;
152 exponent = 0;
153
154 exponent_add = 0;
155 integer_length = 0;
156 fraction_length = 0;
157
158 FT_UNUSED( rest );
159
160 /* First of all, read the integer part. */
161 phase = 4;
162
163 for (;;)
164 {
165 /* If we entered this iteration with phase == 4, we need to */
166 /* read a new byte. This also skips past the initial 0x1E. */
167 if ( phase )
168 {
169 p++;
170
171 /* Make sure we don't read past the end. */
172 if ( p >= limit )
173 goto Exit;
174 }
175
176 /* Get the nibble. */
177 nib = ( p[0] >> phase ) & 0xF;
178 phase = 4 - phase;
179
180 if ( nib == 0xE )
181 sign = 1;
182 else if ( nib > 9 )
183 break;
184 else
185 {
186 /* Increase exponent if we can't add the digit. */
187 if ( number >= 0xCCCCCCCL )
188 exponent_add++;
189 /* Skip leading zeros. */
190 else if ( nib || number )
191 {
192 integer_length++;
193 number = number * 10 + nib;
194 }
195 }
196 }
197
198 /* Read fraction part, if any. */
199 if ( nib == 0xa )
200 for (;;)
201 {
202 /* If we entered this iteration with phase == 4, we need */
203 /* to read a new byte. */
204 if ( phase )
205 {
206 p++;
207
208 /* Make sure we don't read past the end. */
209 if ( p >= limit )
210 goto Exit;
211 }
212
213 /* Get the nibble. */
214 nib = ( p[0] >> phase ) & 0xF;
215 phase = 4 - phase;
216 if ( nib >= 10 )
217 break;
218
219 /* Skip leading zeros if possible. */
220 if ( !nib && !number )
221 exponent_add--;
222 /* Only add digit if we don't overflow. */
223 else if ( number < 0xCCCCCCCL && fraction_length < 9 )
224 {
225 fraction_length++;
226 number = number * 10 + nib;
227 }
228 }
229
230 /* Read exponent, if any. */
231 if ( nib == 12 )
232 {
233 exponent_sign = 1;
234 nib = 11;
235 }
236
237 if ( nib == 11 )
238 {
239 for (;;)
240 {
241 /* If we entered this iteration with phase == 4, */
242 /* we need to read a new byte. */
243 if ( phase )
244 {
245 p++;
246
247 /* Make sure we don't read past the end. */
248 if ( p >= limit )
249 goto Exit;
250 }
251
252 /* Get the nibble. */
253 nib = ( p[0] >> phase ) & 0xF;
254 phase = 4 - phase;
255 if ( nib >= 10 )
256 break;
257
258 exponent = exponent * 10 + nib;
259
260 /* Arbitrarily limit exponent. */
261 if ( exponent > 1000 )
262 goto Exit;
263 }
264
265 if ( exponent_sign )
266 exponent = -exponent;
267 }
268
269 /* We don't check `power_ten' and `exponent_add'. */
270 exponent += power_ten + exponent_add;
271
272 if ( scaling )
273 {
274 /* Only use `fraction_length'. */
275 fraction_length += integer_length;
276 exponent += integer_length;
277
278 if ( fraction_length <= 5 )
279 {
280 if ( number > 0x7FFFL )
281 {
282 result = FT_DivFix( number, 10 );
283 *scaling = exponent - fraction_length + 1;
284 }
285 else
286 {
287 if ( exponent > 0 )
288 {
289 FT_Long new_fraction_length, shift;
290
291
292 /* Make `scaling' as small as possible. */
293 new_fraction_length = FT_MIN( exponent, 5 );
294 exponent -= new_fraction_length;
295 shift = new_fraction_length - fraction_length;
296
297 number *= power_tens[shift];
298 if ( number > 0x7FFFL )
299 {
300 number /= 10;
301 exponent += 1;
302 }
303 }
304 else
305 exponent -= fraction_length;
306
307 result = number << 16;
308 *scaling = exponent;
309 }
310 }
311 else
312 {
313 if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL )
314 {
315 result = FT_DivFix( number, power_tens[fraction_length - 4] );
316 *scaling = exponent - 4;
317 }
318 else
319 {
320 result = FT_DivFix( number, power_tens[fraction_length - 5] );
321 *scaling = exponent - 5;
322 }
323 }
324 }
325 else
326 {
327 integer_length += exponent;
328 fraction_length -= exponent;
329
330 /* Check for overflow and underflow. */
331 if ( FT_ABS( integer_length ) > 5 )
332 goto Exit;
333
334 /* Remove non-significant digits. */
335 if ( integer_length < 0 ) {
336 number /= power_tens[-integer_length];
337 fraction_length += integer_length;
338 }
339
340 /* Convert into 16.16 format. */
341 if ( fraction_length > 0 )
342 {
343 if ( ( number / power_tens[fraction_length] ) > 0x7FFFL )
344 goto Exit;
345
346 result = FT_DivFix( number, power_tens[fraction_length] );
347 }
348 else
349 {
350 number *= power_tens[-fraction_length];
351
352 if ( number > 0x7FFFL )
353 goto Exit;
354
355 result = number << 16;
356 }
357 }
358
359 if ( sign )
360 result = -result;
361
362 Exit:
363 return result;
364 }
365
366
367 /* read a number, either integer or real */
368 static FT_Long
369 cff_parse_num( FT_Byte** d )
370 {
371 return **d == 30 ? ( cff_parse_real( d[0], d[1], 0, NULL ) >> 16 )
372 : cff_parse_integer( d[0], d[1] );
373 }
374
375
376 /* read a floating point number, either integer or real */
377 static FT_Fixed
378 cff_parse_fixed( FT_Byte** d )
379 {
380 return **d == 30 ? cff_parse_real( d[0], d[1], 0, NULL )
381 : cff_parse_integer( d[0], d[1] ) << 16;
382 }
383
384
385 /* read a floating point number, either integer or real, */
386 /* but return `10^scaling' times the number read in */
387 static FT_Fixed
388 cff_parse_fixed_scaled( FT_Byte** d,
389 FT_Long scaling )
390 {
391 return **d == 30 ? cff_parse_real( d[0], d[1], scaling, NULL )
392 : ( cff_parse_integer( d[0], d[1] ) *
393 power_tens[scaling] ) << 16;
394 }
395
396
397 /* read a floating point number, either integer or real, */
398 /* and return it as precise as possible -- `scaling' returns */
399 /* the scaling factor (as a power of 10) */
400 static FT_Fixed
401 cff_parse_fixed_dynamic( FT_Byte** d,
402 FT_Long* scaling )
403 {
404 FT_ASSERT( scaling );
405
406 if ( **d == 30 )
407 return cff_parse_real( d[0], d[1], 0, scaling );
408 else
409 {
410 FT_Long number;
411 FT_Int integer_length;
412
413
414 number = cff_parse_integer( d[0], d[1] );
415
416 if ( number > 0x7FFFL )
417 {
418 for ( integer_length = 5; integer_length < 10; integer_length++ )
419 if ( number < power_tens[integer_length] )
420 break;
421
422 if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL )
423 {
424 *scaling = integer_length - 4;
425 return FT_DivFix( number, power_tens[integer_length - 4] );
426 }
427 else
428 {
429 *scaling = integer_length - 5;
430 return FT_DivFix( number, power_tens[integer_length - 5] );
431 }
432 }
433 else
434 {
435 *scaling = 0;
436 return number << 16;
437 }
438 }
439 }
440
441
442 static FT_Error
443 cff_parse_font_matrix( CFF_Parser parser )
444 {
445 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
446 FT_Matrix* matrix = &dict->font_matrix;
447 FT_Vector* offset = &dict->font_offset;
448 FT_ULong* upm = &dict->units_per_em;
449 FT_Byte** data = parser->stack;
450 FT_Error error = CFF_Err_Stack_Underflow;
451
452
453 if ( parser->top >= parser->stack + 6 )
454 {
455 FT_Long scaling;
456
457
458 error = CFF_Err_Ok;
459
460 /* We expect a well-formed font matrix, this is, the matrix elements */
461 /* `xx' and `yy' are of approximately the same magnitude. To avoid */
462 /* loss of precision, we use the magnitude of element `xx' to scale */
463 /* all other elements. The scaling factor is then contained in the */
464 /* `units_per_em' value. */
465
466 matrix->xx = cff_parse_fixed_dynamic( data++, &scaling );
467
468 scaling = -scaling;
469
470 if ( scaling < 0 || scaling > 9 )
471 {
472 /* Return default matrix in case of unlikely values. */
473 matrix->xx = 0x10000L;
474 matrix->yx = 0;
475 matrix->yx = 0;
476 matrix->yy = 0x10000L;
477 offset->x = 0;
478 offset->y = 0;
479 *upm = 1;
480
481 goto Exit;
482 }
483
484 matrix->yx = cff_parse_fixed_scaled( data++, scaling );
485 matrix->xy = cff_parse_fixed_scaled( data++, scaling );
486 matrix->yy = cff_parse_fixed_scaled( data++, scaling );
487 offset->x = cff_parse_fixed_scaled( data++, scaling );
488 offset->y = cff_parse_fixed_scaled( data, scaling );
489
490 *upm = power_tens[scaling];
491 }
492
493 Exit:
494 return error;
495 }
496
497
498 static FT_Error
499 cff_parse_font_bbox( CFF_Parser parser )
500 {
501 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
502 FT_BBox* bbox = &dict->font_bbox;
503 FT_Byte** data = parser->stack;
504 FT_Error error;
505
506
507 error = CFF_Err_Stack_Underflow;
508
509 if ( parser->top >= parser->stack + 4 )
510 {
511 bbox->xMin = FT_RoundFix( cff_parse_fixed( data++ ) );
512 bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) );
513 bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) );
514 bbox->yMax = FT_RoundFix( cff_parse_fixed( data ) );
515 error = CFF_Err_Ok;
516 }
517
518 return error;
519 }
520
521
522 static FT_Error
523 cff_parse_private_dict( CFF_Parser parser )
524 {
525 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
526 FT_Byte** data = parser->stack;
527 FT_Error error;
528
529
530 error = CFF_Err_Stack_Underflow;
531
532 if ( parser->top >= parser->stack + 2 )
533 {
534 dict->private_size = cff_parse_num( data++ );
535 dict->private_offset = cff_parse_num( data );
536 error = CFF_Err_Ok;
537 }
538
539 return error;
540 }
541
542
543 static FT_Error
544 cff_parse_cid_ros( CFF_Parser parser )
545 {
546 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
547 FT_Byte** data = parser->stack;
548 FT_Error error;
549
550
551 error = CFF_Err_Stack_Underflow;
552
553 if ( parser->top >= parser->stack + 3 )
554 {
555 dict->cid_registry = (FT_UInt)cff_parse_num ( data++ );
556 dict->cid_ordering = (FT_UInt)cff_parse_num ( data++ );
557 if ( **data == 30 )
558 FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" ));
559 dict->cid_supplement = cff_parse_num( data );
560 if ( dict->cid_supplement < 0 )
561 FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n",
562 dict->cid_supplement ));
563 error = CFF_Err_Ok;
564 }
565
566 return error;
567 }
568
569
570 #define CFF_FIELD_NUM( code, name ) \
571 CFF_FIELD( code, name, cff_kind_num )
572 #define CFF_FIELD_FIXED( code, name ) \
573 CFF_FIELD( code, name, cff_kind_fixed )
574 #define CFF_FIELD_FIXED_1000( code, name ) \
575 CFF_FIELD( code, name, cff_kind_fixed_thousand )
576 #define CFF_FIELD_STRING( code, name ) \
577 CFF_FIELD( code, name, cff_kind_string )
578 #define CFF_FIELD_BOOL( code, name ) \
579 CFF_FIELD( code, name, cff_kind_bool )
580 #define CFF_FIELD_DELTA( code, name, max ) \
581 CFF_FIELD( code, name, cff_kind_delta )
582
583 #define CFFCODE_TOPDICT 0x1000
584 #define CFFCODE_PRIVATE 0x2000
585
586 #ifndef FT_CONFIG_OPTION_PIC
587
588 #define CFF_FIELD_CALLBACK( code, name ) \
589 { \
590 cff_kind_callback, \
591 code | CFFCODE, \
592 0, 0, \
593 cff_parse_ ## name, \
594 0, 0 \
595 },
596
597 #undef CFF_FIELD
598 #define CFF_FIELD( code, name, kind ) \
599 { \
600 kind, \
601 code | CFFCODE, \
602 FT_FIELD_OFFSET( name ), \
603 FT_FIELD_SIZE( name ), \
604 0, 0, 0 \
605 },
606
607 #undef CFF_FIELD_DELTA
608 #define CFF_FIELD_DELTA( code, name, max ) \
609 { \
610 cff_kind_delta, \
611 code | CFFCODE, \
612 FT_FIELD_OFFSET( name ), \
613 FT_FIELD_SIZE_DELTA( name ), \
614 0, \
615 max, \
616 FT_FIELD_OFFSET( num_ ## name ) \
617 },
618
619 static const CFF_Field_Handler cff_field_handlers[] =
620 {
621
622 #include "cfftoken.h"
623
624 { 0, 0, 0, 0, 0, 0, 0 }
625 };
626
627
628 #else /* FT_CONFIG_OPTION_PIC */
629
630 void FT_Destroy_Class_cff_field_handlers(FT_Library library, CFF_Field_Handler* clazz)
631 {
632 FT_Memory memory = library->memory;
633 if ( clazz )
634 FT_FREE( clazz );
635 }
636
637 FT_Error FT_Create_Class_cff_field_handlers(FT_Library library, CFF_Field_Handler** output_class)
638 {
639 CFF_Field_Handler* clazz;
640 FT_Error error;
641 FT_Memory memory = library->memory;
642 int i=0;
643
644 #undef CFF_FIELD
645 #undef CFF_FIELD_DELTA
646 #undef CFF_FIELD_CALLBACK
647 #define CFF_FIELD_CALLBACK( code, name ) i++;
648 #define CFF_FIELD( code, name, kind ) i++;
649 #define CFF_FIELD_DELTA( code, name, max ) i++;
650
651 #include "cfftoken.h"
652 i++;/*{ 0, 0, 0, 0, 0, 0, 0 }*/
653
654 if ( FT_ALLOC( clazz, sizeof(CFF_Field_Handler)*i ) )
655 return error;
656
657 i=0;
658 #undef CFF_FIELD
659 #undef CFF_FIELD_DELTA
660 #undef CFF_FIELD_CALLBACK
661
662 #define CFF_FIELD_CALLBACK( code_, name_ ) \
663 clazz[i].kind = cff_kind_callback; \
664 clazz[i].code = code_ | CFFCODE; \
665 clazz[i].offset = 0; \
666 clazz[i].size = 0; \
667 clazz[i].reader = cff_parse_ ## name_; \
668 clazz[i].array_max = 0; \
669 clazz[i].count_offset = 0; \
670 i++;
671
672 #undef CFF_FIELD
673 #define CFF_FIELD( code_, name_, kind_ ) \
674 clazz[i].kind = kind_; \
675 clazz[i].code = code_ | CFFCODE; \
676 clazz[i].offset = FT_FIELD_OFFSET( name_ ); \
677 clazz[i].size = FT_FIELD_SIZE( name_ ); \
678 clazz[i].reader = 0; \
679 clazz[i].array_max = 0; \
680 clazz[i].count_offset = 0; \
681 i++; \
682
683 #undef CFF_FIELD_DELTA
684 #define CFF_FIELD_DELTA( code_, name_, max_ ) \
685 clazz[i].kind = cff_kind_delta; \
686 clazz[i].code = code_ | CFFCODE; \
687 clazz[i].offset = FT_FIELD_OFFSET( name_ ); \
688 clazz[i].size = FT_FIELD_SIZE_DELTA( name_ ); \
689 clazz[i].reader = 0; \
690 clazz[i].array_max = max_; \
691 clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \
692 i++;
693
694 #include "cfftoken.h"
695
696 clazz[i].kind = 0;
697 clazz[i].code = 0;
698 clazz[i].offset = 0;
699 clazz[i].size = 0;
700 clazz[i].reader = 0;
701 clazz[i].array_max = 0;
702 clazz[i].count_offset = 0;
703
704 *output_class = clazz;
705 return FT_Err_Ok;
706 }
707
708
709 #endif /* FT_CONFIG_OPTION_PIC */
710
711
712 FT_LOCAL_DEF( FT_Error )
713 cff_parser_run( CFF_Parser parser,
714 FT_Byte* start,
715 FT_Byte* limit )
716 {
717 FT_Byte* p = start;
718 FT_Error error = CFF_Err_Ok;
719 FT_Library library = parser->library;
720 FT_UNUSED(library);
721
722
723 parser->top = parser->stack;
724 parser->start = start;
725 parser->limit = limit;
726 parser->cursor = start;
727
728 while ( p < limit )
729 {
730 FT_UInt v = *p;
731
732
733 if ( v >= 27 && v != 31 )
734 {
735 /* it's a number; we will push its position on the stack */
736 if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )
737 goto Stack_Overflow;
738
739 *parser->top ++ = p;
740
741 /* now, skip it */
742 if ( v == 30 )
743 {
744 /* skip real number */
745 p++;
746 for (;;)
747 {
748 /* An unterminated floating point number at the */
749 /* end of a dictionary is invalid but harmless. */
750 if ( p >= limit )
751 goto Exit;
752 v = p[0] >> 4;
753 if ( v == 15 )
754 break;
755 v = p[0] & 0xF;
756 if ( v == 15 )
757 break;
758 p++;
759 }
760 }
761 else if ( v == 28 )
762 p += 2;
763 else if ( v == 29 )
764 p += 4;
765 else if ( v > 246 )
766 p += 1;
767 }
768 else
769 {
770 /* This is not a number, hence it's an operator. Compute its code */
771 /* and look for it in our current list. */
772
773 FT_UInt code;
774 FT_UInt num_args = (FT_UInt)
775 ( parser->top - parser->stack );
776 const CFF_Field_Handler* field;
777
778
779 *parser->top = p;
780 code = v;
781 if ( v == 12 )
782 {
783 /* two byte operator */
784 p++;
785 if ( p >= limit )
786 goto Syntax_Error;
787
788 code = 0x100 | p[0];
789 }
790 code = code | parser->object_code;
791
792 for ( field = FT_CFF_FIELD_HANDLERS_GET; field->kind; field++ )
793 {
794 if ( field->code == (FT_Int)code )
795 {
796 /* we found our field's handler; read it */
797 FT_Long val;
798 FT_Byte* q = (FT_Byte*)parser->object + field->offset;
799
800
801 /* check that we have enough arguments -- except for */
802 /* delta encoded arrays, which can be empty */
803 if ( field->kind != cff_kind_delta && num_args < 1 )
804 goto Stack_Underflow;
805
806 switch ( field->kind )
807 {
808 case cff_kind_bool:
809 case cff_kind_string:
810 case cff_kind_num:
811 val = cff_parse_num( parser->stack );
812 goto Store_Number;
813
814 case cff_kind_fixed:
815 val = cff_parse_fixed( parser->stack );
816 goto Store_Number;
817
818 case cff_kind_fixed_thousand:
819 val = cff_parse_fixed_scaled( parser->stack, 3 );
820
821 Store_Number:
822 switch ( field->size )
823 {
824 case (8 / FT_CHAR_BIT):
825 *(FT_Byte*)q = (FT_Byte)val;
826 break;
827
828 case (16 / FT_CHAR_BIT):
829 *(FT_Short*)q = (FT_Short)val;
830 break;
831
832 case (32 / FT_CHAR_BIT):
833 *(FT_Int32*)q = (FT_Int)val;
834 break;
835
836 default: /* for 64-bit systems */
837 *(FT_Long*)q = val;
838 }
839 break;
840
841 case cff_kind_delta:
842 {
843 FT_Byte* qcount = (FT_Byte*)parser->object +
844 field->count_offset;
845
846 FT_Byte** data = parser->stack;
847
848
849 if ( num_args > field->array_max )
850 num_args = field->array_max;
851
852 /* store count */
853 *qcount = (FT_Byte)num_args;
854
855 val = 0;
856 while ( num_args > 0 )
857 {
858 val += cff_parse_num( data++ );
859 switch ( field->size )
860 {
861 case (8 / FT_CHAR_BIT):
862 *(FT_Byte*)q = (FT_Byte)val;
863 break;
864
865 case (16 / FT_CHAR_BIT):
866 *(FT_Short*)q = (FT_Short)val;
867 break;
868
869 case (32 / FT_CHAR_BIT):
870 *(FT_Int32*)q = (FT_Int)val;
871 break;
872
873 default: /* for 64-bit systems */
874 *(FT_Long*)q = val;
875 }
876
877 q += field->size;
878 num_args--;
879 }
880 }
881 break;
882
883 default: /* callback */
884 error = field->reader( parser );
885 if ( error )
886 goto Exit;
887 }
888 goto Found;
889 }
890 }
891
892 /* this is an unknown operator, or it is unsupported; */
893 /* we will ignore it for now. */
894
895 Found:
896 /* clear stack */
897 parser->top = parser->stack;
898 }
899 p++;
900 }
901
902 Exit:
903 return error;
904
905 Stack_Overflow:
906 error = CFF_Err_Invalid_Argument;
907 goto Exit;
908
909 Stack_Underflow:
910 error = CFF_Err_Invalid_Argument;
911 goto Exit;
912
913 Syntax_Error:
914 error = CFF_Err_Invalid_Argument;
915 goto Exit;
916 }
917
918
919 /* END */