Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
cffparse.c
Go to the documentation of this file.
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 <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  FT_LOCAL_DEF( void )
40  FT_UInt code,
41  void* object,
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 
934  FT_Byte* start,
935  FT_Byte* limit )
936  {
937  FT_Byte* p = start;
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 
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 
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 */
#define FT_ALLOC(ptr, size)
Definition: ftmemory.h:260
int FT_Error
Definition: fttypes.h:296
FT_Byte * stack[CFF_MAX_STACK_DEPTH+1]
Definition: cffparse.h:44
FT_DivFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:586
signed long FT_Long
Definition: fttypes.h:238
unsigned long FT_ULong
Definition: fttypes.h:249
GLfloat GLfloat p
CFF_Field_Reader reader
Definition: cffparse.h:89
#define FT_MEM_ZERO(dest, count)
Definition: ftmemory.h:208
#define NULL
Definition: ftobjs.h:61
T sign(T a)
Definition: glsl_math.hpp:669
signed int FT_Int
Definition: fttypes.h:216
FT_ULong private_offset
Definition: cfftypes.h:129
GLdouble GLdouble GLdouble GLdouble q
FT_BBox bbox
Definition: ftbbox.c:565
cff_parser_init(CFF_Parser parser, FT_UInt code, void *object, FT_Library library)
Definition: cffparse.c:39
return FT_THROW(Missing_Property)
FT_RoundFix(FT_Fixed a)
Definition: ftcalc.c:76
#define FT_UNUSED(arg)
Definition: ftconfig.h:76
FT_UInt count_offset
Definition: cffparse.h:91
#define FT_MIN(a, b)
Definition: ftobjs.h:70
GLuint start
struct CFF_FontRecDictRec_ * CFF_FontRecDict
FT_ULong private_size
Definition: cfftypes.h:130
FT_Long cid_supplement
Definition: cfftypes.h:137
FT_Library library
Definition: cffdrivr.c:414
return FT_Err_Ok
Definition: ftbbox.c:645
png_uint_32 i
Definition: png.h:2640
FT_Vector font_offset
Definition: cfftypes.h:122
FT_Bool has_font_matrix
Definition: cfftypes.h:120
#define FT_TRACE1(varformat)
Definition: ftdebug.h:158
FT_Library library
Definition: cffparse.h:39
unsigned char FT_Byte
Definition: fttypes.h:150
#define FT_ASSERT(condition)
Definition: ftdebug.h:211
#define FT_TRACE4(varformat)
Definition: ftdebug.h:161
#define CFF_MAX_STACK_DEPTH
Definition: cffparse.h:31
FT_Byte ** top
Definition: cffparse.h:45
FT_Memory memory
Definition: ftobjs.h:860
#define CFF_FIELD_HANDLERS_GET
Definition: cffpic.h:39
#define FT_FREE(ptr)
Definition: ftmemory.h:286
GLint exponent[16]
FT_Pos yMax
Definition: ftimage.h:119
FT_Pos xMin
Definition: ftimage.h:118
#define FT_ERR(e)
Definition: fttypes.h:582
FT_Error error
Definition: cffdrivr.c:411
const GLdouble * v
GLsizei GLsizei GLenum GLenum const GLvoid * data
cff_parser_run(CFF_Parser parser, FT_Byte *start, FT_Byte *limit)
Definition: cffparse.c:933
void * object
Definition: cffparse.h:48
#define FT_DEBUG_LEVEL_TRACE
Definition: ftoption.h:389
GLuint GLfloat * val
signed int FT_Int32
Definition: ftconfig.h:132
GLintptr offset
FT_Pos xMax
Definition: ftimage.h:119
signed short FT_Short
Definition: fttypes.h:194
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
FT_Byte * limit
Definition: cffparse.h:41
Definition: inftree9.h:24
if(!abbox) return FT_THROW(Invalid_Argument)
signed long FT_Fixed
Definition: fttypes.h:284
FT_UInt cid_ordering
Definition: cfftypes.h:136
GLuint64EXT * result
unsigned int FT_UInt
Definition: fttypes.h:227
FT_Byte * start
Definition: cffparse.h:40
FT_ULong units_per_em
Definition: cfftypes.h:121
FT_Matrix font_matrix
Definition: cfftypes.h:119
local int * code
Definition: enough.c:174
FT_Byte * cursor
Definition: cffparse.h:42
unsigned short FT_UShort
Definition: fttypes.h:205
FT_UInt object_code
Definition: cffparse.h:47
FT_Pos yMin
Definition: ftimage.h:118
FT_UInt offset
Definition: cffparse.h:87
GLuint GLenum matrix
#define TRUE
Definition: ftobjs.h:53
FT_UInt cid_registry
Definition: cfftypes.h:135
void * object
Definition: jmemsys.h:48
GLint limit
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:236
#define FT_CHAR_BIT
Definition: ftconfig.h:70
FT_UInt array_max
Definition: cffparse.h:90