blob: d6d77dd08da329bd15a86fb9980b659db2d221fb [file] [log] [blame]
David Turner19ed8af2000-12-08 02:42:29 +00001/***************************************************************************/
2/* */
3/* cffparse.c */
4/* */
5/* CFF token stream parser (body) */
6/* */
Werner Lemberg210d6182008-04-01 05:55:48 +00007/* Copyright 1996-2001, 2002, 2003, 2004, 2007, 2008 by */
David Turner19ed8af2000-12-08 02:42:29 +00008/* 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
Werner Lembergcc069be2000-12-08 16:17:16 +000018
David Turner19ed8af2000-12-08 02:42:29 +000019#include <ft2build.h>
David Turner8d3a4012001-03-20 11:14:24 +000020#include "cffparse.h"
David Turner19ed8af2000-12-08 02:42:29 +000021#include FT_INTERNAL_STREAM_H
Werner Lemberg6174e172008-06-10 05:58:25 +000022#include FT_INTERNAL_DEBUG_H
David Turner19ed8af2000-12-08 02:42:29 +000023
Werner Lemberg1f7f0e82001-06-06 17:30:41 +000024#include "cfferrs.h"
25
Werner Lembergcc069be2000-12-08 16:17:16 +000026
David Turner19ed8af2000-12-08 02:42:29 +000027 /*************************************************************************/
28 /* */
29 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
30 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
31 /* messages during execution. */
32 /* */
33#undef FT_COMPONENT
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +000034#define FT_COMPONENT trace_cffparse
David Turner19ed8af2000-12-08 02:42:29 +000035
36
David Turner19ed8af2000-12-08 02:42:29 +000037 enum
38 {
39 cff_kind_none = 0,
40 cff_kind_num,
41 cff_kind_fixed,
Werner Lembergbf7c8322003-06-06 05:07:53 +000042 cff_kind_fixed_thousand,
David Turner19ed8af2000-12-08 02:42:29 +000043 cff_kind_string,
44 cff_kind_bool,
45 cff_kind_delta,
46 cff_kind_callback,
47
48 cff_kind_max /* do not remove */
49 };
50
51
52 /* now generate handlers for the most simple fields */
Werner Lemberg48c984b2002-03-30 16:41:09 +000053 typedef FT_Error (*CFF_Field_Reader)( CFF_Parser parser );
David Turner19ed8af2000-12-08 02:42:29 +000054
55 typedef struct CFF_Field_Handler_
56 {
57 int kind;
58 int code;
59 FT_UInt offset;
60 FT_Byte size;
61 CFF_Field_Reader reader;
62 FT_UInt array_max;
63 FT_UInt count_offset;
64
65 } CFF_Field_Handler;
66
67
David Turnerbc82f1b2002-03-01 02:26:22 +000068 FT_LOCAL_DEF( void )
David Turnerb9b2cac2002-07-10 16:52:06 +000069 cff_parser_init( CFF_Parser parser,
Werner Lemberg48c984b2002-03-30 16:41:09 +000070 FT_UInt code,
71 void* object )
David Turner19ed8af2000-12-08 02:42:29 +000072 {
Werner Lembergb3d5e9c2002-07-28 05:05:24 +000073 FT_MEM_ZERO( parser, sizeof ( *parser ) );
David Turner19ed8af2000-12-08 02:42:29 +000074
75 parser->top = parser->stack;
76 parser->object_code = code;
77 parser->object = object;
78 }
79
80
Werner Lembergcc069be2000-12-08 16:17:16 +000081 /* read an integer */
Werner Lemberg93616ec2001-06-27 19:46:12 +000082 static FT_Long
83 cff_parse_integer( FT_Byte* start,
84 FT_Byte* limit )
David Turner19ed8af2000-12-08 02:42:29 +000085 {
86 FT_Byte* p = start;
87 FT_Int v = *p++;
88 FT_Long val = 0;
89
90
91 if ( v == 28 )
92 {
93 if ( p + 2 > limit )
94 goto Bad;
95
96 val = (FT_Short)( ( (FT_Int)p[0] << 8 ) | p[1] );
97 p += 2;
98 }
99 else if ( v == 29 )
100 {
101 if ( p + 4 > limit )
102 goto Bad;
103
104 val = ( (FT_Long)p[0] << 24 ) |
105 ( (FT_Long)p[1] << 16 ) |
106 ( (FT_Long)p[2] << 8 ) |
107 p[3];
108 p += 4;
109 }
110 else if ( v < 247 )
111 {
112 val = v - 139;
113 }
114 else if ( v < 251 )
115 {
116 if ( p + 1 > limit )
117 goto Bad;
118
119 val = ( v - 247 ) * 256 + p[0] + 108;
120 p++;
121 }
122 else
123 {
124 if ( p + 1 > limit )
125 goto Bad;
126
127 val = -( v - 251 ) * 256 - p[0] - 108;
128 p++;
129 }
130
131 Exit:
132 return val;
133
134 Bad:
135 val = 0;
136 goto Exit;
137 }
138
139
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000140 static const FT_Long power_tens[] =
141 {
142 1L,
143 10L,
144 100L,
145 1000L,
146 10000L,
147 100000L,
148 1000000L,
149 10000000L,
150 100000000L,
151 1000000000L
152 };
153
154
David Turner19ed8af2000-12-08 02:42:29 +0000155 /* read a real */
Werner Lemberg93616ec2001-06-27 19:46:12 +0000156 static FT_Fixed
157 cff_parse_real( FT_Byte* start,
158 FT_Byte* limit,
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000159 FT_Int power_ten,
160 FT_Int* scaling )
David Turner19ed8af2000-12-08 02:42:29 +0000161 {
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000162 FT_Byte* p = start;
David Turner8edbcab2001-06-19 08:28:24 +0000163 FT_UInt nib;
164 FT_UInt phase;
David Turner19ed8af2000-12-08 02:42:29 +0000165
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000166 FT_Long result, number, rest, exponent;
167 FT_Int sign = 0, exponent_sign = 0;
168 FT_Int exponent_add, integer_length, fraction_length;
David Turner19ed8af2000-12-08 02:42:29 +0000169
David Turner19ed8af2000-12-08 02:42:29 +0000170
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000171 if ( scaling )
172 *scaling = 0;
173
174 result = 0;
175
176 number = 0;
177 rest = 0;
178 exponent = 0;
179
180 exponent_add = 0;
181 integer_length = 0;
182 fraction_length = 0;
183
184 /* First of all, read the integer part. */
David Turner19ed8af2000-12-08 02:42:29 +0000185 phase = 4;
186
187 for (;;)
188 {
David Turner19ed8af2000-12-08 02:42:29 +0000189 /* If we entered this iteration with phase == 4, we need to */
Werner Lemberg6e87ed92007-01-26 22:18:56 +0000190 /* read a new byte. This also skips past the initial 0x1E. */
David Turner19ed8af2000-12-08 02:42:29 +0000191 if ( phase )
192 {
193 p++;
194
195 /* Make sure we don't read past the end. */
196 if ( p >= limit )
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000197 goto Exit;
David Turner19ed8af2000-12-08 02:42:29 +0000198 }
199
200 /* Get the nibble. */
201 nib = ( p[0] >> phase ) & 0xF;
202 phase = 4 - phase;
203
204 if ( nib == 0xE )
205 sign = 1;
206 else if ( nib > 9 )
207 break;
208 else
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000209 {
210 /* Increase exponent if we can't add the digit. */
211 if ( number >= 0xCCCCCCCL )
212 exponent_add++;
213 /* Skip leading zeros. */
214 else if ( nib || number )
215 {
216 integer_length++;
217 number = number * 10 + nib;
218 }
219 }
David Turner19ed8af2000-12-08 02:42:29 +0000220 }
221
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000222 /* Read fraction part, if any. */
David Turner19ed8af2000-12-08 02:42:29 +0000223 if ( nib == 0xa )
224 for (;;)
225 {
David Turner19ed8af2000-12-08 02:42:29 +0000226 /* If we entered this iteration with phase == 4, we need */
227 /* to read a new byte. */
228 if ( phase )
Werner Lembergcc069be2000-12-08 16:17:16 +0000229 {
David Turner19ed8af2000-12-08 02:42:29 +0000230 p++;
231
232 /* Make sure we don't read past the end. */
233 if ( p >= limit )
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000234 goto Exit;
Werner Lembergcc069be2000-12-08 16:17:16 +0000235 }
David Turner19ed8af2000-12-08 02:42:29 +0000236
237 /* Get the nibble. */
238 nib = ( p[0] >> phase ) & 0xF;
239 phase = 4 - phase;
240 if ( nib >= 10 )
241 break;
242
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000243 /* Skip leading zeros if possible. */
244 if ( !nib && !number )
245 exponent_add--;
246 /* Only add digit if we don't overflow. */
247 else if ( number < 0xCCCCCCCL )
David Turner19ed8af2000-12-08 02:42:29 +0000248 {
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000249 fraction_length++;
250 number = number * 10 + nib;
David Turner19ed8af2000-12-08 02:42:29 +0000251 }
252 }
253
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000254 /* Read exponent, if any. */
David Turner19ed8af2000-12-08 02:42:29 +0000255 if ( nib == 12 )
256 {
Werner Lemberg4b8397c2004-08-29 16:50:09 +0000257 exponent_sign = 1;
258 nib = 11;
David Turner19ed8af2000-12-08 02:42:29 +0000259 }
260
261 if ( nib == 11 )
262 {
David Turner19ed8af2000-12-08 02:42:29 +0000263 for (;;)
264 {
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000265 /* If we entered this iteration with phase == 4, */
266 /* we need to read a new byte. */
David Turner19ed8af2000-12-08 02:42:29 +0000267 if ( phase )
Werner Lembergcc069be2000-12-08 16:17:16 +0000268 {
David Turner19ed8af2000-12-08 02:42:29 +0000269 p++;
270
271 /* Make sure we don't read past the end. */
272 if ( p >= limit )
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000273 goto Exit;
Werner Lembergcc069be2000-12-08 16:17:16 +0000274 }
David Turner19ed8af2000-12-08 02:42:29 +0000275
276 /* Get the nibble. */
277 nib = ( p[0] >> phase ) & 0xF;
278 phase = 4 - phase;
279 if ( nib >= 10 )
280 break;
281
Werner Lemberg4b8397c2004-08-29 16:50:09 +0000282 exponent = exponent * 10 + nib;
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000283
284 /* Arbitrarily limit exponent. */
285 if ( exponent > 1000 )
286 goto Exit;
David Turner19ed8af2000-12-08 02:42:29 +0000287 }
288
Werner Lemberg4b8397c2004-08-29 16:50:09 +0000289 if ( exponent_sign )
290 exponent = -exponent;
David Turner19ed8af2000-12-08 02:42:29 +0000291 }
292
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000293 /* We don't check `power_ten' and `exponent_add'. */
294 exponent += power_ten + exponent_add;
Tom Kacvinskyc27cd282001-02-07 01:11:54 +0000295
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000296 if ( scaling )
Werner Lembergd156cab2007-12-14 07:48:32 +0000297 {
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000298 /* Only use `fraction_length'. */
299 fraction_length += integer_length;
300 exponent += integer_length;
Werner Lembergd156cab2007-12-14 07:48:32 +0000301
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000302 if ( fraction_length <= 5 )
303 {
304 if ( number > 0x7FFFL )
305 {
306 result = FT_DivFix( number, 10 );
307 *scaling = exponent - fraction_length + 1;
308 }
309 else
310 {
311 if ( exponent > 0 )
312 {
313 FT_Int new_fraction_length, shift;
314
315
316 /* Make `scaling' as small as possible. */
317 new_fraction_length = FT_MIN( exponent, 5 );
318 exponent -= new_fraction_length;
319 shift = new_fraction_length - fraction_length;
320
321 number *= power_tens[shift];
322 if ( number > 0x7FFFL )
323 {
324 number /= 10;
325 exponent += 1;
326 }
327 }
328 else
329 exponent -= fraction_length;
330
331 result = number << 16;
332 *scaling = exponent;
333 }
334 }
335 else
336 {
337 if ( ( number / power_tens[fraction_length - 5] ) > 0x7FFFL )
338 {
339 result = FT_DivFix( number, power_tens[fraction_length - 4] );
340 *scaling = exponent - 4;
341 }
342 else
343 {
344 result = FT_DivFix( number, power_tens[fraction_length - 5] );
345 *scaling = exponent - 5;
346 }
347 }
Werner Lembergd156cab2007-12-14 07:48:32 +0000348 }
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000349 else
Werner Lembergd156cab2007-12-14 07:48:32 +0000350 {
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000351 integer_length += exponent;
352 fraction_length -= exponent;
Werner Lembergd156cab2007-12-14 07:48:32 +0000353
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000354 /* Check for overflow and underflow. */
355 if ( FT_ABS( integer_length ) > 5 )
356 goto Exit;
357
358 /* Convert into 16.16 format. */
359 if ( fraction_length > 0 )
360 {
361 if ( ( number / power_tens[fraction_length] ) > 0x7FFFL )
362 goto Exit;
363
364 result = FT_DivFix( number, power_tens[fraction_length] );
365 }
366 else
367 {
368 number *= power_tens[-fraction_length];
369
370 if ( number > 0x7FFFL )
371 goto Exit;
372
373 result = number << 16;
374 }
Werner Lembergd156cab2007-12-14 07:48:32 +0000375 }
376
David Turner19ed8af2000-12-08 02:42:29 +0000377 if ( sign )
378 result = -result;
379
380 Exit:
381 return result;
David Turner19ed8af2000-12-08 02:42:29 +0000382 }
383
384
385 /* read a number, either integer or real */
Werner Lemberg93616ec2001-06-27 19:46:12 +0000386 static FT_Long
387 cff_parse_num( FT_Byte** d )
David Turner19ed8af2000-12-08 02:42:29 +0000388 {
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000389 return **d == 30 ? ( cff_parse_real( d[0], d[1], 0, NULL ) >> 16 )
390 : cff_parse_integer( d[0], d[1] );
David Turner19ed8af2000-12-08 02:42:29 +0000391 }
392
393
Werner Lembergcc069be2000-12-08 16:17:16 +0000394 /* read a floating point number, either integer or real */
Werner Lemberg93616ec2001-06-27 19:46:12 +0000395 static FT_Fixed
396 cff_parse_fixed( FT_Byte** d )
David Turner19ed8af2000-12-08 02:42:29 +0000397 {
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000398 return **d == 30 ? cff_parse_real( d[0], d[1], 0, NULL )
399 : cff_parse_integer( d[0], d[1] ) << 16;
David Turner19ed8af2000-12-08 02:42:29 +0000400 }
401
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000402
Tom Kacvinskyc27cd282001-02-07 01:11:54 +0000403 /* read a floating point number, either integer or real, */
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000404 /* but return `10^scaling' times the number read in */
Werner Lemberg93616ec2001-06-27 19:46:12 +0000405 static FT_Fixed
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000406 cff_parse_fixed_scaled( FT_Byte** d,
407 FT_Int scaling )
Tom Kacvinskyc27cd282001-02-07 01:11:54 +0000408 {
Werner Lemberg500dc852001-02-10 17:45:01 +0000409 return **d ==
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000410 30 ? cff_parse_real( d[0], d[1], scaling, NULL )
411 : (FT_Fixed)FT_MulFix( cff_parse_integer( d[0], d[1] ) << 16,
412 power_tens[scaling] );
Tom Kacvinskyc27cd282001-02-07 01:11:54 +0000413 }
David Turner19ed8af2000-12-08 02:42:29 +0000414
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000415
Werner Lemberge6e6ead2008-05-14 23:05:38 +0000416 /* read a floating point number, either integer or real, */
417 /* and return it as precise as possible -- `scaling' returns */
418 /* the scaling factor (as a power of 10) */
419 static FT_Fixed
420 cff_parse_fixed_dynamic( FT_Byte** d,
421 FT_Int* scaling )
422 {
423 FT_ASSERT( scaling );
424
425 if ( **d == 30 )
426 return cff_parse_real( d[0], d[1], 0, scaling );
427 else
428 {
429 FT_Long number;
430 FT_Int integer_length;
431
432
433 number = cff_parse_integer( d[0], d[1] );
434
435 if ( number > 0x7FFFL )
436 {
437 for ( integer_length = 5; integer_length < 10; integer_length++ )
438 if ( number < power_tens[integer_length] )
439 break;
440
441 if ( ( number / power_tens[integer_length - 5] ) > 0x7FFFL )
442 {
443 *scaling = integer_length - 4;
444 return FT_DivFix( number, power_tens[integer_length - 4] );
445 }
446 else
447 {
448 *scaling = integer_length - 5;
449 return FT_DivFix( number, power_tens[integer_length - 5] );
450 }
451 }
452 else
453 {
454 *scaling = 0;
455 return number << 16;
456 }
457 }
458 }
459
460
Werner Lemberg93616ec2001-06-27 19:46:12 +0000461 static FT_Error
Werner Lemberg48c984b2002-03-30 16:41:09 +0000462 cff_parse_font_matrix( CFF_Parser parser )
David Turner19ed8af2000-12-08 02:42:29 +0000463 {
David Turnerab4fc4d2002-03-14 08:57:10 +0000464 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
Werner Lemberg48c984b2002-03-30 16:41:09 +0000465 FT_Matrix* matrix = &dict->font_matrix;
466 FT_Vector* offset = &dict->font_offset;
Werner Lemberge6e6ead2008-05-14 23:05:38 +0000467 FT_ULong* upm = &dict->units_per_em;
Werner Lemberg48c984b2002-03-30 16:41:09 +0000468 FT_Byte** data = parser->stack;
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000469 FT_Error error = CFF_Err_Stack_Underflow;
David Turner19ed8af2000-12-08 02:42:29 +0000470
Werner Lemberg6b766632000-12-30 22:14:58 +0000471
David Turner19ed8af2000-12-08 02:42:29 +0000472 if ( parser->top >= parser->stack + 6 )
473 {
Werner Lemberge6e6ead2008-05-14 23:05:38 +0000474 FT_Int scaling;
Tom Kacvinskya05c02c2000-12-24 09:57:28 +0000475
Tom Kacvinskya05c02c2000-12-24 09:57:28 +0000476
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000477 error = CFF_Err_Ok;
Werner Lemberge6e6ead2008-05-14 23:05:38 +0000478
479 /* We expect a well-formed font matrix, this is, the matrix elements */
480 /* `xx' and `yy' are of approximately the same magnitude. To avoid */
481 /* loss of precision, we use the magnitude of element `xx' to scale */
482 /* all other elements. The scaling factor is then contained in the */
483 /* `units_per_em' value. */
484
485 matrix->xx = cff_parse_fixed_dynamic( data++, &scaling );
486
487 scaling = -scaling;
488
489 if ( scaling < 0 || scaling > 9 )
490 {
491 /* Return default matrix in case of unlikely values. */
492 matrix->xx = 0x10000L;
493 matrix->yx = 0;
494 matrix->yx = 0;
495 matrix->yy = 0x10000L;
496 offset->x = 0;
497 offset->y = 0;
498 *upm = 1;
499
500 goto Exit;
501 }
502
503 matrix->yx = cff_parse_fixed_scaled( data++, scaling );
504 matrix->xy = cff_parse_fixed_scaled( data++, scaling );
505 matrix->yy = cff_parse_fixed_scaled( data++, scaling );
506 offset->x = cff_parse_fixed_scaled( data++, scaling );
507 offset->y = cff_parse_fixed_scaled( data, scaling );
508
509 *upm = power_tens[scaling];
David Turner19ed8af2000-12-08 02:42:29 +0000510 }
511
Werner Lemberge6e6ead2008-05-14 23:05:38 +0000512 Exit:
David Turner19ed8af2000-12-08 02:42:29 +0000513 return error;
514 }
515
516
Werner Lemberg93616ec2001-06-27 19:46:12 +0000517 static FT_Error
Werner Lemberg48c984b2002-03-30 16:41:09 +0000518 cff_parse_font_bbox( CFF_Parser parser )
David Turner19ed8af2000-12-08 02:42:29 +0000519 {
David Turnerab4fc4d2002-03-14 08:57:10 +0000520 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
Werner Lemberg48c984b2002-03-30 16:41:09 +0000521 FT_BBox* bbox = &dict->font_bbox;
522 FT_Byte** data = parser->stack;
523 FT_Error error;
David Turner19ed8af2000-12-08 02:42:29 +0000524
525
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000526 error = CFF_Err_Stack_Underflow;
David Turner19ed8af2000-12-08 02:42:29 +0000527
528 if ( parser->top >= parser->stack + 4 )
529 {
Tom Kacvinskyc24eff82001-03-17 19:01:25 +0000530 bbox->xMin = FT_RoundFix( cff_parse_fixed( data++ ) );
531 bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) );
532 bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) );
533 bbox->yMax = FT_RoundFix( cff_parse_fixed( data ) );
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000534 error = CFF_Err_Ok;
David Turner19ed8af2000-12-08 02:42:29 +0000535 }
536
537 return error;
538 }
539
540
Werner Lemberg93616ec2001-06-27 19:46:12 +0000541 static FT_Error
Werner Lemberg48c984b2002-03-30 16:41:09 +0000542 cff_parse_private_dict( CFF_Parser parser )
David Turner19ed8af2000-12-08 02:42:29 +0000543 {
David Turnerab4fc4d2002-03-14 08:57:10 +0000544 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
Werner Lemberg48c984b2002-03-30 16:41:09 +0000545 FT_Byte** data = parser->stack;
546 FT_Error error;
David Turner19ed8af2000-12-08 02:42:29 +0000547
548
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000549 error = CFF_Err_Stack_Underflow;
David Turner19ed8af2000-12-08 02:42:29 +0000550
551 if ( parser->top >= parser->stack + 2 )
552 {
553 dict->private_size = cff_parse_num( data++ );
554 dict->private_offset = cff_parse_num( data );
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000555 error = CFF_Err_Ok;
David Turner19ed8af2000-12-08 02:42:29 +0000556 }
557
558 return error;
559 }
560
561
Werner Lemberg93616ec2001-06-27 19:46:12 +0000562 static FT_Error
Werner Lemberg48c984b2002-03-30 16:41:09 +0000563 cff_parse_cid_ros( CFF_Parser parser )
David Turner19ed8af2000-12-08 02:42:29 +0000564 {
David Turnerab4fc4d2002-03-14 08:57:10 +0000565 CFF_FontRecDict dict = (CFF_FontRecDict)parser->object;
Werner Lemberg48c984b2002-03-30 16:41:09 +0000566 FT_Byte** data = parser->stack;
567 FT_Error error;
David Turner19ed8af2000-12-08 02:42:29 +0000568
569
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000570 error = CFF_Err_Stack_Underflow;
David Turner19ed8af2000-12-08 02:42:29 +0000571
572 if ( parser->top >= parser->stack + 3 )
573 {
574 dict->cid_registry = (FT_UInt)cff_parse_num ( data++ );
575 dict->cid_ordering = (FT_UInt)cff_parse_num ( data++ );
576 dict->cid_supplement = (FT_ULong)cff_parse_num( data );
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000577 error = CFF_Err_Ok;
David Turner19ed8af2000-12-08 02:42:29 +0000578 }
579
580 return error;
581 }
582
583
584#define CFF_FIELD_NUM( code, name ) \
585 CFF_FIELD( code, name, cff_kind_num )
586#define CFF_FIELD_FIXED( code, name ) \
587 CFF_FIELD( code, name, cff_kind_fixed )
Werner Lembergbf7c8322003-06-06 05:07:53 +0000588#define CFF_FIELD_FIXED_1000( code, name ) \
589 CFF_FIELD( code, name, cff_kind_fixed_thousand )
David Turner19ed8af2000-12-08 02:42:29 +0000590#define CFF_FIELD_STRING( code, name ) \
591 CFF_FIELD( code, name, cff_kind_string )
592#define CFF_FIELD_BOOL( code, name ) \
593 CFF_FIELD( code, name, cff_kind_bool )
594#define CFF_FIELD_DELTA( code, name, max ) \
595 CFF_FIELD( code, name, cff_kind_delta )
596
597#define CFF_FIELD_CALLBACK( code, name ) \
598 { \
599 cff_kind_callback, \
600 code | CFFCODE, \
601 0, 0, \
602 cff_parse_ ## name, \
603 0, 0 \
604 },
605
606#undef CFF_FIELD
607#define CFF_FIELD( code, name, kind ) \
608 { \
609 kind, \
610 code | CFFCODE, \
611 FT_FIELD_OFFSET( name ), \
612 FT_FIELD_SIZE( name ), \
613 0, 0, 0 \
614 },
615
616#undef CFF_FIELD_DELTA
617#define CFF_FIELD_DELTA( code, name, max ) \
618 { \
619 cff_kind_delta, \
620 code | CFFCODE, \
621 FT_FIELD_OFFSET( name ), \
622 FT_FIELD_SIZE_DELTA( name ), \
623 0, \
624 max, \
625 FT_FIELD_OFFSET( num_ ## name ) \
626 },
627
628#define CFFCODE_TOPDICT 0x1000
629#define CFFCODE_PRIVATE 0x2000
630
631 static const CFF_Field_Handler cff_field_handlers[] =
632 {
633
David Turner8d3a4012001-03-20 11:14:24 +0000634#include "cfftoken.h"
David Turner19ed8af2000-12-08 02:42:29 +0000635
636 { 0, 0, 0, 0, 0, 0, 0 }
637 };
638
639
David Turnerbc82f1b2002-03-01 02:26:22 +0000640 FT_LOCAL_DEF( FT_Error )
David Turnerb9b2cac2002-07-10 16:52:06 +0000641 cff_parser_run( CFF_Parser parser,
Werner Lemberg48c984b2002-03-30 16:41:09 +0000642 FT_Byte* start,
643 FT_Byte* limit )
David Turner19ed8af2000-12-08 02:42:29 +0000644 {
645 FT_Byte* p = start;
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000646 FT_Error error = CFF_Err_Ok;
David Turner19ed8af2000-12-08 02:42:29 +0000647
648
649 parser->top = parser->stack;
650 parser->start = start;
651 parser->limit = limit;
652 parser->cursor = start;
653
654 while ( p < limit )
655 {
David Turner8edbcab2001-06-19 08:28:24 +0000656 FT_UInt v = *p;
David Turner19ed8af2000-12-08 02:42:29 +0000657
658
659 if ( v >= 27 && v != 31 )
660 {
661 /* it's a number; we will push its position on the stack */
662 if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )
663 goto Stack_Overflow;
664
665 *parser->top ++ = p;
666
667 /* now, skip it */
668 if ( v == 30 )
669 {
670 /* skip real number */
671 p++;
672 for (;;)
673 {
674 if ( p >= limit )
675 goto Syntax_Error;
676 v = p[0] >> 4;
677 if ( v == 15 )
678 break;
679 v = p[0] & 0xF;
680 if ( v == 15 )
681 break;
682 p++;
683 }
684 }
685 else if ( v == 28 )
686 p += 2;
687 else if ( v == 29 )
688 p += 4;
689 else if ( v > 246 )
690 p += 1;
691 }
692 else
693 {
694 /* This is not a number, hence it's an operator. Compute its code */
695 /* and look for it in our current list. */
696
Werner Lembergcc069be2000-12-08 16:17:16 +0000697 FT_UInt code;
698 FT_UInt num_args = (FT_UInt)
699 ( parser->top - parser->stack );
David Turner19ed8af2000-12-08 02:42:29 +0000700 const CFF_Field_Handler* field;
701
702
David Turner19ed8af2000-12-08 02:42:29 +0000703 *parser->top = p;
704 code = v;
705 if ( v == 12 )
706 {
707 /* two byte operator */
708 p++;
David Turner25f845a2002-09-09 23:45:29 +0000709 if ( p >= limit )
710 goto Syntax_Error;
711
David Turner19ed8af2000-12-08 02:42:29 +0000712 code = 0x100 | p[0];
713 }
714 code = code | parser->object_code;
715
716 for ( field = cff_field_handlers; field->kind; field++ )
717 {
718 if ( field->code == (FT_Int)code )
719 {
720 /* we found our field's handler; read it */
721 FT_Long val;
722 FT_Byte* q = (FT_Byte*)parser->object + field->offset;
723
Werner Lembergcc069be2000-12-08 16:17:16 +0000724
David Turner25f845a2002-09-09 23:45:29 +0000725 /* check that we have enough arguments -- except for */
726 /* delta encoded arrays, which can be empty */
727 if ( field->kind != cff_kind_delta && num_args < 1 )
728 goto Stack_Underflow;
729
David Turner19ed8af2000-12-08 02:42:29 +0000730 switch ( field->kind )
731 {
732 case cff_kind_bool:
733 case cff_kind_string:
734 case cff_kind_num:
735 val = cff_parse_num( parser->stack );
736 goto Store_Number;
737
738 case cff_kind_fixed:
739 val = cff_parse_fixed( parser->stack );
Werner Lembergbf7c8322003-06-06 05:07:53 +0000740 goto Store_Number;
741
742 case cff_kind_fixed_thousand:
Werner Lemberg551dd3c2008-05-04 13:37:38 +0000743 val = cff_parse_fixed_scaled( parser->stack, 3 );
David Turner19ed8af2000-12-08 02:42:29 +0000744
745 Store_Number:
746 switch ( field->size )
747 {
Werner Lemberg2b32a172004-04-24 06:06:39 +0000748 case (8 / FT_CHAR_BIT):
David Turner19ed8af2000-12-08 02:42:29 +0000749 *(FT_Byte*)q = (FT_Byte)val;
750 break;
751
Werner Lemberg2b32a172004-04-24 06:06:39 +0000752 case (16 / FT_CHAR_BIT):
David Turner19ed8af2000-12-08 02:42:29 +0000753 *(FT_Short*)q = (FT_Short)val;
754 break;
755
Werner Lemberg2b32a172004-04-24 06:06:39 +0000756 case (32 / FT_CHAR_BIT):
David Turner19ed8af2000-12-08 02:42:29 +0000757 *(FT_Int32*)q = (FT_Int)val;
758 break;
759
Werner Lemberg2b32a172004-04-24 06:06:39 +0000760 default: /* for 64-bit systems */
David Turner19ed8af2000-12-08 02:42:29 +0000761 *(FT_Long*)q = val;
762 }
763 break;
764
765 case cff_kind_delta:
766 {
767 FT_Byte* qcount = (FT_Byte*)parser->object +
768 field->count_offset;
769
770 FT_Byte** data = parser->stack;
771
772
773 if ( num_args > field->array_max )
774 num_args = field->array_max;
775
776 /* store count */
777 *qcount = (FT_Byte)num_args;
778
779 val = 0;
780 while ( num_args > 0 )
781 {
782 val += cff_parse_num( data++ );
783 switch ( field->size )
784 {
Werner Lemberg2b32a172004-04-24 06:06:39 +0000785 case (8 / FT_CHAR_BIT):
David Turner19ed8af2000-12-08 02:42:29 +0000786 *(FT_Byte*)q = (FT_Byte)val;
787 break;
788
Werner Lemberg2b32a172004-04-24 06:06:39 +0000789 case (16 / FT_CHAR_BIT):
David Turner19ed8af2000-12-08 02:42:29 +0000790 *(FT_Short*)q = (FT_Short)val;
791 break;
792
Werner Lemberg2b32a172004-04-24 06:06:39 +0000793 case (32 / FT_CHAR_BIT):
David Turner19ed8af2000-12-08 02:42:29 +0000794 *(FT_Int32*)q = (FT_Int)val;
795 break;
796
797 default: /* for 64-bit systems */
798 *(FT_Long*)q = val;
799 }
800
801 q += field->size;
802 num_args--;
803 }
804 }
805 break;
806
807 default: /* callback */
808 error = field->reader( parser );
809 if ( error )
810 goto Exit;
811 }
812 goto Found;
813 }
814 }
815
816 /* this is an unknown operator, or it is unsupported; */
817 /* we will ignore it for now. */
818
819 Found:
820 /* clear stack */
821 parser->top = parser->stack;
822 }
823 p++;
824 }
825
826 Exit:
827 return error;
828
829 Stack_Overflow:
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000830 error = CFF_Err_Invalid_Argument;
David Turner19ed8af2000-12-08 02:42:29 +0000831 goto Exit;
832
833 Stack_Underflow:
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000834 error = CFF_Err_Invalid_Argument;
David Turner19ed8af2000-12-08 02:42:29 +0000835 goto Exit;
836
837 Syntax_Error:
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000838 error = CFF_Err_Invalid_Argument;
David Turner19ed8af2000-12-08 02:42:29 +0000839 goto Exit;
840 }
841
842
843/* END */