:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / subsys / win32k / freetype / src / cff / t2parse.c
1 /***************************************************************************/
2 /*                                                                         */
3 /*  t2parse.c                                                              */
4 /*                                                                         */
5 /*    OpenType 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
18
19 #ifdef FT_FLAT_COMPILE
20
21 #include "t2parse.h"
22
23 #else
24
25 #include <freetype/src/cff/t2parse.h>
26
27 #endif
28
29
30 #include <freetype/internal/t2errors.h>
31
32
33   /*************************************************************************/
34   /*                                                                       */
35   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
36   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
37   /* messages during execution.                                            */
38   /*                                                                       */
39 #undef  FT_COMPONENT
40 #define FT_COMPONENT  trace_t2parse
41
42
43 #define T2_Err_Stack_Underflow   FT_Err_Invalid_Argument
44 #define T2_Err_Syntax_Error      FT_Err_Invalid_Argument
45
46
47   enum
48   {
49     t2_kind_none = 0,
50     t2_kind_num,
51     t2_kind_fixed,
52     t2_kind_string,
53     t2_kind_bool,
54     t2_kind_delta,
55     t2_kind_callback,
56
57     t2_kind_max  /* do not remove */
58   };
59
60
61   /* now generate handlers for the most simple fields */
62   typedef FT_Error  (*T2_Field_Reader)( T2_Parser*  parser );
63
64   typedef struct  T2_Field_Handler_
65   {
66     int              kind;
67     int              code;
68     FT_UInt          offset;
69     FT_Byte          size;
70     T2_Field_Reader  reader;
71     FT_UInt          array_max;
72     FT_UInt          count_offset;
73
74   } T2_Field_Handler;
75
76
77   LOCAL_FUNC
78   void  T2_Parser_Init( T2_Parser*  parser,
79                         FT_UInt     code,
80                         void*       object )
81   {
82     MEM_Set( parser, 0, sizeof ( *parser ) );
83
84     parser->top         = parser->stack;
85     parser->object_code = code;
86     parser->object      = object;
87   }
88
89
90   /* reads an integer */
91   static
92   FT_Long  parse_t2_integer( FT_Byte*  start,
93                              FT_Byte*  limit )
94   {
95     FT_Byte*  p   = start;
96     FT_Int    v   = *p++;
97     FT_Long   val = 0;
98
99
100     if ( v == 28 )
101     {
102       if ( p + 2 > limit )
103         goto Bad;
104
105       val = (FT_Short)( ( (FT_Int)p[0] << 8 ) | p[1] );
106       p  += 2;
107     }
108     else if ( v == 29 )
109     {
110       if ( p + 4 > limit )
111         goto Bad;
112
113       val = ( (FT_Long)p[0] << 24 ) |
114             ( (FT_Long)p[1] << 16 ) |
115             ( (FT_Long)p[2] <<  8 ) |
116                        p[3];
117       p += 4;
118     }
119     else if ( v < 247 )
120     {
121       val = v - 139;
122     }
123     else if ( v < 251 )
124     {
125       if ( p + 1 > limit )
126         goto Bad;
127
128       val = ( v - 247 ) * 256 + p[0] + 108;
129       p++;
130     }
131     else
132     {
133       if ( p + 1 > limit )
134         goto Bad;
135
136       val = -( v - 251 ) * 256 - p[0] - 108;
137       p++;
138     }
139
140   Exit:
141     return val;
142
143   Bad:
144     val = 0;
145     goto Exit;
146   }
147
148
149   /* read a real */
150   static
151   FT_Fixed  parse_t2_real( FT_Byte*  start,
152                            FT_Byte*  limit,
153                            FT_Int    power_ten )
154   {
155     FT_Byte*  p    = start;
156     FT_Long   num, divider, result, exp;
157     FT_Int    sign = 0, exp_sign = 0;
158     FT_Byte   nib;
159     FT_Byte   phase;
160
161
162     result  = 0;
163     num     = 0;
164     divider = 1;
165
166     /* first of all, read the integer part */
167     phase = 4;
168     p--;
169
170     for (;;)
171     {
172       /* read one nibble at a time */
173       if ( phase && ++p >= limit )
174         goto Bad;
175
176       nib   = ( p[0] >> phase ) & 0xF;
177       phase = 4 - phase;
178
179       if ( nib == 0xE )
180         sign = 1;
181       else if ( nib > 9 )
182         break;
183       else
184         result = result * 10 + nib;
185     }
186
187     /* read decimal part, if any */
188     if ( nib == 0xa )
189       for (;;)
190       {
191         /* read one nibble at a time */
192         if ( !phase && ++p >= limit )
193           goto Bad;
194
195         phase = 4 - phase;
196         nib   = ( p[0] >> phase ) & 0xF;
197
198         if ( nib >= 10 )
199           break;
200
201         if (divider < 10000000L)
202         {
203           num      = num * 10 + nib;
204           divider *= 10;
205         }
206       }
207
208     /* read exponent, if any */
209     if ( nib == 12 )
210     {
211       exp_sign = 1;
212       nib      = 11;
213     }
214
215     if ( nib == 11 )
216     {
217       exp = 0;
218
219       for (;;)
220       {
221         /* read one nibble at a time */
222         if ( !phase && ++p >= limit )
223           goto Bad;
224
225         phase = 4 - phase;
226         nib   = ( p[0] >> phase ) & 0xF;
227
228         if ( nib >= 10 )
229           break;
230
231         exp = exp * 10 + nib;
232       }
233
234       if ( exp_sign )
235         exp = -exp;
236
237       power_ten += exp;
238     }
239
240     /* raise to power of ten if needed */
241     while ( power_ten > 0 )
242     {
243       result = result * 10;
244       num    = num * 10;
245
246       power_ten--;
247     }
248
249     while ( power_ten < 0 )
250     {
251       result  = result / 10;
252       divider = divider * 10;
253
254       power_ten++;
255     }
256
257     if ( num )
258       result += FT_DivFix( num, divider );
259
260     if ( sign )
261       result = -result;
262
263   Exit:
264     return result;
265
266   Bad:
267     result = 0;
268     goto Exit;
269   }
270
271
272   /* read a number, either integer or real */
273   static
274   FT_Long  t2_parse_num( FT_Byte**  d )
275   {
276     return ( **d == 30 ? ( parse_t2_real( d[0], d[1], 0 ) >> 16 )
277                        : parse_t2_integer( d[0], d[1] ) );
278   }
279
280
281   /* reads a floating point number, either integer or real */
282   static
283   FT_Fixed  t2_parse_fixed( FT_Byte**  d )
284   {
285     return ( **d == 30 ? parse_t2_real( d[0], d[1], 0 )
286                        : parse_t2_integer( d[0], d[1] ) << 16 );
287   }
288
289
290   static
291   FT_Error  parse_font_matrix( T2_Parser*  parser )
292   {
293     CFF_Font_Dict*  dict   = (CFF_Font_Dict*)parser->object;
294     FT_Matrix*      matrix = &dict->font_matrix;
295     FT_Byte**       data   = parser->stack;
296     FT_Error        error;
297
298
299     error = T2_Err_Stack_Underflow;
300
301     if ( parser->top >= parser->stack + 4 )
302     {
303       matrix->xx = t2_parse_fixed( data++ );
304       matrix->yx = t2_parse_fixed( data++ );
305       matrix->xy = t2_parse_fixed( data++ );
306       matrix->yy = t2_parse_fixed( data   );
307       error = T2_Err_Ok;
308     }
309
310     return error;
311   }
312
313
314   static
315   FT_Error  parse_font_bbox( T2_Parser*  parser )
316   {
317     CFF_Font_Dict*  dict = (CFF_Font_Dict*)parser->object;
318     FT_BBox*        bbox = &dict->font_bbox;
319     FT_Byte**       data = parser->stack;
320     FT_Error        error;
321
322
323     error = T2_Err_Stack_Underflow;
324
325     if ( parser->top >= parser->stack + 4 )
326     {
327       bbox->xMin = t2_parse_num( data++ );
328       bbox->yMin = t2_parse_num( data++ );
329       bbox->xMax = t2_parse_num( data++ );
330       bbox->yMax = t2_parse_num( data   );
331       error = T2_Err_Ok;
332     }
333
334     return error;
335   }
336
337
338   static
339   FT_Error  parse_private_dict( T2_Parser*  parser )
340   {
341     CFF_Font_Dict*  dict = (CFF_Font_Dict*)parser->object;
342     FT_Byte**       data = parser->stack;
343     FT_Error        error;
344
345
346     error = T2_Err_Stack_Underflow;
347
348     if ( parser->top >= parser->stack + 2 )
349     {
350       dict->private_size   = t2_parse_num( data++ );
351       dict->private_offset = t2_parse_num( data   );
352       error = T2_Err_Ok;
353     }
354
355     return error;
356   }
357
358
359   static
360   FT_Error  parse_cid_ros( T2_Parser*  parser )
361   {
362     CFF_Font_Dict*  dict   = (CFF_Font_Dict*)parser->object;
363     FT_Byte**       data   = parser->stack;
364     FT_Error        error;
365
366
367     error = T2_Err_Stack_Underflow;
368
369     if ( parser->top >= parser->stack + 3 )
370     {
371       dict->cid_registry   = (FT_UInt)t2_parse_num( data++ );
372       dict->cid_ordering   = (FT_UInt)t2_parse_num( data++ );
373       dict->cid_supplement = (FT_ULong)t2_parse_num( data );
374       error = T2_Err_Ok;
375     }
376
377     return error;
378   }
379
380
381 #define T2_FIELD_NUM( code, name ) \
382           T2_FIELD( code, name, t2_kind_num )
383 #define T2_FIELD_FIXED( code, name ) \
384           T2_FIELD( code, name, t2_kind_fixed )
385 #define T2_FIELD_STRING( code, name ) \
386           T2_FIELD( code, name, t2_kind_string )
387 #define T2_FIELD_BOOL( code, name ) \
388           T2_FIELD( code, name, t2_kind_bool )
389 #define T2_FIELD_DELTA( code, name,max ) \
390           T2_FIELD( code, name, t2_kind_delta )
391
392 #define T2_REF( s, f )  ( ((s*)0)->f )
393
394 #define T2_FIELD_CALLBACK( code, name ) \
395           {                             \
396             t2_kind_callback,           \
397             code | T2CODE,              \
398             0, 0,                       \
399             parse_ ## name,             \
400             0, 0                        \
401           },
402
403 #undef  T2_FIELD
404 #define T2_FIELD( code, name, kind )                 \
405           {                                          \
406             kind,                                    \
407             code | T2CODE,                           \
408             (FT_UInt)(char*)&T2_REF( T2TYPE, name ), \
409             sizeof( T2_REF( T2TYPE, name ) ),        \
410             0, 0, 0                                  \
411           },
412
413 #undef  T2_FIELD_DELTA
414 #define T2_FIELD_DELTA( code, name, max )                    \
415         {                                                    \
416           t2_kind_delta,                                     \
417           code | T2CODE,                                     \
418           (FT_UInt)(char*)&T2_REF( T2TYPE, name ),           \
419           sizeof( T2_REF( T2TYPE, name )[0] ),               \
420           0,                                                 \
421           max,                                               \
422           (FT_UInt)(char*)&T2_REF( T2TYPE, num_ ## name )    \
423         },
424
425 #define T2CODE_TOPDICT  0x1000
426 #define T2CODE_PRIVATE  0x2000
427
428   static const T2_Field_Handler  t2_field_handlers[] =
429   {
430
431 #ifdef FT_FLAT_COMPILE
432
433 #include "t2tokens.h"
434
435 #else
436
437 #include <freetype/src/cff/t2tokens.h>
438
439 #endif
440
441     { 0, 0, 0, 0, 0, 0, 0 }
442   };
443
444
445   LOCAL_FUNC
446   FT_Error  T2_Parser_Run( T2_Parser*  parser,
447                            FT_Byte*    start,
448                            FT_Byte*    limit )
449   {
450     FT_Byte*  p     = start;
451     FT_Error  error = T2_Err_Ok;
452
453
454     parser->top    = parser->stack;
455     parser->start  = start;
456     parser->limit  = limit;
457     parser->cursor = start;
458
459     while ( p < limit )
460     {
461       FT_Byte  v = *p;
462
463
464       if ( v >= 27 && v != 31 )
465       {
466         /* it's a number; we will push its position on the stack */
467         if ( parser->top - parser->stack >= T2_MAX_STACK_DEPTH )
468           goto Stack_Overflow;
469
470         *parser->top ++ = p;
471
472         /* now, skip it */
473         if ( v == 30 )
474         {
475           /* skip real number */
476           for (;;)
477           {
478             if ( p >= limit )
479               goto Syntax_Error;
480             v = p[0] >> 4;
481             if ( v == 15 )
482               break;
483             v = p[0] & 0xF;
484             if ( v == 15 )
485               break;
486             p++;
487           }
488           p++;
489         }
490         else if ( v == 28 )
491           p += 2;
492         else if ( v == 29 )
493           p += 4;
494         else if ( v > 246 )
495           p += 1;
496       }
497       else
498       {
499         /* This is not a number, hence it's an operator.  Compute its code */
500         /* and look for it in our current list.                            */
501
502         FT_UInt                  code;
503         FT_UInt                  num_args = (FT_UInt)
504                                               ( parser->top - parser->stack );
505         const T2_Field_Handler*  field;
506
507
508         /* first of all, a trivial check */
509         if ( num_args < 1 )
510           goto Stack_Underflow;
511
512         *parser->top = p;
513         code = v;
514         if ( v == 12 )
515         {
516           /* two byte operator */
517           p++;
518           code = 0x100 | p[0];
519         }
520         code = code | parser->object_code;
521
522         for ( field = t2_field_handlers; field->kind; field++ )
523         {
524           if ( field->code == (FT_Int)code )
525           {
526             /* we found our field's handler; read it */
527             FT_Long   val;
528             FT_Byte*  q = (FT_Byte*)parser->object + field->offset;
529
530
531             switch ( field->kind )
532             {
533             case t2_kind_bool:
534             case t2_kind_string:
535             case t2_kind_num:
536               val = t2_parse_num( parser->stack );
537               goto Store_Number;
538
539             case t2_kind_fixed:
540               val = t2_parse_fixed( parser->stack );
541
542             Store_Number:
543               switch ( field->size )
544               {
545               case 1:
546                 *(FT_Byte*)q = (FT_Byte)val;
547                 break;
548
549               case 2:
550                 *(FT_Short*)q = (FT_Short)val;
551                 break;
552
553               case 4:
554                 *(FT_Int32*)q = (FT_Int)val;
555                 break;
556
557               default:  /* for 64-bit systems where long is 8 bytes */
558                 *(FT_Long*)q = val;
559               }
560               break;
561
562             case t2_kind_delta:
563               {
564                 FT_Byte*   qcount = (FT_Byte*)parser->object +
565                                       field->count_offset;
566
567                 FT_Long    val;
568                 FT_Byte**  data = parser->stack;
569
570
571                 if ( num_args > field->array_max )
572                   num_args = field->array_max;
573
574                 /* store count */
575                 *qcount = (FT_Byte)num_args;
576
577                 val = 0;
578                 while ( num_args > 0 )
579                 {
580                   val += t2_parse_num( data++ );
581                   switch ( field->size )
582                   {
583                   case 1:
584                     *(FT_Byte*)q = (FT_Byte)val;
585                     break;
586
587                   case 2:
588                     *(FT_Short*)q = (FT_Short)val;
589                     break;
590
591                   case 4:
592                     *(FT_Int32*)q = (FT_Int)val;
593                     break;
594
595                   default:  /* for 64-bit systems */
596                     *(FT_Long*)q = val;
597                   }
598
599                   q += field->size;
600                   num_args--;
601                 }
602               }
603               break;
604
605             default:  /* callback */
606               error = field->reader( parser );
607               if ( error )
608                 goto Exit;
609             }
610             goto Found;
611           }
612         }
613
614         /* this is an unknown operator, or it is unsupported; */
615         /* we will ignore it for now.                         */
616
617       Found:
618         /* clear stack */
619         parser->top = parser->stack;
620       }
621       p++;
622     }
623
624   Exit:
625     return error;
626
627   Stack_Overflow:
628     error = T2_Err_Invalid_Argument;
629     goto Exit;
630
631   Stack_Underflow:
632     error = T2_Err_Invalid_Argument;
633     goto Exit;
634
635   Syntax_Error:
636     error = T2_Err_Invalid_Argument;
637     goto Exit;
638   }
639
640
641 /* END */