shithub: freetype+ttf2subf

Download patch

ref: a39acf55f753b7a6cba7b3f0839505e5f420cea7
parent: 5ef3c95377cdeac700242e3b21a4d2370007e4aa
author: David Turner <[email protected]>
date: Tue Aug 22 22:47:57 EDT 2000

updated "psaux" and "type1z".

The Type 1 driver now completely relies on "psaux". I
now need to change the CID driver accordingly, then
finally move the Type 2 parsing routines to "psaux"
when appropriate..

git/fs: mount .git/fs: mount/attach disallowed
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,15 @@
 LATEST CHANGES
 
+  - updated "docs/docmaker.py", a draft API reference is available at
+    http://www.freetype.org/ft2api.html
+
+  - changed "type1z" to use "psaux"
+
+  - created a new module named "psaux" to hold the Type 1 & Type 2 parsing
+    routines. It should be used by "type1z", "cid" and "cff" in the future
+
+  - fixed an important bug in "FT_Glyph_Get_CBox"
+
   - fixed some compiler warnings that happened since the TrueType
     bytecode decoder was deactivated by default..
 
--- a/include/freetype/internal/psaux.h
+++ b/include/freetype/internal/psaux.h
@@ -37,10 +37,43 @@
   /*************************************************************************/
   /*************************************************************************/
 
+  typedef struct PS_Table_  PS_Table;
 
   /*************************************************************************/
   /*                                                                       */
   /* <Struct>                                                              */
+  /*    PS_Table_Funcs                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A set of function pointers used to manage PS_Table objects..       */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    table_init    :: used to initialise a a table                      */
+  /*    table_done    :: finalize/destroy a given table                    */
+  /*    table_add     :: add one new object to a table                     */
+  /*    table_release :: release table data, then finalize it              */
+  /*                                                                       */
+  typedef  struct PS_Table_Funcs_
+  {
+    FT_Error   (*init)   ( PS_Table*   table,
+                           FT_Int     count,
+                           FT_Memory  memory );
+  
+    void       (*done)   ( PS_Table*  table );                              
+  
+    FT_Error   (*add)    ( PS_Table*   table,
+                           FT_Int      index,
+                           void*       object,
+                           FT_Int      length );
+
+    void       (*release)( PS_Table*  table );                              
+  
+  } PS_Table_Funcs;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
   /*    PS_Table                                                           */
   /*                                                                       */
   /* <Description>                                                         */
@@ -68,7 +101,9 @@
   /*    memory    :: The object used for memory operations                 */
   /*                 (alloc/realloc).                                      */
   /*                                                                       */
-  typedef struct  PS_Table_
+  /*    funcs     :: table of method pointers for this object              */
+  /*                                                                       */
+  struct  PS_Table_
   {
     FT_Byte*   block;          /* current memory block           */
     FT_Int     cursor;         /* current cursor in memory block */
@@ -80,44 +115,14 @@
     FT_Byte**  elements;       /* addresses of table elements */
     FT_Int*    lengths;        /* lengths of table elements   */
 
-    FT_Memory  memory;
+    FT_Memory       memory;
+    PS_Table_Funcs  funcs;
 
-  } PS_Table;
+  };
 
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Struct>                                                              */
-  /*    PS_Table_Funcs                                                     */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A set of function pointers used to manage PS_Table objects..       */
-  /*                                                                       */
-  /* <Fields>                                                              */
-  /*    table_init    :: used to initialise a a table                      */
-  /*    table_done    :: finalize/destroy a given table                    */
-  /*    table_add     :: add one new object to a table                     */
-  /*    table_release :: release table data, then finalize it              */
-  /*                                                                       */
-  typedef  struct PS_Table_Funcs_
-  {
-    FT_Error   (*init)   ( PS_Table*   table,
-                           FT_Int     count,
-                           FT_Memory  memory );
-  
-    void       (*done)   ( PS_Table*  table );                              
-  
-    FT_Error   (*add)    ( PS_Table*   table,
-                           FT_Int      index,
-                           void*       object,
-                           FT_Int      length );
 
-    void       (*release)( PS_Table*  table );                              
-  
-  } PS_Table_Funcs;
-
-
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
@@ -276,17 +281,11 @@
   /*                                                                       */
   /*    error  :: The last error returned.                                 */
   /*                                                                       */
-  typedef struct  T1_Parser_
-  {
-    FT_Byte*   cursor;
-    FT_Byte*   base;
-    FT_Byte*   limit;
-    FT_Error   error;
-    FT_Memory  memory;
-  
-  } T1_Parser;
+  /*    funcs  :: table of functions for the parser                        */
+  /*                                                                       */
+  /*                                                                       */
+  typedef struct  T1_Parser_  T1_Parser;
 
-
   typedef struct  T1_Parser_Funcs_
   {
     void      (*init)          ( T1_Parser*  parser,
@@ -293,9 +292,9 @@
                                  FT_Byte*    base,
                                  FT_Byte*    limit,
                                  FT_Memory   memory );
-                       
-    void      (*done)          ( T1_Parser*  parser );
 
+    void      (*done)          ( T1_Parser*  parser );
+    
     void      (*skip_spaces)   ( T1_Parser*  parser );
     void      (*skip_alpha)    ( T1_Parser*  parser );
   
@@ -331,7 +330,20 @@
 
   } T1_Parser_Funcs;
 
+  
+  struct T1_Parser_
+  {
+    FT_Byte*   cursor;
+    FT_Byte*   base;
+    FT_Byte*   limit;
+    FT_Error   error;
+    FT_Memory  memory;
+    
+    T1_Parser_Funcs  funcs;
+  };
 
+
+
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
@@ -340,7 +352,49 @@
   /*************************************************************************/
   /*************************************************************************/
 
+  typedef struct T1_Builder_  T1_Builder;
 
+  typedef FT_Error  (*T1_Builder_Check_Points_Func) ( T1_Builder*  builder,
+                                                     FT_Int       count );
+                                                      
+  typedef void      (*T1_Builder_Add_Point_Func)    ( T1_Builder*  builder,
+                                                      FT_Pos       x,
+                                                      FT_Pos       y,
+                                                      FT_Byte      flag );    
+  
+  typedef FT_Error  (*T1_Builder_Add_Point1_Func)   ( T1_Builder*  builder,
+                                                      FT_Pos       x,
+                                                      FT_Pos       y );
+                                                    
+  typedef FT_Error  (*T1_Builder_Add_Contour_Func)  ( T1_Builder*  builder );
+
+  typedef FT_Error  (*T1_Builder_Start_Point_Func)  ( T1_Builder*  builder,
+                                                      FT_Pos       x,
+                                                      FT_Pos       y );
+
+  typedef void      (*T1_Builder_Close_Contour_Func)( T1_Builder*  builder );
+
+
+  typedef struct  T1_Builder_Funcs_
+  {
+    void      (*init)( T1_Builder*   builder,
+                       FT_Face       face,
+                       FT_Size       size,
+                       FT_GlyphSlot  slot );
+  
+    void      (*done)( T1_Builder*   builder );
+    
+    T1_Builder_Check_Points_Func   check_points;
+    T1_Builder_Add_Point_Func      add_point;
+    T1_Builder_Add_Point1_Func     add_point1;
+    T1_Builder_Add_Contour_Func    add_contour;
+    T1_Builder_Start_Point_Func    start_point;
+    T1_Builder_Close_Contour_Func  close_contour;
+  
+  } T1_Builder_Funcs;
+
+
+
   /*************************************************************************/
   /*                                                                       */
   /* <Structure>                                                           */
@@ -395,7 +449,9 @@
   /*                    the metrics of a given glyph, not load all of its  */
   /*                    points.                                            */
   /*                                                                       */
-  typedef struct  T1_Builder_
+  /*    funcs        :: array of function pointers for the builder         */
+  /*                                                                       */
+  struct  T1_Builder_
   {
     FT_Memory        memory;
     FT_Face          face;
@@ -424,49 +480,10 @@
     FT_Error         error;         /* only used for memory errors */
     FT_Bool          metrics_only;
 
-  } T1_Builder;
+    T1_Builder_Funcs funcs;
+  };
 
 
-  typedef FT_Error  (*T1_Builder_Check_Points_Func) ( T1_Builder*  builder,
-                                                     FT_Int       count );
-                                                      
-  typedef void      (*T1_Builder_Add_Point_Func)    ( T1_Builder*  builder,
-                                                      FT_Pos       x,
-                                                      FT_Pos       y,
-                                                      FT_Byte      flag );    
-  
-  typedef FT_Error  (*T1_Builder_Add_Point1_Func)   ( T1_Builder*  builder,
-                                                      FT_Pos       x,
-                                                      FT_Pos       y );
-                                                    
-  typedef FT_Error  (*T1_Builder_Add_Contour_Func)  ( T1_Builder*  builder );
-
-  typedef FT_Error  (*T1_Builder_Start_Point_Func)  ( T1_Builder*  builder,
-                                                      FT_Pos       x,
-                                                      FT_Pos       y );
-
-  typedef void      (*T1_Builder_Close_Contour_Func)( T1_Builder*  builder );
-
-
-  typedef struct  T1_Builder_Funcs_
-  {
-    void      (*init)( T1_Builder*   builder,
-                       FT_Face       face,
-                       FT_Size       size,
-                       FT_GlyphSlot  slot );
-  
-    void      (*done)( T1_Builder*   builder );
-    
-    T1_Builder_Check_Points_Func   check_points;
-    T1_Builder_Add_Point_Func      add_point;
-    T1_Builder_Add_Point1_Func     add_point1;
-    T1_Builder_Add_Contour_Func    add_contour;
-    T1_Builder_Start_Point_Func    start_point;
-    T1_Builder_Close_Contour_Func  close_contour;
-  
-  } T1_Builder_Funcs;
-
-
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
@@ -509,9 +526,28 @@
   typedef struct T1_Decoder_        T1_Decoder;
   typedef struct T1_Decoder_Funcs_  T1_Decoder_Funcs;
 
-  typedef  FT_Error  (*T1_Decoder_Parse_Func)( T1_Decoder*  decoder,
-                                               FT_UInt      glyph_index );
+  typedef  FT_Error  (*T1_Decoder_Callback)( T1_Decoder*  decoder,
+                                             FT_UInt      glyph_index );
 
+  struct T1_Decoder_Funcs_
+  {
+    FT_Error     (*init) ( T1_Decoder*          decoder,
+                           FT_Face              face,
+                           FT_Size              size,
+                           FT_GlyphSlot         slot,
+                           FT_Byte**            glyph_names,
+                           T1_Blend*            blend,
+                           T1_Decoder_Callback  callback );
+    
+    void         (*done) ( T1_Decoder*  decoder );
+    
+    FT_Error     (*parse_charstrings)( T1_Decoder*  decoder,
+                                       FT_Byte*     base,
+                                       FT_UInt      len );
+  };
+
+
+
   struct T1_Decoder_
   {
     T1_Builder               builder;
@@ -539,30 +575,11 @@
 
     T1_Blend*                blend;       /* for multiple master support */
     
-    const T1_Decoder_Funcs*  funcs;
-    T1_Decoder_Parse_Func    parse_glyph;  
+    T1_Decoder_Callback      parse_callback;
+    T1_Decoder_Funcs         funcs;
   };
 
 
-  struct T1_Decoder_Funcs_
-  {
-    FT_Error     (*init)             ( T1_Decoder*            decoder,
-                                       FT_Face                face,
-                                       FT_Size                size,
-                                       FT_GlyphSlot           slot,
-                                       FT_Byte**              glyph_names,
-                                       T1_Blend*              blend,
-                                       T1_Decoder_Parse_Func  parse );
-    
-    void         (*done)             ( T1_Decoder*  decoder );
-    
-    FT_Error     (*parse_charstrings)( T1_Decoder*  decoder,
-                                       FT_Byte*     base,
-                                       FT_UInt      len );
-    
-  
-  };
-
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
@@ -573,7 +590,7 @@
 
   typedef struct  PSAux_Interface_
   {
-    const PS_Table_Funcs*   t1_table_funcs;
+    const PS_Table_Funcs*   ps_table_funcs;
     const T1_Parser_Funcs*  t1_parser_funcs;
     const T1_Builder_Funcs* t1_builder_funcs;
     const T1_Decoder_Funcs* t1_decoder_funcs;
--- a/src/autohint/ahhint.c
+++ b/src/autohint/ahhint.c
@@ -1000,6 +1000,7 @@
 
 
   /* discard a face's autohint globals */
+  LOCAL_FUNC
   void  ah_hinter_done_face_globals( AH_Face_Globals*  globals )
   {
     FT_Face    face   = globals->face;
--- a/src/psaux/psmodule.c
+++ b/src/psaux/psmodule.c
@@ -2,7 +2,7 @@
 #include <psaux/psobjs.h>
 #include <psaux/t1decode.h>
 
-  static
+  LOCAL_FUNC
   const PS_Table_Funcs    ps_table_funcs =
   {
     PS_Table_New,
@@ -12,7 +12,7 @@
   };
 
 
-  static
+  LOCAL_FUNC
   const T1_Parser_Funcs   t1_parser_funcs =
   {
     T1_Init_Parser,
@@ -30,7 +30,7 @@
   };
 
 
-  static
+  LOCAL_FUNC
   const T1_Builder_Funcs  t1_builder_funcs =
   {
     T1_Builder_Init,
@@ -44,7 +44,7 @@
   };
 
 
-  static
+  LOCAL_FUNC
   const T1_Decoder_Funcs  t1_decoder_funcs =
   {
     T1_Decoder_Init,
@@ -53,7 +53,7 @@
   };
 
 
-  static
+  LOCAL_FUNC
   const PSAux_Interface   psaux_interface =
   {
     &ps_table_funcs,
--- a/src/psaux/psobjs.c
+++ b/src/psaux/psobjs.c
@@ -78,6 +78,7 @@
     table->block     = 0;
     table->capacity  = 0;
     table->cursor    = 0;
+    table->funcs     = ps_table_funcs;
 
   Exit:
     if ( error )
@@ -1009,6 +1010,7 @@
     parser->limit  = limit;
     parser->cursor = base;
     parser->memory = memory;
+    parser->funcs  = t1_parser_funcs;
   }                            
 
 
@@ -1082,6 +1084,8 @@
     builder->left_bearing.y = 0;
     builder->advance.x      = 0;
     builder->advance.y      = 0;
+    
+    builder->funcs = t1_builder_funcs;
   }
 
 
--- a/src/psaux/psobjs.h
+++ b/src/psaux/psobjs.h
@@ -35,7 +35,15 @@
   /*************************************************************************/
   /*************************************************************************/
 
+  LOCAL_DEF
+  const PS_Table_Funcs    ps_table_funcs;
 
+  LOCAL_DEF
+  const T1_Parser_Funcs   t1_parser_funcs;
+  
+  LOCAL_DEF
+  const T1_Builder_Funcs  t1_builder_funcs;
+  
   LOCAL_DEF
   FT_Error  PS_Table_New( PS_Table*  table,
                           FT_Int     count,
--- a/src/psaux/t1decode.c
+++ b/src/psaux/t1decode.c
@@ -977,18 +977,18 @@
   FT_Error  T1_Decoder_Parse_Glyph( T1_Decoder*  decoder,
                                     FT_UInt      glyph )
   {
-    return decoder->parse_glyph( decoder, glyph );
+    return decoder->parse_callback( decoder, glyph );
   }
 
 
   LOCAL_FUNC
-  FT_Error  T1_Decoder_Init( T1_Decoder*             decoder,
-                             FT_Face                 face,
-                             FT_Size                 size,
-                             FT_GlyphSlot            slot,
-                             FT_Byte**               glyph_names,
-                             T1_Blend*               blend,
-                             T1_Decoder_Parse_Func   parse_glyph )
+  FT_Error  T1_Decoder_Init( T1_Decoder*          decoder,
+                             FT_Face              face,
+                             FT_Size              size,
+                             FT_GlyphSlot         slot,
+                             FT_Byte**            glyph_names,
+                             T1_Blend*            blend,
+                             T1_Decoder_Callback  parse_callback )
   {
     MEM_Set( decoder, 0, sizeof(*decoder) );
     
@@ -1008,12 +1008,12 @@
     }
     T1_Builder_Init( &decoder->builder, face, size, slot );
     
-    decoder->num_glyphs  = face->num_glyphs;
-    decoder->glyph_names = glyph_names;
-    decoder->blend       = blend;
-    decoder->parse_glyph = parse_glyph;
+    decoder->num_glyphs     = face->num_glyphs;
+    decoder->glyph_names    = glyph_names;
+    decoder->blend          = blend;
+    decoder->parse_callback = parse_callback;
     
-    decoder->funcs       = &t1_decoder_funcs;
+    decoder->funcs       = t1_decoder_funcs;
     return 0;
   }
 
--- a/src/psaux/t1decode.h
+++ b/src/psaux/t1decode.h
@@ -18,13 +18,13 @@
                                            FT_UInt     len );
 
   LOCAL_DEF
-  FT_Error  T1_Decoder_Init( T1_Decoder*            decoder,
-                             FT_Face                face,
-                             FT_Size                size,
-                             FT_GlyphSlot           slot,
-                             FT_Byte**              glyph_names,
-                             T1_Blend*              blend,
-                             T1_Decoder_Parse_Func  parse_glyph );
+  FT_Error  T1_Decoder_Init( T1_Decoder*          decoder,
+                             FT_Face              face,
+                             FT_Size              size,
+                             FT_GlyphSlot         slot,
+                             FT_Byte**            glyph_names,
+                             T1_Blend*            blend,
+                             T1_Decoder_Callback  parse_glyph );
 
   LOCAL_DEF
   void  T1_Decoder_Done( T1_Decoder*  decoder );
--- a/src/raster1/ftraster.c
+++ b/src/raster1/ftraster.c
@@ -22,7 +22,11 @@
   /*************************************************************************/
 
 
-#include "ftraster.h"
+#ifdef FT_FLAT_COMPILE
+#  include "ftraster.h"
+#else
+#  include <raster1/ftraster.h>
+#endif
 #include <freetype/internal/ftcalc.h>      /* for FT_MulDiv() only */
 
 
--- a/src/type1z/z1gload.c
+++ b/src/type1z/z1gload.c
@@ -71,7 +71,7 @@
     T1_Face  face  = (T1_Face)decoder->builder.face;
     T1_Font* type1 = &face->type1;
     
-    return decoder->funcs->parse_charstrings( decoder,
+    return decoder->funcs.parse_charstrings( decoder,
                                         type1->charstrings    [glyph_index],
                                         type1->charstrings_len[glyph_index] );
   }
--- a/src/type1z/z1load.c
+++ b/src/type1z/z1load.c
@@ -393,7 +393,7 @@
   void  parse_blend_axis_types( T1_Face     face,
                                 Z1_Loader*  loader )
   {
-    Z1_Token_Rec  axis_tokens[ T1_MAX_MM_AXIS ];
+    T1_Token  axis_tokens[ T1_MAX_MM_AXIS ];
     FT_Int        n, num_axis;
     FT_Error      error = 0;
     T1_Blend*     blend;
@@ -422,7 +422,7 @@
     /* each token is an immediate containing the name of the axis */
     for ( n = 0; n < num_axis; n++ )
     {
-      Z1_Token_Rec*  token = axis_tokens + n;
+      T1_Token*  token = axis_tokens + n;
       FT_Byte*       name;
       FT_Int         len;
 
@@ -446,7 +446,7 @@
     }
 
   Exit:
-    loader->parser.error = error;
+    loader->parser.root.error = error;
   }
 
 
@@ -454,7 +454,7 @@
   void  parse_blend_design_positions( T1_Face     face,
                                       Z1_Loader*  loader )
   {
-    Z1_Token_Rec  design_tokens[ T1_MAX_MM_DESIGNS ];
+    T1_Token  design_tokens[ T1_MAX_MM_DESIGNS ];
     FT_Int        num_designs;
     FT_Int        num_axis;
     Z1_Parser*    parser = &loader->parser;
@@ -475,8 +475,8 @@
     }
 
     {
-      FT_Byte*  old_cursor = parser->cursor;
-      FT_Byte*  old_limit  = parser->limit;
+      FT_Byte*  old_cursor = parser->root.cursor;
+      FT_Byte*  old_limit  = parser->root.limit;
       FT_UInt   n;
 
 
@@ -485,15 +485,15 @@
 
       for ( n = 0; n < (FT_UInt)num_designs; n++ )
       {
-        Z1_Token_Rec   axis_tokens[ T1_MAX_MM_DESIGNS ];
-        Z1_Token_Rec*  token;
-        FT_Int         axis, n_axis;
+        T1_Token   axis_tokens[ T1_MAX_MM_DESIGNS ];
+        T1_Token*  token;
+        FT_Int     axis, n_axis;
 
 
         /* read axis/coordinates tokens */
         token = design_tokens + n;
-        parser->cursor = token->start - 1;
-        parser->limit  = token->limit + 1;
+        parser->root.cursor = token->start - 1;
+        parser->root.limit  = token->limit + 1;
         Z1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &n_axis );
 
         if ( n == 0 )
@@ -514,21 +514,21 @@
         /* now, read each axis token into the design position */
         for ( axis = 0; axis < n_axis; axis++ )
         {
-          Z1_Token_Rec*  token2 = axis_tokens + axis;
+          T1_Token*  token2 = axis_tokens + axis;
 
 
-          parser->cursor = token2->start;
-          parser->limit  = token2->limit;
+          parser->root.cursor = token2->start;
+          parser->root.limit  = token2->limit;
           blend->design_pos[n][axis] = Z1_ToFixed( parser, 0 );
         }
       }
 
-      loader->parser.cursor = old_cursor;
-      loader->parser.limit  = old_limit;
+      loader->parser.root.cursor = old_cursor;
+      loader->parser.root.limit  = old_limit;
     }
 
   Exit:
-    loader->parser.error = error;
+    loader->parser.root.error = error;
   }
 
 
@@ -539,7 +539,7 @@
     FT_Error      error  = 0;
     Z1_Parser*    parser = &loader->parser;
     T1_Blend*     blend;
-    Z1_Token_Rec  axis_tokens[ T1_MAX_MM_AXIS ];
+    T1_Token  axis_tokens[ T1_MAX_MM_AXIS ];
     FT_Int        n, num_axis;
     FT_Byte*      old_cursor;
     FT_Byte*      old_limit;
@@ -554,8 +554,8 @@
       error = T1_Err_Invalid_File_Format;
       goto Exit;
     }
-    old_cursor = parser->cursor;
-    old_limit  = parser->limit;
+    old_cursor = parser->root.cursor;
+    old_limit  = parser->root.limit;
 
     error = t1_allocate_blend( face, 0, num_axis );
     if ( error )
@@ -566,13 +566,13 @@
     for ( n = 0; n < num_axis; n++ )
     {
       T1_DesignMap*   map = blend->design_map + n;
-      Z1_Token_Rec*   token;
+      T1_Token*   token;
       FT_Int          p, num_points;
 
 
       token = axis_tokens + n;
-      parser->cursor = token->start;
-      parser->limit  = token->limit;
+      parser->root.cursor = token->start;
+      parser->root.limit  = token->limit;
 
       /* count the number of map points */
       {
@@ -605,11 +605,11 @@
       }
     }
 
-    parser->cursor = old_cursor;
-    parser->limit  = old_limit;
+    parser->root.cursor = old_cursor;
+    parser->root.limit  = old_limit;
 
   Exit:
-    parser->error = error;
+    parser->root.error = error;
   }
 
 
@@ -620,7 +620,7 @@
     FT_Error      error  = 0;
     Z1_Parser*    parser = &loader->parser;
     T1_Blend*     blend  = face->blend;
-    Z1_Token_Rec  master;
+    T1_Token  master;
     FT_UInt       n;
     FT_Byte*      old_cursor;
     FT_Byte*      old_limit;
@@ -634,7 +634,7 @@
     }
 
     Z1_ToToken( parser, &master );
-    if ( master.type != z1_token_array )
+    if ( master.type != t1_token_array )
     {
       FT_ERROR(( "parse_weight_vector: incorrect format!\n" ));
       error = T1_Err_Invalid_File_Format;
@@ -641,11 +641,11 @@
       goto Exit;
     }
 
-    old_cursor = parser->cursor;
-    old_limit  = parser->limit;
+    old_cursor = parser->root.cursor;
+    old_limit  = parser->root.limit;
 
-    parser->cursor = master.start;
-    parser->limit  = master.limit;
+    parser->root.cursor = master.start;
+    parser->root.limit  = master.limit;
 
     for ( n = 0; n < blend->num_designs; n++ )
     {
@@ -653,11 +653,11 @@
       blend->weight_vector[n]         = Z1_ToFixed( parser, 0 );
     }
 
-    parser->cursor = old_cursor;
-    parser->limit  = old_limit;
+    parser->root.cursor = old_cursor;
+    parser->root.limit  = old_limit;
 
   Exit:
-    parser->error = error;
+    parser->root.error = error;
   }
 
 
@@ -674,8 +674,8 @@
     FT_UNUSED( face );
 
 
-    parser->cursor = parser->limit;
-    parser->error  = 0;
+    parser->root.cursor = parser->root.limit;
+    parser->root.error  = 0;
   }
 
 #endif /* Z1_CONFIG_OPTION_NO_MM_SUPPORT */
@@ -693,49 +693,49 @@
   /*************************************************************************/
   /*                                                                       */
   /* First of all, define the token field static variables.  This is a set */
-  /* of Z1_Field_Rec variables used later.                                 */
+  /* of T1_Field variables used later.                                 */
   /*                                                                       */
   /*************************************************************************/
 
 #define Z1_NEW_STRING( _name, _field )              \
           static                                    \
-          const Z1_Field_Rec  z1_field_ ## _field = \
-            Z1_FIELD_STRING( _field );
+          const T1_Field  z1_field_ ## _field = \
+            T1_FIELD_STRING( _field );
 
 #define Z1_NEW_BOOL( _name, _field )                \
           static                                    \
-          const Z1_Field_Rec  z1_field_ ## _field = \
-            Z1_FIELD_BOOL( _field );
+          const T1_Field  z1_field_ ## _field = \
+            T1_FIELD_BOOL( _field );
 
 #define Z1_NEW_NUM( _name, _field )                 \
           static                                    \
-          const Z1_Field_Rec  z1_field_ ## _field = \
-            Z1_FIELD_NUM( _field );
+          const T1_Field  z1_field_ ## _field = \
+            T1_FIELD_NUM( _field );
 
 #define Z1_NEW_FIXED( _name, _field )                 \
           static                                      \
-          const Z1_Field_Rec  z1_field_ ## _field =   \
-            Z1_FIELD_FIXED( _field, _power );
+          const T1_Field  z1_field_ ## _field =   \
+            T1_FIELD_FIXED( _field, _power );
 
 #define Z1_NEW_NUM_TABLE( _name, _field, _max, _count )         \
           static                                                \
-          const Z1_Field_Rec  z1_field_ ## _field =             \
-            Z1_FIELD_NUM_ARRAY( _field, _count, _max );
+          const T1_Field  z1_field_ ## _field =             \
+            T1_FIELD_NUM_ARRAY( _field, _count, _max );
 
 #define Z1_NEW_FIXED_TABLE( _name, _field, _max, _count )         \
           static                                                  \
-          const Z1_Field_Rec  z1_field_ ## _field =               \
-            Z1_FIELD_FIXED_ARRAY( _field, _count, _max );
+          const T1_Field  z1_field_ ## _field =               \
+            T1_FIELD_FIXED_ARRAY( _field, _count, _max );
 
 #define Z1_NEW_NUM_TABLE2( _name, _field, _max )         \
           static                                         \
-          const Z1_Field_Rec  z1_field_ ## _field =      \
-            Z1_FIELD_NUM_ARRAY2( _field, _max );
+          const T1_Field  z1_field_ ## _field =      \
+            T1_FIELD_NUM_ARRAY2( _field, _max );
 
 #define Z1_NEW_FIXED_TABLE2( _name, _field, _max )         \
           static                                           \
-          const Z1_Field_Rec  z1_field_ ## _field =        \
-            Z1_FIELD_FIXED_ARRAY2( _field, _max );
+          const T1_Field  z1_field_ ## _field =        \
+            T1_FIELD_FIXED_ARRAY2( _field, _max );
 
 
 #define Z1_FONTINFO_STRING( n, f )          Z1_NEW_STRING( n, f )
@@ -796,7 +796,7 @@
     Z1_KeyWord_Type      type;
     Z1_KeyWord_Location  location;
     Z1_Parse_Func        parsing;
-    const Z1_Field_Rec*  field;
+    const T1_Field*  field;
 
   } Z1_KeyWord;
 
@@ -871,7 +871,7 @@
     if ( keyword->type == t1_keyword_callback )
     {
       keyword->parsing( face, loader );
-      error = loader->parser.error;
+      error = loader->parser.root.error;
       goto Exit;
     }
 
@@ -922,53 +922,27 @@
 
 
   static
-  int  is_space( char  c )
+  int  is_space( FT_Byte  c )
   {
-    return ( c == ' ' || c == '\t' || c == '\r' || c == '\n' );
+    return (c == ' ' || c == '\t' || c == '\r' || c == '\n' );
   }
 
 
   static
-  int  is_alpha( char c )
+  int  is_alpha( FT_Byte  c )
   {
-    return ( isalnum( (int)c ) ||
-             ( c == '.' )      ||
-             ( c == '_' )      );
+    return (isalnum(c) || c == '.' || c == '_' );
   }
 
 
-  static
-  void  skip_whitespace( Z1_Parser*  parser )
-  {
-    FT_Byte*  cur = parser->cursor;
 
-
-    while ( cur < parser->limit && is_space( *cur ) )
-      cur++;
-
-    parser->cursor = cur;
-  }
-
-
   static
-  void skip_blackspace( Z1_Parser*  parser )
-  {
-    FT_Byte*  cur = parser->cursor;
-
-    while ( cur < parser->limit && !is_space( *cur ) )
-      cur++;
-
-    parser->cursor = cur;
-  }
-
-
-  static
   int  read_binary_data( Z1_Parser*  parser,
                          FT_Int*     size,
                          FT_Byte**   base )
   {
     FT_Byte*  cur;
-    FT_Byte*  limit = parser->limit;
+    FT_Byte*  limit = parser->root.limit;
 
 
     /* the binary data has the following format */
@@ -976,26 +950,26 @@
     /* `size' [white*] RD white ....... ND      */
     /*                                          */
 
-    skip_whitespace( parser );
-    cur = parser->cursor;
+    Z1_Skip_Spaces( parser );
+    cur = parser->root.cursor;
 
     if ( cur < limit && (FT_Byte)( *cur - '0' ) < 10 )
     {
       *size = Z1_ToInt( parser );
 
-      skip_whitespace( parser );
-      skip_blackspace( parser );  /* `RD' or `-|' or something else */
+      Z1_Skip_Spaces( parser );
+      Z1_Skip_Alpha ( parser );  /* `RD' or `-|' or something else */
 
       /* there is only one whitespace char after the */
       /* `RD' or `-|' token                          */
-      *base = parser->cursor + 1;
+      *base = parser->root.cursor + 1;
 
-      parser->cursor += *size+1;
+      parser->root.cursor += *size+1;
       return 1;
     }
 
     FT_ERROR(( "read_binary_data: invalid size field\n" ));
-    parser->error = T1_Err_Invalid_File_Format;
+    parser->root.error = T1_Err_Invalid_File_Format;
     return 0;
   }
 
@@ -1010,7 +984,7 @@
   {
     Z1_Parser*  parser = &loader->parser;
     FT_Error    error;
-    FT_Memory   memory = parser->memory;
+    FT_Memory   memory = parser->root.memory;
     FT_Int      len;
     FT_Byte*    cur;
     FT_Byte*    cur2;
@@ -1017,10 +991,10 @@
     FT_Byte*    limit;
 
 
-    skip_whitespace( parser );
+    Z1_Skip_Spaces( parser );
 
-    cur   = parser->cursor;
-    limit = parser->limit;
+    cur   = parser->root.cursor;
+    limit = parser->root.limit;
 
     if ( cur >= limit - 1 || *cur != '/' )
       return;
@@ -1035,7 +1009,7 @@
     {
       if ( ALLOC( face->type1.font_name, len + 1 ) )
       {
-        parser->error = error;
+        parser->root.error = error;
         return;
       }
 
@@ -1042,7 +1016,7 @@
       MEM_Copy( face->type1.font_name, cur, len );
       face->type1.font_name[len] = '\0';
     }
-    parser->cursor = cur2;
+    parser->root.cursor = cur2;
   }
 
 
@@ -1104,8 +1078,10 @@
                         Z1_Loader*  loader )
   {
     Z1_Parser*  parser = &loader->parser;
-    FT_Byte*    cur   = parser->cursor;
-    FT_Byte*    limit = parser->limit;
+    FT_Byte*    cur   = parser->root.cursor;
+    FT_Byte*    limit = parser->root.limit;
+    
+    PSAux_Interface*  psaux = (PSAux_Interface*)face->psaux;
 
 
     /* skip whitespace */
@@ -1115,7 +1091,7 @@
       if ( cur >= limit )
       {
         FT_ERROR(( "parse_encoding: out of bounds!\n" ));
-        parser->error = T1_Err_Invalid_File_Format;
+        parser->root.error = T1_Err_Invalid_File_Format;
         return;
       }
     }
@@ -1126,14 +1102,14 @@
     {
       T1_Encoding*  encode     = &face->type1.encoding;
       FT_Int        count, n;
-      Z1_Table*     char_table = &loader->encoding_table;
-      FT_Memory     memory     = parser->memory;
+      PS_Table*     char_table = &loader->encoding_table;
+      FT_Memory     memory     = parser->root.memory;
       FT_Error      error;
 
 
       /* read the number of entries in the encoding, should be 256 */
       count = Z1_ToInt( parser );
-      if ( parser->error )
+      if ( parser->root.error )
         return;
 
       /* we use a Z1_Table to store our charnames */
@@ -1140,9 +1116,9 @@
       encode->num_chars = count;
       if ( ALLOC_ARRAY( encode->char_index, count, FT_Short   )       ||
            ALLOC_ARRAY( encode->char_name,  count, FT_String* )       ||
-           ( error = Z1_New_Table( char_table, count, memory ) ) != 0 )
+           ( error = psaux->ps_table_funcs->init( char_table, count, memory ) ) != 0 )
       {
-        parser->error = error;
+        parser->root.error = error;
         return;
       }
 
@@ -1159,8 +1135,8 @@
       /*                                                        */
       /* We stop when we encounter a `def'.                     */
 
-      cur   = parser->cursor;
-      limit = parser->limit;
+      cur   = parser->root.cursor;
+      limit = parser->root.limit;
       n     = 0;
 
       for ( ; cur < limit; )
@@ -1189,9 +1165,9 @@
           FT_Int  charcode;
 
 
-          parser->cursor = cur;
+          parser->root.cursor = cur;
           charcode = Z1_ToInt( parser );
-          cur = parser->cursor;
+          cur = parser->root.cursor;
 
           /* skip whitespace */
           while ( cur < limit && is_space( *cur ) )
@@ -1210,10 +1186,10 @@
 
             len = cur2 - cur - 1;
 
-            parser->error = Z1_Add_Table( char_table, charcode,
+            parser->root.error = Z1_Add_Table( char_table, charcode,
                                           cur + 1, len + 1 );
             char_table->elements[charcode][len] = '\0';
-            if ( parser->error )
+            if ( parser->root.error )
               return;
 
             cur = cur2;
@@ -1224,7 +1200,7 @@
       }
 
       face->type1.encoding_type = t1_encoding_array;
-      parser->cursor            = cur;
+      parser->root.cursor            = cur;
     }
     /* Otherwise, we should have either `StandardEncoding' or */
     /* `ExpertEncoding'                                       */
@@ -1241,7 +1217,7 @@
       else
       {
         FT_ERROR(( "parse_encoding: invalid token!\n" ));
-        parser->error = T1_Err_Invalid_File_Format;
+        parser->root.error = T1_Err_Invalid_File_Format;
       }
     }
   }
@@ -1252,23 +1228,24 @@
                      Z1_Loader*  loader )
   {
     Z1_Parser*  parser = &loader->parser;
-    Z1_Table*   table  = &loader->subrs;
-    FT_Memory   memory = parser->memory;
+    PS_Table*   table  = &loader->subrs;
+    FT_Memory   memory = parser->root.memory;
     FT_Error    error;
     FT_Int      n;
 
-
+    PSAux_Interface*  psaux = (PSAux_Interface*)face->psaux;
+    
     loader->num_subrs = Z1_ToInt( parser );
-    if ( parser->error )
+    if ( parser->root.error )
       return;
 
     /* position the parser right before the `dup' of the first subr */
-    skip_whitespace( parser );
-    skip_blackspace( parser );      /* `array' */
-    skip_whitespace( parser );
+    Z1_Skip_Spaces( parser );
+    Z1_Skip_Alpha( parser );      /* `array' */
+    Z1_Skip_Spaces( parser );
 
     /* initialize subrs array */
-    error = Z1_New_Table( table, loader->num_subrs, memory );
+    error = psaux->ps_table_funcs->init( table, loader->num_subrs, memory );
     if ( error )
       goto Fail;
 
@@ -1285,7 +1262,7 @@
 
       /* If the next token isn't `dup', we are also done.  This */
       /* happens when there are `holes' in the Subrs array.     */
-      if ( strncmp( (char*)parser->cursor, "dup", 3 ) != 0 )
+      if ( strncmp( (char*)parser->root.cursor, "dup", 3 ) != 0 )
         break;
 
       index = Z1_ToInt( parser );
@@ -1297,14 +1274,14 @@
       /* (bound to `noaccess put') or by two separate tokens:  */
       /* `noaccess' & `put'.  We position the parser right     */
       /* before the next `dup', if any.                        */
-      skip_whitespace( parser );
-      skip_blackspace( parser );    /* `NP' or `I' or `noaccess' */
-      skip_whitespace( parser );
+      Z1_Skip_Spaces( parser );
+      Z1_Skip_Alpha( parser );    /* `NP' or `I' or `noaccess' */
+      Z1_Skip_Spaces( parser );
 
-      if ( strncmp( (char*)parser->cursor, "put", 3 ) == 0 )
+      if ( strncmp( (char*)parser->root.cursor, "put", 3 ) == 0 )
       {
-        skip_blackspace( parser );  /* skip `put' */
-        skip_whitespace( parser );
+        Z1_Skip_Alpha( parser );  /* skip `put' */
+        Z1_Skip_Spaces( parser );
       }
 
       /* some fonts use a value of -1 for lenIV to indicate that */
@@ -1326,7 +1303,7 @@
     return;
 
   Fail:
-    parser->error = error;
+    parser->root.error = error;
   }
 
 
@@ -1335,13 +1312,15 @@
                            Z1_Loader*  loader )
   {
     Z1_Parser*  parser     = &loader->parser;
-    Z1_Table*   code_table = &loader->charstrings;
-    Z1_Table*   name_table = &loader->glyph_names;
-    FT_Memory   memory     = parser->memory;
+    PS_Table*   code_table = &loader->charstrings;
+    PS_Table*   name_table = &loader->glyph_names;
+    FT_Memory   memory     = parser->root.memory;
     FT_Error    error;
 
+    PSAux_Interface*  psaux = (PSAux_Interface*)face->psaux;
+
     FT_Byte*    cur;
-    FT_Byte*    limit = parser->limit;
+    FT_Byte*    limit = parser->root.limit;
     FT_Int      n;
 
 
@@ -1350,12 +1329,15 @@
       return;
 
     loader->num_glyphs = Z1_ToInt( parser );
-    if ( parser->error )
+    if ( parser->root.error )
       return;
 
     /* initialize tables */
-    error = Z1_New_Table( code_table, loader->num_glyphs, memory ) ||
-            Z1_New_Table( name_table, loader->num_glyphs, memory );
+    error = psaux->ps_table_funcs->init( code_table, loader->num_glyphs, memory );
+    if (error)
+      goto Fail;
+
+    error = psaux->ps_table_funcs->init( name_table, loader->num_glyphs, memory );
     if ( error )
       goto Fail;
 
@@ -1371,9 +1353,9 @@
       /*                                          */
       /* note that we stop when we find a `def'   */
       /*                                          */
-      skip_whitespace( parser );
+      Z1_Skip_Spaces( parser );
 
-      cur = parser->cursor;
+      cur = parser->root.cursor;
       if ( cur >= limit )
         break;
 
@@ -1391,7 +1373,7 @@
         break;
 
       if ( *cur != '/' )
-        skip_blackspace( parser );
+        Z1_Skip_Alpha( parser );
       else
       {
         FT_Byte*  cur2 = cur + 1;
@@ -1409,7 +1391,7 @@
         /* add a trailing zero to the name table */
         name_table->elements[n][len] = '\0';
 
-        parser->cursor = cur2;
+        parser->root.cursor = cur2;
         if ( !read_binary_data( parser, &size, &base ) )
           return;
 
@@ -1433,7 +1415,7 @@
     return;
 
   Fail:
-    parser->error = error;
+    parser->root.error = error;
   }
 
 
@@ -1480,9 +1462,9 @@
     Z1_Parser*  parser = &loader->parser;
 
 
-    parser->cursor = base;
-    parser->limit  = base + size;
-    parser->error  = 0;
+    parser->root.cursor = base;
+    parser->root.limit  = base + size;
+    parser->root.error  = 0;
 
     {
       FT_Byte*  cur   = base;
@@ -1509,17 +1491,17 @@
 
           if ( cur < limit )
           {
-            Z1_Token_Rec  token;
+            T1_Token  token;
 
 
             /* skip the `known' keyword and the token following it */
             cur += 5;
-            loader->parser.cursor = cur;
+            loader->parser.root.cursor = cur;
             Z1_ToToken( &loader->parser, &token );
 
             /* if the last token was an array, skip it! */
-            if ( token.type == z1_token_array )
-              cur2 = parser->cursor;
+            if ( token.type == t1_token_array )
+              cur2 = parser->root.cursor;
           }
           cur = cur2;
         }
@@ -1571,13 +1553,13 @@
                   if ( n >= len )
                   {
                     /* we found it -- run the parsing callback! */
-                    parser->cursor = cur2;
-                    skip_whitespace( parser );
-                    parser->error = t1_load_keyword( face, loader, keyword );
-                    if ( parser->error )
-                      return parser->error;
+                    parser->root.cursor = cur2;
+                    Z1_Skip_Spaces( parser );
+                    parser->root.error = t1_load_keyword( face, loader, keyword );
+                    if ( parser->root.error )
+                      return parser->root.error;
 
-                    cur = parser->cursor;
+                    cur = parser->root.cursor;
                     break;
                   }
                 }
@@ -1588,7 +1570,7 @@
         }
       }
     }
-    return parser->error;
+    return parser->root.error;
   }
 
 
@@ -1635,8 +1617,9 @@
     Z1_Parser*  parser;
     T1_Font*    type1 = &face->type1;
     FT_Error    error;
+    
+    PSAux_Interface*  psaux = (PSAux_Interface*)face->psaux;
 
-
     t1_init_loader( &loader, face );
 
     /* default lenIV */
@@ -1643,7 +1626,7 @@
     type1->private_dict.lenIV = 4;
 
     parser = &loader.parser;
-    error = Z1_New_Parser( parser, face->root.stream, face->root.memory );
+    error = Z1_New_Parser( parser, face->root.stream, face->root.memory, psaux );
     if ( error )
       goto Exit;
 
--- a/src/type1z/z1load.h
+++ b/src/type1z/z1load.h
@@ -44,15 +44,15 @@
     Z1_Parser  parser;          /* parser used to read the stream */
 
     FT_Int     num_chars;       /* number of characters in encoding */
-    Z1_Table   encoding_table;  /* Z1_Table used to store the       */
+    PS_Table   encoding_table;  /* PS_Table used to store the       */
                                 /* encoding character names         */
 
     FT_Int     num_glyphs;
-    Z1_Table   glyph_names;
-    Z1_Table   charstrings;
+    PS_Table   glyph_names;
+    PS_Table   charstrings;
 
     FT_Int     num_subrs;
-    Z1_Table   subrs;
+    PS_Table   subrs;
     FT_Bool    fontdata;
 
   } Z1_Loader;
--- a/src/type1z/z1parse.c
+++ b/src/type1z/z1parse.c
@@ -38,8 +38,8 @@
 #include <freetype/internal/ftobjs.h>
 #include <freetype/internal/ftstream.h>
 #include <freetype/internal/t1errors.h>
+#include <freetype/internal/psaux.h>
 
-
 #ifdef FT_FLAT_COMPILE
 
 #include "z1parse.h"
@@ -68,221 +68,6 @@
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
-  /*****              IMPLEMENTATION OF Z1_TABLE OBJECT                *****/
-  /*****                                                               *****/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Z1_New_Table                                                       */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Initialises a Z1_Table.                                            */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    table  :: The address of the target table.                         */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    count  :: The table size = the maximum number of elements.         */
-  /*                                                                       */
-  /*    memory :: The memory object to use for all subsequent              */
-  /*              reallocations.                                           */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  LOCAL_FUNC
-  FT_Error  Z1_New_Table( Z1_Table*  table,
-                          FT_Int     count,
-                          FT_Memory  memory )
-  {
-    FT_Error  error;
-
-
-    table->memory = memory;
-    if ( ALLOC_ARRAY( table->elements, count, FT_Byte*  ) ||
-         ALLOC_ARRAY( table->lengths, count, FT_Byte* )   )
-      goto Exit;
-
-    table->max_elems = count;
-    table->init      = 0xdeadbeef;
-    table->num_elems = 0;
-    table->block     = 0;
-    table->capacity  = 0;
-    table->cursor    = 0;
-
-  Exit:
-    if ( error )
-      FREE( table->elements );
-
-    return error;
-  }
-
-
-  static
-  void  shift_elements( Z1_Table*  table,
-                        FT_Byte*   old_base )
-  {
-    FT_Long    delta  = table->block - old_base;
-    FT_Byte**  offset = table->elements;
-    FT_Byte**  limit  = offset + table->max_elems;
-
-
-    if ( delta )
-      for ( ; offset < limit; offset++ )
-      {
-        if ( offset[0] )
-          offset[0] += delta;
-      }
-  }
-
-
-  static
-  FT_Error  reallocate_t1_table( Z1_Table*  table,
-                                 FT_Int     new_size )
-  {
-    FT_Memory  memory   = table->memory;
-    FT_Byte*   old_base = table->block;
-    FT_Error   error;
-
-
-    /* reallocate the base block */
-    if ( REALLOC( table->block, table->capacity, new_size ) )
-      return error;
-
-    table->capacity = new_size;
-
-    /* shift all offsets if necessary */
-    if ( old_base )
-      shift_elements( table, old_base );
-
-    return T1_Err_Ok;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Z1_Add_Table                                                       */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Adds an object to a Z1_Table, possibly growing its memory block.   */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    table  :: The target table.                                        */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    index  :: The index of the object in the table.                    */
-  /*                                                                       */
-  /*    object :: The address of the object to copy in memory.             */
-  /*                                                                       */
-  /*    length :: The length in bytes of the source object.                */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.  An error is returned if a  */
-  /*    reallocation fails.                                                */
-  /*                                                                       */
-  LOCAL_FUNC
-  FT_Error  Z1_Add_Table( Z1_Table*  table,
-                          FT_Int     index,
-                          void*      object,
-                          FT_Int     length )
-  {
-    if ( index < 0 || index > table->max_elems )
-    {
-      FT_ERROR(( "Z1_Add_Table: invalid index\n" ));
-      return T1_Err_Syntax_Error;
-    }
-
-    /* grow the base block if needed */
-    if ( table->cursor + length > table->capacity )
-    {
-      FT_Error  error;
-      FT_Int    new_size = table->capacity;
-
-
-      while ( new_size < table->cursor + length )
-        new_size += 1024;
-
-      error = reallocate_t1_table( table, new_size );
-      if ( error )
-        return error;
-    }
-
-    /* add the object to the base block and adjust offset */
-    table->elements[index] = table->block + table->cursor;
-    table->lengths [index] = length;
-    MEM_Copy( table->block + table->cursor, object, length );
-
-    table->cursor += length;
-    return T1_Err_Ok;
-  }
-
-
-#if 0
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Z1_Done_Table                                                      */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Finalizes a Z1_Table (i.e., reallocate it to its current cursor).  */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    table :: The target table.                                         */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    This function does NOT release the heap's memory block.  It is up  */
-  /*    to the caller to clean it, or reference it in its own structures.  */
-  /*                                                                       */
-  LOCAL_FUNC
-  void  Z1_Done_Table( Z1_Table*  table )
-  {
-    FT_Memory  memory = table->memory;
-    FT_Error   error;
-    FT_Byte*   old_base;
-
-
-    /* should never fail, as rec.cursor <= rec.size */
-    old_base = table->block;
-    if ( !old_base )
-      return;
-
-    (void)REALLOC( table->block, table->capacity, table->cursor );
-    table->capacity = table->cursor;
-
-    if ( old_base != table->block )
-      shift_elements( table, old_base );
-  }
-
-#endif /* 0 */
-
-
-  LOCAL_FUNC
-  void  Z1_Release_Table( Z1_Table*  table )
-  {
-    FT_Memory  memory = table->memory;
-
-
-    if ( table->init == (FT_Long)0xDEADBEEF )
-    {
-      FREE( table->block );
-      FREE( table->elements );
-      FREE( table->lengths );
-      table->init = 0;
-    }
-  }
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*****                                                               *****/
   /*****                   INPUT STREAM PARSER                         *****/
   /*****                                                               *****/
   /*************************************************************************/
@@ -296,771 +81,62 @@
 #define IS_Z1_SPACE( c )  ( IS_Z1_WHITESPACE( c ) || IS_Z1_LINESPACE( c ) )
 
 
-  LOCAL_FUNC
-  void  Z1_Skip_Spaces( Z1_Parser*  parser )
+  typedef struct PFB_Tag_
   {
-    FT_Byte* cur   = parser->cursor;
-    FT_Byte* limit = parser->limit;
+    FT_UShort  tag;
+    FT_Long    size;
+    
+  } PFB_Tag;
 
 
-    while ( cur < limit )
-    {
-      FT_Byte  c = *cur;
+#undef  FT_STRUCTURE
+#define FT_STRUCTURE  PFB_Tag
 
-
-      if ( !IS_Z1_SPACE( c ) )
-        break;
-      cur++;
-    }
-    parser->cursor = cur;
-  }
-
-
-  LOCAL_FUNC
-  void  Z1_ToToken( Z1_Parser*     parser,
-                    Z1_Token_Rec*  token )
-  {
-    FT_Byte*  cur;
-    FT_Byte*  limit;
-    FT_Byte   starter, ender;
-    FT_Int    embed;
-
-
-    token->type  = z1_token_none;
-    token->start = 0;
-    token->limit = 0;
-
-    /* first of all, skip space */
-    Z1_Skip_Spaces( parser );
-
-    cur   = parser->cursor;
-    limit = parser->limit;
-
-    if ( cur < limit )
-    {
-      switch ( *cur )
-      {
-        /************* check for strings ***********************/
-      case '(':
-        token->type = z1_token_string;
-        ender = ')';
-        goto Lookup_Ender;
-
-        /************* check for programs/array ****************/
-      case '{':
-        token->type = z1_token_array;
-        ender = '}';
-        goto Lookup_Ender;
-
-        /************* check for table/array ******************/
-      case '[':
-        token->type = z1_token_array;
-        ender = ']';
-
-      Lookup_Ender:
-        embed   = 1;
-        starter = *cur++;
-        token->start = cur;
-        while ( cur < limit )
-        {
-          if ( *cur == starter )
-            embed++;
-          else if ( *cur == ender )
-          {
-            embed--;
-            if ( embed <= 0 )
-            {
-              token->limit = cur++;
-              break;
-            }
-          }
-          cur++;
-        }
-        break;
-
-        /* **************** otherwise, it's any token **********/
-      default:
-        token->start = cur++;
-        token->type  = z1_token_any;
-        while ( cur < limit && !IS_Z1_SPACE( *cur ) )
-          cur++;
-
-        token->limit = cur;
-      }
-
-      if ( !token->limit )
-      {
-        token->start = 0;
-        token->type  = z1_token_none;
-      }
-
-      parser->cursor = cur;
-    }
-  }
-
-
-  LOCAL_FUNC
-  void  Z1_ToTokenArray( Z1_Parser*     parser,
-                         Z1_Token_Rec*  tokens,
-                         FT_UInt        max_tokens,
-                         FT_Int*        pnum_tokens )
-  {
-    Z1_Token_Rec  master;
-
-
-    *pnum_tokens = -1;
-
-    Z1_ToToken( parser, &master );
-    if ( master.type == z1_token_array )
-    {
-      FT_Byte*       old_cursor = parser->cursor;
-      FT_Byte*       old_limit  = parser->limit;
-      Z1_Token_Rec*  cur        = tokens;
-      Z1_Token_Rec*  limit      = cur + max_tokens;
-
-
-      parser->cursor = master.start;
-      parser->limit  = master.limit;
-
-      while ( parser->cursor < parser->limit )
-      {
-        Z1_Token_Rec  token;
-
-
-        Z1_ToToken( parser, &token );
-        if ( !token.type )
-          break;
-
-        if ( cur < limit )
-          *cur = token;
-
-        cur++;
-      }
-
-      *pnum_tokens = cur - tokens;
-
-      parser->cursor = old_cursor;
-      parser->limit  = old_limit;
-    }
-  }
-
-
   static
-  FT_Long  t1_toint( FT_Byte**  cursor,
-                     FT_Byte*   limit )
+  const FT_Frame_Field  pfb_tag_fields[] =
   {
-    FT_Long   result = 0;
-    FT_Byte*  cur    = *cursor;
-    FT_Byte   c = '\0', d;
+    FT_FRAME_START(6),
+      FT_FRAME_USHORT ( tag ),
+      FT_FRAME_LONG_LE( size ),
+    FT_FRAME_END
+  };
 
 
-    for ( ; cur < limit; cur++ )
-    {
-      c = *cur;
-      d = (FT_Byte)( c - '0' );
-      if ( d < 10 )
-        break;
-
-      if ( c == '-' )
-      {
-        cur++;
-        break;
-      }
-    }
-
-    if ( cur < limit )
-    {
-      do
-      {
-        d = (FT_Byte)( cur[0] - '0' );
-        if ( d >= 10 )
-          break;
-
-        result = result * 10 + d;
-        cur++;
-
-      } while ( cur < limit );
-
-      if ( c == '-' )
-        result = -result;
-    }
-
-    *cursor = cur;
-    return result;
-  }
-
-
   static
-  FT_Long  t1_tofixed( FT_Byte**  cursor,
-                       FT_Byte*   limit,
-                       FT_Long    power_ten )
-  {
-    FT_Byte* cur  = *cursor;
-    FT_Long  num, divider, result;
-    FT_Int   sign = 0;
-    FT_Byte  d;
-
-
-    if ( cur >= limit )
-      return 0;
-
-    /* first of all, check the sign */
-    if ( *cur == '-' )
-    {
-      sign = 1;
-      cur++;
-    }
-
-    /* then, read the integer part, if any */
-    if ( *cur != '.' )
-      result = t1_toint( &cur, limit ) << 16;
-    else
-      result = 0;
-
-    num     = 0;
-    divider = 1;
-
-    if ( cur >= limit )
-      goto Exit;
-
-    /* read decimal part, if any */
-    if ( *cur == '.' && cur + 1 < limit )
-    {
-      cur++;
-
-      for (;;)
-      {
-        d = (FT_Byte)( *cur - '0' );
-        if ( d >= 10 )
-          break;
-
-        if ( divider < 10000000L )
-        {
-          num      = num * 10 + d;
-          divider *= 10;
-        }
-
-        cur++;
-        if ( cur >= limit )
-          break;
-      }
-    }
-
-    /* read exponent, if any */
-    if ( cur + 1 < limit && ( *cur == 'e' || *cur == 'E' ) )
-    {
-      cur++;
-      power_ten += t1_toint( &cur, limit );
-    }
-
-  Exit:
-    /* raise to power of ten if needed */
-    while ( power_ten > 0 )
-    {
-      result = result * 10;
-      num    = num * 10;
-      power_ten--;
-    }
-
-    while ( power_ten < 0 )
-    {
-      result  = result / 10;
-      divider = divider * 10;
-      power_ten++;
-    }
-
-    if ( num )
-      result += FT_DivFix( num, divider );
-
-    if ( sign )
-      result = -result;
-
-    *cursor = cur;
-    return result;
-  }
-
-
-  static
-  FT_Int  t1_tocoordarray( FT_Byte**  cursor,
-                           FT_Byte*   limit,
-                           FT_Int     max_coords,
-                           FT_Short*  coords )
-  {
-    FT_Byte*  cur   = *cursor;
-    FT_Int    count = 0;
-    FT_Byte   c, ender;
-
-
-    if ( cur >= limit )
-      goto Exit;
-
-    /* check for the beginning of an array. If not, only one number will */
-    /* be read                                                           */
-    c     = *cur;
-    ender = 0;
-
-    if ( c == '[' )
-      ender = ']';
-
-    if ( c == '{' )
-      ender = '}';
-
-    if ( ender )
-      cur++;
-
-    /* now, read the coordinates */
-    for ( ; cur < limit; )
-    {
-      /* skip whitespace in front of data */
-      for (;;)
-      {
-        c = *cur;
-        if ( c != ' ' && c != '\t' )
-          break;
-
-        cur++;
-        if ( cur >= limit )
-          goto Exit;
-      }
-
-      if ( count >= max_coords || c == ender )
-        break;
-
-      coords[count] = (FT_Short)( t1_tofixed( &cur, limit, 0 ) >> 16 );
-      count++;
-
-      if ( !ender )
-        break;
-    }
-
-  Exit:
-    *cursor = cur;
-    return count;
-  }
-
-
-  static
-  FT_Int  t1_tofixedarray( FT_Byte**  cursor,
-                           FT_Byte*   limit,
-                           FT_Int     max_values,
-                           FT_Fixed*  values,
-                           FT_Int     power_ten )
-  {
-    FT_Byte*  cur   = *cursor;
-    FT_Int    count = 0;
-    FT_Byte   c, ender;
-
-
-    if ( cur >= limit ) goto Exit;
-
-    /* check for the beginning of an array. If not, only one number will */
-    /* be read                                                           */
-    c     = *cur;
-    ender = 0;
-
-    if ( c == '[' )
-      ender = ']';
-
-    if ( c == '{' )
-      ender = '}';
-
-    if ( ender )
-      cur++;
-
-    /* now, read the values */
-    for ( ; cur < limit; )
-    {
-      /* skip whitespace in front of data */
-      for (;;)
-      {
-        c = *cur;
-        if ( c != ' ' && c != '\t' )
-          break;
-
-        cur++;
-        if ( cur >= limit )
-          goto Exit;
-      }
-
-      if ( count >= max_values || c == ender )
-        break;
-
-      values[count] = t1_tofixed( &cur, limit, power_ten );
-      count++;
-
-      if ( !ender )
-        break;
-    }
-
-  Exit:
-    *cursor = cur;
-    return count;
-  }
-
-
-#if 0
-
-  static
-  FT_String*  t1_tostring( FT_Byte**  cursor,
-                           FT_Byte*   limit,
-                           FT_Memory  memory )
-  {
-    FT_Byte*    cur = *cursor;
-    FT_Int      len = 0;
-    FT_Int      count;
-    FT_String*  result;
-    FT_Error    error;
-
-
-    /* XXX: some stupid fonts have a `Notice' or `Copyright' string     */
-    /*      that simply doesn't begin with an opening parenthesis, even */
-    /*      though they have a closing one!  E.g. "amuncial.pfb"        */
-    /*                                                                  */
-    /*      We must deal with these ill-fated cases there.  Note that   */
-    /*      these fonts didn't work with the old Type 1 driver as the   */
-    /*      notice/copyright was not recognized as a valid string token */
-    /*      and made the old token parser commit errors.                */
-
-    while ( cur < limit && ( *cur == ' ' || *cur == '\t' ) )
-      cur++;
-    if ( cur + 1 >= limit )
-      return 0;
-
-    if ( *cur == '(' )
-      cur++;  /* skip the opening parenthesis, if there is one */
-
-    *cursor = cur;
-    count   = 0;
-
-    /* then, count its length */
-    for ( ; cur < limit; cur++ )
-    {
-      if ( *cur == '(' )
-        count++;
-
-      else if ( *cur == ')' )
-      {
-        count--;
-        if ( count < 0 )
-          break;
-      }
-    }
-
-    len = cur - *cursor;
-    if ( cur >= limit || ALLOC( result, len + 1 ) )
-      return 0;
-
-    /* now copy the string */
-    MEM_Copy( result, *cursor, len );
-    result[len] = '\0';
-    *cursor = cur;
-    return result;
-  }
-
-#endif /* 0 */
-
-
-  static
-  int  t1_tobool( FT_Byte**  cursor,
-                  FT_Byte*   limit )
-  {
-    FT_Byte*  cur    = *cursor;
-    FT_Bool   result = 0;
-
-
-    /* return 1 if we find `true', 0 otherwise */
-    if ( cur + 3 < limit &&
-         cur[0] == 't' &&
-         cur[1] == 'r' &&
-         cur[2] == 'u' &&
-         cur[3] == 'e' )
-    {
-      result = 1;
-      cur   += 5;
-    }
-    else if ( cur + 4 < limit &&
-              cur[0] == 'f' &&
-              cur[1] == 'a' &&
-              cur[2] == 'l' &&
-              cur[3] == 's' &&
-              cur[4] == 'e' )
-    {
-      result = 0;
-      cur   += 6;
-    }
-
-    *cursor = cur;
-    return result;
-  }
-
-
-  /* Load a simple field (i.e. non-table) into the current list of objects */
-  LOCAL_FUNC
-  FT_Error  Z1_Load_Field( Z1_Parser*           parser,
-                           const Z1_Field_Rec*  field,
-                           void**               objects,
-                           FT_UInt              max_objects,
-                           FT_ULong*            pflags )
-  {
-    Z1_Token_Rec  token;
-    FT_Byte*      cur;
-    FT_Byte*      limit;
-    FT_UInt       count;
-    FT_UInt       index;
-    FT_Error      error;
-
-
-    Z1_ToToken( parser, &token );
-    if ( !token.type )
-      goto Fail;
-
-    count = 1;
-    index = 0;
-    cur   = token.start;
-    limit = token.limit;
-
-    if ( token.type == z1_token_array )
-    {
-      /* if this is an array, and we have no blend, an error occurs */
-      if ( max_objects == 0 )
-        goto Fail;
-
-      count = max_objects;
-      index = 1;
-    }
-
-    for ( ; count > 0; count--, index++ )
-    {
-      FT_Byte*    q = (FT_Byte*)objects[index] + field->offset;
-      FT_Long     val;
-      FT_String*  string;
-
-      switch ( field->type )
-      {
-      case z1_field_bool:
-        val = t1_tobool( &cur, limit );
-        goto Store_Integer;
-
-      case z1_field_fixed:
-        val = t1_tofixed( &cur, limit, 3 );
-        goto Store_Integer;
-
-      case z1_field_integer:
-        val = t1_toint( &cur, limit );
-
-      Store_Integer:
-        switch ( field->size )
-        {
-        case 1:
-          *(FT_Byte*)q = (FT_Byte)val;
-          break;
-
-        case 2:
-          *(FT_UShort*)q = (FT_UShort)val;
-          break;
-
-        case 4:
-          *(FT_UInt32*)q = (FT_UInt32)val;
-          break;
-
-        default:  /* for 64-bit systems */
-          *(FT_Long*)q = val;
-        }
-        break;
-
-      case z1_field_string:
-        {
-          FT_Memory  memory = parser->memory;
-          FT_UInt    len    = limit-cur;
-
-          if ( *(FT_String**)q )
-            /*  with synthetic fonts, it's possible to find a field twice  */
-            break;
-
-          if ( ALLOC( string, len + 1 ) )
-            goto Exit;
-
-          MEM_Copy( string, cur, len );
-          string[len] = 0;
-
-          *(FT_String**)q = string;
-        }
-        break;
-
-      default:
-        /* an error occured */
-        goto Fail;
-      }
-    }
-
-    if ( pflags )
-      *pflags |= 1L << field->flag_bit;
-
-    error = FT_Err_Ok;
-
-  Exit:
-    return error;
-
-  Fail:
-    error = T1_Err_Invalid_File_Format;
-    goto Exit;
-  }
-
-
-#define T1_MAX_TABLE_ELEMENTS  32
-
-
-  LOCAL_FUNC
-  FT_Error  Z1_Load_Field_Table( Z1_Parser*           parser,
-                                 const Z1_Field_Rec*  field,
-                                 void**               objects,
-                                 FT_UInt              max_objects,
-                                 FT_ULong*            pflags )
-  {
-    Z1_Token_Rec   elements[T1_MAX_TABLE_ELEMENTS];
-    Z1_Token_Rec*  token;
-    FT_Int         num_elements;
-    FT_Error       error = 0;
-    FT_Byte*       old_cursor;
-    FT_Byte*       old_limit;
-    Z1_Field_Rec   fieldrec = *(Z1_Field_Rec*)field;
-
-
-    Z1_ToTokenArray( parser, elements, 32, &num_elements );
-    if ( num_elements < 0 )
-      goto Fail;
-
-    if ( num_elements > T1_MAX_TABLE_ELEMENTS )
-      num_elements = T1_MAX_TABLE_ELEMENTS;
-
-    old_cursor = parser->cursor;
-    old_limit  = parser->limit;
-
-    /* we store the elements count */
-    *(FT_Byte*)( (FT_Byte*)objects[0] + field->count_offset ) = num_elements;
-
-    /* we now load each element, adjusting the field.offset on each one */
-    token = elements;
-    for ( ; num_elements > 0; num_elements--, token++ )
-    {
-      parser->cursor = token->start;
-      parser->limit  = token->limit;
-      Z1_Load_Field( parser, &fieldrec, objects, max_objects, 0 );
-      fieldrec.offset += fieldrec.size;
-    }
-
-    if ( pflags )
-      *pflags |= 1L << field->flag_bit;
-
-    parser->cursor = old_cursor;
-    parser->limit  = old_limit;
-
-  Exit:
-    return error;
-
-  Fail:
-    error = T1_Err_Invalid_File_Format;
-    goto Exit;
-  }
-
-
-  LOCAL_FUNC
-  FT_Long  Z1_ToInt  ( Z1_Parser*  parser )
-  {
-    return t1_toint( &parser->cursor, parser->limit );
-  }
-
-
-  LOCAL_FUNC
-  FT_Long  Z1_ToFixed( Z1_Parser*  parser,
-                       FT_Int      power_ten )
-  {
-    return t1_tofixed( &parser->cursor, parser->limit, power_ten );
-  }
-
-
-  LOCAL_FUNC
-  FT_Int  Z1_ToCoordArray( Z1_Parser*  parser,
-                           FT_Int      max_coords,
-                           FT_Short*   coords )
-  {
-    return t1_tocoordarray( &parser->cursor, parser->limit,
-                            max_coords, coords );
-  }
-
-
-  LOCAL_FUNC
-  FT_Int  Z1_ToFixedArray( Z1_Parser*  parser,
-                           FT_Int      max_values,
-                           FT_Fixed*   values,
-                           FT_Int      power_ten )
-  {
-    return t1_tofixedarray( &parser->cursor, parser->limit,
-                            max_values, values, power_ten );
-  }
-
-
-#if 0
-
-  LOCAL_FUNC
-  FT_String*  Z1_ToString( Z1_Parser*  parser )
-  {
-    return t1_tostring( &parser->cursor, parser->limit, parser->memory );
-  }
-
-
-  LOCAL_FUNC
-  FT_Bool  Z1_ToBool( Z1_Parser*  parser )
-  {
-    return t1_tobool( &parser->cursor, parser->limit );
-  }
-
-#endif /* 0 */
-
-
-  static
   FT_Error  read_pfb_tag( FT_Stream   stream,
                           FT_UShort*  tag,
                           FT_Long*    size )
   {
     FT_Error  error;
+    PFB_Tag   head;
 
-
-    if ( READ_UShort( *tag ) )
-      goto Exit;
-
-    if ( *tag == 0x8001 || *tag == 0x8002 )
+    *tag  = 0;
+    *size = 0;
+    if ( !READ_Fields( pfb_tag_fields, &head ) )
     {
-      FT_Long  asize;
-
-
-      if ( READ_ULong( asize ) )
-        goto Exit;
-
-      /* swap between big and little endianness */
-      *size  = ( ( asize & 0xFF000000UL ) >> 24 ) |
-               ( ( asize & 0x00FF0000UL ) >> 8  ) |
-               ( ( asize & 0x0000FF00UL ) << 8  ) |
-               ( ( asize & 0x000000FFUL ) << 24 );
+      if ( head.tag == 0x8001 || head.tag == 0x8002 )
+      {
+        *tag  = head.tag;
+        *size = head.size;
+      }
     }
-
-  Exit:
     return error;
   }
 
 
   LOCAL_FUNC
-  FT_Error  Z1_New_Parser( Z1_Parser*  parser,
-                           FT_Stream   stream,
-                           FT_Memory   memory )
+  FT_Error  Z1_New_Parser( Z1_Parser*        parser,
+                           FT_Stream         stream,
+                           FT_Memory         memory,
+                           PSAux_Interface*  psaux )
   {
     FT_Error  error;
     FT_UShort tag;
     FT_Long   size;
 
+    psaux->t1_parser_funcs->init( &parser->root,0, 0, memory );
 
     parser->stream       = stream;
-    parser->memory       = memory;
     parser->base_len     = 0;
     parser->base_dict    = 0;
     parser->private_len  = 0;
@@ -1069,9 +145,6 @@
     parser->in_memory    = 0;
     parser->single_block = 0;
 
-    parser->cursor       = 0;
-    parser->limit        = 0;
-
     /******************************************************************/
     /*                                                                */
     /* Here a short summary of what is going on:                      */
@@ -1145,8 +218,9 @@
       }
       else
       {
-        parser->cursor = parser->base_dict;
-        parser->limit  = parser->cursor + parser->base_len;
+        parser->root.base   = parser->base_dict;
+        parser->root.cursor = parser->base_dict;
+        parser->root.limit  = parser->root.cursor + parser->base_len;
       }
     }
 
@@ -1161,7 +235,7 @@
   LOCAL_FUNC
   void  Z1_Done_Parser( Z1_Parser*  parser )
   {
-    FT_Memory   memory = parser->memory;
+    FT_Memory   memory = parser->root.memory;
 
 
     /* always free the private dictionary */
@@ -1170,6 +244,8 @@
     /* free the base dictionary only when we have a disk stream */
     if ( !parser->in_memory )
       FREE( parser->base_dict );
+      
+    parser->root.funcs.done( &parser->root );
   }
 
 
@@ -1218,7 +294,7 @@
   FT_Error  Z1_Get_Private_Dict( Z1_Parser*  parser )
   {
     FT_Stream  stream = parser->stream;
-    FT_Memory  memory = parser->memory;
+    FT_Memory  memory = parser->root.memory;
     FT_Error   error  = 0;
     FT_Long    size;
 
@@ -1395,8 +471,9 @@
 
     /* we now decrypt the encoded binary private dictionary */
     Z1_Decrypt( parser->private_dict, parser->private_len, 55665 );
-    parser->cursor = parser->private_dict;
-    parser->limit  = parser->cursor + parser->private_len;
+    parser->root.base = parser->private_dict;
+    parser->root.cursor = parser->private_dict;
+    parser->root.limit  = parser->root.cursor + parser->private_len;
 
   Fail:
   Exit:
--- a/src/type1z/z1parse.h
+++ b/src/type1z/z1parse.h
@@ -27,184 +27,9 @@
 #endif
 
 
-  /* simple enumeration type used to identify token types */
-  typedef enum  Z1_Token_Type_
-  {
-    z1_token_none = 0,
-    z1_token_any,
-    z1_token_string,
-    z1_token_array,
-
-    /* do not remove */
-    z1_token_max
-
-  } Z1_Token_Type;
-
-
-  /* a simple structure used to identify tokens */
-  typedef struct  Z1_Token_Rec_
-  {
-    FT_Byte*       start;   /* first character of token in input stream */
-    FT_Byte*       limit;   /* first character after the token          */
-    Z1_Token_Type  type;    /* type of token..                          */
-
-  } Z1_Token_Rec;
-
-
-  /* enumeration type used to identify object fields */
-  typedef enum  Z1_Field_Type_
-  {
-    z1_field_none = 0,
-    z1_field_bool,
-    z1_field_integer,
-    z1_field_fixed,
-    z1_field_string,
-    z1_field_integer_array,
-    z1_field_fixed_array,
-
-    /* do not remove */
-    z1_field_max
-
-  } Z1_Field_Type;
-
-
-  /* structure type used to model object fields */
-  typedef struct  Z1_Field_Rec_
-  {
-    Z1_Field_Type  type;          /* type of field                        */
-    FT_UInt        offset;        /* offset of field in object            */
-    FT_Byte        size;          /* size of field in bytes               */
-    FT_UInt        array_max;     /* maximum number of elements for array */
-    FT_UInt        count_offset;  /* offset of element count for arrays   */
-    FT_Int         flag_bit;      /* bit number for field flag            */
-
-  } Z1_Field_Rec;
-
-
-#define Z1_FIELD_BOOL( _fname )        \
-          {                            \
-            z1_field_bool,             \
-            FT_FIELD_OFFSET( _fname ), \
-            FT_FIELD_SIZE( _fname ),   \
-            0, 0, 0                    \
-          }
-
-#define Z1_FIELD_NUM( _fname )         \
-          {                            \
-            z1_field_integer,          \
-            FT_FIELD_OFFSET( _fname ), \
-            FT_FIELD_SIZE( _fname ),   \
-            0, 0, 0                    \
-          }
-
-#define Z1_FIELD_FIXED( _fname, _power ) \
-          {                              \
-            z1_field_fixed,              \
-            FT_FIELD_OFFSET( _fname ),   \
-            FT_FIELD_SIZE( _fname ),     \
-            0, 0, 0                      \
-          }
-
-#define Z1_FIELD_STRING( _fname )      \
-          {                            \
-            z1_field_string,           \
-            FT_FIELD_OFFSET( _fname ), \
-            FT_FIELD_SIZE( _fname ),   \
-            0, 0, 0                    \
-          }
-
-#define Z1_FIELD_NUM_ARRAY( _fname, _fcount, _fmax )  \
-          {                                           \
-            z1_field_integer,                         \
-            FT_FIELD_OFFSET( _fname ),                \
-            FT_FIELD_SIZE_DELTA( _fname ),            \
-            _fmax,                                    \
-            FT_FIELD_OFFSET( _fcount ),               \
-            0                                         \
-          }
-
-#define Z1_FIELD_FIXED_ARRAY( _fname, _fcount, _fmax ) \
-          {                                            \
-            z1_field_fixed,                            \
-            FT_FIELD_OFFSET( _fname ),                 \
-            FT_FIELD_SIZE_DELTA( _fname ),             \
-            _fmax,                                     \
-            FT_FIELD_OFFSET( _fcount ),                \
-            0                                          \
-          }
-
-#define Z1_FIELD_NUM_ARRAY2( _fname, _fmax ) \
-          {                                  \
-            z1_field_integer,                \
-            FT_FIELD_OFFSET( _fname ),       \
-            FT_FIELD_SIZE_DELTA( _fname ),   \
-            _fmax,                           \
-            0, 0                             \
-          }
-
-#define Z1_FIELD_FIXED_ARRAY2( _fname, _fmax ) \
-          {                                    \
-            z1_field_fixed,                    \
-            FT_FIELD_OFFSTE( _fname ),         \
-            FT_FIELD_SIZE_DELTA( _fname ),     \
-            _fmax,                             \
-            0, 0                               \
-          }
-
-
   /*************************************************************************/
   /*                                                                       */
   /* <Struct>                                                              */
-  /*    Z1_Table                                                           */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A Z1_Table is a simple object used to store an array of objects in */
-  /*    a single memory block.                                             */
-  /*                                                                       */
-  /* <Fields>                                                              */
-  /*    block     :: The address in memory of the growheap's block.  This  */
-  /*                 can change between two object adds, due to the use of */
-  /*                 reallocation.                                         */
-  /*                                                                       */
-  /*    cursor    :: The current top of the grow heap within its block.    */
-  /*                                                                       */
-  /*    capacity  :: The current size of the heap block.  Increments in    */
-  /*                 1kByte blocks.                                        */
-  /*                                                                       */
-  /*    init      :: A boolean.  Set when the table has been initialized   */
-  /*                 (the table user should set this field).               */
-  /*                                                                       */
-  /*    max_elems :: The maximum number of elements in the table.          */
-  /*                                                                       */
-  /*    num_elems :: The current number of elements in the table.          */
-  /*                                                                       */
-  /*    elements  :: A table of element addresses within the block.        */
-  /*                                                                       */
-  /*    lengths   :: A table of element sizes within the block.            */
-  /*                                                                       */
-  /*    memory    :: The memory object used for memory operations          */
-  /*                 (allocation/reallocation).                            */
-  /*                                                                       */
-  typedef struct  Z1_Table_
-  {
-    FT_Byte*   block;          /* current memory block           */
-    FT_Int     cursor;         /* current cursor in memory block */
-    FT_Int     capacity;       /* current size of memory block   */
-    FT_Long    init;
-
-    FT_Int     max_elems;
-    FT_Int     num_elems;
-    FT_Byte**  elements;       /* addresses of table elements */
-    FT_Int*    lengths;        /* lengths of table elements   */
-
-    FT_Memory  memory;
-
-  } Z1_Table;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Struct>                                                              */
   /*    Z1_Parser                                                          */
   /*                                                                       */
   /* <Description>                                                         */
@@ -241,8 +66,8 @@
   /*                                                                       */
   typedef struct  Z1_Parser_
   {
+    T1_Parser  root;
     FT_Stream  stream;
-    FT_Memory  memory;
 
     FT_Byte*   base_dict;
     FT_Int     base_len;
@@ -254,92 +79,33 @@
     FT_Byte    in_memory;
     FT_Byte    single_block;
 
-    FT_Byte*   cursor;
-    FT_Byte*   limit;
-    FT_Error   error;
-
   } Z1_Parser;
 
 
-  LOCAL_DEF
-  FT_Error  Z1_New_Table( Z1_Table*  table,
-                          FT_Int     count,
-                          FT_Memory  memory );
+#define Z1_Add_Table(p,i,o,l)     (p)->funcs.add( (p), i, o, l )
+#define Z1_Done_Table(p)          do { if ((p)->funcs.done) (p)->funcs.done( p ); } while (0)
+#define Z1_Release_Table(p)       do { if ((p)->funcs.release) (p)->funcs.release( p ); } while (0)
 
 
-  LOCAL_DEF
-  FT_Error  Z1_Add_Table( Z1_Table*  table,
-                          FT_Int     index,
-                          void*      object,
-                          FT_Int     length );
+#define Z1_Skip_Spaces(p)   (p)->root.funcs.skip_spaces( &(p)->root )
+#define Z1_Skip_Alpha(p)    (p)->root.funcs.skip_alpha ( &(p)->root )
 
-#if 0
-  LOCAL_DEF
-  void  Z1_Done_Table( Z1_Table*  table );
-#endif
+#define Z1_ToInt(p)        (p)->root.funcs.to_int( &(p)->root )
+#define Z1_ToFixed(p,t)    (p)->root.funcs.to_fixed( &(p)->root, t )
 
-  LOCAL_DEF
-  void  Z1_Release_Table( Z1_Table*  table );
+#define Z1_ToCoordArray(p,m,c)     (p)->root.funcs.to_coord_array( &(p)->root, m, c )
+#define Z1_ToFixedArray(p,m,f,t)   (p)->root.funcs.to_fixed_array( &(p)->root, m, f, t )
+#define Z1_ToToken(p,t)            (p)->root.funcs.to_token( &(p)->root, t )
+#define Z1_ToTokenArray(p,t,m,c)   (p)->root.funcs.to_token_array( &(p)->root, t, m, c )
 
-  LOCAL_DEF
-  FT_Long  Z1_ToInt( Z1_Parser*  parser );
+#define Z1_Load_Field(p,f,o,m,pf)        (p)->root.funcs.load_field( &(p)->root, f, o, m, pf )
+#define Z1_Load_Field_Table(p,f,o,m,pf)  (p)->root.funcs.load_field_table( &(p)->root, f, o, m, pf )
 
   LOCAL_DEF
-  FT_Long  Z1_ToFixed( Z1_Parser*  parser,
-                       FT_Int      power_ten );
-
-  LOCAL_DEF
-  FT_Int  Z1_ToCoordArray( Z1_Parser*  parser,
-                           FT_Int      max_coords,
-                           FT_Short*   coords );
-
-  LOCAL_DEF
-  FT_Int  Z1_ToFixedArray( Z1_Parser*  parser,
-                           FT_Int      max_values,
-                           FT_Fixed*   values,
-                           FT_Int      power_ten );
-
-#if 0
-  LOCAL_DEF
-  FT_String*  Z1_ToString( Z1_Parser*  parser );
-
-  LOCAL_DEF
-  FT_Bool  Z1_ToBool( Z1_Parser*  parser );
-#endif
-
-
-  LOCAL_DEF
-  void  Z1_Skip_Spaces( Z1_Parser*  parser );
-
-  LOCAL_DEF
-  void  Z1_ToToken( Z1_Parser*     parser,
-                    Z1_Token_Rec*  token );
-
-  LOCAL_FUNC
-  void  Z1_ToTokenArray( Z1_Parser*     parser,
-                         Z1_Token_Rec*  tokens,
-                         FT_UInt        max_tokens,
-                         FT_Int*        pnum_tokens );
-
-  LOCAL_DEF
-  FT_Error  Z1_Load_Field( Z1_Parser*           parser,
-                           const Z1_Field_Rec*  field,
-                           void**               objects,
-                           FT_UInt              max_objects,
-                           FT_ULong*            pflags );
-
-  LOCAL_DEF
-  FT_Error  Z1_Load_Field_Table( Z1_Parser*           parser,
-                                 const Z1_Field_Rec*  field,
-                                 void**               objects,
-                                 FT_UInt              max_objects,
-                                 FT_ULong*            pflags );
-
-
-  LOCAL_DEF
-  FT_Error  Z1_New_Parser( Z1_Parser*  parser,
-                           FT_Stream   stream,
-                           FT_Memory   memory );
+  FT_Error  Z1_New_Parser( Z1_Parser*        parser,
+                           FT_Stream         stream,
+                           FT_Memory         memory,
+                           PSAux_Interface*  psaux );
 
   LOCAL_DEF
   FT_Error  Z1_Get_Private_Dict( Z1_Parser*  parser );