blob: 7ba385b1e49dd22c59493e42846d46ca2ffd3d7c [file] [log] [blame]
David Turner19ed8af2000-12-08 02:42:29 +00001/***************************************************************************/
2/* */
3/* cffparse.c */
4/* */
5/* CFF token stream parser (body) */
6/* */
7/* Copyright 1996-2000 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
Werner Lembergcc069be2000-12-08 16:17:16 +000018
David Turner19ed8af2000-12-08 02:42:29 +000019#include <ft2build.h>
David Turner170c0d42000-12-13 19:55:11 +000020#include FT_SOURCE_FILE(cff,cffparse.h)
David Turner19ed8af2000-12-08 02:42:29 +000021#include FT_INTERNAL_CFF_ERRORS_H
22#include FT_INTERNAL_STREAM_H
23
Werner Lembergcc069be2000-12-08 16:17:16 +000024
David Turner19ed8af2000-12-08 02:42:29 +000025 /*************************************************************************/
26 /* */
27 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
28 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
29 /* messages during execution. */
30 /* */
31#undef FT_COMPONENT
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +000032#define FT_COMPONENT trace_cffparse
David Turner19ed8af2000-12-08 02:42:29 +000033
34
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +000035#define CFF_Err_Stack_Underflow FT_Err_Invalid_Argument
36#define CFF_Err_Syntax_Error FT_Err_Invalid_Argument
David Turner19ed8af2000-12-08 02:42:29 +000037
38
39 enum
40 {
41 cff_kind_none = 0,
42 cff_kind_num,
43 cff_kind_fixed,
44 cff_kind_string,
45 cff_kind_bool,
46 cff_kind_delta,
47 cff_kind_callback,
48
49 cff_kind_max /* do not remove */
50 };
51
52
53 /* now generate handlers for the most simple fields */
54 typedef FT_Error (*CFF_Field_Reader)( CFF_Parser* parser );
55
56 typedef struct CFF_Field_Handler_
57 {
58 int kind;
59 int code;
60 FT_UInt offset;
61 FT_Byte size;
62 CFF_Field_Reader reader;
63 FT_UInt array_max;
64 FT_UInt count_offset;
65
66 } CFF_Field_Handler;
67
68
Werner Lembergcc069be2000-12-08 16:17:16 +000069 FT_LOCAL_DEF
70 void CFF_Parser_Init( CFF_Parser* parser,
71 FT_UInt code,
72 void* object )
David Turner19ed8af2000-12-08 02:42:29 +000073 {
74 MEM_Set( parser, 0, sizeof ( *parser ) );
75
76 parser->top = parser->stack;
77 parser->object_code = code;
78 parser->object = object;
79 }
80
81
Werner Lembergcc069be2000-12-08 16:17:16 +000082 /* read an integer */
83 static
84 FT_Long cff_parse_integer( FT_Byte* start,
85 FT_Byte* limit )
David Turner19ed8af2000-12-08 02:42:29 +000086 {
87 FT_Byte* p = start;
88 FT_Int v = *p++;
89 FT_Long val = 0;
90
91
92 if ( v == 28 )
93 {
94 if ( p + 2 > limit )
95 goto Bad;
96
97 val = (FT_Short)( ( (FT_Int)p[0] << 8 ) | p[1] );
98 p += 2;
99 }
100 else if ( v == 29 )
101 {
102 if ( p + 4 > limit )
103 goto Bad;
104
105 val = ( (FT_Long)p[0] << 24 ) |
106 ( (FT_Long)p[1] << 16 ) |
107 ( (FT_Long)p[2] << 8 ) |
108 p[3];
109 p += 4;
110 }
111 else if ( v < 247 )
112 {
113 val = v - 139;
114 }
115 else if ( v < 251 )
116 {
117 if ( p + 1 > limit )
118 goto Bad;
119
120 val = ( v - 247 ) * 256 + p[0] + 108;
121 p++;
122 }
123 else
124 {
125 if ( p + 1 > limit )
126 goto Bad;
127
128 val = -( v - 251 ) * 256 - p[0] - 108;
129 p++;
130 }
131
132 Exit:
133 return val;
134
135 Bad:
136 val = 0;
137 goto Exit;
138 }
139
140
141 /* read a real */
Werner Lembergcc069be2000-12-08 16:17:16 +0000142 static
143 FT_Fixed cff_parse_real( FT_Byte* start,
144 FT_Byte* limit,
145 FT_Int power_ten )
David Turner19ed8af2000-12-08 02:42:29 +0000146 {
147 FT_Byte* p = start;
148 FT_Long num, divider, result, exp;
149 FT_Int sign = 0, exp_sign = 0;
150 FT_Byte nib;
151 FT_Byte phase;
152
153
154 result = 0;
155 num = 0;
156 divider = 1;
157
158 /* first of all, read the integer part */
159 phase = 4;
160
161 for (;;)
162 {
David Turner19ed8af2000-12-08 02:42:29 +0000163 /* If we entered this iteration with phase == 4, we need to */
164 /* read a new byte. This also skips past the intial 0x1E. */
165 if ( phase )
166 {
167 p++;
168
169 /* Make sure we don't read past the end. */
170 if ( p >= limit )
171 goto Bad;
172 }
173
174 /* Get the nibble. */
175 nib = ( p[0] >> phase ) & 0xF;
176 phase = 4 - phase;
177
178 if ( nib == 0xE )
179 sign = 1;
180 else if ( nib > 9 )
181 break;
182 else
183 result = result * 10 + nib;
184 }
185
186 /* read decimal part, if any */
187 if ( nib == 0xa )
188 for (;;)
189 {
David Turner19ed8af2000-12-08 02:42:29 +0000190 /* If we entered this iteration with phase == 4, we need */
191 /* to read a new byte. */
192 if ( phase )
Werner Lembergcc069be2000-12-08 16:17:16 +0000193 {
David Turner19ed8af2000-12-08 02:42:29 +0000194 p++;
195
196 /* Make sure we don't read past the end. */
197 if ( p >= limit )
198 goto Bad;
Werner Lembergcc069be2000-12-08 16:17:16 +0000199 }
David Turner19ed8af2000-12-08 02:42:29 +0000200
201 /* Get the nibble. */
202 nib = ( p[0] >> phase ) & 0xF;
203 phase = 4 - phase;
204 if ( nib >= 10 )
205 break;
206
Werner Lembergcc069be2000-12-08 16:17:16 +0000207 if ( divider < 10000000L )
David Turner19ed8af2000-12-08 02:42:29 +0000208 {
209 num = num * 10 + nib;
210 divider *= 10;
211 }
212 }
213
214 /* read exponent, if any */
215 if ( nib == 12 )
216 {
217 exp_sign = 1;
218 nib = 11;
219 }
220
221 if ( nib == 11 )
222 {
223 exp = 0;
224
225 for (;;)
226 {
227 /* If we entered this iteration with phase == 4, we need */
228 /* to read a new byte. */
229 if ( phase )
Werner Lembergcc069be2000-12-08 16:17:16 +0000230 {
David Turner19ed8af2000-12-08 02:42:29 +0000231 p++;
232
233 /* Make sure we don't read past the end. */
234 if ( p >= limit )
235 goto Bad;
Werner Lembergcc069be2000-12-08 16:17:16 +0000236 }
David Turner19ed8af2000-12-08 02:42:29 +0000237
238 /* Get the nibble. */
239 nib = ( p[0] >> phase ) & 0xF;
240 phase = 4 - phase;
241 if ( nib >= 10 )
242 break;
243
244 exp = exp * 10 + nib;
245 }
246
247 if ( exp_sign )
248 exp = -exp;
249
250 power_ten += exp;
251 }
252
253 /* raise to power of ten if needed */
254 while ( power_ten > 0 )
255 {
256 result = result * 10;
257 num = num * 10;
258
259 power_ten--;
260 }
261
262 while ( power_ten < 0 )
263 {
264 result = result / 10;
265 divider = divider * 10;
266
267 power_ten++;
268 }
269
Tom Kacvinskyc27cd282001-02-07 01:11:54 +0000270 /* Move the integer part into the high 16 bits. */
271 result <<= 16;
272
273 /* Place the decimal part into the low 16 bits. */
David Turner19ed8af2000-12-08 02:42:29 +0000274 if ( num )
Tom Kacvinskyc27cd282001-02-07 01:11:54 +0000275 result |= FT_DivFix( num, divider );
David Turner19ed8af2000-12-08 02:42:29 +0000276
277 if ( sign )
278 result = -result;
279
280 Exit:
281 return result;
282
283 Bad:
284 result = 0;
285 goto Exit;
286 }
287
288
289 /* read a number, either integer or real */
Werner Lembergcc069be2000-12-08 16:17:16 +0000290 static
291 FT_Long cff_parse_num( FT_Byte** d )
David Turner19ed8af2000-12-08 02:42:29 +0000292 {
293 return ( **d == 30 ? ( cff_parse_real ( d[0], d[1], 0 ) >> 16 )
294 : cff_parse_integer( d[0], d[1] ) );
295 }
296
297
Werner Lembergcc069be2000-12-08 16:17:16 +0000298 /* read a floating point number, either integer or real */
299 static
300 FT_Fixed cff_parse_fixed( FT_Byte** d )
David Turner19ed8af2000-12-08 02:42:29 +0000301 {
302 return ( **d == 30 ? cff_parse_real ( d[0], d[1], 0 )
303 : cff_parse_integer( d[0], d[1] ) << 16 );
304 }
305
Tom Kacvinskyc27cd282001-02-07 01:11:54 +0000306 /* read a floating point number, either integer or real, */
307 /* but return 1000 times the number read in. */
308 static
309 FT_Fixed cff_parse_fixed_thousand( FT_Byte** d )
310 {
311 return ( **d == 30 ? cff_parse_real ( d[0], d[1], 3 )
312 : (FT_Fixed)FT_MulFix ( cff_parse_integer( d[0], d[1] ) << 16, 1000 ) );
313 }
David Turner19ed8af2000-12-08 02:42:29 +0000314
Werner Lembergcc069be2000-12-08 16:17:16 +0000315 static
316 FT_Error cff_parse_font_matrix( CFF_Parser* parser )
David Turner19ed8af2000-12-08 02:42:29 +0000317 {
318 CFF_Font_Dict* dict = (CFF_Font_Dict*)parser->object;
319 FT_Matrix* matrix = &dict->font_matrix;
320 FT_Vector* offset = &dict->font_offset;
Tom Kacvinskyc27cd282001-02-07 01:11:54 +0000321 FT_UShort* upm = &dict->units_per_em;
David Turner19ed8af2000-12-08 02:42:29 +0000322 FT_Byte** data = parser->stack;
323 FT_Error error;
Tom Kacvinskya05c02c2000-12-24 09:57:28 +0000324 FT_Fixed temp;
David Turner19ed8af2000-12-08 02:42:29 +0000325
Werner Lemberg6b766632000-12-30 22:14:58 +0000326
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000327 error = CFF_Err_Stack_Underflow;
David Turner19ed8af2000-12-08 02:42:29 +0000328
329 if ( parser->top >= parser->stack + 6 )
330 {
Tom Kacvinskyc27cd282001-02-07 01:11:54 +0000331 matrix->xx = cff_parse_fixed_thousand( data++ );
332 matrix->yx = cff_parse_fixed_thousand( data++ );
333 matrix->xy = cff_parse_fixed_thousand( data++ );
334 matrix->yy = cff_parse_fixed_thousand( data++ );
335 offset->x = cff_parse_fixed_thousand( data++ );
336 offset->y = cff_parse_fixed_thousand( data );
Tom Kacvinskya05c02c2000-12-24 09:57:28 +0000337
338 temp = ABS( matrix->yy );
339
Tom Kacvinskyc27cd282001-02-07 01:11:54 +0000340 *upm = (FT_UShort)FT_DivFix( 0x10000L, FT_DivFix( temp, 1000 ) );
341 fprintf (stderr, "cff_parse_font_matrix: matrix->xx = %08lX, upm = %d\n", matrix->xx, *upm) ;
342
Tom Kacvinskya05c02c2000-12-24 09:57:28 +0000343 if ( temp != 0x10000L )
344 {
345 matrix->xx = FT_DivFix( matrix->xx, temp );
346 matrix->yx = FT_DivFix( matrix->yx, temp );
347 matrix->xy = FT_DivFix( matrix->xy, temp );
348 matrix->yy = FT_DivFix( matrix->yy, temp );
349 offset->x = FT_DivFix( offset->x, temp );
350 offset->y = FT_DivFix( offset->y, temp );
351 }
352
353 /* note that the offsets must be expressed in integer font units */
354 offset->x >>= 16;
355 offset->y >>= 16;
356
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000357 error = CFF_Err_Ok;
David Turner19ed8af2000-12-08 02:42:29 +0000358 }
359
360 return error;
361 }
362
363
Werner Lembergcc069be2000-12-08 16:17:16 +0000364 static
365 FT_Error cff_parse_font_bbox( CFF_Parser* parser )
David Turner19ed8af2000-12-08 02:42:29 +0000366 {
367 CFF_Font_Dict* dict = (CFF_Font_Dict*)parser->object;
368 FT_BBox* bbox = &dict->font_bbox;
369 FT_Byte** data = parser->stack;
370 FT_Error error;
371
372
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000373 error = CFF_Err_Stack_Underflow;
David Turner19ed8af2000-12-08 02:42:29 +0000374
375 if ( parser->top >= parser->stack + 4 )
376 {
377 bbox->xMin = cff_parse_num( data++ );
378 bbox->yMin = cff_parse_num( data++ );
379 bbox->xMax = cff_parse_num( data++ );
380 bbox->yMax = cff_parse_num( data );
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000381 error = CFF_Err_Ok;
David Turner19ed8af2000-12-08 02:42:29 +0000382 }
383
384 return error;
385 }
386
387
Werner Lembergcc069be2000-12-08 16:17:16 +0000388 static
389 FT_Error cff_parse_private_dict( CFF_Parser* parser )
David Turner19ed8af2000-12-08 02:42:29 +0000390 {
391 CFF_Font_Dict* dict = (CFF_Font_Dict*)parser->object;
392 FT_Byte** data = parser->stack;
393 FT_Error error;
394
395
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000396 error = CFF_Err_Stack_Underflow;
David Turner19ed8af2000-12-08 02:42:29 +0000397
398 if ( parser->top >= parser->stack + 2 )
399 {
400 dict->private_size = cff_parse_num( data++ );
401 dict->private_offset = cff_parse_num( data );
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000402 error = CFF_Err_Ok;
David Turner19ed8af2000-12-08 02:42:29 +0000403 }
404
405 return error;
406 }
407
408
Werner Lembergcc069be2000-12-08 16:17:16 +0000409 static
410 FT_Error cff_parse_cid_ros( CFF_Parser* parser )
David Turner19ed8af2000-12-08 02:42:29 +0000411 {
412 CFF_Font_Dict* dict = (CFF_Font_Dict*)parser->object;
413 FT_Byte** data = parser->stack;
414 FT_Error error;
415
416
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000417 error = CFF_Err_Stack_Underflow;
David Turner19ed8af2000-12-08 02:42:29 +0000418
419 if ( parser->top >= parser->stack + 3 )
420 {
421 dict->cid_registry = (FT_UInt)cff_parse_num ( data++ );
422 dict->cid_ordering = (FT_UInt)cff_parse_num ( data++ );
423 dict->cid_supplement = (FT_ULong)cff_parse_num( data );
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000424 error = CFF_Err_Ok;
David Turner19ed8af2000-12-08 02:42:29 +0000425 }
426
427 return error;
428 }
429
430
431#define CFF_FIELD_NUM( code, name ) \
432 CFF_FIELD( code, name, cff_kind_num )
433#define CFF_FIELD_FIXED( code, name ) \
434 CFF_FIELD( code, name, cff_kind_fixed )
435#define CFF_FIELD_STRING( code, name ) \
436 CFF_FIELD( code, name, cff_kind_string )
437#define CFF_FIELD_BOOL( code, name ) \
438 CFF_FIELD( code, name, cff_kind_bool )
439#define CFF_FIELD_DELTA( code, name, max ) \
440 CFF_FIELD( code, name, cff_kind_delta )
441
442#define CFF_FIELD_CALLBACK( code, name ) \
443 { \
444 cff_kind_callback, \
445 code | CFFCODE, \
446 0, 0, \
447 cff_parse_ ## name, \
448 0, 0 \
449 },
450
451#undef CFF_FIELD
452#define CFF_FIELD( code, name, kind ) \
453 { \
454 kind, \
455 code | CFFCODE, \
456 FT_FIELD_OFFSET( name ), \
457 FT_FIELD_SIZE( name ), \
458 0, 0, 0 \
459 },
460
461#undef CFF_FIELD_DELTA
462#define CFF_FIELD_DELTA( code, name, max ) \
463 { \
464 cff_kind_delta, \
465 code | CFFCODE, \
466 FT_FIELD_OFFSET( name ), \
467 FT_FIELD_SIZE_DELTA( name ), \
468 0, \
469 max, \
470 FT_FIELD_OFFSET( num_ ## name ) \
471 },
472
473#define CFFCODE_TOPDICT 0x1000
474#define CFFCODE_PRIVATE 0x2000
475
476 static const CFF_Field_Handler cff_field_handlers[] =
477 {
478
Werner Lemberg63408a12000-12-13 23:44:37 +0000479#include FT_SOURCE_FILE(cff,cfftoken.h)
David Turner19ed8af2000-12-08 02:42:29 +0000480
481 { 0, 0, 0, 0, 0, 0, 0 }
482 };
483
484
Werner Lembergcc069be2000-12-08 16:17:16 +0000485 FT_LOCAL_DEF
486 FT_Error CFF_Parser_Run( CFF_Parser* parser,
487 FT_Byte* start,
488 FT_Byte* limit )
David Turner19ed8af2000-12-08 02:42:29 +0000489 {
490 FT_Byte* p = start;
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000491 FT_Error error = CFF_Err_Ok;
David Turner19ed8af2000-12-08 02:42:29 +0000492
493
494 parser->top = parser->stack;
495 parser->start = start;
496 parser->limit = limit;
497 parser->cursor = start;
498
499 while ( p < limit )
500 {
501 FT_Byte v = *p;
502
503
504 if ( v >= 27 && v != 31 )
505 {
506 /* it's a number; we will push its position on the stack */
507 if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )
508 goto Stack_Overflow;
509
510 *parser->top ++ = p;
511
512 /* now, skip it */
513 if ( v == 30 )
514 {
515 /* skip real number */
516 p++;
517 for (;;)
518 {
519 if ( p >= limit )
520 goto Syntax_Error;
521 v = p[0] >> 4;
522 if ( v == 15 )
523 break;
524 v = p[0] & 0xF;
525 if ( v == 15 )
526 break;
527 p++;
528 }
529 }
530 else if ( v == 28 )
531 p += 2;
532 else if ( v == 29 )
533 p += 4;
534 else if ( v > 246 )
535 p += 1;
536 }
537 else
538 {
539 /* This is not a number, hence it's an operator. Compute its code */
540 /* and look for it in our current list. */
541
Werner Lembergcc069be2000-12-08 16:17:16 +0000542 FT_UInt code;
543 FT_UInt num_args = (FT_UInt)
544 ( parser->top - parser->stack );
David Turner19ed8af2000-12-08 02:42:29 +0000545 const CFF_Field_Handler* field;
546
547
548 /* first of all, a trivial check */
549 if ( num_args < 1 )
550 goto Stack_Underflow;
551
552 *parser->top = p;
553 code = v;
554 if ( v == 12 )
555 {
556 /* two byte operator */
557 p++;
558 code = 0x100 | p[0];
559 }
560 code = code | parser->object_code;
561
562 for ( field = cff_field_handlers; field->kind; field++ )
563 {
564 if ( field->code == (FT_Int)code )
565 {
566 /* we found our field's handler; read it */
567 FT_Long val;
568 FT_Byte* q = (FT_Byte*)parser->object + field->offset;
569
Werner Lembergcc069be2000-12-08 16:17:16 +0000570
David Turner19ed8af2000-12-08 02:42:29 +0000571 switch ( field->kind )
572 {
573 case cff_kind_bool:
574 case cff_kind_string:
575 case cff_kind_num:
576 val = cff_parse_num( parser->stack );
577 goto Store_Number;
578
579 case cff_kind_fixed:
580 val = cff_parse_fixed( parser->stack );
581
582 Store_Number:
583 switch ( field->size )
584 {
585 case 1:
586 *(FT_Byte*)q = (FT_Byte)val;
587 break;
588
589 case 2:
590 *(FT_Short*)q = (FT_Short)val;
591 break;
592
593 case 4:
594 *(FT_Int32*)q = (FT_Int)val;
595 break;
596
597 default: /* for 64-bit systems where long is 8 bytes */
598 *(FT_Long*)q = val;
599 }
600 break;
601
602 case cff_kind_delta:
603 {
604 FT_Byte* qcount = (FT_Byte*)parser->object +
605 field->count_offset;
606
607 FT_Byte** data = parser->stack;
608
609
610 if ( num_args > field->array_max )
611 num_args = field->array_max;
612
613 /* store count */
614 *qcount = (FT_Byte)num_args;
615
616 val = 0;
617 while ( num_args > 0 )
618 {
619 val += cff_parse_num( data++ );
620 switch ( field->size )
621 {
622 case 1:
623 *(FT_Byte*)q = (FT_Byte)val;
624 break;
625
626 case 2:
627 *(FT_Short*)q = (FT_Short)val;
628 break;
629
630 case 4:
631 *(FT_Int32*)q = (FT_Int)val;
632 break;
633
634 default: /* for 64-bit systems */
635 *(FT_Long*)q = val;
636 }
637
638 q += field->size;
639 num_args--;
640 }
641 }
642 break;
643
644 default: /* callback */
645 error = field->reader( parser );
646 if ( error )
647 goto Exit;
648 }
649 goto Found;
650 }
651 }
652
653 /* this is an unknown operator, or it is unsupported; */
654 /* we will ignore it for now. */
655
656 Found:
657 /* clear stack */
658 parser->top = parser->stack;
659 }
660 p++;
661 }
662
663 Exit:
664 return error;
665
666 Stack_Overflow:
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000667 error = CFF_Err_Invalid_Argument;
David Turner19ed8af2000-12-08 02:42:29 +0000668 goto Exit;
669
670 Stack_Underflow:
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000671 error = CFF_Err_Invalid_Argument;
David Turner19ed8af2000-12-08 02:42:29 +0000672 goto Exit;
673
674 Syntax_Error:
Tom Kacvinsky8d1f6042001-01-03 00:21:59 +0000675 error = CFF_Err_Invalid_Argument;
David Turner19ed8af2000-12-08 02:42:29 +0000676 goto Exit;
677 }
678
679
680/* END */