This commit was manufactured by cvs2svn to create branch 'captive'.
[reactos.git] / subsys / win32k / freetype / src / type1z / z1parse.c
1 /***************************************************************************/
2 /*                                                                         */
3 /*  z1parse.c                                                              */
4 /*                                                                         */
5 /*    Experimental Type 1 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   /*************************************************************************/
20   /*                                                                       */
21   /* The Type 1 parser is in charge of the following:                      */
22   /*                                                                       */
23   /*  - provide an implementation of a growing sequence of objects called  */
24   /*    a `Z1_Table' (used to build various tables needed by the loader).  */
25   /*                                                                       */
26   /*  - opening .pfb and .pfa files to extract their top-level and private */
27   /*    dictionaries.                                                      */
28   /*                                                                       */
29   /*  - read numbers, arrays & strings from any dictionary.                */
30   /*                                                                       */
31   /* See `z1load.c' to see how data is loaded from the font file.          */
32   /*                                                                       */
33   /*************************************************************************/
34
35
36 #include <freetype/internal/ftdebug.h>
37 #include <freetype/internal/ftcalc.h>
38 #include <freetype/internal/ftobjs.h>
39 #include <freetype/internal/ftstream.h>
40 #include <freetype/internal/t1errors.h>
41
42
43 #ifdef FT_FLAT_COMPILE
44
45 #include "z1parse.h"
46
47 #else
48
49 #include <freetype/src/type1z/z1parse.h>
50
51 #endif
52
53
54 #include <string.h>     /* for strncmp() */
55
56
57   /*************************************************************************/
58   /*                                                                       */
59   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
60   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
61   /* messages during execution.                                            */
62   /*                                                                       */
63 #undef  FT_COMPONENT
64 #define FT_COMPONENT  trace_z1parse
65
66
67   /*************************************************************************/
68   /*************************************************************************/
69   /*************************************************************************/
70   /*****                                                               *****/
71   /*****              IMPLEMENTATION OF Z1_TABLE OBJECT                *****/
72   /*****                                                               *****/
73   /*************************************************************************/
74   /*************************************************************************/
75   /*************************************************************************/
76
77
78   /*************************************************************************/
79   /*                                                                       */
80   /* <Function>                                                            */
81   /*    Z1_New_Table                                                       */
82   /*                                                                       */
83   /* <Description>                                                         */
84   /*    Initialises a Z1_Table.                                            */
85   /*                                                                       */
86   /* <InOut>                                                               */
87   /*    table  :: The address of the target table.                         */
88   /*                                                                       */
89   /* <Input>                                                               */
90   /*    count  :: The table size = the maximum number of elements.         */
91   /*                                                                       */
92   /*    memory :: The memory object to use for all subsequent              */
93   /*              reallocations.                                           */
94   /*                                                                       */
95   /* <Return>                                                              */
96   /*    FreeType error code.  0 means success.                             */
97   /*                                                                       */
98   LOCAL_FUNC
99   FT_Error  Z1_New_Table( Z1_Table*  table,
100                           FT_Int     count,
101                           FT_Memory  memory )
102   {
103     FT_Error  error;
104
105
106     table->memory = memory;
107     if ( ALLOC_ARRAY( table->elements, count, FT_Byte*  ) ||
108          ALLOC_ARRAY( table->lengths, count, FT_Byte* )   )
109       goto Exit;
110
111     table->max_elems = count;
112     table->init      = 0xdeadbeef;
113     table->num_elems = 0;
114     table->block     = 0;
115     table->capacity  = 0;
116     table->cursor    = 0;
117
118   Exit:
119     if ( error )
120       FREE( table->elements );
121
122     return error;
123   }
124
125
126   static
127   void  shift_elements( Z1_Table*  table,
128                         FT_Byte*   old_base )
129   {
130     FT_Long    delta  = table->block - old_base;
131     FT_Byte**  offset = table->elements;
132     FT_Byte**  limit  = offset + table->max_elems;
133
134
135     if ( delta )
136       for ( ; offset < limit; offset++ )
137       {
138         if ( offset[0] )
139           offset[0] += delta;
140       }
141   }
142
143
144   static
145   FT_Error  reallocate_t1_table( Z1_Table*  table,
146                                  FT_Int     new_size )
147   {
148     FT_Memory  memory   = table->memory;
149     FT_Byte*   old_base = table->block;
150     FT_Error   error;
151
152
153     /* reallocate the base block */
154     if ( REALLOC( table->block, table->capacity, new_size ) )
155       return error;
156
157     table->capacity = new_size;
158
159     /* shift all offsets if necessary */
160     if ( old_base )
161       shift_elements( table, old_base );
162
163     return T1_Err_Ok;
164   }
165
166
167   /*************************************************************************/
168   /*                                                                       */
169   /* <Function>                                                            */
170   /*    Z1_Add_Table                                                       */
171   /*                                                                       */
172   /* <Description>                                                         */
173   /*    Adds an object to a Z1_Table, possibly growing its memory block.   */
174   /*                                                                       */
175   /* <InOut>                                                               */
176   /*    table  :: The target table.                                        */
177   /*                                                                       */
178   /* <Input>                                                               */
179   /*    index  :: The index of the object in the table.                    */
180   /*                                                                       */
181   /*    object :: The address of the object to copy in memory.             */
182   /*                                                                       */
183   /*    length :: The length in bytes of the source object.                */
184   /*                                                                       */
185   /* <Return>                                                              */
186   /*    FreeType error code.  0 means success.  An error is returned if a  */
187   /*    reallocation fails.                                                */
188   /*                                                                       */
189   LOCAL_FUNC
190   FT_Error  Z1_Add_Table( Z1_Table*  table,
191                           FT_Int     index,
192                           void*      object,
193                           FT_Int     length )
194   {
195     if ( index < 0 || index > table->max_elems )
196     {
197       FT_ERROR(( "Z1_Add_Table: invalid index\n" ));
198       return T1_Err_Syntax_Error;
199     }
200
201     /* grow the base block if needed */
202     if ( table->cursor + length > table->capacity )
203     {
204       FT_Error  error;
205       FT_Int    new_size = table->capacity;
206
207
208       while ( new_size < table->cursor + length )
209         new_size += 1024;
210
211       error = reallocate_t1_table( table, new_size );
212       if ( error )
213         return error;
214     }
215
216     /* add the object to the base block and adjust offset */
217     table->elements[index] = table->block + table->cursor;
218     table->lengths [index] = length;
219     MEM_Copy( table->block + table->cursor, object, length );
220
221     table->cursor += length;
222     return T1_Err_Ok;
223   }
224
225
226 #if 0
227
228   /*************************************************************************/
229   /*                                                                       */
230   /* <Function>                                                            */
231   /*    Z1_Done_Table                                                      */
232   /*                                                                       */
233   /* <Description>                                                         */
234   /*    Finalizes a Z1_Table (i.e., reallocate it to its current cursor).  */
235   /*                                                                       */
236   /* <InOut>                                                               */
237   /*    table :: The target table.                                         */
238   /*                                                                       */
239   /* <Note>                                                                */
240   /*    This function does NOT release the heap's memory block.  It is up  */
241   /*    to the caller to clean it, or reference it in its own structures.  */
242   /*                                                                       */
243   LOCAL_FUNC
244   void  Z1_Done_Table( Z1_Table*  table )
245   {
246     FT_Memory  memory = table->memory;
247     FT_Error   error;
248     FT_Byte*   old_base;
249
250
251     /* should never fail, as rec.cursor <= rec.size */
252     old_base = table->block;
253     if ( !old_base )
254       return;
255
256     (void)REALLOC( table->block, table->capacity, table->cursor );
257     table->capacity = table->cursor;
258
259     if ( old_base != table->block )
260       shift_elements( table, old_base );
261   }
262
263 #endif /* 0 */
264
265
266   LOCAL_FUNC
267   void  Z1_Release_Table( Z1_Table*  table )
268   {
269     FT_Memory  memory = table->memory;
270
271
272     if ( table->init == (FT_Long)0xDEADBEEF )
273     {
274       FREE( table->block );
275       FREE( table->elements );
276       FREE( table->lengths );
277       table->init = 0;
278     }
279   }
280
281
282   /*************************************************************************/
283   /*************************************************************************/
284   /*************************************************************************/
285   /*****                                                               *****/
286   /*****                   INPUT STREAM PARSER                         *****/
287   /*****                                                               *****/
288   /*************************************************************************/
289   /*************************************************************************/
290   /*************************************************************************/
291
292
293 #define IS_Z1_WHITESPACE( c )  ( (c) == ' '  || (c) == '\t' )
294 #define IS_Z1_LINESPACE( c )   ( (c) == '\r' || (c) == '\n' )
295
296 #define IS_Z1_SPACE( c )  ( IS_Z1_WHITESPACE( c ) || IS_Z1_LINESPACE( c ) )
297
298
299   LOCAL_FUNC
300   void  Z1_Skip_Spaces( Z1_Parser*  parser )
301   {
302     FT_Byte* cur   = parser->cursor;
303     FT_Byte* limit = parser->limit;
304
305
306     while ( cur < limit )
307     {
308       FT_Byte  c = *cur;
309
310
311       if ( !IS_Z1_SPACE( c ) )
312         break;
313       cur++;
314     }
315     parser->cursor = cur;
316   }
317
318
319   LOCAL_FUNC
320   void  Z1_ToToken( Z1_Parser*     parser,
321                     Z1_Token_Rec*  token )
322   {
323     FT_Byte*  cur;
324     FT_Byte*  limit;
325     FT_Byte   starter, ender;
326     FT_Int    embed;
327
328
329     token->type  = t1_token_none;
330     token->start = 0;
331     token->limit = 0;
332
333     /* first of all, skip space */
334     Z1_Skip_Spaces( parser );
335
336     cur   = parser->cursor;
337     limit = parser->limit;
338
339     if ( cur < limit )
340     {
341       switch ( *cur )
342       {
343         /************* check for strings ***********************/
344       case '(':
345         token->type = t1_token_string;
346         ender = ')';
347         goto Lookup_Ender;
348
349         /************* check for programs/array ****************/
350       case '{':
351         token->type = t1_token_array;
352         ender = '}';
353         goto Lookup_Ender;
354
355         /************* check for table/array ******************/
356       case '[':
357         token->type = t1_token_array;
358         ender = ']';
359
360       Lookup_Ender:
361         embed   = 1;
362         starter = *cur++;
363         token->start = cur;
364         while ( cur < limit )
365         {
366           if ( *cur == starter )
367             embed++;
368           else if ( *cur == ender )
369           {
370             embed--;
371             if ( embed <= 0 )
372             {
373               token->limit = cur++;
374               break;
375             }
376           }
377           cur++;
378         }
379         break;
380
381         /* **************** otherwise, it's any token **********/
382       default:
383         token->start = cur++;
384         token->type  = t1_token_any;
385         while ( cur < limit && !IS_Z1_SPACE( *cur ) )
386           cur++;
387
388         token->limit = cur;
389       }
390
391       if ( !token->limit )
392       {
393         token->start = 0;
394         token->type  = t1_token_none;
395       }
396
397       parser->cursor = cur;
398     }
399   }
400
401
402   LOCAL_FUNC
403   void  Z1_ToTokenArray( Z1_Parser*     parser,
404                          Z1_Token_Rec*  tokens,
405                          FT_UInt        max_tokens,
406                          FT_Int*        pnum_tokens )
407   {
408     Z1_Token_Rec  master;
409
410
411     *pnum_tokens = -1;
412
413     Z1_ToToken( parser, &master );
414     if ( master.type == t1_token_array )
415     {
416       FT_Byte*       old_cursor = parser->cursor;
417       FT_Byte*       old_limit  = parser->limit;
418       Z1_Token_Rec*  cur        = tokens;
419       Z1_Token_Rec*  limit      = cur + max_tokens;
420
421
422       parser->cursor = master.start;
423       parser->limit  = master.limit;
424
425       while ( parser->cursor < parser->limit )
426       {
427         Z1_Token_Rec  token;
428
429
430         Z1_ToToken( parser, &token );
431         if ( !token.type )
432           break;
433
434         if ( cur < limit )
435           *cur = token;
436
437         cur++;
438       }
439
440       *pnum_tokens = cur - tokens;
441
442       parser->cursor = old_cursor;
443       parser->limit  = old_limit;
444     }
445   }
446
447
448   static
449   FT_Long  t1_toint( FT_Byte**  cursor,
450                      FT_Byte*   limit )
451   {
452     FT_Long   result = 0;
453     FT_Byte*  cur    = *cursor;
454     FT_Byte   c, d;
455
456
457     for ( ; cur < limit; cur++ )
458     {
459       c = *cur;
460       d = (FT_Byte)( c - '0' );
461       if ( d < 10 )
462         break;
463
464       if ( c == '-' )
465       {
466         cur++;
467         break;
468       }
469     }
470
471     if ( cur < limit )
472     {
473       do
474       {
475         d = (FT_Byte)( cur[0] - '0' );
476         if ( d >= 10 )
477           break;
478
479         result = result * 10 + d;
480         cur++;
481
482       } while ( cur < limit );
483
484       if ( c == '-' )
485         result = -result;
486     }
487
488     *cursor = cur;
489     return result;
490   }
491
492
493   static
494   FT_Long  t1_tofixed( FT_Byte**  cursor,
495                        FT_Byte*   limit,
496                        FT_Long    power_ten )
497   {
498     FT_Byte* cur  = *cursor;
499     FT_Long  num, divider, result;
500     FT_Int   sign = 0;
501     FT_Byte  d;
502
503
504     if ( cur >= limit )
505       return 0;
506
507     /* first of all, read the integer part */
508     result  = t1_toint( &cur, limit ) << 16;
509     num     = 0;
510     divider = 1;
511
512     if ( result < 0 )
513     {
514       sign   = 1;
515       result = -result;
516     }
517
518     if ( cur >= limit )
519       goto Exit;
520
521     /* read decimal part, if any */
522     if ( *cur == '.' && cur + 1 < limit )
523     {
524       cur++;
525
526       for (;;)
527       {
528         d = (FT_Byte)( *cur - '0' );
529         if ( d >= 10 )
530           break;
531
532         if ( divider < 10000000L )
533         {
534           num      = num * 10 + d;
535           divider *= 10;
536         }
537
538         cur++;
539         if ( cur >= limit )
540           break;
541       }
542     }
543
544     /* read exponent, if any */
545     if ( cur + 1 < limit && ( *cur == 'e' || *cur == 'E' ) )
546     {
547       cur++;
548       power_ten += t1_toint( &cur, limit );
549     }
550
551   Exit:
552     /* raise to power of ten if needed */
553     while ( power_ten > 0 )
554     {
555       result = result * 10;
556       num    = num * 10;
557       power_ten--;
558     }
559
560     while ( power_ten < 0 )
561     {
562       result  = result / 10;
563       divider = divider * 10;
564       power_ten++;
565     }
566
567     if ( num )
568       result += FT_DivFix( num, divider );
569
570     if ( sign )
571       result = -result;
572
573     *cursor = cur;
574     return result;
575   }
576
577
578   static
579   FT_Int  t1_tocoordarray( FT_Byte**  cursor,
580                            FT_Byte*   limit,
581                            FT_Int     max_coords,
582                            FT_Short*  coords )
583   {
584     FT_Byte*  cur   = *cursor;
585     FT_Int    count = 0;
586     FT_Byte   c, ender;
587
588
589     if ( cur >= limit )
590       goto Exit;
591
592     /* check for the beginning of an array. If not, only one number will */
593     /* be read                                                           */
594     c     = *cur;
595     ender = 0;
596
597     if ( c == '[' )
598       ender = ']';
599
600     if ( c == '{' )
601       ender = '}';
602
603     if ( ender )
604       cur++;
605
606     /* now, read the coordinates */
607     for ( ; cur < limit; )
608     {
609       /* skip whitespace in front of data */
610       for (;;)
611       {
612         c = *cur;
613         if ( c != ' ' && c != '\t' )
614           break;
615
616         cur++;
617         if ( cur >= limit )
618           goto Exit;
619       }
620
621       if ( count >= max_coords || c == ender )
622         break;
623
624       coords[count] = (FT_Short)( t1_tofixed( &cur, limit, 0 ) >> 16 );
625       count++;
626
627       if ( !ender )
628         break;
629     }
630
631   Exit:
632     *cursor = cur;
633     return count;
634   }
635
636
637   static
638   FT_Int  t1_tofixedarray( FT_Byte**  cursor,
639                            FT_Byte*   limit,
640                            FT_Int     max_values,
641                            FT_Fixed*  values,
642                            FT_Int     power_ten )
643   {
644     FT_Byte*  cur   = *cursor;
645     FT_Int    count = 0;
646     FT_Byte   c, ender;
647
648
649     if ( cur >= limit ) goto Exit;
650
651     /* check for the beginning of an array. If not, only one number will */
652     /* be read                                                           */
653     c     = *cur;
654     ender = 0;
655
656     if ( c == '[' )
657       ender = ']';
658
659     if ( c == '{' )
660       ender = '}';
661
662     if ( ender )
663       cur++;
664
665     /* now, read the values */
666     for ( ; cur < limit; )
667     {
668       /* skip whitespace in front of data */
669       for (;;)
670       {
671         c = *cur;
672         if ( c != ' ' && c != '\t' )
673           break;
674
675         cur++;
676         if ( cur >= limit )
677           goto Exit;
678       }
679
680       if ( count >= max_values || c == ender )
681         break;
682
683       values[count] = t1_tofixed( &cur, limit, power_ten );
684       count++;
685
686       if ( !ender )
687         break;
688     }
689
690   Exit:
691     *cursor = cur;
692     return count;
693   }
694
695
696 #if 0
697
698   static
699   FT_String*  t1_tostring( FT_Byte**  cursor,
700                            FT_Byte*   limit,
701                            FT_Memory  memory )
702   {
703     FT_Byte*    cur = *cursor;
704     FT_Int      len = 0;
705     FT_Int      count;
706     FT_String*  result;
707     FT_Error    error;
708
709
710     /* XXX: some stupid fonts have a `Notice' or `Copyright' string     */
711     /*      that simply doesn't begin with an opening parenthesis, even */
712     /*      though they have a closing one!  E.g. "amuncial.pfb"        */
713     /*                                                                  */
714     /*      We must deal with these ill-fated cases there.  Note that   */
715     /*      these fonts didn't work with the old Type 1 driver as the   */
716     /*      notice/copyright was not recognized as a valid string token */
717     /*      and made the old token parser commit errors.                */
718
719     while ( cur < limit && ( *cur == ' ' || *cur == '\t' ) )
720       cur++;
721     if ( cur + 1 >= limit )
722       return 0;
723
724     if ( *cur == '(' )
725       cur++;  /* skip the opening parenthesis, if there is one */
726
727     *cursor = cur;
728     count   = 0;
729
730     /* then, count its length */
731     for ( ; cur < limit; cur++ )
732     {
733       if ( *cur == '(' )
734         count++;
735
736       else if ( *cur == ')' )
737       {
738         count--;
739         if ( count < 0 )
740           break;
741       }
742     }
743
744     len = cur - *cursor;
745     if ( cur >= limit || ALLOC( result, len + 1 ) )
746       return 0;
747
748     /* now copy the string */
749     MEM_Copy( result, *cursor, len );
750     result[len] = '\0';
751     *cursor = cur;
752     return result;
753   }
754
755 #endif /* 0 */
756
757
758   static
759   int  t1_tobool( FT_Byte**  cursor,
760                   FT_Byte*   limit )
761   {
762     FT_Byte*  cur    = *cursor;
763     FT_Bool   result = 0;
764
765
766     /* return 1 if we find `true', 0 otherwise */
767     if ( cur + 3 < limit &&
768          cur[0] == 't' &&
769          cur[1] == 'r' &&
770          cur[2] == 'u' &&
771          cur[3] == 'e' )
772     {
773       result = 1;
774       cur   += 5;
775     }
776     else if ( cur + 4 < limit &&
777               cur[0] == 'f' &&
778               cur[1] == 'a' &&
779               cur[2] == 'l' &&
780               cur[3] == 's' &&
781               cur[4] == 'e' )
782     {
783       result = 0;
784       cur   += 6;
785     }
786
787     *cursor = cur;
788     return result;
789   }
790
791
792   /* Load a simple field (i.e. non-table) into the current list of objects */
793   LOCAL_FUNC
794   FT_Error  Z1_Load_Field( Z1_Parser*           parser,
795                            const Z1_Field_Rec*  field,
796                            void**               objects,
797                            FT_UInt              max_objects,
798                            FT_ULong*            pflags )
799   {
800     Z1_Token_Rec  token;
801     FT_Byte*      cur;
802     FT_Byte*      limit;
803     FT_UInt       count;
804     FT_UInt       index;
805     FT_Error      error;
806
807
808     Z1_ToToken( parser, &token );
809     if ( !token.type )
810       goto Fail;
811
812     count = 1;
813     index = 0;
814     cur   = token.start;
815     limit = token.limit;
816
817     if ( token.type == t1_token_array )
818     {
819       /* if this is an array, and we have no blend, an error occurs */
820       if ( max_objects == 0 )
821         goto Fail;
822
823       count = max_objects;
824       index = 1;
825     }
826
827     for ( ; count > 0; count--, index++ )
828     {
829       FT_Byte*    q = (FT_Byte*)objects[index] + field->offset;
830       FT_Long     val;
831       FT_String*  string;
832
833       switch ( field->type )
834       {
835       case t1_field_bool:
836         val = t1_tobool( &cur, limit );
837         goto Store_Integer;
838
839       case t1_field_fixed:
840         val = t1_tofixed( &cur, limit, 3 );
841         goto Store_Integer;
842
843       case t1_field_integer:
844         val = t1_toint( &cur, limit );
845
846       Store_Integer:
847         switch ( field->size )
848         {
849         case 1:
850           *(FT_Byte*)q = (FT_Byte)val;
851           break;
852
853         case 2:
854           *(FT_UShort*)q = (FT_UShort)val;
855           break;
856
857         case 4:
858           *(FT_UInt32*)q = (FT_UInt32)val;
859           break;
860
861         default:  /* for 64-bit systems */
862           *(FT_Long*)q = val;
863         }
864         break;
865
866       case t1_field_string:
867         {
868           FT_Memory  memory = parser->memory;
869           FT_UInt    len    = limit-cur;
870
871           if ( ALLOC( string, len + 1 ) )
872             goto Exit;
873
874           MEM_Copy( string, cur, len );
875           string[len] = 0;
876
877           *(FT_String**)q = string;
878         }
879         break;
880
881       default:
882         /* an error occured */
883         goto Fail;
884       }
885     }
886
887     if ( pflags )
888       *pflags |= 1L << field->flag_bit;
889
890     error = FT_Err_Ok;
891
892   Exit:
893     return error;
894
895   Fail:
896     error = T1_Err_Invalid_File_Format;
897     goto Exit;
898   }
899
900
901 #define T1_MAX_TABLE_ELEMENTS  32
902
903
904   LOCAL_FUNC
905   FT_Error  Z1_Load_Field_Table( Z1_Parser*           parser,
906                                  const Z1_Field_Rec*  field,
907                                  void**               objects,
908                                  FT_UInt              max_objects,
909                                  FT_ULong*            pflags )
910   {
911     Z1_Token_Rec   elements[T1_MAX_TABLE_ELEMENTS];
912     Z1_Token_Rec*  token;
913     FT_Int         num_elements;
914     FT_Error       error = 0;
915     FT_Byte*       old_cursor;
916     FT_Byte*       old_limit;
917     Z1_Field_Rec   fieldrec = *(Z1_Field_Rec*)field;
918
919
920     Z1_ToTokenArray( parser, elements, 32, &num_elements );
921     if ( num_elements < 0 )
922       goto Fail;
923
924     if ( num_elements > T1_MAX_TABLE_ELEMENTS )
925       num_elements = T1_MAX_TABLE_ELEMENTS;
926
927     old_cursor = parser->cursor;
928     old_limit  = parser->limit;
929
930     /* we store the elements count */
931     *(FT_Byte*)( (FT_Byte*)objects[0] + field->count_offset ) = num_elements;
932
933     /* we now load each element, adjusting the field.offset on each one */
934     token = elements;
935     for ( ; num_elements > 0; num_elements--, token++ )
936     {
937       parser->cursor = token->start;
938       parser->limit  = token->limit;
939       Z1_Load_Field( parser, &fieldrec, objects, max_objects, 0 );
940       fieldrec.offset += fieldrec.size;
941     }
942
943     if ( pflags )
944       *pflags |= 1L << field->flag_bit;
945
946     parser->cursor = old_cursor;
947     parser->limit  = old_limit;
948
949   Exit:
950     return error;
951
952   Fail:
953     error = T1_Err_Invalid_File_Format;
954     goto Exit;
955   }
956
957
958   LOCAL_FUNC
959   FT_Long  Z1_ToInt  ( Z1_Parser*  parser )
960   {
961     return t1_toint( &parser->cursor, parser->limit );
962   }
963
964
965   LOCAL_FUNC
966   FT_Long  Z1_ToFixed( Z1_Parser*  parser,
967                        FT_Int      power_ten )
968   {
969     return t1_tofixed( &parser->cursor, parser->limit, power_ten );
970   }
971
972
973   LOCAL_FUNC
974   FT_Int  Z1_ToCoordArray( Z1_Parser*  parser,
975                            FT_Int      max_coords,
976                            FT_Short*   coords )
977   {
978     return t1_tocoordarray( &parser->cursor, parser->limit,
979                             max_coords, coords );
980   }
981
982
983   LOCAL_FUNC
984   FT_Int  Z1_ToFixedArray( Z1_Parser*  parser,
985                            FT_Int      max_values,
986                            FT_Fixed*   values,
987                            FT_Int      power_ten )
988   {
989     return t1_tofixedarray( &parser->cursor, parser->limit,
990                             max_values, values, power_ten );
991   }
992
993
994 #if 0
995
996   LOCAL_FUNC
997   FT_String*  Z1_ToString( Z1_Parser*  parser )
998   {
999     return t1_tostring( &parser->cursor, parser->limit, parser->memory );
1000   }
1001
1002
1003   LOCAL_FUNC
1004   FT_Bool  Z1_ToBool( Z1_Parser*  parser )
1005   {
1006     return t1_tobool( &parser->cursor, parser->limit );
1007   }
1008
1009 #endif /* 0 */
1010
1011
1012   static
1013   FT_Error  read_pfb_tag( FT_Stream   stream,
1014                           FT_UShort*  tag,
1015                           FT_Long*    size )
1016   {
1017     FT_Error  error;
1018
1019
1020     if ( READ_UShort( *tag ) )
1021       goto Exit;
1022
1023     if ( *tag == 0x8001 || *tag == 0x8002 )
1024     {
1025       FT_Long  asize;
1026
1027
1028       if ( READ_ULong( asize ) )
1029         goto Exit;
1030
1031       /* swap between big and little endianness */
1032       *size  = ( ( asize & 0xFF000000L ) >> 24 ) |
1033                ( ( asize & 0x00FF0000L ) >> 8  ) |
1034                ( ( asize & 0x0000FF00L ) << 8  ) |
1035                ( ( asize & 0x000000FFL ) << 24 );
1036     }
1037
1038   Exit:
1039     return error;
1040   }
1041
1042
1043   LOCAL_FUNC
1044   FT_Error  Z1_New_Parser( Z1_Parser*  parser,
1045                            FT_Stream   stream,
1046                            FT_Memory   memory )
1047   {
1048     FT_Error  error;
1049     FT_UShort tag;
1050     FT_Long   size;
1051
1052
1053     parser->stream       = stream;
1054     parser->memory       = memory;
1055     parser->base_len     = 0;
1056     parser->base_dict    = 0;
1057     parser->private_len  = 0;
1058     parser->private_dict = 0;
1059     parser->in_pfb       = 0;
1060     parser->in_memory    = 0;
1061     parser->single_block = 0;
1062
1063     parser->cursor       = 0;
1064     parser->limit        = 0;
1065
1066     /******************************************************************/
1067     /*                                                                */
1068     /* Here a short summary of what is going on:                      */
1069     /*                                                                */
1070     /*   When creating a new Type 1 parser, we try to locate and load */
1071     /*   the base dictionary if this is possible (i.e. for PFB        */
1072     /*   files).  Otherwise, we load the whole font into memory.      */
1073     /*                                                                */
1074     /*   When `loading' the base dictionary, we only setup pointers   */
1075     /*   in the case of a memory-based stream.  Otherwise, we         */
1076     /*   allocate and load the base dictionary in it.                 */
1077     /*                                                                */
1078     /*   parser->in_pfb is set if we are in a binary (".pfb") font.   */
1079     /*   parser->in_memory is set if we have a memory stream.         */
1080     /*                                                                */
1081
1082     /* try to compute the size of the base dictionary;   */
1083     /* look for a Postscript binary file tag, i.e 0x8001 */
1084     if ( FILE_Seek( 0L ) )
1085       goto Exit;
1086
1087     error = read_pfb_tag( stream, &tag, &size );
1088     if ( error )
1089       goto Exit;
1090
1091     if ( tag != 0x8001 )
1092     {
1093       /* assume that this is a PFA file for now; an error will */
1094       /* be produced later when more things are checked        */
1095       (void)FILE_Seek( 0L );
1096       size = stream->size;
1097     }
1098     else
1099       parser->in_pfb = 1;
1100
1101     /* now, try to load `size' bytes of the `base' dictionary we */
1102     /* found previously                                          */
1103
1104     /* if it is a memory-based resource, set up pointers */
1105     if ( !stream->read )
1106     {
1107       parser->base_dict = (FT_Byte*)stream->base + stream->pos;
1108       parser->base_len  = size;
1109       parser->in_memory = 1;
1110
1111       /* check that the `size' field is valid */
1112       if ( FILE_Skip( size ) )
1113         goto Exit;
1114     }
1115     else
1116     {
1117       /* read segment in memory */
1118       if ( ALLOC( parser->base_dict, size )     ||
1119            FILE_Read( parser->base_dict, size ) )
1120         goto Exit;
1121       parser->base_len = size;
1122     }
1123
1124     /* Now check font format; we must see `%!PS-AdobeFont-1' */
1125     /* or `%!FontType'                                       */
1126     {
1127       if ( size <= 16                                    ||
1128            ( strncmp( (const char*)parser->base_dict,
1129                       "%!PS-AdobeFont-1", 16 )        &&
1130              strncmp( (const char*)parser->base_dict,
1131                       "%!FontType", 10 )              )  )
1132       {
1133         FT_TRACE2(( "[not a Type1 font]\n" ));
1134         error = FT_Err_Unknown_File_Format;
1135       }
1136       else
1137       {
1138         parser->cursor = parser->base_dict;
1139         parser->limit  = parser->cursor + parser->base_len;
1140       }
1141     }
1142
1143   Exit:
1144     if ( error && !parser->in_memory )
1145       FREE( parser->base_dict );
1146
1147     return error;
1148   }
1149
1150
1151   LOCAL_FUNC
1152   void  Z1_Done_Parser( Z1_Parser*  parser )
1153   {
1154     FT_Memory   memory = parser->memory;
1155
1156
1157     /* always free the private dictionary */
1158     FREE( parser->private_dict );
1159
1160     /* free the base dictionary only when we have a disk stream */
1161     if ( !parser->in_memory )
1162       FREE( parser->base_dict );
1163   }
1164
1165
1166   /* return the value of an hexadecimal digit */
1167   static
1168   int  hexa_value( char  c )
1169   {
1170    unsigned int  d;
1171
1172
1173     d = (unsigned int)( c - '0' );
1174     if ( d <= 9 )
1175       return (int)d;
1176
1177     d = (unsigned int)( c - 'a' );
1178     if ( d <= 5 )
1179       return (int)( d + 10 );
1180
1181     d = (unsigned int)( c - 'A' );
1182     if ( d <= 5 )
1183       return (int)( d + 10 );
1184
1185     return -1;
1186   }
1187
1188
1189   LOCAL_FUNC
1190   void  Z1_Decrypt( FT_Byte*   buffer,
1191                     FT_Int     length,
1192                     FT_UShort  seed )
1193   {
1194     while ( length > 0 )
1195     {
1196       FT_Byte  plain;
1197
1198
1199       plain     = ( *buffer ^ ( seed >> 8 ) );
1200       seed      = ( *buffer + seed ) * 52845 + 22719;
1201       *buffer++ = plain;
1202       length--;
1203     }
1204   }
1205
1206
1207   LOCAL_FUNC
1208   FT_Error  Z1_Get_Private_Dict( Z1_Parser*  parser )
1209   {
1210     FT_Stream  stream = parser->stream;
1211     FT_Memory  memory = parser->memory;
1212     FT_Error   error  = 0;
1213     FT_Long    size;
1214
1215
1216     if ( parser->in_pfb )
1217     {
1218       /* in the case of the PFB format, the private dictionary can be  */
1219       /* made of several segments.  We thus first read the number of   */
1220       /* segments to compute the total size of the private dictionary  */
1221       /* then re-read them into memory.                                */
1222       FT_Long    start_pos = FILE_Pos();
1223       FT_UShort  tag;
1224       FT_Long    size;
1225
1226
1227       parser->private_len = 0;
1228       for (;;)
1229       {
1230         error = read_pfb_tag( stream, &tag, &size );
1231         if ( error )
1232           goto Fail;
1233
1234         if ( tag != 0x8002 )
1235           break;
1236
1237         parser->private_len += size;
1238
1239         if ( FILE_Skip( size ) )
1240           goto Fail;
1241       }
1242
1243       /* Check that we have a private dictionary there */
1244       /* and allocate private dictionary buffer        */
1245       if ( parser->private_len == 0 )
1246       {
1247         FT_ERROR(( "Z1_Get_Private_Dict:" ));
1248         FT_ERROR(( " invalid private dictionary section\n" ));
1249         error = T1_Err_Invalid_File_Format;
1250         goto Fail;
1251       }
1252
1253       if ( FILE_Seek( start_pos )                             ||
1254            ALLOC( parser->private_dict, parser->private_len ) )
1255         goto Fail;
1256
1257       parser->private_len = 0;
1258       for (;;)
1259       {
1260         error = read_pfb_tag( stream, &tag, &size );
1261         if ( error || tag != 0x8002 )
1262         {
1263           error = FT_Err_Ok;
1264           break;
1265         }
1266
1267         if ( FILE_Read( parser->private_dict + parser->private_len, size ) )
1268           goto Fail;
1269
1270         parser->private_len += size;
1271       }
1272     }
1273     else
1274     {
1275       /* we have already `loaded' the whole PFA font file into memory; */
1276       /* if this is a memory resource, allocate a new block to hold    */
1277       /* the private dict. Otherwise, simply overwrite into the base   */
1278       /* dictionary block in the heap.                                 */
1279
1280       /* first of all, look at the `eexec' keyword */
1281       FT_Byte*  cur   = parser->base_dict;
1282       FT_Byte*  limit = cur + parser->base_len;
1283       FT_Byte   c;
1284
1285
1286       for (;;)
1287       {
1288         c = cur[0];
1289         if ( c == 'e' && cur + 9 < limit )  /* 9 = 5 letters for `eexec' + */
1290                                             /* newline + 4 chars           */
1291         {
1292           if ( cur[1] == 'e' && cur[2] == 'x' &&
1293                cur[3] == 'e' && cur[4] == 'c' )
1294           {
1295             cur += 6; /* we skip the newling after the `eexec' */
1296
1297             /* XXX: Some fonts use DOS-linefeeds, i.e. \r\n; we need to */
1298             /*      skip the extra \n if we find it                     */
1299             if ( cur[0] == '\n' )
1300               cur++;
1301
1302             break;
1303           }
1304         }
1305         cur++;
1306         if ( cur >= limit )
1307         {
1308           FT_ERROR(( "Z1_Get_Private_Dict:" ));
1309           FT_ERROR(( " could not find `eexec' keyword\n" ));
1310           error = T1_Err_Invalid_File_Format;
1311           goto Exit;
1312         }
1313       }
1314
1315       /* now determine where to write the _encrypted_ binary private  */
1316       /* dictionary.  We overwrite the base dictionary for disk-based */
1317       /* resources and allocate a new block otherwise                 */
1318
1319       size = parser->base_len - ( cur - parser->base_dict);
1320
1321       if ( parser->in_memory )
1322       {
1323         /* note that we allocate one more byte to put a terminating `0' */
1324         if ( ALLOC( parser->private_dict, size + 1 ) )
1325           goto Fail;
1326         parser->private_len = size;
1327       }
1328       else
1329       {
1330         parser->single_block = 1;
1331         parser->private_dict = parser->base_dict;
1332         parser->private_len  = size;
1333         parser->base_dict    = 0;
1334         parser->base_len     = 0;
1335       }
1336
1337       /* now determine whether the private dictionary is encoded in binary */
1338       /* or hexadecimal ASCII format -- decode it accordingly              */
1339
1340       /* we need to access the next 4 bytes (after the final \r following */
1341       /* the `eexec' keyword); if they all are hexadecimal digits, then   */
1342       /* we have a case of ASCII storage                                  */
1343
1344       if ( ( hexa_value( cur[0] ) | hexa_value( cur[1] ) |
1345              hexa_value( cur[2] ) | hexa_value( cur[3] ) ) < 0 )
1346
1347         /* binary encoding -- `simply' copy the private dict */
1348         MEM_Copy( parser->private_dict, cur, size );
1349
1350       else
1351       {
1352         /* ASCII hexadecimal encoding */
1353
1354         FT_Byte*  write;
1355         FT_Int    count;
1356
1357
1358         write = parser->private_dict;
1359         count = 0;
1360
1361         for ( ;cur < limit; cur++ )
1362         {
1363           int  hex1;
1364
1365
1366           /* check for newline */
1367           if ( cur[0] == '\r' || cur[0] == '\n' )
1368             continue;
1369
1370           /* exit if we have a non-hexadecimal digit that isn't a newline */
1371           hex1 = hexa_value( cur[0] );
1372           if ( hex1 < 0 || cur + 1 >= limit )
1373             break;
1374
1375           /* otherwise, store byte */
1376           *write++ = ( hex1 << 4 ) | hexa_value( cur[1] );
1377           count++;
1378           cur++;
1379         }
1380
1381         /* put a safeguard */
1382         parser->private_len = write - parser->private_dict;
1383         *write++ = 0;
1384       }
1385     }
1386
1387     /* we now decrypt the encoded binary private dictionary */
1388     Z1_Decrypt( parser->private_dict, parser->private_len, 55665 );
1389     parser->cursor = parser->private_dict;
1390     parser->limit  = parser->cursor + parser->private_len;
1391
1392   Fail:
1393   Exit:
1394     return error;
1395   }
1396
1397
1398 /* END */