Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Side by Side Diff: core/src/fxge/fx_freetype/fxft2.5.01/src/cff/cffparse.c

Issue 815103002: Update freetype to 2.5.4. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Adjust GYP and GN Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /***************************************************************************/
2 /* */
3 /* cffparse.c */
4 /* */
5 /* CFF token stream parser (body) */
6 /* */
7 /* Copyright 1996-2004, 2007-2013 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 "../../include/ft2build.h"
20 #include "cffparse.h"
21 #include "../../include/freetype/internal/ftstream.h"
22 #include "../../include/freetype/internal/ftdebug.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 FT_LOCAL_DEF( void )
39 cff_parser_init( CFF_Parser parser,
40 FT_UInt code,
41 void* object,
42 FT_Library library)
43 {
44 FT_MEM_ZERO( parser, sizeof ( *parser ) );
45
46 parser->top = parser->stack;
47 parser->object_code = code;
48 parser->object = object;
49 parser->library = library;
50 }
51
52
53 /* read an integer */
54 static FT_Long
55 cff_parse_integer( FT_Byte* start,
56 FT_Byte* limit )
57 {
58 FT_Byte* p = start;
59 FT_Int v = *p++;
60 FT_Long val = 0;
61
62
63 if ( v == 28 )
64 {
65 if ( p + 2 > limit )
66 goto Bad;
67
68 val = (FT_Short)( ( (FT_UShort)p[0] << 8 ) | p[1] );
69 p += 2;
70 }
71 else if ( v == 29 )
72 {
73 if ( p + 4 > limit )
74 goto Bad;
75
76 val = (FT_Long)( ( (FT_ULong)p[0] << 24 ) |
77 ( (FT_ULong)p[1] << 16 ) |
78 ( (FT_ULong)p[2] << 8 ) |
79 (FT_ULong)p[3] );
80 p += 4;
81 }
82 else if ( v < 247 )
83 {
84 val = v - 139;
85 }
86 else if ( v < 251 )
87 {
88 if ( p + 1 > limit )
89 goto Bad;
90
91 val = ( v - 247 ) * 256 + p[0] + 108;
92 p++;
93 }
94 else
95 {
96 if ( p + 1 > limit )
97 goto Bad;
98
99 val = -( v - 251 ) * 256 - p[0] - 108;
100 p++;
101 }
102
103 Exit:
104 return val;
105
106 Bad:
107 val = 0;
108 FT_TRACE4(( "!!!END OF DATA:!!!" ));
109 goto Exit;
110 }
111
112
113 static const FT_Long power_tens[] =
114 {
115 1L,
116 10L,
117 100L,
118 1000L,
119 10000L,
120 100000L,
121 1000000L,
122 10000000L,
123 100000000L,
124 1000000000L
125 };
126
127
128 /* read a real */
129 static FT_Fixed
130 cff_parse_real( FT_Byte* start,
131 FT_Byte* limit,
132 FT_Long power_ten,
133 FT_Long* scaling )
134 {
135 FT_Byte* p = start;
136 FT_UInt nib;
137 FT_UInt phase;
138
139 FT_Long result, number, exponent;
140 FT_Int sign = 0, exponent_sign = 0, have_overflow = 0;
141 FT_Long exponent_add, integer_length, fraction_length;
142
143
144 if ( scaling )
145 *scaling = 0;
146
147 result = 0;
148
149 number = 0;
150 exponent = 0;
151
152 exponent_add = 0;
153 integer_length = 0;
154 fraction_length = 0;
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 {
182 /* Increase exponent if we can't add the digit. */
183 if ( number >= 0xCCCCCCCL )
184 exponent_add++;
185 /* Skip leading zeros. */
186 else if ( nib || number )
187 {
188 integer_length++;
189 number = number * 10 + nib;
190 }
191 }
192 }
193
194 /* Read fraction part, if any. */
195 if ( nib == 0xa )
196 for (;;)
197 {
198 /* If we entered this iteration with phase == 4, we need */
199 /* to read a new byte. */
200 if ( phase )
201 {
202 p++;
203
204 /* Make sure we don't read past the end. */
205 if ( p >= limit )
206 goto Bad;
207 }
208
209 /* Get the nibble. */
210 nib = ( p[0] >> phase ) & 0xF;
211 phase = 4 - phase;
212 if ( nib >= 10 )
213 break;
214
215 /* Skip leading zeros if possible. */
216 if ( !nib && !number )
217 exponent_add--;
218 /* Only add digit if we don't overflow. */
219 else if ( number < 0xCCCCCCCL && fraction_length < 9 )
220 {
221 fraction_length++;
222 number = number * 10 + nib;
223 }
224 }
225
226 /* Read exponent, if any. */
227 if ( nib == 12 )
228 {
229 exponent_sign = 1;
230 nib = 11;
231 }
232
233 if ( nib == 11 )
234 {
235 for (;;)
236 {
237 /* If we entered this iteration with phase == 4, */
238 /* we need to read a new byte. */
239 if ( phase )
240 {
241 p++;
242
243 /* Make sure we don't read past the end. */
244 if ( p >= limit )
245 goto Bad;
246 }
247
248 /* Get the nibble. */
249 nib = ( p[0] >> phase ) & 0xF;
250 phase = 4 - phase;
251 if ( nib >= 10 )
252 break;
253
254 /* Arbitrarily limit exponent. */
255 if ( exponent > 1000 )
256 have_overflow = 1;
257 else
258 exponent = exponent * 10 + nib;
259 }
260
261 if ( exponent_sign )
262 exponent = -exponent;
263 }
264
265 if ( !number )
266 goto Exit;
267
268 if ( have_overflow )
269 {
270 if ( exponent_sign )
271 goto Underflow;
272 else
273 goto Overflow;
274 }
275
276 /* We don't check `power_ten' and `exponent_add'. */
277 exponent += power_ten + exponent_add;
278
279 if ( scaling )
280 {
281 /* Only use `fraction_length'. */
282 fraction_length += integer_length;
283 exponent += integer_length;
284
285 if ( fraction_length <= 5 )
286 {
287 if ( number > 0x7FFFL )
288 {
289 result = FT_DivFix( number, 10 );
290 *scaling = exponent - fraction_length + 1;
291 }
292 else
293 {
294 if ( exponent > 0 )
295 {
296 FT_Long new_fraction_length, shift;
297
298
299 /* Make `scaling' as small as possible. */
300 new_fraction_length = FT_MIN( exponent, 5 );
301 shift = new_fraction_length - fraction_length;
302
303 if ( shift > 0 )
304 {
305 exponent -= new_fraction_length;
306 number *= power_tens[shift];
307 if ( number > 0x7FFFL )
308 {
309 number /= 10;
310 exponent += 1;
311 }
312 }
313 else
314 exponent -= fraction_length;
315 }
316 else
317 exponent -= fraction_length;
318
319 result = (FT_Long)( (FT_ULong)number << 16 );
320 *scaling = exponent;
321 }
322 }
323 else
324 {
325 if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL )
326 {
327 result = FT_DivFix( number, power_tens[fraction_length - 4] );
328 *scaling = exponent - 4;
329 }
330 else
331 {
332 result = FT_DivFix( number, power_tens[fraction_length - 5] );
333 *scaling = exponent - 5;
334 }
335 }
336 }
337 else
338 {
339 integer_length += exponent;
340 fraction_length -= exponent;
341
342 if ( integer_length > 5 )
343 goto Overflow;
344 if ( integer_length < -5 )
345 goto Underflow;
346
347 /* Remove non-significant digits. */
348 if ( integer_length < 0 )
349 {
350 number /= power_tens[-integer_length];
351 fraction_length += integer_length;
352 }
353
354 /* this can only happen if exponent was non-zero */
355 if ( fraction_length == 10 )
356 {
357 number /= 10;
358 fraction_length -= 1;
359 }
360
361 /* Convert into 16.16 format. */
362 if ( fraction_length > 0 )
363 {
364 if ( ( number / power_tens[fraction_length] ) > 0x7FFFL )
365 goto Exit;
366
367 result = FT_DivFix( number, power_tens[fraction_length] );
368 }
369 else
370 {
371 number *= power_tens[-fraction_length];
372
373 if ( number > 0x7FFFL )
374 goto Overflow;
375
376 result = (FT_Long)( (FT_ULong)number << 16 );
377 }
378 }
379
380 Exit:
381 if ( sign )
382 result = -result;
383
384 return result;
385
386 Overflow:
387 result = 0x7FFFFFFFL;
388 FT_TRACE4(( "!!!OVERFLOW:!!!" ));
389 goto Exit;
390
391 Underflow:
392 result = 0;
393 FT_TRACE4(( "!!!UNDERFLOW:!!!" ));
394 goto Exit;
395
396 Bad:
397 result = 0;
398 FT_TRACE4(( "!!!END OF DATA:!!!" ));
399 goto Exit;
400 }
401
402
403 /* read a number, either integer or real */
404 static FT_Long
405 cff_parse_num( FT_Byte** d )
406 {
407 return **d == 30 ? ( cff_parse_real( d[0], d[1], 0, NULL ) >> 16 )
408 : cff_parse_integer( d[0], d[1] );
409 }
410
411
412 /* read a floating point number, either integer or real */
413 static FT_Fixed
414 do_fixed( FT_Byte** d,
415 FT_Long scaling )
416 {
417 if ( **d == 30 )
418 return cff_parse_real( d[0], d[1], scaling, NULL );
419 else
420 {
421 FT_Long val = cff_parse_integer( d[0], d[1] );
422
423
424 if ( scaling )
425 val *= power_tens[scaling];
426
427 if ( val > 0x7FFF )
428 {
429 val = 0x7FFFFFFFL;
430 goto Overflow;
431 }
432 else if ( val < -0x7FFF )
433 {
434 val = -0x7FFFFFFFL;
435 goto Overflow;
436 }
437
438 return (FT_Long)( (FT_ULong)val << 16 );
439
440 Overflow:
441 FT_TRACE4(( "!!!OVERFLOW:!!!" ));
442 return val;
443 }
444 }
445
446
447 /* read a floating point number, either integer or real */
448 static FT_Fixed
449 cff_parse_fixed( FT_Byte** d )
450 {
451 return do_fixed( d, 0 );
452 }
453
454
455 /* read a floating point number, either integer or real, */
456 /* but return `10^scaling' times the number read in */
457 static FT_Fixed
458 cff_parse_fixed_scaled( FT_Byte** d,
459 FT_Long scaling )
460 {
461 return do_fixed( d, scaling );
462 }
463
464
465 /* read a floating point number, either integer or real, */
466 /* and return it as precise as possible -- `scaling' returns */
467 /* the scaling factor (as a power of 10) */
468 static FT_Fixed
469 cff_parse_fixed_dynamic( FT_Byte** d,
470 FT_Long* scaling )
471 {
472 FT_ASSERT( scaling );
473
474 if ( **d == 30 )
475 return cff_parse_real( d[0], d[1], 0, scaling );
476 else
477 {
478 FT_Long number;
479 FT_Int integer_length;
480
481
482 number = cff_parse_integer( d[0], d[1] );
483
484 if ( number > 0x7FFFL )
485 {
486 for ( integer_length = 5; integer_length < 10; integer_length++ )
487 if ( number < power_tens[integer_length] )
488 break;
489
490 if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL )
491 {
492 *scaling = integer_length - 4;
493 return FT_DivFix( number, power_tens[integer_length - 4] );
494 }
495 else
496 {
497 *scaling = integer_length - 5;
498 return FT_DivFix( number, power_tens[integer_length - 5] );
499 }
500 }
501 else
502 {
503 *scaling = 0;
504 return (FT_Long)( (FT_ULong)number << 16 );
505 }
506 }
507 }
508
509
510 static FT_Error
511 cff_parse_font_matrix( CFF_Parser parser )
512 {
513 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
514 FT_Matrix* matrix = &dict->font_matrix;
515 FT_Vector* offset = &dict->font_offset;
516 FT_ULong* upm = &dict->units_per_em;
517 FT_Byte** data = parser->stack;
518 FT_Error error = FT_ERR( Stack_Underflow );
519
520
521 if ( parser->top >= parser->stack + 6 )
522 {
523 FT_Long scaling;
524
525
526 error = FT_Err_Ok;
527
528 dict->has_font_matrix = TRUE;
529
530 /* We expect a well-formed font matrix, this is, the matrix elements */
531 /* `xx' and `yy' are of approximately the same magnitude. To avoid */
532 /* loss of precision, we use the magnitude of element `xx' to scale */
533 /* all other elements. The scaling factor is then contained in the */
534 /* `units_per_em' value. */
535
536 matrix->xx = cff_parse_fixed_dynamic( data++, &scaling );
537
538 scaling = -scaling;
539
540 if ( scaling < 0 || scaling > 9 )
541 {
542 /* Return default matrix in case of unlikely values. */
543
544 FT_TRACE1(( "cff_parse_font_matrix:"
545 " strange scaling value for xx element (%d),\n"
546 " "
547 " using default matrix\n", scaling ));
548
549 matrix->xx = 0x10000L;
550 matrix->yx = 0;
551 matrix->xy = 0;
552 matrix->yy = 0x10000L;
553 offset->x = 0;
554 offset->y = 0;
555 *upm = 1;
556
557 goto Exit;
558 }
559
560 matrix->yx = cff_parse_fixed_scaled( data++, scaling );
561 matrix->xy = cff_parse_fixed_scaled( data++, scaling );
562 matrix->yy = cff_parse_fixed_scaled( data++, scaling );
563 offset->x = cff_parse_fixed_scaled( data++, scaling );
564 offset->y = cff_parse_fixed_scaled( data, scaling );
565
566 *upm = power_tens[scaling];
567
568 FT_TRACE4(( " [%f %f %f %f %f %f]\n",
569 (double)matrix->xx / *upm / 65536,
570 (double)matrix->xy / *upm / 65536,
571 (double)matrix->yx / *upm / 65536,
572 (double)matrix->yy / *upm / 65536,
573 (double)offset->x / *upm / 65536,
574 (double)offset->y / *upm / 65536 ));
575 }
576
577 Exit:
578 return error;
579 }
580
581
582 static FT_Error
583 cff_parse_font_bbox( CFF_Parser parser )
584 {
585 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
586 FT_BBox* bbox = &dict->font_bbox;
587 FT_Byte** data = parser->stack;
588 FT_Error error;
589
590
591 error = FT_ERR( Stack_Underflow );
592
593 if ( parser->top >= parser->stack + 4 )
594 {
595 bbox->xMin = FT_RoundFix( cff_parse_fixed( data++ ) );
596 bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) );
597 bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) );
598 bbox->yMax = FT_RoundFix( cff_parse_fixed( data ) );
599 error = FT_Err_Ok;
600
601 FT_TRACE4(( " [%d %d %d %d]\n",
602 bbox->xMin / 65536,
603 bbox->yMin / 65536,
604 bbox->xMax / 65536,
605 bbox->yMax / 65536 ));
606 }
607
608 return error;
609 }
610
611
612 static FT_Error
613 cff_parse_private_dict( CFF_Parser parser )
614 {
615 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
616 FT_Byte** data = parser->stack;
617 FT_Error error;
618
619
620 error = FT_ERR( Stack_Underflow );
621
622 if ( parser->top >= parser->stack + 2 )
623 {
624 dict->private_size = cff_parse_num( data++ );
625 dict->private_offset = cff_parse_num( data );
626 FT_TRACE4(( " %lu %lu\n",
627 dict->private_size, dict->private_offset ));
628
629 error = FT_Err_Ok;
630 }
631
632 return error;
633 }
634
635
636 static FT_Error
637 cff_parse_cid_ros( CFF_Parser parser )
638 {
639 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
640 FT_Byte** data = parser->stack;
641 FT_Error error;
642
643
644 error = FT_ERR( Stack_Underflow );
645
646 if ( parser->top >= parser->stack + 3 )
647 {
648 dict->cid_registry = (FT_UInt)cff_parse_num( data++ );
649 dict->cid_ordering = (FT_UInt)cff_parse_num( data++ );
650 if ( **data == 30 )
651 FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" ));
652 dict->cid_supplement = cff_parse_num( data );
653 if ( dict->cid_supplement < 0 )
654 FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n",
655 dict->cid_supplement ));
656 error = FT_Err_Ok;
657
658 FT_TRACE4(( " %d %d %d\n",
659 dict->cid_registry,
660 dict->cid_ordering,
661 dict->cid_supplement ));
662 }
663
664 return error;
665 }
666
667
668 #define CFF_FIELD_NUM( code, name, id ) \
669 CFF_FIELD( code, name, id, cff_kind_num )
670 #define CFF_FIELD_FIXED( code, name, id ) \
671 CFF_FIELD( code, name, id, cff_kind_fixed )
672 #define CFF_FIELD_FIXED_1000( code, name, id ) \
673 CFF_FIELD( code, name, id, cff_kind_fixed_thousand )
674 #define CFF_FIELD_STRING( code, name, id ) \
675 CFF_FIELD( code, name, id, cff_kind_string )
676 #define CFF_FIELD_BOOL( code, name, id ) \
677 CFF_FIELD( code, name, id, cff_kind_bool )
678
679 #define CFFCODE_TOPDICT 0x1000
680 #define CFFCODE_PRIVATE 0x2000
681
682
683 #ifndef FT_CONFIG_OPTION_PIC
684
685
686 #undef CFF_FIELD
687 #undef CFF_FIELD_DELTA
688
689
690 #ifndef FT_DEBUG_LEVEL_TRACE
691
692
693 #define CFF_FIELD_CALLBACK( code, name, id ) \
694 { \
695 cff_kind_callback, \
696 code | CFFCODE, \
697 0, 0, \
698 cff_parse_ ## name, \
699 0, 0 \
700 },
701
702 #define CFF_FIELD( code, name, id, kind ) \
703 { \
704 kind, \
705 code | CFFCODE, \
706 FT_FIELD_OFFSET( name ), \
707 FT_FIELD_SIZE( name ), \
708 0, 0, 0 \
709 },
710
711 #define CFF_FIELD_DELTA( code, name, max, id ) \
712 { \
713 cff_kind_delta, \
714 code | CFFCODE, \
715 FT_FIELD_OFFSET( name ), \
716 FT_FIELD_SIZE_DELTA( name ), \
717 0, \
718 max, \
719 FT_FIELD_OFFSET( num_ ## name ) \
720 },
721
722 static const CFF_Field_Handler cff_field_handlers[] =
723 {
724
725 #include "cfftoken.h"
726
727 { 0, 0, 0, 0, 0, 0, 0 }
728 };
729
730
731 #else /* FT_DEBUG_LEVEL_TRACE */
732
733
734
735 #define CFF_FIELD_CALLBACK( code, name, id ) \
736 { \
737 cff_kind_callback, \
738 code | CFFCODE, \
739 0, 0, \
740 cff_parse_ ## name, \
741 0, 0, \
742 id \
743 },
744
745 #define CFF_FIELD( code, name, id, kind ) \
746 { \
747 kind, \
748 code | CFFCODE, \
749 FT_FIELD_OFFSET( name ), \
750 FT_FIELD_SIZE( name ), \
751 0, 0, 0, \
752 id \
753 },
754
755 #define CFF_FIELD_DELTA( code, name, max, id ) \
756 { \
757 cff_kind_delta, \
758 code | CFFCODE, \
759 FT_FIELD_OFFSET( name ), \
760 FT_FIELD_SIZE_DELTA( name ), \
761 0, \
762 max, \
763 FT_FIELD_OFFSET( num_ ## name ), \
764 id \
765 },
766
767 static const CFF_Field_Handler cff_field_handlers[] =
768 {
769
770 #include "cfftoken.h"
771
772 { 0, 0, 0, 0, 0, 0, 0, 0 }
773 };
774
775
776 #endif /* FT_DEBUG_LEVEL_TRACE */
777
778
779 #else /* FT_CONFIG_OPTION_PIC */
780
781
782 void
783 FT_Destroy_Class_cff_field_handlers( FT_Library library,
784 CFF_Field_Handler* clazz )
785 {
786 FT_Memory memory = library->memory;
787
788
789 if ( clazz )
790 FT_FREE( clazz );
791 }
792
793
794 FT_Error
795 FT_Create_Class_cff_field_handlers( FT_Library library,
796 CFF_Field_Handler** output_class )
797 {
798 CFF_Field_Handler* clazz = NULL;
799 FT_Error error;
800 FT_Memory memory = library->memory;
801
802 int i = 0;
803
804
805 #undef CFF_FIELD
806 #define CFF_FIELD( code, name, id, kind ) i++;
807 #undef CFF_FIELD_DELTA
808 #define CFF_FIELD_DELTA( code, name, max, id ) i++;
809 #undef CFF_FIELD_CALLBACK
810 #define CFF_FIELD_CALLBACK( code, name, id ) i++;
811
812 #include "cfftoken.h"
813
814 i++; /* { 0, 0, 0, 0, 0, 0, 0 } */
815
816 if ( FT_ALLOC( clazz, sizeof ( CFF_Field_Handler ) * i ) )
817 return error;
818
819 i = 0;
820
821
822 #ifndef FT_DEBUG_LEVEL_TRACE
823
824
825 #undef CFF_FIELD_CALLBACK
826 #define CFF_FIELD_CALLBACK( code_, name_, id_ ) \
827 clazz[i].kind = cff_kind_callback; \
828 clazz[i].code = code_ | CFFCODE; \
829 clazz[i].offset = 0; \
830 clazz[i].size = 0; \
831 clazz[i].reader = cff_parse_ ## name_; \
832 clazz[i].array_max = 0; \
833 clazz[i].count_offset = 0; \
834 i++;
835
836 #undef CFF_FIELD
837 #define CFF_FIELD( code_, name_, id_, kind_ ) \
838 clazz[i].kind = kind_; \
839 clazz[i].code = code_ | CFFCODE; \
840 clazz[i].offset = FT_FIELD_OFFSET( name_ ); \
841 clazz[i].size = FT_FIELD_SIZE( name_ ); \
842 clazz[i].reader = 0; \
843 clazz[i].array_max = 0; \
844 clazz[i].count_offset = 0; \
845 i++; \
846
847 #undef CFF_FIELD_DELTA
848 #define CFF_FIELD_DELTA( code_, name_, max_, id_ ) \
849 clazz[i].kind = cff_kind_delta; \
850 clazz[i].code = code_ | CFFCODE; \
851 clazz[i].offset = FT_FIELD_OFFSET( name_ ); \
852 clazz[i].size = FT_FIELD_SIZE_DELTA( name_ ); \
853 clazz[i].reader = 0; \
854 clazz[i].array_max = max_; \
855 clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \
856 i++;
857
858 #include "cfftoken.h"
859
860 clazz[i].kind = 0;
861 clazz[i].code = 0;
862 clazz[i].offset = 0;
863 clazz[i].size = 0;
864 clazz[i].reader = 0;
865 clazz[i].array_max = 0;
866 clazz[i].count_offset = 0;
867
868
869 #else /* FT_DEBUG_LEVEL_TRACE */
870
871
872 #undef CFF_FIELD_CALLBACK
873 #define CFF_FIELD_CALLBACK( code_, name_, id_ ) \
874 clazz[i].kind = cff_kind_callback; \
875 clazz[i].code = code_ | CFFCODE; \
876 clazz[i].offset = 0; \
877 clazz[i].size = 0; \
878 clazz[i].reader = cff_parse_ ## name_; \
879 clazz[i].array_max = 0; \
880 clazz[i].count_offset = 0; \
881 clazz[i].id = id_; \
882 i++;
883
884 #undef CFF_FIELD
885 #define CFF_FIELD( code_, name_, id_, kind_ ) \
886 clazz[i].kind = kind_; \
887 clazz[i].code = code_ | CFFCODE; \
888 clazz[i].offset = FT_FIELD_OFFSET( name_ ); \
889 clazz[i].size = FT_FIELD_SIZE( name_ ); \
890 clazz[i].reader = 0; \
891 clazz[i].array_max = 0; \
892 clazz[i].count_offset = 0; \
893 clazz[i].id = id_; \
894 i++; \
895
896 #undef CFF_FIELD_DELTA
897 #define CFF_FIELD_DELTA( code_, name_, max_, id_ ) \
898 clazz[i].kind = cff_kind_delta; \
899 clazz[i].code = code_ | CFFCODE; \
900 clazz[i].offset = FT_FIELD_OFFSET( name_ ); \
901 clazz[i].size = FT_FIELD_SIZE_DELTA( name_ ); \
902 clazz[i].reader = 0; \
903 clazz[i].array_max = max_; \
904 clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \
905 clazz[i].id = id_; \
906 i++;
907
908 #include "cfftoken.h"
909
910 clazz[i].kind = 0;
911 clazz[i].code = 0;
912 clazz[i].offset = 0;
913 clazz[i].size = 0;
914 clazz[i].reader = 0;
915 clazz[i].array_max = 0;
916 clazz[i].count_offset = 0;
917 clazz[i].id = 0;
918
919
920 #endif /* FT_DEBUG_LEVEL_TRACE */
921
922
923 *output_class = clazz;
924
925 return FT_Err_Ok;
926 }
927
928
929 #endif /* FT_CONFIG_OPTION_PIC */
930
931
932 FT_LOCAL_DEF( FT_Error )
933 cff_parser_run( CFF_Parser parser,
934 FT_Byte* start,
935 FT_Byte* limit )
936 {
937 FT_Byte* p = start;
938 FT_Error error = FT_Err_Ok;
939 FT_Library library = parser->library;
940 FT_UNUSED( library );
941
942
943 parser->top = parser->stack;
944 parser->start = start;
945 parser->limit = limit;
946 parser->cursor = start;
947
948 while ( p < limit )
949 {
950 FT_UInt v = *p;
951
952
953 if ( v >= 27 && v != 31 )
954 {
955 /* it's a number; we will push its position on the stack */
956 if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )
957 goto Stack_Overflow;
958
959 *parser->top ++ = p;
960
961 /* now, skip it */
962 if ( v == 30 )
963 {
964 /* skip real number */
965 p++;
966 for (;;)
967 {
968 /* An unterminated floating point number at the */
969 /* end of a dictionary is invalid but harmless. */
970 if ( p >= limit )
971 goto Exit;
972 v = p[0] >> 4;
973 if ( v == 15 )
974 break;
975 v = p[0] & 0xF;
976 if ( v == 15 )
977 break;
978 p++;
979 }
980 }
981 else if ( v == 28 )
982 p += 2;
983 else if ( v == 29 )
984 p += 4;
985 else if ( v > 246 )
986 p += 1;
987 }
988 else
989 {
990 /* This is not a number, hence it's an operator. Compute its code */
991 /* and look for it in our current list. */
992
993 FT_UInt code;
994 FT_UInt num_args = (FT_UInt)
995 ( parser->top - parser->stack );
996 const CFF_Field_Handler* field;
997
998
999 *parser->top = p;
1000 code = v;
1001 if ( v == 12 )
1002 {
1003 /* two byte operator */
1004 p++;
1005 if ( p >= limit )
1006 goto Syntax_Error;
1007
1008 code = 0x100 | p[0];
1009 }
1010 code = code | parser->object_code;
1011
1012 for ( field = CFF_FIELD_HANDLERS_GET; field->kind; field++ )
1013 {
1014 if ( field->code == (FT_Int)code )
1015 {
1016 /* we found our field's handler; read it */
1017 FT_Long val;
1018 FT_Byte* q = (FT_Byte*)parser->object + field->offset;
1019
1020
1021 #ifdef FT_DEBUG_LEVEL_TRACE
1022 FT_TRACE4(( " %s", field->id ));
1023 #endif
1024
1025 /* check that we have enough arguments -- except for */
1026 /* delta encoded arrays, which can be empty */
1027 if ( field->kind != cff_kind_delta && num_args < 1 )
1028 goto Stack_Underflow;
1029
1030 switch ( field->kind )
1031 {
1032 case cff_kind_bool:
1033 case cff_kind_string:
1034 case cff_kind_num:
1035 val = cff_parse_num( parser->stack );
1036 goto Store_Number;
1037
1038 case cff_kind_fixed:
1039 val = cff_parse_fixed( parser->stack );
1040 goto Store_Number;
1041
1042 case cff_kind_fixed_thousand:
1043 val = cff_parse_fixed_scaled( parser->stack, 3 );
1044
1045 Store_Number:
1046 switch ( field->size )
1047 {
1048 case (8 / FT_CHAR_BIT):
1049 *(FT_Byte*)q = (FT_Byte)val;
1050 break;
1051
1052 case (16 / FT_CHAR_BIT):
1053 *(FT_Short*)q = (FT_Short)val;
1054 break;
1055
1056 case (32 / FT_CHAR_BIT):
1057 *(FT_Int32*)q = (FT_Int)val;
1058 break;
1059
1060 default: /* for 64-bit systems */
1061 *(FT_Long*)q = val;
1062 }
1063
1064 #ifdef FT_DEBUG_LEVEL_TRACE
1065 switch ( field->kind )
1066 {
1067 case cff_kind_bool:
1068 FT_TRACE4(( " %s\n", val ? "true" : "false" ));
1069 break;
1070
1071 case cff_kind_string:
1072 FT_TRACE4(( " %ld (SID)\n", val ));
1073 break;
1074
1075 case cff_kind_num:
1076 FT_TRACE4(( " %ld\n", val ));
1077 break;
1078
1079 case cff_kind_fixed:
1080 FT_TRACE4(( " %f\n", (double)val / 65536 ));
1081 break;
1082
1083 case cff_kind_fixed_thousand:
1084 FT_TRACE4(( " %f\n", (double)val / 65536 / 1000 ));
1085
1086 default:
1087 ; /* never reached */
1088 }
1089 #endif
1090
1091 break;
1092
1093 case cff_kind_delta:
1094 {
1095 FT_Byte* qcount = (FT_Byte*)parser->object +
1096 field->count_offset;
1097
1098 FT_Byte** data = parser->stack;
1099
1100
1101 if ( num_args > field->array_max )
1102 num_args = field->array_max;
1103
1104 FT_TRACE4(( " [" ));
1105
1106 /* store count */
1107 *qcount = (FT_Byte)num_args;
1108
1109 val = 0;
1110 while ( num_args > 0 )
1111 {
1112 val += cff_parse_num( data++ );
1113 switch ( field->size )
1114 {
1115 case (8 / FT_CHAR_BIT):
1116 *(FT_Byte*)q = (FT_Byte)val;
1117 break;
1118
1119 case (16 / FT_CHAR_BIT):
1120 *(FT_Short*)q = (FT_Short)val;
1121 break;
1122
1123 case (32 / FT_CHAR_BIT):
1124 *(FT_Int32*)q = (FT_Int)val;
1125 break;
1126
1127 default: /* for 64-bit systems */
1128 *(FT_Long*)q = val;
1129 }
1130
1131 FT_TRACE4(( " %ld", val ));
1132
1133 q += field->size;
1134 num_args--;
1135 }
1136
1137 FT_TRACE4(( "]\n" ));
1138 }
1139 break;
1140
1141 default: /* callback */
1142 error = field->reader( parser );
1143 if ( error )
1144 goto Exit;
1145 }
1146 goto Found;
1147 }
1148 }
1149
1150 /* this is an unknown operator, or it is unsupported; */
1151 /* we will ignore it for now. */
1152
1153 Found:
1154 /* clear stack */
1155 parser->top = parser->stack;
1156 }
1157 p++;
1158 }
1159
1160 Exit:
1161 return error;
1162
1163 Stack_Overflow:
1164 error = FT_THROW( Invalid_Argument );
1165 goto Exit;
1166
1167 Stack_Underflow:
1168 error = FT_THROW( Invalid_Argument );
1169 goto Exit;
1170
1171 Syntax_Error:
1172 error = FT_THROW( Invalid_Argument );
1173 goto Exit;
1174 }
1175
1176
1177 /* END */
OLDNEW
« no previous file with comments | « core/src/fxge/fx_freetype/fxft2.5.01/src/cff/cffparse.h ('k') | core/src/fxge/fx_freetype/fxft2.5.01/src/cff/cffpic.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698